diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2013-03-14 05:42:27 +0000 |
---|---|---|
committer | <> | 2013-04-03 16:25:08 +0000 |
commit | c4dd7a1a684490673e25aaf4fabec5df138854c4 (patch) | |
tree | 4d57c44caae4480efff02b90b9be86f44bf25409 /ext/mysqli | |
download | php2-master.tar.gz |
Imported from /home/lorry/working-area/delta_php2/php-5.4.13.tar.bz2.HEADphp-5.4.13master
Diffstat (limited to 'ext/mysqli')
417 files changed, 48138 insertions, 0 deletions
diff --git a/ext/mysqli/CREDITS b/ext/mysqli/CREDITS new file mode 100644 index 0000000..a3f4161 --- /dev/null +++ b/ext/mysqli/CREDITS @@ -0,0 +1,2 @@ +MySQLi +Zak Greant, Georg Richter, Andrey Hristov, Ulf Wendel diff --git a/ext/mysqli/TODO b/ext/mysqli/TODO new file mode 100644 index 0000000..c241b9b --- /dev/null +++ b/ext/mysqli/TODO @@ -0,0 +1,2 @@ +- documentation +- ini-settings diff --git a/ext/mysqli/config.m4 b/ext/mysqli/config.m4 new file mode 100644 index 0000000..687b422 --- /dev/null +++ b/ext/mysqli/config.m4 @@ -0,0 +1,88 @@ +dnl +dnl $Id$ +dnl config.m4 for extension mysqli + +PHP_ARG_WITH(mysqli, for MySQLi support, +[ --with-mysqli[=FILE] Include MySQLi support. FILE is the path + to mysql_config. If no value or mysqlnd is passed + as FILE, the MySQL native driver will be used]) + +PHP_ARG_ENABLE(embedded_mysqli, whether to enable embedded MySQLi support, +[ --enable-embedded-mysqli MYSQLi: Enable embedded support + Note: Does not work with MySQL native driver!], no, no) + +if test "$PHP_MYSQLI" = "yes" || test "$PHP_MYSQLI" = "mysqlnd"; then + dnl This needs to be set in any extension which wishes to use mysqlnd + PHP_MYSQLND_ENABLED=yes + +elif test "$PHP_MYSQLI" != "no"; then + + MYSQL_CONFIG=$PHP_MYSQLI + + MYSQL_LIB_NAME='mysqlclient' + if test "$PHP_EMBEDDED_MYSQLI" = "yes"; then + AC_DEFINE(HAVE_EMBEDDED_MYSQLI, 1, [embedded MySQL support enabled]) + MYSQL_LIB_CFG='--libmysqld-libs' + dnl mysqlnd doesn't support embedded, so we have to add some extra stuff + mysqli_extra_sources="mysqli_embedded.c" + elif test "$enable_maintainer_zts" = "yes"; then + MYSQL_LIB_CFG='--libs_r' + MYSQL_LIB_NAME='mysqlclient_r' + else + MYSQL_LIB_CFG='--libs' + fi + + if test -x "$MYSQL_CONFIG" && $MYSQL_CONFIG $MYSQL_LIB_CFG > /dev/null 2>&1; then + MYSQLI_INCLINE=`$MYSQL_CONFIG --cflags | $SED -e "s/'//g"` + MYSQLI_LIBLINE=`$MYSQL_CONFIG $MYSQL_LIB_CFG | $SED -e "s/'//g"` + else + AC_MSG_RESULT([mysql_config not found]) + AC_MSG_ERROR([Please reinstall the mysql distribution]) + fi + + dnl + dnl Check the library + dnl + PHP_CHECK_LIBRARY($MYSQL_LIB_NAME, mysql_set_server_option, + [ + PHP_EVAL_INCLINE($MYSQLI_INCLINE) + PHP_EVAL_LIBLINE($MYSQLI_LIBLINE, MYSQLI_SHARED_LIBADD) + AC_DEFINE(HAVE_MYSQLILIB, 1, [ ]) + PHP_CHECK_LIBRARY($MYSQL_LIB_NAME, mysql_set_character_set, + [ ],[ + AC_MSG_ERROR([MySQLI doesn't support versions < 4.1.13 (for MySQL 4.1.x) and < 5.0.7 for (MySQL 5.0.x) anymore. Please update your libraries.]) + ],[$MYSQLI_LIBLINE]) + ],[ + AC_MSG_ERROR([wrong mysql library version or lib not found. Check config.log for more information.]) + ],[ + $MYSQLI_LIBLINE + ]) + dnl + dnl Check the library for mysql_stmt_next_result + dnl + PHP_CHECK_LIBRARY($MYSQL_LIB_NAME, mysql_stmt_next_result, + [ + AC_DEFINE(HAVE_STMT_NEXT_RESULT, 1, [ ]) + ],[ + ],[ + $MYSQLI_LIBLINE + ]) +fi + +dnl Build extension +if test "$PHP_MYSQLI" != "no"; then + mysqli_sources="mysqli.c mysqli_api.c mysqli_prop.c mysqli_nonapi.c \ + mysqli_fe.c mysqli_report.c mysqli_driver.c mysqli_warning.c \ + mysqli_exception.c mysqli_result_iterator.c $mysqli_extra_sources" + PHP_NEW_EXTENSION(mysqli, $mysqli_sources, $ext_shared) + PHP_SUBST(MYSQLI_SHARED_LIBADD) + PHP_INSTALL_HEADERS([ext/mysqli/php_mysqli_structs.h]) + + if test "$PHP_MYSQLI" = "yes" || test "$PHP_MYSQLI" = "mysqlnd"; then + PHP_ADD_EXTENSION_DEP(mysqli, mysqlnd) + AC_DEFINE([MYSQLI_USE_MYSQLND], 1, [Whether mysqlnd is enabled]) + PHP_INSTALL_HEADERS([ext/mysqli/mysqli_mysqlnd.h]) + else + PHP_INSTALL_HEADERS([ext/mysqli/mysqli_libmysql.h]) + fi +fi diff --git a/ext/mysqli/config.w32 b/ext/mysqli/config.w32 new file mode 100644 index 0000000..ab8bcd0 --- /dev/null +++ b/ext/mysqli/config.w32 @@ -0,0 +1,46 @@ +// $Id$ +// vim:ft=javascript + +// Note: The extension name is "mysqli", you enable it with "--with-mysqli". +// Passing value "mysqlnd" to it enables the bundled +// client library to connect to the MySQL server, i.e. no external MySQL +// client library is needed to perform the build. + +ARG_WITH("mysqli", "MySQLi support", "no"); + +if (PHP_MYSQLI != "no") { + mysqli_source = + "mysqli.c " + + "mysqli_api.c " + + "mysqli_driver.c " + + "mysqli_embedded.c " + + "mysqli_exception.c " + + "mysqli_fe.c " + + "mysqli_nonapi.c " + + "mysqli_prop.c " + + "mysqli_result_iterator.c " + + "mysqli_report.c " + + "mysqli_warning.c"; + + if (PHP_MYSQLI == "yes" || PHP_MYSQLI == "mysqlnd") { + EXTENSION("mysqli", mysqli_source); + AC_DEFINE('MYSQLI_USE_MYSQLND', 1, 'Using MySQL native driver'); + AC_DEFINE('HAVE_MYSQLILIB', 1, 'Have MySQLi library'); + ADD_EXTENSION_DEP('mysqli', 'mysqlnd', true); + MESSAGE("\tmysqlnd build"); + PHP_INSTALL_HEADERS("ext/mysqli", "php_mysqli_structs.h"); + } else { + if (CHECK_LIB("libmysql.lib", "mysqli", PHP_MYSQLI) && + CHECK_HEADER_ADD_INCLUDE("mysql.h", "CFLAGS_MYSQLI", PHP_MYSQLI + + "\\include;" + PHP_PHP_BUILD + + "\\include\\mysql;" + PHP_MYSQLI)) { + EXTENSION("mysqli", mysqli_source); + AC_DEFINE('HAVE_MYSQLILIB', 1, 'Have MySQLi library'); + MESSAGE("\tlibmysql build"); + PHP_INSTALL_HEADERS("ext/mysqli", "php_mysqli_structs.h"); + } else { + WARNING("mysqli not enabled; libraries and headers not found"); + PHP_MYSQLI = "no" + } + } +} diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c new file mode 100644 index 0000000..a4c1b87 --- /dev/null +++ b/ext/mysqli/mysqli.c @@ -0,0 +1,1546 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Georg Richter <georg@php.net> | + | Andrey Hristov <andrey@php.net> | + | Ulf Wendel <uw@php.net> | + +----------------------------------------------------------------------+ + + $Id$ +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <signal.h> + +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +#include "ext/standard/php_string.h" +#include "php_mysqli.h" +#include "php_mysqli_structs.h" +#include "mysqli_priv.h" +#include "zend_exceptions.h" +#include "zend_interfaces.h" + +ZEND_DECLARE_MODULE_GLOBALS(mysqli) +static PHP_GINIT_FUNCTION(mysqli); + +#define MYSQLI_ADD_PROPERTIES(a,b) \ +{ \ + int i = 0; \ + while (b[i].pname != NULL) { \ + mysqli_add_property((a), (b)[i].pname, (b)[i].pname_length, \ + (mysqli_read_t)(b)[i].r_func, (mysqli_write_t)(b)[i].w_func TSRMLS_CC); \ + i++; \ + }\ +} + +#define MYSQLI_ADD_PROPERTIES_INFO(a,b) \ +{ \ + int i = 0; \ + while (b[i].name != NULL) { \ + zend_declare_property_null((a), (b)[i].name, (b)[i].name_length, ZEND_ACC_PUBLIC TSRMLS_CC); \ + i++; \ + }\ +} + + + +static zend_object_handlers mysqli_object_handlers; +static HashTable classes; +static HashTable mysqli_driver_properties; +static HashTable mysqli_link_properties; +static HashTable mysqli_result_properties; +static HashTable mysqli_stmt_properties; +static HashTable mysqli_warning_properties; + +zend_class_entry *mysqli_link_class_entry; +zend_class_entry *mysqli_stmt_class_entry; +zend_class_entry *mysqli_result_class_entry; +zend_class_entry *mysqli_driver_class_entry; +zend_class_entry *mysqli_warning_class_entry; +zend_class_entry *mysqli_exception_class_entry; + + +typedef int (*mysqli_read_t)(mysqli_object *obj, zval **retval TSRMLS_DC); +typedef int (*mysqli_write_t)(mysqli_object *obj, zval *newval TSRMLS_DC); + +typedef struct _mysqli_prop_handler { + char *name; + size_t name_len; + mysqli_read_t read_func; + mysqli_write_t write_func; +} mysqli_prop_handler; + +static int le_pmysqli; + + +/* Destructor for mysqli entries in free_links/used_links */ +void php_mysqli_dtor_p_elements(void *data) +{ + MYSQL *mysql = (MYSQL *) data; + TSRMLS_FETCH(); + mysqli_close(mysql, MYSQLI_CLOSE_IMPLICIT); +} + + +ZEND_RSRC_DTOR_FUNC(php_mysqli_dtor) +{ + if (rsrc->ptr) { + mysqli_plist_entry *plist = (mysqli_plist_entry *) rsrc->ptr; + zend_ptr_stack_clean(&plist->free_links, php_mysqli_dtor_p_elements, 0); + zend_ptr_stack_destroy(&plist->free_links); + free(plist); + } +} + + +int php_le_pmysqli(void) +{ + return le_pmysqli; +} + +#ifndef MYSQLI_USE_MYSQLND +/* {{{ php_free_stmt_bind_buffer */ +void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type) +{ + unsigned int i; + + if (!bbuf.var_cnt) { + return; + } + + for (i=0; i < bbuf.var_cnt; i++) { + + /* free temporary bind buffer */ + if (type == FETCH_RESULT && bbuf.buf[i].val) { + efree(bbuf.buf[i].val); + } + + if (bbuf.vars[i]) { + zval_ptr_dtor(&bbuf.vars[i]); + } + } + + if (bbuf.vars) { + efree(bbuf.vars); + } + + /* + Don't free bbuf.is_null for FETCH_RESULT since we have allocated + is_null and buf in one block so we free only buf, which is the beginning + of the block. When FETCH_SIMPLE then buf wasn't allocated together with + buf and we have to free it. + */ + if (type == FETCH_RESULT) { + efree(bbuf.buf); + } else if (type == FETCH_SIMPLE){ + efree(bbuf.is_null); + } + + bbuf.var_cnt = 0; +} +/* }}} */ +#endif + +/* {{{ php_clear_stmt_bind */ +void php_clear_stmt_bind(MY_STMT *stmt TSRMLS_DC) +{ + if (stmt->stmt) { + if (mysqli_stmt_close(stmt->stmt, TRUE)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error occurred while closing statement"); + return; + } + } + + /* + mysqlnd keeps track of the binding and has freed its + structures in stmt_close() above + */ +#ifndef MYSQLI_USE_MYSQLND + /* Clean param bind */ + php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE); + /* Clean output bind */ + php_free_stmt_bind_buffer(stmt->result, FETCH_RESULT); +#endif + + if (stmt->query) { + efree(stmt->query); + } + efree(stmt); +} +/* }}} */ + +/* {{{ php_clear_mysql */ +void php_clear_mysql(MY_MYSQL *mysql) { + if (mysql->hash_key) { + efree(mysql->hash_key); + mysql->hash_key = NULL; + } + if (mysql->li_read) { + zval_ptr_dtor(&(mysql->li_read)); + mysql->li_read = NULL; + } +} +/* }}} */ + +/* {{{ mysqli_objects_free_storage + */ +static void mysqli_objects_free_storage(void *object TSRMLS_DC) +{ + zend_object *zo = (zend_object *)object; + mysqli_object *intern = (mysqli_object *)zo; + MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr; + + my_efree(my_res); + zend_object_std_dtor(&intern->zo TSRMLS_CC); + efree(intern); +} +/* }}} */ + +/* mysqli_link_free_storage partly doubles the work of PHP_FUNCTION(mysqli_close) */ + +/* {{{ mysqli_link_free_storage + */ +static void mysqli_link_free_storage(void *object TSRMLS_DC) +{ + zend_object *zo = (zend_object *)object; + mysqli_object *intern = (mysqli_object *)zo; + MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr; + + if (my_res && my_res->ptr) { + MY_MYSQL *mysql = (MY_MYSQL *)my_res->ptr; + if (mysql->mysql) { + php_mysqli_close(mysql, MYSQLI_CLOSE_EXPLICIT, my_res->status TSRMLS_CC); + } + php_clear_mysql(mysql); + efree(mysql); + my_res->status = MYSQLI_STATUS_UNKNOWN; + } + mysqli_objects_free_storage(object TSRMLS_CC); +} +/* }}} */ + +/* {{{ mysql_driver_free_storage */ +static void mysqli_driver_free_storage(void *object TSRMLS_DC) +{ + mysqli_objects_free_storage(object TSRMLS_CC); +} +/* }}} */ + +/* {{{ mysqli_stmt_free_storage + */ +static void mysqli_stmt_free_storage(void *object TSRMLS_DC) +{ + zend_object *zo = (zend_object *)object; + mysqli_object *intern = (mysqli_object *)zo; + MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr; + + if (my_res && my_res->ptr) { + MY_STMT *stmt = (MY_STMT *)my_res->ptr; + php_clear_stmt_bind(stmt TSRMLS_CC); + } + mysqli_objects_free_storage(object TSRMLS_CC); +} +/* }}} */ + +/* {{{ mysqli_result_free_storage + */ +static void mysqli_result_free_storage(void *object TSRMLS_DC) +{ + zend_object *zo = (zend_object *)object; + mysqli_object *intern = (mysqli_object *)zo; + MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr; + + if (my_res && my_res->ptr) { + mysql_free_result(my_res->ptr); + } + mysqli_objects_free_storage(object TSRMLS_CC); +} +/* }}} */ + +/* {{{ mysqli_warning_free_storage + */ +static void mysqli_warning_free_storage(void *object TSRMLS_DC) +{ + zend_object *zo = (zend_object *)object; + mysqli_object *intern = (mysqli_object *)zo; + MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr; + + if (my_res && my_res->ptr) { + php_clear_warnings((MYSQLI_WARNING *)my_res->info); + my_res->ptr = NULL; + } + mysqli_objects_free_storage(object TSRMLS_CC); +} +/* }}} */ + +/* {{{ mysqli_read_na */ +static int mysqli_read_na(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + *retval = NULL; + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot read property"); + return FAILURE; +} +/* }}} */ + +/* {{{ mysqli_write_na */ +static int mysqli_write_na(mysqli_object *obj, zval *newval TSRMLS_DC) +{ + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot write property"); + return FAILURE; +} +/* }}} */ + +#ifndef Z_ADDREF_P +/* PHP 5.2, old GC */ +#define Z_ADDREF_P(pz) (++(pz)->refcount) +#define Z_REFCOUNT_P(pz) ((pz)->refcount) +#define Z_SET_REFCOUNT_P(pz, rc) ((pz)->refcount = rc) +#endif + + +/* {{{ mysqli_read_property */ +zval *mysqli_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) +{ + zval tmp_member; + zval *retval; + mysqli_object *obj; + mysqli_prop_handler *hnd; + int ret; + + ret = FAILURE; + obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC); + + if (member->type != IS_STRING) { + tmp_member = *member; + zval_copy_ctor(&tmp_member); + convert_to_string(&tmp_member); + member = &tmp_member; + } + + if (obj->prop_handler != NULL) { + ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); + } + + if (ret == SUCCESS) { + ret = hnd->read_func(obj, &retval TSRMLS_CC); + if (ret == SUCCESS) { + /* ensure we're creating a temporary variable */ + Z_SET_REFCOUNT_P(retval, 0); + } else { + retval = EG(uninitialized_zval_ptr); + } + } else { + zend_object_handlers * std_hnd = zend_get_std_object_handlers(); + retval = std_hnd->read_property(object, member, type, key TSRMLS_CC); + } + + if (member == &tmp_member) { + zval_dtor(member); + } + return(retval); +} +/* }}} */ + +/* {{{ mysqli_write_property */ +void mysqli_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) +{ + zval tmp_member; + mysqli_object *obj; + mysqli_prop_handler *hnd; + int ret; + + if (member->type != IS_STRING) { + tmp_member = *member; + zval_copy_ctor(&tmp_member); + convert_to_string(&tmp_member); + member = &tmp_member; + } + + ret = FAILURE; + obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC); + + if (obj->prop_handler != NULL) { + ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); + } + if (ret == SUCCESS) { + hnd->write_func(obj, value TSRMLS_CC); + if (! PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) == 0) { + Z_ADDREF_P(value); + zval_ptr_dtor(&value); + } + } else { + zend_object_handlers * std_hnd = zend_get_std_object_handlers(); + std_hnd->write_property(object, member, value, key TSRMLS_CC); + } + + if (member == &tmp_member) { + zval_dtor(member); + } +} +/* }}} */ + +/* {{{ void mysqli_add_property(HashTable *h, char *pname, mysqli_read_t r_func, mysqli_write_t w_func TSRMLS_DC) */ +void mysqli_add_property(HashTable *h, const char *pname, size_t pname_len, mysqli_read_t r_func, mysqli_write_t w_func TSRMLS_DC) { + mysqli_prop_handler p; + + p.name = (char*) pname; + p.name_len = pname_len; + p.read_func = (r_func) ? r_func : mysqli_read_na; + p.write_func = (w_func) ? w_func : mysqli_write_na; + zend_hash_add(h, pname, pname_len + 1, &p, sizeof(mysqli_prop_handler), NULL); +} +/* }}} */ + +static int mysqli_object_has_property(zval *object, zval *member, int has_set_exists, const zend_literal *key TSRMLS_DC) /* {{{ */ +{ + mysqli_object *obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC); + mysqli_prop_handler p; + int ret = 0; + + if (zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member) + 1, (void **)&p) == SUCCESS) { + switch (has_set_exists) { + case 2: + ret = 1; + break; + case 1: { + zval *value = mysqli_read_property(object, member, BP_VAR_IS, key TSRMLS_CC); + if (value != EG(uninitialized_zval_ptr)) { + convert_to_boolean(value); + ret = Z_BVAL_P(value)? 1:0; + /* refcount is 0 */ + Z_ADDREF_P(value); + zval_ptr_dtor(&value); + } + break; + } + case 0:{ + zval *value = mysqli_read_property(object, member, BP_VAR_IS, key TSRMLS_CC); + if (value != EG(uninitialized_zval_ptr)) { + ret = Z_TYPE_P(value) != IS_NULL? 1:0; + /* refcount is 0 */ + Z_ADDREF_P(value); + zval_ptr_dtor(&value); + } + break; + } + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for has_set_exists"); + } + } else { + zend_object_handlers * std_hnd = zend_get_std_object_handlers(); + ret = std_hnd->has_property(object, member, has_set_exists, key TSRMLS_CC); + } + return ret; +} /* }}} */ + + +#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3 +HashTable * mysqli_object_get_debug_info(zval *object, int *is_temp TSRMLS_DC) +{ + mysqli_object *obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC); + HashTable *retval, *props = obj->prop_handler; + HashPosition pos; + mysqli_prop_handler *entry; + + ALLOC_HASHTABLE(retval); + ZEND_INIT_SYMTABLE_EX(retval, zend_hash_num_elements(props) + 1, 0); + + zend_hash_internal_pointer_reset_ex(props, &pos); + while (zend_hash_get_current_data_ex(props, (void **)&entry, &pos) == SUCCESS) { + zval member; + zval *value; + INIT_ZVAL(member); + ZVAL_STRINGL(&member, entry->name, entry->name_len, 0); + value = mysqli_read_property(object, &member, BP_VAR_IS, 0 TSRMLS_CC); + if (value != EG(uninitialized_zval_ptr)) { + Z_ADDREF_P(value); + zend_hash_add(retval, entry->name, entry->name_len + 1, &value, sizeof(zval *), NULL); + } + zend_hash_move_forward_ex(props, &pos); + } + + *is_temp = 1; + return retval; +} +#endif + +/* {{{ mysqli_objects_new + */ +PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_type TSRMLS_DC) +{ + zend_object_value retval; + mysqli_object *intern; + zend_class_entry *mysqli_base_class; + zend_objects_free_object_storage_t free_storage; + + intern = emalloc(sizeof(mysqli_object)); + memset(intern, 0, sizeof(mysqli_object)); + intern->ptr = NULL; + intern->prop_handler = NULL; + + mysqli_base_class = class_type; + while (mysqli_base_class->type != ZEND_INTERNAL_CLASS && + mysqli_base_class->parent != NULL) { + mysqli_base_class = mysqli_base_class->parent; + } + zend_hash_find(&classes, mysqli_base_class->name, mysqli_base_class->name_length + 1, + (void **) &intern->prop_handler); + + zend_object_std_init(&intern->zo, class_type TSRMLS_CC); + object_properties_init(&intern->zo, class_type); + + /* link object */ + if (instanceof_function(class_type, mysqli_link_class_entry TSRMLS_CC)) { + free_storage = mysqli_link_free_storage; + } else if (instanceof_function(class_type, mysqli_driver_class_entry TSRMLS_CC)) { /* driver object */ + free_storage = mysqli_driver_free_storage; + } else if (instanceof_function(class_type, mysqli_stmt_class_entry TSRMLS_CC)) { /* stmt object */ + free_storage = mysqli_stmt_free_storage; + } else if (instanceof_function(class_type, mysqli_result_class_entry TSRMLS_CC)) { /* result object */ + free_storage = mysqli_result_free_storage; + } else if (instanceof_function(class_type, mysqli_warning_class_entry TSRMLS_CC)) { /* warning object */ + free_storage = mysqli_warning_free_storage; + } else { + free_storage = mysqli_objects_free_storage; + } + + retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, free_storage, NULL TSRMLS_CC); + retval.handlers = &mysqli_object_handlers; + + return retval; +} +/* }}} */ + +#ifdef MYSQLI_USE_MYSQLND +#include "ext/mysqlnd/mysqlnd_reverse_api.h" +static MYSQLND *mysqli_convert_zv_to_mysqlnd(zval * zv TSRMLS_DC) +{ + if (Z_TYPE_P(zv) == IS_OBJECT && Z_OBJCE_P(zv) == mysqli_link_class_entry) { + MY_MYSQL * mysql; + MYSQLI_RESOURCE * my_res; + mysqli_object * intern = (mysqli_object *)zend_object_store_get_object(zv TSRMLS_CC); + if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) { + /* We know that we have a mysqli object, so this failure should be emitted */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", intern->zo.ce->name); + return NULL; + } + mysql = (MY_MYSQL *)(my_res->ptr); + return mysql ? mysql->mysql : NULL; + } + return NULL; +} + +static MYSQLND_REVERSE_API mysqli_reverse_api = { + &mysqli_module_entry, + mysqli_convert_zv_to_mysqlnd +}; +#endif + +/* {{{ PHP_INI_BEGIN +*/ +PHP_INI_BEGIN() + STD_PHP_INI_ENTRY_EX("mysqli.max_links", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_links, zend_mysqli_globals, mysqli_globals, display_link_numbers) + STD_PHP_INI_ENTRY_EX("mysqli.max_persistent", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_persistent, zend_mysqli_globals, mysqli_globals, display_link_numbers) + STD_PHP_INI_BOOLEAN("mysqli.allow_persistent", "1", PHP_INI_SYSTEM, OnUpdateLong, allow_persistent, zend_mysqli_globals, mysqli_globals) + STD_PHP_INI_ENTRY("mysqli.default_host", NULL, PHP_INI_ALL, OnUpdateString, default_host, zend_mysqli_globals, mysqli_globals) + STD_PHP_INI_ENTRY("mysqli.default_user", NULL, PHP_INI_ALL, OnUpdateString, default_user, zend_mysqli_globals, mysqli_globals) + STD_PHP_INI_ENTRY("mysqli.default_pw", NULL, PHP_INI_ALL, OnUpdateString, default_pw, zend_mysqli_globals, mysqli_globals) + STD_PHP_INI_ENTRY("mysqli.default_port", "3306", PHP_INI_ALL, OnUpdateLong, default_port, zend_mysqli_globals, mysqli_globals) +#ifdef PHP_MYSQL_UNIX_SOCK_ADDR + STD_PHP_INI_ENTRY("mysqli.default_socket", MYSQL_UNIX_ADDR,PHP_INI_ALL,OnUpdateStringUnempty, default_socket, zend_mysqli_globals, mysqli_globals) +#else + STD_PHP_INI_ENTRY("mysqli.default_socket", NULL, PHP_INI_ALL, OnUpdateStringUnempty, default_socket, zend_mysqli_globals, mysqli_globals) +#endif + STD_PHP_INI_BOOLEAN("mysqli.reconnect", "0", PHP_INI_SYSTEM, OnUpdateLong, reconnect, zend_mysqli_globals, mysqli_globals) + STD_PHP_INI_BOOLEAN("mysqli.allow_local_infile", "1", PHP_INI_SYSTEM, OnUpdateLong, allow_local_infile, zend_mysqli_globals, mysqli_globals) +PHP_INI_END() +/* }}} */ + + +/* {{{ PHP_GINIT_FUNCTION + */ +static PHP_GINIT_FUNCTION(mysqli) +{ + mysqli_globals->num_links = 0; + mysqli_globals->num_active_persistent = 0; + mysqli_globals->num_inactive_persistent = 0; + mysqli_globals->max_links = -1; + mysqli_globals->max_persistent = -1; + mysqli_globals->allow_persistent = 1; + mysqli_globals->default_port = 0; + mysqli_globals->default_host = NULL; + mysqli_globals->default_user = NULL; + mysqli_globals->default_pw = NULL; + mysqli_globals->default_socket = NULL; + mysqli_globals->reconnect = 0; + mysqli_globals->report_mode = 0; + mysqli_globals->report_ht = 0; + mysqli_globals->allow_local_infile = 1; +#ifdef HAVE_EMBEDDED_MYSQLI + mysqli_globals->embedded = 1; +#else + mysqli_globals->embedded = 0; +#endif +} +/* }}} */ + +/* {{{ PHP_MINIT_FUNCTION + */ +PHP_MINIT_FUNCTION(mysqli) +{ + zend_class_entry *ce,cex; + zend_object_handlers *std_hnd = zend_get_std_object_handlers(); + + REGISTER_INI_ENTRIES(); +#ifndef MYSQLI_USE_MYSQLND +#if MYSQL_VERSION_ID >= 40000 + if (mysql_server_init(0, NULL, NULL)) { + return FAILURE; + } +#endif +#endif + + memcpy(&mysqli_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + mysqli_object_handlers.clone_obj = NULL; + mysqli_object_handlers.read_property = mysqli_read_property; + mysqli_object_handlers.write_property = mysqli_write_property; + mysqli_object_handlers.get_property_ptr_ptr = std_hnd->get_property_ptr_ptr; + mysqli_object_handlers.has_property = mysqli_object_has_property; +#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3 + mysqli_object_handlers.get_debug_info = mysqli_object_get_debug_info; +#endif + + zend_hash_init(&classes, 0, NULL, NULL, 1); + + /* persistent connections */ + le_pmysqli = zend_register_list_destructors_ex(NULL, php_mysqli_dtor, + "MySqli persistent connection", module_number); + + INIT_CLASS_ENTRY(cex, "mysqli_sql_exception", mysqli_exception_methods); +#ifdef HAVE_SPL + mysqli_exception_class_entry = zend_register_internal_class_ex(&cex, spl_ce_RuntimeException, NULL TSRMLS_CC); +#else + mysqli_exception_class_entry = zend_register_internal_class_ex(&cex, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC); +#endif + mysqli_exception_class_entry->ce_flags |= ZEND_ACC_FINAL; + zend_declare_property_long(mysqli_exception_class_entry, "code", sizeof("code")-1, 0, ZEND_ACC_PROTECTED TSRMLS_CC); + zend_declare_property_string(mysqli_exception_class_entry, "sqlstate", sizeof("sqlstate")-1, "00000", ZEND_ACC_PROTECTED TSRMLS_CC); + + REGISTER_MYSQLI_CLASS_ENTRY("mysqli_driver", mysqli_driver_class_entry, mysqli_driver_methods); + ce = mysqli_driver_class_entry; + zend_hash_init(&mysqli_driver_properties, 0, NULL, NULL, 1); + MYSQLI_ADD_PROPERTIES(&mysqli_driver_properties, mysqli_driver_property_entries); + MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_driver_property_info_entries); + zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_driver_properties, sizeof(mysqli_driver_properties), NULL); + ce->ce_flags |= ZEND_ACC_FINAL_CLASS; + + REGISTER_MYSQLI_CLASS_ENTRY("mysqli", mysqli_link_class_entry, mysqli_link_methods); + ce = mysqli_link_class_entry; + zend_hash_init(&mysqli_link_properties, 0, NULL, NULL, 1); + MYSQLI_ADD_PROPERTIES(&mysqli_link_properties, mysqli_link_property_entries); + MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_link_property_info_entries); + zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_link_properties, sizeof(mysqli_link_properties), NULL); + + REGISTER_MYSQLI_CLASS_ENTRY("mysqli_warning", mysqli_warning_class_entry, mysqli_warning_methods); + ce = mysqli_warning_class_entry; + ce->ce_flags |= ZEND_ACC_FINAL_CLASS | ZEND_ACC_PROTECTED; + zend_hash_init(&mysqli_warning_properties, 0, NULL, NULL, 1); + MYSQLI_ADD_PROPERTIES(&mysqli_warning_properties, mysqli_warning_property_entries); + MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_warning_property_info_entries); + zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_warning_properties, sizeof(mysqli_warning_properties), NULL); + + REGISTER_MYSQLI_CLASS_ENTRY("mysqli_result", mysqli_result_class_entry, mysqli_result_methods); + ce = mysqli_result_class_entry; + zend_hash_init(&mysqli_result_properties, 0, NULL, NULL, 1); + MYSQLI_ADD_PROPERTIES(&mysqli_result_properties, mysqli_result_property_entries); + MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_result_property_info_entries); + mysqli_result_class_entry->get_iterator = php_mysqli_result_get_iterator; + mysqli_result_class_entry->iterator_funcs.funcs = &php_mysqli_result_iterator_funcs; + zend_class_implements(mysqli_result_class_entry TSRMLS_CC, 1, zend_ce_traversable); + zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_result_properties, sizeof(mysqli_result_properties), NULL); + + REGISTER_MYSQLI_CLASS_ENTRY("mysqli_stmt", mysqli_stmt_class_entry, mysqli_stmt_methods); + ce = mysqli_stmt_class_entry; + zend_hash_init(&mysqli_stmt_properties, 0, NULL, NULL, 1); + MYSQLI_ADD_PROPERTIES(&mysqli_stmt_properties, mysqli_stmt_property_entries); + MYSQLI_ADD_PROPERTIES_INFO(ce, mysqli_stmt_property_info_entries); + zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_stmt_properties, sizeof(mysqli_stmt_properties), NULL); + + /* mysqli_options */ + REGISTER_LONG_CONSTANT("MYSQLI_READ_DEFAULT_GROUP", MYSQL_READ_DEFAULT_GROUP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_READ_DEFAULT_FILE", MYSQL_READ_DEFAULT_FILE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_OPT_CONNECT_TIMEOUT", MYSQL_OPT_CONNECT_TIMEOUT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_OPT_LOCAL_INFILE", MYSQL_OPT_LOCAL_INFILE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_INIT_COMMAND", MYSQL_INIT_COMMAND, CONST_CS | CONST_PERSISTENT); +#if defined(MYSQLI_USE_MYSQLND) + REGISTER_LONG_CONSTANT("MYSQLI_OPT_NET_CMD_BUFFER_SIZE", MYSQLND_OPT_NET_CMD_BUFFER_SIZE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_OPT_NET_READ_BUFFER_SIZE", MYSQLND_OPT_NET_READ_BUFFER_SIZE, CONST_CS | CONST_PERSISTENT); +#endif +#ifdef MYSQLND_STRING_TO_INT_CONVERSION + REGISTER_LONG_CONSTANT("MYSQLI_OPT_INT_AND_FLOAT_NATIVE", MYSQLND_OPT_INT_AND_FLOAT_NATIVE, CONST_CS | CONST_PERSISTENT); +#endif +#if MYSQL_VERSION_ID > 50110 || defined(MYSQLI_USE_MYSQLND) + REGISTER_LONG_CONSTANT("MYSQLI_OPT_SSL_VERIFY_SERVER_CERT", MYSQL_OPT_SSL_VERIFY_SERVER_CERT, CONST_CS | CONST_PERSISTENT); +#endif + + /* mysqli_real_connect flags */ + REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL", CLIENT_SSL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_COMPRESS",CLIENT_COMPRESS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_INTERACTIVE", CLIENT_INTERACTIVE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_IGNORE_SPACE", CLIENT_IGNORE_SPACE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_NO_SCHEMA", CLIENT_NO_SCHEMA, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_FOUND_ROWS", CLIENT_FOUND_ROWS, CONST_CS | CONST_PERSISTENT); + + /* for mysqli_query */ + REGISTER_LONG_CONSTANT("MYSQLI_STORE_RESULT", MYSQLI_STORE_RESULT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_USE_RESULT", MYSQLI_USE_RESULT, CONST_CS | CONST_PERSISTENT); +#if defined (MYSQLI_USE_MYSQLND) + REGISTER_LONG_CONSTANT("MYSQLI_ASYNC", MYSQLI_ASYNC, CONST_CS | CONST_PERSISTENT); +#endif + + /* for mysqli_fetch_assoc */ + REGISTER_LONG_CONSTANT("MYSQLI_ASSOC", MYSQLI_ASSOC, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_NUM", MYSQLI_NUM, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_BOTH", MYSQLI_BOTH, CONST_CS | CONST_PERSISTENT); + + /* for mysqli_stmt_set_attr */ + REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH", STMT_ATTR_UPDATE_MAX_LENGTH, CONST_CS | CONST_PERSISTENT); + +#if MYSQL_VERSION_ID > 50003 || defined(MYSQLI_USE_MYSQLND) + REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_CURSOR_TYPE", STMT_ATTR_CURSOR_TYPE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_NO_CURSOR", CURSOR_TYPE_NO_CURSOR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_READ_ONLY", CURSOR_TYPE_READ_ONLY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_FOR_UPDATE", CURSOR_TYPE_FOR_UPDATE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_SCROLLABLE", CURSOR_TYPE_SCROLLABLE, CONST_CS | CONST_PERSISTENT); +#endif + +#if MYSQL_VERSION_ID > 50007 || defined(MYSQLI_USE_MYSQLND) + REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_PREFETCH_ROWS", STMT_ATTR_PREFETCH_ROWS, CONST_CS | CONST_PERSISTENT); +#endif + + /* column information */ + REGISTER_LONG_CONSTANT("MYSQLI_NOT_NULL_FLAG", NOT_NULL_FLAG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_PRI_KEY_FLAG", PRI_KEY_FLAG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_UNIQUE_KEY_FLAG", UNIQUE_KEY_FLAG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_MULTIPLE_KEY_FLAG", MULTIPLE_KEY_FLAG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_BLOB_FLAG", BLOB_FLAG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_UNSIGNED_FLAG", UNSIGNED_FLAG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_ZEROFILL_FLAG", ZEROFILL_FLAG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_AUTO_INCREMENT_FLAG", AUTO_INCREMENT_FLAG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TIMESTAMP_FLAG", TIMESTAMP_FLAG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_SET_FLAG", SET_FLAG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_NUM_FLAG", NUM_FLAG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_PART_KEY_FLAG", PART_KEY_FLAG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_GROUP_FLAG", GROUP_FLAG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_ENUM_FLAG", ENUM_FLAG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_BINARY_FLAG", BINARY_FLAG, CONST_CS | CONST_PERSISTENT); +#if MYSQL_VERSION_ID > 50001 || defined(MYSQLI_USE_MYSQLND) + REGISTER_LONG_CONSTANT("MYSQLI_NO_DEFAULT_VALUE_FLAG", NO_DEFAULT_VALUE_FLAG, CONST_CS | CONST_PERSISTENT); +#endif + +#if (MYSQL_VERSION_ID > 51122 && MYSQL_VERSION_ID < 60000) || (MYSQL_VERSION_ID > 60003) || defined(MYSQLI_USE_MYSQLND) + REGISTER_LONG_CONSTANT("MYSQLI_ON_UPDATE_NOW_FLAG", ON_UPDATE_NOW_FLAG, CONST_CS | CONST_PERSISTENT); +#endif + + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_DECIMAL", FIELD_TYPE_DECIMAL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_TINY", FIELD_TYPE_TINY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_SHORT", FIELD_TYPE_SHORT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_LONG", FIELD_TYPE_LONG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_FLOAT", FIELD_TYPE_FLOAT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_DOUBLE", FIELD_TYPE_DOUBLE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_NULL", FIELD_TYPE_NULL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_TIMESTAMP", FIELD_TYPE_TIMESTAMP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_LONGLONG", FIELD_TYPE_LONGLONG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_INT24", FIELD_TYPE_INT24, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_DATE", FIELD_TYPE_DATE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_TIME", FIELD_TYPE_TIME, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_DATETIME", FIELD_TYPE_DATETIME , CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_YEAR", FIELD_TYPE_YEAR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_NEWDATE", FIELD_TYPE_NEWDATE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_ENUM", FIELD_TYPE_ENUM, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_SET", FIELD_TYPE_SET, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_TINY_BLOB", FIELD_TYPE_TINY_BLOB, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_MEDIUM_BLOB", FIELD_TYPE_MEDIUM_BLOB, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_LONG_BLOB", FIELD_TYPE_LONG_BLOB, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_BLOB", FIELD_TYPE_BLOB, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_VAR_STRING", FIELD_TYPE_VAR_STRING, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_STRING", FIELD_TYPE_STRING, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_CHAR", FIELD_TYPE_CHAR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_INTERVAL", FIELD_TYPE_INTERVAL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_GEOMETRY", FIELD_TYPE_GEOMETRY, CONST_CS | CONST_PERSISTENT); + +#if MYSQL_VERSION_ID > 50002 || defined(MYSQLI_USE_MYSQLND) + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_NEWDECIMAL", FIELD_TYPE_NEWDECIMAL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_TYPE_BIT", FIELD_TYPE_BIT, CONST_CS | CONST_PERSISTENT); +#endif + + REGISTER_LONG_CONSTANT("MYSQLI_SET_CHARSET_NAME", MYSQL_SET_CHARSET_NAME, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_SET_CHARSET_DIR", MYSQL_SET_CHARSET_DIR, CONST_CS | CONST_PERSISTENT); + + /* bind support */ + REGISTER_LONG_CONSTANT("MYSQLI_NO_DATA", MYSQL_NO_DATA, CONST_CS | CONST_PERSISTENT); +#ifdef MYSQL_DATA_TRUNCATED + REGISTER_LONG_CONSTANT("MYSQLI_DATA_TRUNCATED", MYSQL_DATA_TRUNCATED, CONST_CS | CONST_PERSISTENT); +#endif + + /* reporting */ + REGISTER_LONG_CONSTANT("MYSQLI_REPORT_INDEX", MYSQLI_REPORT_INDEX, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_REPORT_ERROR", MYSQLI_REPORT_ERROR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_REPORT_STRICT", MYSQLI_REPORT_STRICT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_REPORT_ALL", MYSQLI_REPORT_ALL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_REPORT_OFF", 0, CONST_CS | CONST_PERSISTENT); + + /* We use non-nested macros with expansion, as VC has problems */ +#ifdef MYSQLI_USE_MYSQLND + REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", MYSQLND_DBG_ENABLED, CONST_CS | CONST_PERSISTENT); +#else +#ifdef DBUG_ON + REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", 1, CONST_CS | CONST_PERSISTENT); +#else + REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", 0, CONST_CS | CONST_PERSISTENT); +#endif +#endif + + REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED", SERVER_QUERY_NO_GOOD_INDEX_USED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_INDEX_USED", SERVER_QUERY_NO_INDEX_USED, CONST_CS | CONST_PERSISTENT); +#ifdef SERVER_QUERY_WAS_SLOW + REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_WAS_SLOW", SERVER_QUERY_WAS_SLOW, CONST_CS | CONST_PERSISTENT); +#endif +#ifdef SERVER_PS_OUT_PARAMS + REGISTER_LONG_CONSTANT("MYSQLI_SERVER_PS_OUT_PARAMS", SERVER_PS_OUT_PARAMS, CONST_CS | CONST_PERSISTENT); +#endif + + REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_GRANT", REFRESH_GRANT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_LOG", REFRESH_LOG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_TABLES", REFRESH_TABLES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_HOSTS", REFRESH_HOSTS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_STATUS", REFRESH_STATUS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_THREADS", REFRESH_THREADS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_SLAVE", REFRESH_SLAVE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_MASTER", REFRESH_MASTER, CONST_CS | CONST_PERSISTENT); +#ifdef REFRESH_BACKUP_LOG + REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_BACKUP_LOG", REFRESH_BACKUP_LOG, CONST_CS | CONST_PERSISTENT); +#endif + +#if MYSQL_VERSION_ID >= 50611 || defined(MYSQLI_USE_MYSQLND) + REGISTER_LONG_CONSTANT("MYSQLI_OPT_CAN_HANDLE_EXPIRED_PASSWORDS", MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, CONST_CS | CONST_PERSISTENT); +#endif + +#ifdef MYSQLI_USE_MYSQLND + mysqlnd_reverse_api_register_api(&mysqli_reverse_api TSRMLS_CC); +#endif + + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MSHUTDOWN_FUNCTION + */ +PHP_MSHUTDOWN_FUNCTION(mysqli) +{ +#ifndef MYSQLI_USE_MYSQLND +#if MYSQL_VERSION_ID >= 40000 +#ifdef PHP_WIN32 + unsigned long client_ver = mysql_get_client_version(); + /* + Can't call mysql_server_end() multiple times prior to 5.0.46 on Windows. + PHP bug#41350 MySQL bug#25621 + */ + if ((client_ver >= 50046 && client_ver < 50100) || client_ver > 50122) { + mysql_server_end(); + } +#else + mysql_server_end(); +#endif +#endif +#endif + + zend_hash_destroy(&mysqli_driver_properties); + zend_hash_destroy(&mysqli_result_properties); + zend_hash_destroy(&mysqli_stmt_properties); + zend_hash_destroy(&mysqli_warning_properties); + zend_hash_destroy(&mysqli_link_properties); + zend_hash_destroy(&classes); + + UNREGISTER_INI_ENTRIES(); + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_RINIT_FUNCTION + */ +PHP_RINIT_FUNCTION(mysqli) +{ +#if !defined(MYSQLI_USE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000 + if (mysql_thread_init()) { + return FAILURE; + } +#endif + MyG(error_msg) = NULL; + MyG(error_no) = 0; + MyG(report_mode) = 0; + + return SUCCESS; +} +/* }}} */ + +#if defined(A0) && defined(MYSQLI_USE_MYSQLND) +static void php_mysqli_persistent_helper_for_every(void *p) +{ + TSRMLS_FETCH(); + mysqlnd_end_psession((MYSQLND *) p); +} /* }}} */ + + +static int php_mysqli_persistent_helper_once(zend_rsrc_list_entry *le TSRMLS_DC) +{ + if (le->type == php_le_pmysqli()) { + mysqli_plist_entry *plist = (mysqli_plist_entry *) le->ptr; + zend_ptr_stack_apply(&plist->free_links, php_mysqli_persistent_helper_for_every); + } + return ZEND_HASH_APPLY_KEEP; +} /* }}} */ +#endif + + +/* {{{ PHP_RSHUTDOWN_FUNCTION + */ +PHP_RSHUTDOWN_FUNCTION(mysqli) +{ + /* check persistent connections, move used to free */ + +#if !defined(MYSQLI_USE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000 + mysql_thread_end(); +#endif + if (MyG(error_msg)) { + efree(MyG(error_msg)); + } +#if defined(A0) && defined(MYSQLI_USE_MYSQLND) + /* psession is being called when the connection is freed - explicitly or implicitly */ + zend_hash_apply(&EG(persistent_list), (apply_func_t) php_mysqli_persistent_helper_once TSRMLS_CC); +#endif + return SUCCESS; +} +/* }}} */ + + +/* {{{ PHP_MINFO_FUNCTION + */ +PHP_MINFO_FUNCTION(mysqli) +{ + char buf[32]; + + php_info_print_table_start(); + php_info_print_table_header(2, "MysqlI Support", "enabled"); + php_info_print_table_row(2, "Client API library version", mysql_get_client_info()); + snprintf(buf, sizeof(buf), "%ld", MyG(num_active_persistent)); + php_info_print_table_row(2, "Active Persistent Links", buf); + snprintf(buf, sizeof(buf), "%ld", MyG(num_inactive_persistent)); + php_info_print_table_row(2, "Inactive Persistent Links", buf); + snprintf(buf, sizeof(buf), "%ld", MyG(num_links)); + php_info_print_table_row(2, "Active Links", buf); +#if !defined(MYSQLI_USE_MYSQLND) + php_info_print_table_row(2, "Client API header version", MYSQL_SERVER_VERSION); + php_info_print_table_row(2, "MYSQLI_SOCKET", MYSQL_UNIX_ADDR); +#endif + php_info_print_table_end(); + + DISPLAY_INI_ENTRIES(); +} +/* }}} */ + + +/* Dependancies */ +static const zend_module_dep mysqli_deps[] = { +#if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1)) + ZEND_MOD_REQUIRED("spl") +#endif +#if defined(MYSQLI_USE_MYSQLND) + ZEND_MOD_REQUIRED("mysqlnd") +#endif + ZEND_MOD_END +}; + +/* {{{ mysqli_module_entry + */ +zend_module_entry mysqli_module_entry = { +#if ZEND_MODULE_API_NO >= 20050922 + STANDARD_MODULE_HEADER_EX, NULL, + mysqli_deps, +#elif ZEND_MODULE_API_NO >= 20010901 + STANDARD_MODULE_HEADER, +#endif + "mysqli", + mysqli_functions, + PHP_MINIT(mysqli), + PHP_MSHUTDOWN(mysqli), + PHP_RINIT(mysqli), + PHP_RSHUTDOWN(mysqli), + PHP_MINFO(mysqli), + "0.1", /* Replace with version number for your extension */ + PHP_MODULE_GLOBALS(mysqli), + PHP_GINIT(mysqli), + NULL, + NULL, + STANDARD_MODULE_PROPERTIES_EX +}; +/* }}} */ + +#ifdef COMPILE_DL_MYSQLI +ZEND_GET_MODULE(mysqli) +#endif + + +/* {{{ mixed mysqli_stmt_construct() +constructor for statement object. +Parameters: + object -> mysqli_stmt_init + object, query -> mysqli_prepare +*/ +PHP_FUNCTION(mysqli_stmt_construct) +{ + MY_MYSQL *mysql; + zval *mysql_link; + MY_STMT *stmt; + MYSQLI_RESOURCE *mysqli_resource; + char *statement; + int statement_len; + + switch (ZEND_NUM_ARGS()) + { + case 1: /* mysql_stmt_init */ + if (zend_parse_parameters(1 TSRMLS_CC, "O", &mysql_link, mysqli_link_class_entry)==FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT)); + + stmt->stmt = mysql_stmt_init(mysql->mysql); + break; + case 2: + if (zend_parse_parameters(2 TSRMLS_CC, "Os", &mysql_link, mysqli_link_class_entry, &statement, &statement_len)==FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT)); + + if ((stmt->stmt = mysql_stmt_init(mysql->mysql))) { + mysql_stmt_prepare(stmt->stmt, (char *)statement, statement_len); + } + break; + default: + WRONG_PARAM_COUNT; + break; + } + + if (!stmt->stmt) { + efree(stmt); + RETURN_FALSE; + } + + mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); + mysqli_resource->ptr = (void *)stmt; + mysqli_resource->status = (ZEND_NUM_ARGS() == 1) ? MYSQLI_STATUS_INITIALIZED : MYSQLI_STATUS_VALID; + + ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr = mysqli_resource; +} +/* }}} */ + +/* {{{ mixed mysqli_result_construct() +constructor for result object. +Parameters: + object [, mode] -> mysqli_store/use_result +*/ +PHP_FUNCTION(mysqli_result_construct) +{ + MY_MYSQL *mysql; + MYSQL_RES *result = NULL; + zval *mysql_link; + MYSQLI_RESOURCE *mysqli_resource; + long resmode = MYSQLI_STORE_RESULT; + + switch (ZEND_NUM_ARGS()) { + case 1: + if (zend_parse_parameters(1 TSRMLS_CC, "O", &mysql_link, mysqli_link_class_entry)==FAILURE) { + return; + } + break; + case 2: + if (zend_parse_parameters(2 TSRMLS_CC, "Ol", &mysql_link, mysqli_link_class_entry, &resmode)==FAILURE) { + return; + } + break; + default: + WRONG_PARAM_COUNT; + } + + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + switch (resmode) { + case MYSQLI_STORE_RESULT: + result = mysql_store_result(mysql->mysql); + break; + case MYSQLI_USE_RESULT: + result = mysql_use_result(mysql->mysql); + break; + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for resultmode"); + } + + if (!result) { + RETURN_FALSE; + } + + mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); + mysqli_resource->ptr = (void *)result; + mysqli_resource->status = MYSQLI_STATUS_VALID; + + ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr = mysqli_resource; + +} +/* }}} */ + + +/* {{{ php_mysqli_fetch_into_hash_aux + */ +void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * result, long fetchtype TSRMLS_DC) +{ +#if !defined(MYSQLI_USE_MYSQLND) + MYSQL_ROW row; + unsigned int i; + MYSQL_FIELD *fields; + unsigned long *field_len; + + if (!(row = mysql_fetch_row(result))) { + RETURN_NULL(); + } + + if (fetchtype & MYSQLI_ASSOC) { + fields = mysql_fetch_fields(result); + } + + array_init(return_value); + field_len = mysql_fetch_lengths(result); + + for (i = 0; i < mysql_num_fields(result); i++) { + if (row[i]) { + zval *res; + + MAKE_STD_ZVAL(res); + +#if MYSQL_VERSION_ID > 50002 + if (mysql_fetch_field_direct(result, i)->type == MYSQL_TYPE_BIT) { + my_ulonglong llval; + char tmp[22]; + switch (field_len[i]) { + case 8:llval = (my_ulonglong) bit_uint8korr(row[i]);break; + case 7:llval = (my_ulonglong) bit_uint7korr(row[i]);break; + case 6:llval = (my_ulonglong) bit_uint6korr(row[i]);break; + case 5:llval = (my_ulonglong) bit_uint5korr(row[i]);break; + case 4:llval = (my_ulonglong) bit_uint4korr(row[i]);break; + case 3:llval = (my_ulonglong) bit_uint3korr(row[i]);break; + case 2:llval = (my_ulonglong) bit_uint2korr(row[i]);break; + case 1:llval = (my_ulonglong) uint1korr(row[i]);break; + } + /* even though lval is declared as unsigned, the value + * may be negative. Therefor we cannot use MYSQLI_LLU_SPEC and must + * use MYSQLI_LL_SPEC. + */ + snprintf(tmp, sizeof(tmp), (mysql_fetch_field_direct(result, i)->flags & UNSIGNED_FLAG)? MYSQLI_LLU_SPEC : MYSQLI_LL_SPEC, llval); + ZVAL_STRING(res, tmp, 1); + } else +#endif + { + +#if PHP_API_VERSION < 20100412 + /* check if we need magic quotes */ + if (PG(magic_quotes_runtime)) { + Z_TYPE_P(res) = IS_STRING; + Z_STRVAL_P(res) = php_addslashes(row[i], field_len[i], &Z_STRLEN_P(res), 0 TSRMLS_CC); + } else { +#endif + ZVAL_STRINGL(res, row[i], field_len[i], 1); +#if PHP_API_VERSION < 20100412 + } +#endif + } + + if (fetchtype & MYSQLI_NUM) { + add_index_zval(return_value, i, res); + } + if (fetchtype & MYSQLI_ASSOC) { + if (fetchtype & MYSQLI_NUM) { + Z_ADDREF_P(res); + } + add_assoc_zval(return_value, fields[i].name, res); + } + } else { + if (fetchtype & MYSQLI_NUM) { + add_index_null(return_value, i); + } + if (fetchtype & MYSQLI_ASSOC) { + add_assoc_null(return_value, fields[i].name); + } + } + } +#else + mysqlnd_fetch_into(result, ((fetchtype & MYSQLI_NUM)? MYSQLND_FETCH_NUM:0) | ((fetchtype & MYSQLI_ASSOC)? MYSQLND_FETCH_ASSOC:0), return_value, MYSQLND_MYSQLI); +#endif +} +/* }}} */ + + +/* {{{ php_mysqli_fetch_into_hash + */ +void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags, int into_object) +{ + MYSQL_RES *result; + zval *mysql_result; + long fetchtype; + zval *ctor_params = NULL; + zend_class_entry *ce = NULL; + + if (into_object) { + char *class_name; + int class_name_len; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sz", &mysql_result, mysqli_result_class_entry, &class_name, &class_name_len, &ctor_params) == FAILURE) { + return; + } + if (ZEND_NUM_ARGS() < (getThis() ? 1 : 2)) { + ce = zend_standard_class_def; + } else { + ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC); + } + if (!ce) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name); + return; + } + fetchtype = MYSQLI_ASSOC; + } else { + if (override_flags) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) { + return; + } + fetchtype = override_flags; + } else { + fetchtype = MYSQLI_BOTH; + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &fetchtype) == FAILURE) { + return; + } + } + } + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + + if (fetchtype < MYSQLI_ASSOC || fetchtype > MYSQLI_BOTH) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH"); + RETURN_FALSE; + } + + php_mysqli_fetch_into_hash_aux(return_value, result, fetchtype TSRMLS_CC); + + if (into_object && Z_TYPE_P(return_value) != IS_NULL) { + zval dataset = *return_value; + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval *retval_ptr; + + object_and_properties_init(return_value, ce, NULL); + zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC); + + if (ce->constructor) { + fci.size = sizeof(fci); + fci.function_table = &ce->function_table; + fci.function_name = NULL; + fci.symbol_table = NULL; + fci.object_ptr = return_value; + fci.retval_ptr_ptr = &retval_ptr; + if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) { + if (Z_TYPE_P(ctor_params) == IS_ARRAY) { + HashTable *params_ht = Z_ARRVAL_P(ctor_params); + Bucket *p; + + fci.param_count = 0; + fci.params = safe_emalloc(sizeof(zval*), params_ht->nNumOfElements, 0); + p = params_ht->pListHead; + while (p != NULL) { + fci.params[fci.param_count++] = (zval**)p->pData; + p = p->pListNext; + } + } else { + /* Two problems why we throw exceptions here: PHP is typeless + * and hence passing one argument that's not an array could be + * by mistake and the other way round is possible, too. The + * single value is an array. Also we'd have to make that one + * argument passed by reference. + */ + zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Parameter ctor_params must be an array", 0 TSRMLS_CC); + return; + } + } else { + fci.param_count = 0; + fci.params = NULL; + } + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = ce->constructor; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(return_value); + fcc.object_ptr = return_value; + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) { + zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name); + } else { + if (retval_ptr) { + zval_ptr_dtor(&retval_ptr); + } + } + if (fci.params) { + efree(fci.params); + } + } else if (ctor_params) { + zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Class %s does not have a constructor hence you cannot use ctor_params", ce->name); + } + } +} +/* }}} */ + + +#if !defined(MYSQLI_USE_MYSQLND) + +#define ALLOC_CALLBACK_ARGS(a, b, c)\ +if (c) {\ + a = (zval ***)safe_emalloc(c, sizeof(zval **), 0);\ + for (i = b; i < c; i++) {\ + a[i] = emalloc(sizeof(zval *));\ + MAKE_STD_ZVAL(*a[i]);\ + }\ +} + +#define FREE_CALLBACK_ARGS(a, b, c)\ +if (a) {\ + for (i=b; i < c; i++) {\ + zval_ptr_dtor(a[i]);\ + efree(a[i]);\ + }\ + efree(a);\ +} + +#define LOCAL_INFILE_ERROR_MSG(source,dest)\ + memset(source, 0, LOCAL_INFILE_ERROR_LEN);\ + memcpy(source, dest, MIN(strlen(dest), LOCAL_INFILE_ERROR_LEN-1));\ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", dest); + + +/* {{{ php_local_infile_init + */ +static int php_local_infile_init(void **ptr, const char *filename, void *userdata) +{ + mysqli_local_infile *data; + MY_MYSQL *mysql; + php_stream_context *context = NULL; + + TSRMLS_FETCH(); + + /* save pointer to MY_MYSQL structure (userdata) */ + if (!(*ptr= data= ((mysqli_local_infile *)calloc(1, sizeof(mysqli_local_infile))))) { + return 1; + } + + if (!(mysql = (MY_MYSQL *)userdata)) { + LOCAL_INFILE_ERROR_MSG(data->error_msg, ER(CR_UNKNOWN_ERROR)); + return 1; + } + + /* check open_basedir */ + if (PG(open_basedir)) { + if (php_check_open_basedir_ex(filename, 0 TSRMLS_CC) == -1) { + LOCAL_INFILE_ERROR_MSG(data->error_msg, "open_basedir restriction in effect. Unable to open file"); + return 1; + } + } + + mysql->li_stream = php_stream_open_wrapper_ex((char *)filename, "r", 0, NULL, context); + + if (mysql->li_stream == NULL) { + snprintf((char *)data->error_msg, sizeof(data->error_msg), "Can't find file '%-.64s'.", filename); + return 1; + } + + data->userdata = mysql; + + return 0; +} +/* }}} */ + +/* {{{ int php_local_infile_read */ +static int php_local_infile_read(void *ptr, char *buf, uint buf_len) +{ + mysqli_local_infile *data; + MY_MYSQL *mysql; + zval ***callback_args; + zval *retval; + zval *fp; + int argc = 4; + int i; + long rc; + + TSRMLS_FETCH(); + + data= (mysqli_local_infile *)ptr; + mysql = data->userdata; + + /* default processing */ + if (!mysql->li_read) { + int count = (int)php_stream_read(mysql->li_stream, buf, buf_len); + + if (count < 0) { + LOCAL_INFILE_ERROR_MSG(data->error_msg, ER(2)); + } + + return count; + } + + ALLOC_CALLBACK_ARGS(callback_args, 1, argc); + + /* set parameters: filepointer, buffer, buffer_len, errormsg */ + + MAKE_STD_ZVAL(fp); + php_stream_to_zval(mysql->li_stream, fp); + callback_args[0] = &fp; + ZVAL_STRING(*callback_args[1], "", 1); + ZVAL_LONG(*callback_args[2], buf_len); + ZVAL_STRING(*callback_args[3], "", 1); + + if (call_user_function_ex(EG(function_table), + NULL, + mysql->li_read, + &retval, + argc, + callback_args, + 0, + NULL TSRMLS_CC) == SUCCESS) { + + rc = Z_LVAL_P(retval); + zval_ptr_dtor(&retval); + + if (rc > 0) { + if (rc >= 0 && rc != Z_STRLEN_P(*callback_args[1])) { + LOCAL_INFILE_ERROR_MSG(data->error_msg, + "Mismatch between the return value of the callback and the content " + "length of the buffer."); + rc = -1; + } else if (rc > buf_len) { + /* check buffer overflow */ + LOCAL_INFILE_ERROR_MSG(data->error_msg, "Too much data returned"); + rc = -1; + } else { + memcpy(buf, Z_STRVAL_P(*callback_args[1]), MIN(rc, Z_STRLEN_P(*callback_args[1]))); + } + } else if (rc < 0) { + LOCAL_INFILE_ERROR_MSG(data->error_msg, Z_STRVAL_P(*callback_args[3])); + } + } else { + LOCAL_INFILE_ERROR_MSG(data->error_msg, "Can't execute load data local init callback function"); + rc = -1; + } + /* + If the (ab)user has closed the file handle we should + not try to use it anymore or even close it + */ + if (!zend_rsrc_list_get_rsrc_type(Z_LVAL_P(fp) TSRMLS_CC)) { + LOCAL_INFILE_ERROR_MSG(data->error_msg, "File handle closed"); + rc = -1; + /* Thus the end handler won't try to free already freed memory */ + mysql->li_stream = NULL; + } + + FREE_CALLBACK_ARGS(callback_args, 1, argc); + efree(fp); + return rc; +} +/* }}} */ + +/* {{{ php_local_infile_error + */ +static int php_local_infile_error(void *ptr, char *error_msg, uint error_msg_len) +{ + mysqli_local_infile *data = (mysqli_local_infile *) ptr; + + if (data) { + strlcpy(error_msg, data->error_msg, error_msg_len); + return 2000; + } + strlcpy(error_msg, ER(CR_OUT_OF_MEMORY), error_msg_len); + return CR_OUT_OF_MEMORY; +} +/* }}} */ + +/* {{{ php_local_infile_end + */ +static void php_local_infile_end(void *ptr) +{ + mysqli_local_infile *data; + MY_MYSQL *mysql; + + TSRMLS_FETCH(); + + data= (mysqli_local_infile *)ptr; + + if (!data || !(mysql = data->userdata)) { + if (data) { + free(data); + } + return; + } + + if (mysql->li_stream) { + php_stream_close(mysql->li_stream); + } + free(data); + return; +} +/* }}} */ + + +/* {{{ void php_set_local_infile_handler_default +*/ +void php_set_local_infile_handler_default(MY_MYSQL *mysql) { + /* register internal callback functions */ + mysql_set_local_infile_handler(mysql->mysql, &php_local_infile_init, &php_local_infile_read, + &php_local_infile_end, &php_local_infile_error, (void *)mysql); + if (mysql->li_read) { + zval_ptr_dtor(&mysql->li_read); + mysql->li_read = NULL; + } +} +/* }}} */ +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqli/mysqli.dsp b/ext/mysqli/mysqli.dsp new file mode 100755 index 0000000..a334202 --- /dev/null +++ b/ext/mysqli/mysqli.dsp @@ -0,0 +1,120 @@ +# Microsoft Developer Studio Project File - Name="mysqli" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mysqli - Win32 Debug_TS
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysqli.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysqli.mak" CFG="mysqli - Win32 Debug_TS"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysqli - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mysqli - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysqli - Win32 Release_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release_TS"
+# PROP BASE Intermediate_Dir "Release_TS"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_TS"
+# PROP Intermediate_Dir "Release_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MYSQLI_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\..\php_build\include" /I "..\..\..\php_build\include\mysqli" /D ZEND_DEBUG=0 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "COMPILE_DL_MYSQLI" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D "PHP_MYSQLI_EXPORTS" /D "HAVE_ZLIB" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x407 /d "NDEBUG"
+# ADD RSC /l 0x407 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 php5ts.lib zlib.lib libmySQL.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_mysqli.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline" /libpath:"..\..\..\php_build\release"
+
+!ELSEIF "$(CFG)" == "mysqli - Win32 Debug_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug_TS"
+# PROP BASE Intermediate_Dir "Debug_TS"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug_TS"
+# PROP Intermediate_Dir "Debug_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MYSQLI_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\..\php_build\include" /I "..\..\..\php_build\include\mysqli" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "COMPILE_DL_MYSQLI" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D "PHP_MYSQLI_EXPORTS" /D "HAVE_ZLIB" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x407 /d "_DEBUG"
+# ADD RSC /l 0x407 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 php5ts_debug.lib zlib.lib libmySQL.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS/php_mysqli.dll" /pdbtype:sept /libpath:"..\..\Debug_TS" /libpath:"..\..\..\php_build\release"
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysqli - Win32 Release_TS"
+# Name "mysqli - Win32 Debug_TS"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\mysqli.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mysqli_api.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mysqli_fe.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mysqli_nonapi.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\php_mysqli.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c new file mode 100644 index 0000000..2cda0aa --- /dev/null +++ b/ext/mysqli/mysqli_api.c @@ -0,0 +1,2601 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Georg Richter <georg@php.net> | + | Andrey Hristov <andrey@php.net> | + | Ulf Wendel <uw@php.net> | + +----------------------------------------------------------------------+ + + $Id$ +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <signal.h> + +#include "php.h" +#include "php_ini.h" +#include "php_globals.h" +#include "ext/standard/info.h" +#include "php_mysqli_structs.h" +#include "mysqli_priv.h" + +/* {{{ proto mixed mysqli_affected_rows(object link) + Get number of affected rows in previous MySQL operation */ +PHP_FUNCTION(mysqli_affected_rows) +{ + MY_MYSQL *mysql; + zval *mysql_link; + my_ulonglong rc; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + rc = mysql_affected_rows(mysql->mysql); + if (rc == (my_ulonglong) -1) { + RETURN_LONG(-1); + } + MYSQLI_RETURN_LONG_LONG(rc); +} +/* }}} */ + + +/* {{{ proto bool mysqli_autocommit(object link, bool mode) + Turn auto commit on or of */ +PHP_FUNCTION(mysqli_autocommit) +{ + MY_MYSQL *mysql; + zval *mysql_link; + zend_bool automode; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ob", &mysql_link, mysqli_link_class_entry, &automode) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + if (mysql_autocommit(mysql->mysql, (my_bool)automode)) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ mysqli_stmt_bind_param_do_bind */ +#ifndef MYSQLI_USE_MYSQLND +static +int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned int num_vars, + zval ***args, unsigned int start, const char * const types TSRMLS_DC) +{ + int i, ofs; + MYSQL_BIND *bind; + unsigned long rc; + + /* prevent leak if variables are already bound */ + if (stmt->param.var_cnt) { + php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE); + } + + stmt->param.is_null = ecalloc(num_vars, sizeof(char)); + bind = (MYSQL_BIND *) ecalloc(num_vars, sizeof(MYSQL_BIND)); + + ofs = 0; + for (i = start; i < argc; i++) { + + /* set specified type */ + switch (types[ofs]) { + case 'd': /* Double */ + bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE; + bind[ofs].buffer = &Z_DVAL_PP(args[i]); + bind[ofs].is_null = &stmt->param.is_null[ofs]; + break; + + case 'i': /* Integer */ +#if SIZEOF_LONG==8 + bind[ofs].buffer_type = MYSQL_TYPE_LONGLONG; +#elif SIZEOF_LONG==4 + bind[ofs].buffer_type = MYSQL_TYPE_LONG; +#endif + bind[ofs].buffer = &Z_LVAL_PP(args[i]); + bind[ofs].is_null = &stmt->param.is_null[ofs]; + break; + + case 'b': /* Blob (send data) */ + bind[ofs].buffer_type = MYSQL_TYPE_LONG_BLOB; + /* don't initialize is_null and length to 0 because we use ecalloc */ + break; + + case 's': /* string */ + bind[ofs].buffer_type = MYSQL_TYPE_VAR_STRING; + /* don't initialize buffer and buffer_length because we use ecalloc */ + bind[ofs].is_null = &stmt->param.is_null[ofs]; + break; + + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[ofs], i+1); + rc = 1; + goto end_1; + } + ofs++; + } + rc = mysql_stmt_bind_param(stmt->stmt, bind); + +end_1: + if (rc) { + efree(stmt->param.is_null); + } else { + stmt->param.var_cnt = num_vars; + stmt->param.vars = (zval **)safe_emalloc(num_vars, sizeof(zval), 0); + for (i = 0; i < num_vars; i++) { + if (bind[i].buffer_type != MYSQL_TYPE_LONG_BLOB) { + Z_ADDREF_P(*args[i+start]); + stmt->param.vars[i] = *args[i+start]; + } else { + stmt->param.vars[i] = NULL; + } + } + } + efree(bind); + + return rc; +} +#else +static +int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned int num_vars, + zval ***args, unsigned int start, const char * const types TSRMLS_DC) +{ + unsigned int i; + MYSQLND_PARAM_BIND *params; + enum_func_status ret = FAIL; + + /* If no params -> skip binding and return directly */ + if (argc == start) { + return PASS; + } + params = mysqlnd_stmt_alloc_param_bind(stmt->stmt); + if (!params) { + goto end; + } + for (i = 0; i < (argc - start); i++) { + zend_uchar type; + switch (types[i]) { + case 'd': /* Double */ + type = MYSQL_TYPE_DOUBLE; + break; + case 'i': /* Integer */ +#if SIZEOF_LONG==8 + type = MYSQL_TYPE_LONGLONG; +#elif SIZEOF_LONG==4 + type = MYSQL_TYPE_LONG; +#endif + break; + case 'b': /* Blob (send data) */ + type = MYSQL_TYPE_LONG_BLOB; + break; + case 's': /* string */ + type = MYSQL_TYPE_VAR_STRING; + break; + default: + /* We count parameters from 1 */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[i], i + start + 1); + ret = FAIL; + mysqlnd_stmt_free_param_bind(stmt->stmt, params); + goto end; + } + params[i].zv = *(args[i + start]); + params[i].type = type; + } + ret = mysqlnd_stmt_bind_param(stmt->stmt, params); + +end: + return ret; +} +#endif +/* }}} */ + +/* {{{ proto bool mysqli_stmt_bind_param(object stmt, string types, mixed variable [,mixed,....]) U + Bind variables to a prepared statement as parameters */ +PHP_FUNCTION(mysqli_stmt_bind_param) +{ + zval ***args; + int argc = ZEND_NUM_ARGS(); + int num_vars; + int start = 2; + MY_STMT *stmt; + zval *mysql_stmt; + char *types; + int types_len; + unsigned long rc; + + /* calculate and check number of parameters */ + if (argc < 2) { + /* there has to be at least one pair */ + WRONG_PARAM_COUNT; + } + + if (zend_parse_method_parameters((getThis()) ? 1:2 TSRMLS_CC, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry, + &types, &types_len) == FAILURE) { + return; + } + + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + num_vars = argc - 1; + if (getThis()) { + start = 1; + } else { + /* ignore handle parameter in procedural interface*/ + --num_vars; + } + if (!types_len) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type or no types specified"); + RETURN_FALSE; + } + + if (types_len != argc - start) { + /* number of bind variables doesn't match number of elements in type definition string */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of elements in type definition string doesn't match number of bind variables"); + RETURN_FALSE; + } + + if (types_len != mysql_stmt_param_count(stmt->stmt)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of variables doesn't match number of parameters in prepared statement"); + RETURN_FALSE; + } + + args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0); + + if (zend_get_parameters_array_ex(argc, args) == FAILURE) { + zend_wrong_param_count(TSRMLS_C); + rc = 1; + } else { + rc = mysqli_stmt_bind_param_do_bind(stmt, argc, num_vars, args, start, types TSRMLS_CC); + MYSQLI_REPORT_STMT_ERROR(stmt->stmt); + } + + efree(args); + + RETURN_BOOL(!rc); +} +/* }}} */ + +/* {{{ mysqli_stmt_bind_result_do_bind */ +#ifndef MYSQLI_USE_MYSQLND +/* TODO: + do_alloca, free_alloca +*/ +static int +mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, unsigned int start TSRMLS_DC) +{ + MYSQL_BIND *bind; + int i, ofs; + int var_cnt = argc - start; + long col_type; + ulong rc; + + /* prevent leak if variables are already bound */ + if (stmt->result.var_cnt) { + php_free_stmt_bind_buffer(stmt->result, FETCH_RESULT); + } + + bind = (MYSQL_BIND *)ecalloc(var_cnt, sizeof(MYSQL_BIND)); + { + int size; + char *p= emalloc(size= var_cnt * (sizeof(char) + sizeof(VAR_BUFFER))); + stmt->result.buf = (VAR_BUFFER *) p; + stmt->result.is_null = p + var_cnt * sizeof(VAR_BUFFER); + memset(p, 0, size); + } + + for (i=start; i < var_cnt + start ; i++) { + ofs = i - start; + col_type = (stmt->stmt->fields) ? stmt->stmt->fields[ofs].type : MYSQL_TYPE_STRING; + + switch (col_type) { + case MYSQL_TYPE_DOUBLE: + case MYSQL_TYPE_FLOAT: + convert_to_double_ex(args[i]); + stmt->result.buf[ofs].type = IS_DOUBLE; + stmt->result.buf[ofs].buflen = sizeof(double); + + /* allocate buffer for double */ + stmt->result.buf[ofs].val = (char *)emalloc(sizeof(double)); + bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE; + bind[ofs].buffer = stmt->result.buf[ofs].val; + bind[ofs].is_null = &stmt->result.is_null[ofs]; + break; + + case MYSQL_TYPE_NULL: + stmt->result.buf[ofs].type = IS_NULL; + /* + don't initialize to 0 : + 1. stmt->result.buf[ofs].buflen + 2. bind[ofs].buffer + 3. bind[ofs].buffer_length + because memory was allocated with ecalloc + */ + bind[ofs].buffer_type = MYSQL_TYPE_NULL; + bind[ofs].is_null = &stmt->result.is_null[ofs]; + break; + + case MYSQL_TYPE_SHORT: + case MYSQL_TYPE_TINY: + case MYSQL_TYPE_LONG: + case MYSQL_TYPE_INT24: + case MYSQL_TYPE_YEAR: + convert_to_long_ex(args[i]); + stmt->result.buf[ofs].type = IS_LONG; + /* don't set stmt->result.buf[ofs].buflen to 0, we used ecalloc */ + stmt->result.buf[ofs].val = (char *)emalloc(sizeof(int)); + bind[ofs].buffer_type = MYSQL_TYPE_LONG; + bind[ofs].buffer = stmt->result.buf[ofs].val; + bind[ofs].is_null = &stmt->result.is_null[ofs]; + bind[ofs].is_unsigned = (stmt->stmt->fields[ofs].flags & UNSIGNED_FLAG) ? 1 : 0; + break; + + case MYSQL_TYPE_LONGLONG: +#if MYSQL_VERSION_ID > 50002 || defined(MYSQLI_USE_MYSQLND) + case MYSQL_TYPE_BIT: +#endif + stmt->result.buf[ofs].type = IS_STRING; + stmt->result.buf[ofs].buflen = sizeof(my_ulonglong); + stmt->result.buf[ofs].val = (char *)emalloc(stmt->result.buf[ofs].buflen); + bind[ofs].buffer_type = col_type; + bind[ofs].buffer = stmt->result.buf[ofs].val; + bind[ofs].is_null = &stmt->result.is_null[ofs]; + bind[ofs].buffer_length = stmt->result.buf[ofs].buflen; + bind[ofs].is_unsigned = (stmt->stmt->fields[ofs].flags & UNSIGNED_FLAG) ? 1 : 0; + bind[ofs].length = &stmt->result.buf[ofs].output_len; + break; + + case MYSQL_TYPE_DATE: + case MYSQL_TYPE_TIME: + case MYSQL_TYPE_DATETIME: + case MYSQL_TYPE_NEWDATE: + case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_STRING: + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_TIMESTAMP: + case MYSQL_TYPE_DECIMAL: + case MYSQL_TYPE_GEOMETRY: +#ifdef FIELD_TYPE_NEWDECIMAL + case MYSQL_TYPE_NEWDECIMAL: +#endif + { +#if MYSQL_VERSION_ID >= 50107 + /* Changed to my_bool in MySQL 5.1. See MySQL Bug #16144 */ + my_bool tmp; +#else + uint tmp = 0; +#endif + stmt->result.buf[ofs].type = IS_STRING; + /* + If the user has called $stmt->store_result() then we have asked + max_length to be updated. this is done only for BLOBS because we don't want to allocate + big chunkgs of memory 2^16 or 2^24 + */ + if (stmt->stmt->fields[ofs].max_length == 0 && + !mysql_stmt_attr_get(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp) && !tmp) + { + /* + Allocate directly 256 because it's easier to allocate a bit more + than update max length even for text columns. Try SELECT UNION SELECT UNION with + different lengths and you will see that we get different lengths in stmt->stmt->fields[ofs].length + The just take 256 and saves us from realloc-ing. + */ + stmt->result.buf[ofs].buflen = + (stmt->stmt->fields) ? (stmt->stmt->fields[ofs].length) ? stmt->stmt->fields[ofs].length + 1: 256: 256; + + } else { + /* + the user has called store_result(). if he does not there is no way to determine the + libmysql does not allow us to allocate 0 bytes for a buffer so we try 1 + */ + if (!(stmt->result.buf[ofs].buflen = stmt->stmt->fields[ofs].max_length)) + ++stmt->result.buf[ofs].buflen; + } + stmt->result.buf[ofs].val = (char *)emalloc(stmt->result.buf[ofs].buflen); + bind[ofs].buffer_type = MYSQL_TYPE_STRING; + bind[ofs].buffer = stmt->result.buf[ofs].val; + bind[ofs].is_null = &stmt->result.is_null[ofs]; + bind[ofs].buffer_length = stmt->result.buf[ofs].buflen; + bind[ofs].length = &stmt->result.buf[ofs].output_len; + break; + } + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Server returned unknown type %ld. Probably your client library is incompatible with the server version you use!", col_type); + break; + } + } + + rc = mysql_stmt_bind_result(stmt->stmt, bind); + MYSQLI_REPORT_STMT_ERROR(stmt->stmt); + + if (rc) { + /* dont close the statement or subsequent usage (for example ->execute()) will lead to crash */ + for (i=0; i < var_cnt ; i++) { + if (stmt->result.buf[i].val) { + efree(stmt->result.buf[i].val); + } + } + /* Don't free stmt->result.is_null because is_null & buf are one block of memory */ + efree(stmt->result.buf); + } else { + stmt->result.var_cnt = var_cnt; + stmt->result.vars = (zval **)safe_emalloc((var_cnt), sizeof(zval), 0); + for (i = start; i < var_cnt+start; i++) { + ofs = i-start; + Z_ADDREF_PP(args[i]); + stmt->result.vars[ofs] = *args[i]; + } + } + efree(bind); + + return rc; +} +#else +static int +mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, unsigned int start TSRMLS_DC) +{ + unsigned int i; + MYSQLND_RESULT_BIND * params = mysqlnd_stmt_alloc_result_bind(stmt->stmt); + if (params) { + for (i = 0; i < (argc - start); i++) { + params[i].zv = *(args[i + start]); + } + return mysqlnd_stmt_bind_result(stmt->stmt, params); + } + return FAIL; +} +#endif +/* }}} */ + +/* {{{ proto bool mysqli_stmt_bind_result(object stmt, mixed var, [,mixed, ...]) U + Bind variables to a prepared statement for result storage */ +PHP_FUNCTION(mysqli_stmt_bind_result) +{ + zval ***args; + int argc = ZEND_NUM_ARGS(); + int start = 1; + ulong rc; + MY_STMT *stmt; + zval *mysql_stmt; + + if (getThis()) { + start = 0; + } + + if (zend_parse_method_parameters((getThis()) ? 0:1 TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + if (argc < (getThis() ? 1 : 2)) { + WRONG_PARAM_COUNT; + } + + if ((argc - start) != mysql_stmt_field_count(stmt->stmt)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of bind variables doesn't match number of fields in prepared statement"); + RETURN_FALSE; + } + + args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0); + + if (zend_get_parameters_array_ex(argc, args) == FAILURE) { + efree(args); + WRONG_PARAM_COUNT; + } + + rc = mysqli_stmt_bind_result_do_bind(stmt, args, argc, start TSRMLS_CC); + + efree(args); + + RETURN_BOOL(!rc); +} +/* }}} */ + +/* {{{ proto bool mysqli_change_user(object link, string user, string password, string database) + Change logged-in user of the active connection */ +PHP_FUNCTION(mysqli_change_user) +{ + MY_MYSQL *mysql; + zval *mysql_link = NULL; + char *user, *password, *dbname; + int user_len, password_len, dbname_len; + ulong rc; +#if !defined(MYSQLI_USE_MYSQLND) && defined(HAVE_MYSQLI_SET_CHARSET) + const CHARSET_INFO * old_charset; +#endif + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osss", &mysql_link, mysqli_link_class_entry, &user, &user_len, &password, &password_len, &dbname, &dbname_len) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + +#if !defined(MYSQLI_USE_MYSQLND) && defined(HAVE_MYSQLI_SET_CHARSET) + old_charset = mysql->mysql->charset; +#endif + +#if defined(MYSQLI_USE_MYSQLND) + rc = mysqlnd_change_user_ex(mysql->mysql, user, password, dbname, FALSE, (size_t) password_len); +#else + rc = mysql_change_user(mysql->mysql, user, password, dbname); +#endif + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + + if (rc) { + RETURN_FALSE; + } +#if !defined(MYSQLI_USE_MYSQLND) && defined(HAVE_MYSQLI_SET_CHARSET) + if (mysql_get_server_version(mysql->mysql) < 501023L) { + /* + Request the current charset, or it will be reset to the system one. + 5.0 doesn't support it. Support added in 5.1.23 by fixing the following bug : + Bug #30472 libmysql doesn't reset charset, insert_id after succ. mysql_change_user() call + */ + rc = mysql_set_character_set(mysql->mysql, old_charset->csname); + } +#endif + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto string mysqli_character_set_name(object link) + Returns the name of the character set used for this connection */ +PHP_FUNCTION(mysqli_character_set_name) +{ + MY_MYSQL *mysql; + zval *mysql_link; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + RETURN_STRING((char *)mysql_character_set_name(mysql->mysql), 1); +} +/* }}} */ + + +/* {{{ php_mysqli_close */ +void php_mysqli_close(MY_MYSQL * mysql, int close_type, int resource_status TSRMLS_DC) +{ + if (resource_status > MYSQLI_STATUS_INITIALIZED) { + MyG(num_links)--; + } + + if (!mysql->persistent) { + mysqli_close(mysql->mysql, close_type); + } else { + zend_rsrc_list_entry *le; + if (zend_hash_find(&EG(persistent_list), mysql->hash_key, strlen(mysql->hash_key) + 1, (void **)&le) == SUCCESS) { + if (Z_TYPE_P(le) == php_le_pmysqli()) { + mysqli_plist_entry *plist = (mysqli_plist_entry *) le->ptr; +#if defined(MYSQLI_USE_MYSQLND) + mysqlnd_end_psession(mysql->mysql); +#endif + zend_ptr_stack_push(&plist->free_links, mysql->mysql); + + MyG(num_active_persistent)--; + MyG(num_inactive_persistent)++; + } + } + mysql->persistent = FALSE; + } + mysql->mysql = NULL; + + php_clear_mysql(mysql); +} +/* }}} */ + + +/* {{{ proto bool mysqli_close(object link) + Close connection */ +PHP_FUNCTION(mysqli_close) +{ + zval *mysql_link; + MY_MYSQL *mysql; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_INITIALIZED); + + php_mysqli_close(mysql, MYSQLI_CLOSE_EXPLICIT, ((MYSQLI_RESOURCE *)((mysqli_object *)zend_object_store_get_object(mysql_link TSRMLS_CC))->ptr)->status TSRMLS_CC); + ((MYSQLI_RESOURCE *)((mysqli_object *)zend_object_store_get_object(mysql_link TSRMLS_CC))->ptr)->status = MYSQLI_STATUS_UNKNOWN; + + MYSQLI_CLEAR_RESOURCE(&mysql_link); + efree(mysql); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto bool mysqli_commit(object link) + Commit outstanding actions and close transaction */ +PHP_FUNCTION(mysqli_commit) +{ + MY_MYSQL *mysql; + zval *mysql_link; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + if (mysql_commit(mysql->mysql)) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto bool mysqli_data_seek(object result, int offset) + Move internal result pointer */ +PHP_FUNCTION(mysqli_data_seek) +{ + MYSQL_RES *result; + zval *mysql_result; + long offset; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &offset) == FAILURE) { + return; + } + + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + + if (mysqli_result_is_unbuffered(result)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT"); + RETURN_FALSE; + } + + if (offset < 0 || offset >= mysql_num_rows(result)) { + RETURN_FALSE; + } + + mysql_data_seek(result, offset); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto void mysqli_debug(string debug) U +*/ +PHP_FUNCTION(mysqli_debug) +{ + char *debug; + int debug_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &debug, &debug_len) == FAILURE) { + return; + } + + mysql_debug(debug); + RETURN_TRUE; +} +/* }}} */ + + +/* {{{ proto bool mysqli_dump_debug_info(object link) +*/ +PHP_FUNCTION(mysqli_dump_debug_info) +{ + MY_MYSQL *mysql; + zval *mysql_link; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + RETURN_BOOL(!mysql_dump_debug_info(mysql->mysql)) +} +/* }}} */ + +/* {{{ proto int mysqli_errno(object link) + Returns the numerical value of the error message from previous MySQL operation */ +PHP_FUNCTION(mysqli_errno) +{ + MY_MYSQL *mysql; + zval *mysql_link; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + RETURN_LONG(mysql_errno(mysql->mysql)); +} +/* }}} */ + +/* {{{ proto string mysqli_error(object link) + Returns the text of the error message from previous MySQL operation */ +PHP_FUNCTION(mysqli_error) +{ + MY_MYSQL *mysql; + zval *mysql_link; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + RETURN_STRING((char *)mysql_error(mysql->mysql),1); +} +/* }}} */ + +#ifndef MYSQLI_USE_MYSQLND +/* {{{ php_mysqli_stmt_copy_it */ +static void +php_mysqli_stmt_copy_it(zval *** copies, zval *original, uint param_count, uint current) +{ + if (!*copies) { + *copies = ecalloc(param_count, sizeof(zval *)); + } + MAKE_STD_ZVAL((*copies)[current]); + *(*copies)[current] = *original; + Z_SET_REFCOUNT_P((*copies)[current], 1); + zval_copy_ctor((*copies)[current]); +} +/* }}} */ +#endif + +/* {{{ proto bool mysqli_stmt_execute(object stmt) + Execute a prepared statement */ +PHP_FUNCTION(mysqli_stmt_execute) +{ + MY_STMT *stmt; + zval *mysql_stmt; +#ifndef MYSQLI_USE_MYSQLND + unsigned int i; + zval **copies = NULL; +#endif + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + +#ifndef MYSQLI_USE_MYSQLND + if (stmt->param.var_cnt) { + int j; + for (i = 0; i < stmt->param.var_cnt; i++) { + for (j = i + 1; j < stmt->param.var_cnt; j++) { + /* Oops, someone binding the same variable - clone */ + if (stmt->param.vars[j] == stmt->param.vars[i] && stmt->param.vars[i]) { + php_mysqli_stmt_copy_it(&copies, stmt->param.vars[i], stmt->param.var_cnt, i); + break; + } + } + } + } + for (i = 0; i < stmt->param.var_cnt; i++) { + if (stmt->param.vars[i]) { + if ( !(stmt->param.is_null[i] = (stmt->param.vars[i]->type == IS_NULL)) ) { + zval *the_var = copies && copies[i]? copies[i]:stmt->param.vars[i]; + switch (stmt->stmt->params[i].buffer_type) { + case MYSQL_TYPE_VAR_STRING: + if (the_var == stmt->param.vars[i] && Z_TYPE_P(stmt->param.vars[i]) != IS_STRING) { + php_mysqli_stmt_copy_it(&copies, stmt->param.vars[i], stmt->param.var_cnt, i); + the_var = copies[i]; + } + convert_to_string_ex(&the_var); + stmt->stmt->params[i].buffer = Z_STRVAL_P(the_var); + stmt->stmt->params[i].buffer_length = Z_STRLEN_P(the_var); + break; + case MYSQL_TYPE_DOUBLE: + if (the_var == stmt->param.vars[i] && Z_TYPE_P(stmt->param.vars[i]) != IS_DOUBLE) { + php_mysqli_stmt_copy_it(&copies, stmt->param.vars[i], stmt->param.var_cnt, i); + the_var = copies[i]; + } + convert_to_double_ex(&the_var); + stmt->stmt->params[i].buffer = &Z_DVAL_P(the_var); + break; + case MYSQL_TYPE_LONGLONG: + case MYSQL_TYPE_LONG: + if (the_var == stmt->param.vars[i] && Z_TYPE_P(stmt->param.vars[i]) != IS_LONG) { + php_mysqli_stmt_copy_it(&copies, stmt->param.vars[i], stmt->param.var_cnt, i); + the_var = copies[i]; + } + convert_to_long_ex(&the_var); + stmt->stmt->params[i].buffer = &Z_LVAL_P(the_var); + break; + default: + break; + } + } + } + } +#endif + + if (mysql_stmt_execute(stmt->stmt)) { + MYSQLI_REPORT_STMT_ERROR(stmt->stmt); + RETVAL_FALSE; + } else { + RETVAL_TRUE; + } + +#ifndef MYSQLI_USE_MYSQLND + if (copies) { + for (i = 0; i < stmt->param.var_cnt; i++) { + if (copies[i]) { + zval_ptr_dtor(&copies[i]); + } + } + efree(copies); + } +#endif + + if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { + php_mysqli_report_index(stmt->query, mysqli_stmt_server_status(stmt->stmt) TSRMLS_CC); + } +} +/* }}} */ + +#ifndef MYSQLI_USE_MYSQLND +/* {{{ void mysqli_stmt_fetch_libmysql + Fetch results from a prepared statement into the bound variables */ +void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS) +{ + MY_STMT *stmt; + zval *mysql_stmt; + unsigned int i; + ulong ret; + unsigned int uval; + my_ulonglong llval; + + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + /* reset buffers */ + for (i = 0; i < stmt->result.var_cnt; i++) { + if (stmt->result.buf[i].type == IS_STRING) { + memset(stmt->result.buf[i].val, 0, stmt->result.buf[i].buflen); + } + } + ret = mysql_stmt_fetch(stmt->stmt); +#ifdef MYSQL_DATA_TRUNCATED + if (!ret || ret == MYSQL_DATA_TRUNCATED) { +#else + if (!ret) { +#endif + for (i = 0; i < stmt->result.var_cnt; i++) { + /* + QQ: Isn't it quite better to call zval_dtor(). What if the user has + assigned a resource, or an array to the bound variable? We are going + to leak probably. zval_dtor() will handle also Unicode/Non-unicode mode. + */ + /* Even if the string is of length zero there is one byte alloced so efree() in all cases */ + if (Z_TYPE_P(stmt->result.vars[i]) == IS_STRING) { + STR_FREE(stmt->result.vars[i]->value.str.val); + } + if (!stmt->result.is_null[i]) { + switch (stmt->result.buf[i].type) { + case IS_LONG: + if ((stmt->stmt->fields[i].type == MYSQL_TYPE_LONG) + && (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)) + { + /* unsigned int (11) */ + uval= *(unsigned int *) stmt->result.buf[i].val; +#if SIZEOF_LONG==4 + if (uval > INT_MAX) { + char *tmp, *p; + int j=10; + tmp= emalloc(11); + p= &tmp[9]; + do { + *p-- = (uval % 10) + 48; + uval = uval / 10; + } while (--j > 0); + tmp[10]= '\0'; + /* unsigned int > INT_MAX is 10 digits - ALWAYS */ + ZVAL_STRINGL(stmt->result.vars[i], tmp, 10, 0); + break; + } +#endif + } + if (stmt->stmt->fields[i].flags & UNSIGNED_FLAG) { + ZVAL_LONG(stmt->result.vars[i], *(unsigned int *)stmt->result.buf[i].val); + } else { + ZVAL_LONG(stmt->result.vars[i], *(int *)stmt->result.buf[i].val); + } + break; + case IS_DOUBLE: + ZVAL_DOUBLE(stmt->result.vars[i], *(double *)stmt->result.buf[i].val); + break; + case IS_STRING: + if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_LONGLONG +#if MYSQL_VERSION_ID > 50002 + || stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT +#endif + ) { + my_bool uns= (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? 1:0; +#if MYSQL_VERSION_ID > 50002 + if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT) { + switch (stmt->result.buf[i].output_len) { + case 8:llval = (my_ulonglong) bit_uint8korr(stmt->result.buf[i].val);break; + case 7:llval = (my_ulonglong) bit_uint7korr(stmt->result.buf[i].val);break; + case 6:llval = (my_ulonglong) bit_uint6korr(stmt->result.buf[i].val);break; + case 5:llval = (my_ulonglong) bit_uint5korr(stmt->result.buf[i].val);break; + case 4:llval = (my_ulonglong) bit_uint4korr(stmt->result.buf[i].val);break; + case 3:llval = (my_ulonglong) bit_uint3korr(stmt->result.buf[i].val);break; + case 2:llval = (my_ulonglong) bit_uint2korr(stmt->result.buf[i].val);break; + case 1:llval = (my_ulonglong) uint1korr(stmt->result.buf[i].val);break; + } + } else +#endif + { + llval= *(my_ulonglong *) stmt->result.buf[i].val; + } +#if SIZEOF_LONG==8 + if (uns && llval > 9223372036854775807L) { +#elif SIZEOF_LONG==4 + if ((uns && llval > L64(2147483647)) || + (!uns && (( L64(2147483647) < (my_longlong) llval) || + (L64(-2147483648) > (my_longlong) llval)))) + { +#endif + char tmp[22]; + /* even though lval is declared as unsigned, the value + * may be negative. Therefor we cannot use MYSQLI_LLU_SPEC and must + * use MYSQLI_LL_SPEC. + */ + snprintf(tmp, sizeof(tmp), (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? MYSQLI_LLU_SPEC : MYSQLI_LL_SPEC, llval); + ZVAL_STRING(stmt->result.vars[i], tmp, 1); + } else { + ZVAL_LONG(stmt->result.vars[i], llval); + } + } else { +#if defined(MYSQL_DATA_TRUNCATED) && MYSQL_VERSION_ID > 50002 + if (ret == MYSQL_DATA_TRUNCATED && *(stmt->stmt->bind[i].error) != 0) { + /* result was truncated */ + ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val, + stmt->stmt->bind[i].buffer_length, 1); + } else { +#else + { +#endif + ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val, + stmt->result.buf[i].output_len, 1); + } + } + break; + default: + break; + } + } else { + ZVAL_NULL(stmt->result.vars[i]); + } + } + } else { + MYSQLI_REPORT_STMT_ERROR(stmt->stmt); + } + + switch (ret) { + case 0: +#ifdef MYSQL_DATA_TRUNCATED + /* according to SQL standard truncation (e.g. loss of precision is + not an error) - for detecting possible truncation you have to + check mysqli_stmt_warning + */ + case MYSQL_DATA_TRUNCATED: +#endif + RETURN_TRUE; + break; + case 1: + RETURN_FALSE; + break; + default: + RETURN_NULL(); + break; + } +} +/* }}} */ +#else +/* {{{ mixed mysqli_stmt_fetch_mysqlnd */ +void mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAMETERS) +{ + MY_STMT *stmt; + zval *mysql_stmt; + zend_bool fetched_anything; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + if (FAIL == mysqlnd_stmt_fetch(stmt->stmt, &fetched_anything)) { + RETURN_BOOL(FALSE); + } else if (fetched_anything == TRUE) { + RETURN_BOOL(TRUE); + } else { + RETURN_NULL(); + } +} +#endif +/* }}} */ + + +/* {{{ proto mixed mysqli_stmt_fetch(object stmt) U + Fetch results from a prepared statement into the bound variables */ +PHP_FUNCTION(mysqli_stmt_fetch) +{ +#if !defined(MYSQLI_USE_MYSQLND) + mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAM_PASSTHRU); +#else + mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAM_PASSTHRU); +#endif +} +/* }}} */ + +/* {{{ php_add_field_properties */ +static void php_add_field_properties(zval *value, const MYSQL_FIELD *field TSRMLS_DC) +{ + add_property_string(value, "name",(field->name ? field->name : ""), 1); + add_property_string(value, "orgname",(field->org_name ? field->org_name : ""), 1); + add_property_string(value, "table",(field->table ? field->table : ""), 1); + add_property_string(value, "orgtable",(field->org_table ? field->org_table : ""), 1); + add_property_string(value, "def",(field->def ? field->def : ""), 1); + add_property_string(value, "db",(field->db ? field->db : ""), 1); + + /* FIXME: manually set the catalog to "def" due to bug in + * libmysqlclient which does not initialize field->catalog + * and in addition, the catalog is always be "def" + */ + add_property_string(value, "catalog", "def", 1); + + add_property_long(value, "max_length", field->max_length); + add_property_long(value, "length", field->length); + add_property_long(value, "charsetnr", field->charsetnr); + add_property_long(value, "flags", field->flags); + add_property_long(value, "type", field->type); + add_property_long(value, "decimals", field->decimals); +} +/* }}} */ + +/* {{{ proto mixed mysqli_fetch_field (object result) + Get column information from a result and return as an object */ +PHP_FUNCTION(mysqli_fetch_field) +{ + MYSQL_RES *result; + zval *mysql_result; + const MYSQL_FIELD *field; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) { + return; + } + + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + + if (!(field = mysql_fetch_field(result))) { + RETURN_FALSE; + } + + object_init(return_value); + php_add_field_properties(return_value, field TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto mixed mysqli_fetch_fields (object result) + Return array of objects containing field meta-data */ +PHP_FUNCTION(mysqli_fetch_fields) +{ + MYSQL_RES *result; + zval *mysql_result; + zval *obj; + + unsigned int i; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) { + return; + } + + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + + array_init(return_value); + + for (i = 0; i < mysql_num_fields(result); i++) { + const MYSQL_FIELD *field = mysql_fetch_field_direct(result, i); + + MAKE_STD_ZVAL(obj); + object_init(obj); + + php_add_field_properties(obj, field TSRMLS_CC); + add_index_zval(return_value, i, obj); + } +} +/* }}} */ + +/* {{{ proto mixed mysqli_fetch_field_direct (object result, int offset) + Fetch meta-data for a single field */ +PHP_FUNCTION(mysqli_fetch_field_direct) +{ + MYSQL_RES *result; + zval *mysql_result; + const MYSQL_FIELD *field; + long offset; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &offset) == FAILURE) { + return; + } + + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + + if (offset < 0 || offset >= (long) mysql_num_fields(result)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field offset is invalid for resultset"); + RETURN_FALSE; + } + + if (!(field = mysql_fetch_field_direct(result,offset))) { + RETURN_FALSE; + } + + object_init(return_value); + php_add_field_properties(return_value, field TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto mixed mysqli_fetch_lengths (object result) + Get the length of each output in a result */ +PHP_FUNCTION(mysqli_fetch_lengths) +{ + MYSQL_RES *result; + zval *mysql_result; + unsigned int i; + unsigned long *ret; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) { + return; + } + + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + + if (!(ret = mysql_fetch_lengths(result))) { + RETURN_FALSE; + } + + array_init(return_value); + + for (i = 0; i < mysql_num_fields(result); i++) { + add_index_long(return_value, i, ret[i]); + } +} +/* }}} */ + +/* {{{ proto array mysqli_fetch_row (object result) + Get a result row as an enumerated array */ +PHP_FUNCTION(mysqli_fetch_row) +{ + php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_NUM, 0); +} +/* }}} */ + +/* {{{ proto int mysqli_field_count(object link) + Fetch the number of fields returned by the last query for the given link +*/ +PHP_FUNCTION(mysqli_field_count) +{ + MY_MYSQL *mysql; + zval *mysql_link; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + RETURN_LONG(mysql_field_count(mysql->mysql)); +} +/* }}} */ + +/* {{{ proto int mysqli_field_seek(object result, int fieldnr) + Set result pointer to a specified field offset +*/ +PHP_FUNCTION(mysqli_field_seek) +{ + MYSQL_RES *result; + zval *mysql_result; + unsigned long fieldnr; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &fieldnr) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + + if (fieldnr < 0 || fieldnr >= mysql_num_fields(result)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid field offset"); + RETURN_FALSE; + } + + mysql_field_seek(result, fieldnr); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto int mysqli_field_tell(object result) + Get current field offset of result pointer */ +PHP_FUNCTION(mysqli_field_tell) +{ + MYSQL_RES *result; + zval *mysql_result; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + + RETURN_LONG(mysql_field_tell(result)); +} +/* }}} */ + +/* {{{ proto void mysqli_free_result(object result) + Free query result memory for the given result handle */ +PHP_FUNCTION(mysqli_free_result) +{ + MYSQL_RES *result; + zval *mysql_result; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + + mysqli_free_result(result, FALSE); + MYSQLI_CLEAR_RESOURCE(&mysql_result); +} +/* }}} */ + +/* {{{ proto string mysqli_get_client_info(void) + Get MySQL client info */ +PHP_FUNCTION(mysqli_get_client_info) +{ + RETURN_STRING((char *)mysql_get_client_info(), 1); +} +/* }}} */ + +/* {{{ proto int mysqli_get_client_version(void) + Get MySQL client info */ +PHP_FUNCTION(mysqli_get_client_version) +{ + RETURN_LONG((long)mysql_get_client_version()); +} +/* }}} */ + +/* {{{ proto string mysqli_get_host_info (object link) + Get MySQL host info */ +PHP_FUNCTION(mysqli_get_host_info) +{ + MY_MYSQL *mysql; + zval *mysql_link = NULL; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); +#if !defined(MYSQLI_USE_MYSQLND) + RETURN_STRING((mysql->mysql->host_info) ? mysql->mysql->host_info : "", 1); +#else + RETURN_STRING((mysql->mysql->data->host_info) ? mysql->mysql->data->host_info : "", 1); +#endif +} +/* }}} */ + +/* {{{ proto int mysqli_get_proto_info(object link) + Get MySQL protocol information */ +PHP_FUNCTION(mysqli_get_proto_info) +{ + MY_MYSQL *mysql; + zval *mysql_link = NULL; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + RETURN_LONG(mysql_get_proto_info(mysql->mysql)); +} +/* }}} */ + +/* {{{ proto string mysqli_get_server_info(object link) + Get MySQL server info */ +PHP_FUNCTION(mysqli_get_server_info) +{ + MY_MYSQL *mysql; + zval *mysql_link = NULL; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + RETURN_STRING((char *)mysql_get_server_info(mysql->mysql), 1); +} + +/* }}} */ + +/* {{{ proto int mysqli_get_server_version(object link) + Return the MySQL version for the server referenced by the given link */ +PHP_FUNCTION(mysqli_get_server_version) +{ + MY_MYSQL *mysql; + zval *mysql_link = NULL; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + RETURN_LONG(mysql_get_server_version(mysql->mysql)); +} +/* }}} */ + +/* {{{ proto string mysqli_info(object link) + Get information about the most recent query */ +PHP_FUNCTION(mysqli_info) +{ + MY_MYSQL *mysql; + zval *mysql_link = NULL; + const char *info; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + info = mysql_info(mysql->mysql); + RETURN_STRING((info) ? (char *)info : "", 1); +} +/* }}} */ + + +/* {{{ php_mysqli_init() */ +void php_mysqli_init(INTERNAL_FUNCTION_PARAMETERS) +{ + MYSQLI_RESOURCE *mysqli_resource; + MY_MYSQL *mysql; + + if (getThis() && ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr) { + return; + } + + mysql = (MY_MYSQL *)ecalloc(1, sizeof(MY_MYSQL)); + +#if !defined(MYSQLI_USE_MYSQLND) + if (!(mysql->mysql = mysql_init(NULL))) +#else + /* + We create always persistent, as if the user want to connecto + to p:somehost, we can't convert the handle then + */ + if (!(mysql->mysql = mysql_init(TRUE))) +#endif + { + efree(mysql); + RETURN_FALSE; + } + + mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); + mysqli_resource->ptr = (void *)mysql; + mysqli_resource->status = MYSQLI_STATUS_INITIALIZED; + + if (!getThis() || !instanceof_function(Z_OBJCE_P(getThis()), mysqli_link_class_entry TSRMLS_CC)) { + MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_link_class_entry); + } else { + ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr = mysqli_resource; + } +} +/* }}} */ + + +/* {{{ proto resource mysqli_init(void) + Initialize mysqli and return a resource for use with mysql_real_connect */ +PHP_FUNCTION(mysqli_init) +{ + php_mysqli_init(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto mixed mysqli_insert_id(object link) + Get the ID generated from the previous INSERT operation */ +PHP_FUNCTION(mysqli_insert_id) +{ + MY_MYSQL *mysql; + my_ulonglong rc; + zval *mysql_link; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + rc = mysql_insert_id(mysql->mysql); + MYSQLI_RETURN_LONG_LONG(rc) +} +/* }}} */ + +/* {{{ proto bool mysqli_kill(object link, int processid) + Kill a mysql process on the server */ +PHP_FUNCTION(mysqli_kill) +{ + MY_MYSQL *mysql; + zval *mysql_link; + long processid; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_link, mysqli_link_class_entry, &processid) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + if (processid <= 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "processid should have positive value"); + RETURN_FALSE; + } + + if (mysql_kill(mysql->mysql, processid)) { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto void mysqli_set_local_infile_default(object link) + unsets user defined handler for load local infile command */ +#if !defined(MYSQLI_USE_MYSQLND) +PHP_FUNCTION(mysqli_set_local_infile_default) +{ + MY_MYSQL *mysql; + zval *mysql_link; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + if (mysql->li_read) { + zval_ptr_dtor(&(mysql->li_read)); + mysql->li_read = NULL; + } +} +/* }}} */ + +/* {{{ proto bool mysqli_set_local_infile_handler(object link, callback read_func) + Set callback functions for LOAD DATA LOCAL INFILE */ +PHP_FUNCTION(mysqli_set_local_infile_handler) +{ + MY_MYSQL *mysql; + zval *mysql_link; + char *callback_name; + zval *callback_func; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz", &mysql_link, mysqli_link_class_entry, + &callback_func) == FAILURE) { + return; + } + + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + /* check callback function */ + if (!zend_is_callable(callback_func, 0, &callback_name TSRMLS_CC)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not a valid callback function %s", callback_name); + efree(callback_name); + RETURN_FALSE; + } + efree(callback_name); + + /* save callback function */ + if (!mysql->li_read) { + MAKE_STD_ZVAL(mysql->li_read); + } else { + zval_dtor(mysql->li_read); + } + ZVAL_ZVAL(mysql->li_read, callback_func, 1, 0); + + RETURN_TRUE; +} +#endif +/* }}} */ + +/* {{{ proto bool mysqli_more_results(object link) + check if there any more query results from a multi query */ +PHP_FUNCTION(mysqli_more_results) +{ + MY_MYSQL *mysql; + zval *mysql_link; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + RETURN_BOOL(mysql_more_results(mysql->mysql)); +} +/* }}} */ + +/* {{{ proto bool mysqli_next_result(object link) + read next result from multi_query */ +PHP_FUNCTION(mysqli_next_result) { + MY_MYSQL *mysql; + zval *mysql_link; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + if (!mysql_more_results(mysql->mysql)) { + php_error_docref(NULL TSRMLS_CC, E_STRICT, "There is no next result set. " + "Please, call mysqli_more_results()/mysqli::more_results() to check " + "whether to call this function/method"); + } + + RETURN_BOOL(!mysql_next_result(mysql->mysql)); +} +/* }}} */ + +#if defined(HAVE_STMT_NEXT_RESULT) && defined(MYSQLI_USE_MYSQLND) +/* {{{ proto bool mysqli_stmt_next_result(object link) + check if there any more query results from a multi query */ +PHP_FUNCTION(mysqli_stmt_more_results) +{ + MY_STMT *stmt; + zval *mysql_stmt; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + RETURN_BOOL(mysqlnd_stmt_more_results(stmt->stmt)); +} +/* }}} */ + + +/* {{{ proto bool mysqli_stmt_next_result(object link) + read next result from multi_query */ +PHP_FUNCTION(mysqli_stmt_next_result) { + MY_STMT *stmt; + zval *mysql_stmt; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + if (!mysqlnd_stmt_more_results(stmt->stmt)) { + php_error_docref(NULL TSRMLS_CC, E_STRICT, "There is no next result set. " + "Please, call mysqli_stmt_more_results()/mysqli_stmt::more_results() to check " + "whether to call this function/method"); + } + + RETURN_BOOL(!mysql_stmt_next_result(stmt->stmt)); +} +/* }}} */ +#endif + + +/* {{{ proto int mysqli_num_fields(object result) + Get number of fields in result */ +PHP_FUNCTION(mysqli_num_fields) +{ + MYSQL_RES *result; + zval *mysql_result; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + + RETURN_LONG(mysql_num_fields(result)); +} +/* }}} */ + +/* {{{ proto mixed mysqli_num_rows(object result) + Get number of rows in result */ +PHP_FUNCTION(mysqli_num_rows) +{ + MYSQL_RES *result; + zval *mysql_result; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + + if (mysqli_result_is_unbuffered_and_not_everything_is_fetched(result)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT"); + RETURN_LONG(0); + } + + MYSQLI_RETURN_LONG_LONG(mysql_num_rows(result)); +} +/* }}} */ + +/* {{{ mysqli_options_get_option_zval_type */ +static int mysqli_options_get_option_zval_type(int option) +{ + switch (option) { +#ifdef MYSQLI_USE_MYSQLND +#if PHP_MAJOR_VERSION >= 6 + case MYSQLND_OPT_NUMERIC_AND_DATETIME_AS_UNICODE: +#endif + case MYSQLND_OPT_NET_CMD_BUFFER_SIZE: + case MYSQLND_OPT_NET_READ_BUFFER_SIZE: +#ifdef MYSQLND_STRING_TO_INT_CONVERSION + case MYSQLND_OPT_INT_AND_FLOAT_NATIVE: +#endif +#endif /* MYSQLI_USE_MYSQLND */ + case MYSQL_OPT_CONNECT_TIMEOUT: +#ifdef MYSQL_REPORT_DATA_TRUNCATION + case MYSQL_REPORT_DATA_TRUNCATION: +#endif + case MYSQL_OPT_LOCAL_INFILE: + case MYSQL_OPT_NAMED_PIPE: +#ifdef MYSQL_OPT_PROTOCOL + case MYSQL_OPT_PROTOCOL: +#endif /* MySQL 4.1.0 */ +#ifdef MYSQL_OPT_READ_TIMEOUT + case MYSQL_OPT_READ_TIMEOUT: + case MYSQL_OPT_WRITE_TIMEOUT: + case MYSQL_OPT_GUESS_CONNECTION: + case MYSQL_OPT_USE_EMBEDDED_CONNECTION: + case MYSQL_OPT_USE_REMOTE_CONNECTION: + case MYSQL_SECURE_AUTH: +#endif /* MySQL 4.1.1 */ +#ifdef MYSQL_OPT_RECONNECT + case MYSQL_OPT_RECONNECT: +#endif /* MySQL 5.0.13 */ +#ifdef MYSQL_OPT_SSL_VERIFY_SERVER_CERT + case MYSQL_OPT_SSL_VERIFY_SERVER_CERT: +#endif /* MySQL 5.0.23 */ +#ifdef MYSQL_OPT_COMPRESS + case MYSQL_OPT_COMPRESS: +#endif /* mysqlnd @ PHP 5.3.2 */ +#ifdef MYSQL_OPT_SSL_VERIFY_SERVER_CERT + REGISTER_LONG_CONSTANT("MYSQLI_OPT_SSL_VERIFY_SERVER_CERT", MYSQL_OPT_SSL_VERIFY_SERVER_CERT, CONST_CS | CONST_PERSISTENT); +#endif /* MySQL 5.1.1., mysqlnd @ PHP 5.3.3 */ +#if MYSQL_VERSION_ID >= 50611 || defined(MYSQLI_USE_MYSQLND) + case MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS: +#endif + return IS_LONG; + +#ifdef MYSQL_SHARED_MEMORY_BASE_NAME + case MYSQL_SHARED_MEMORY_BASE_NAME: +#endif /* MySQL 4.1.0 */ +#ifdef MYSQL_SET_CLIENT_IP + case MYSQL_SET_CLIENT_IP: +#endif /* MySQL 4.1.1 */ + case MYSQL_READ_DEFAULT_FILE: + case MYSQL_READ_DEFAULT_GROUP: + case MYSQL_INIT_COMMAND: + case MYSQL_SET_CHARSET_NAME: + case MYSQL_SET_CHARSET_DIR: + return IS_STRING; + + default: + return IS_NULL; + } +} +/* }}} */ + + +/* {{{ proto bool mysqli_options(object link, int flags, mixed values) + Set options */ +PHP_FUNCTION(mysqli_options) +{ + MY_MYSQL *mysql; + zval *mysql_link = NULL; + zval **mysql_value; + long mysql_option; + unsigned int l_value; + long ret; + int expected_type; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OlZ", &mysql_link, mysqli_link_class_entry, &mysql_option, &mysql_value) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_INITIALIZED); + +#if PHP_API_VERSION < 20100412 + if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode)) { +#else + if (PG(open_basedir) && PG(open_basedir)[0] != '\0') { +#endif + if(mysql_option == MYSQL_OPT_LOCAL_INFILE) { + RETURN_FALSE; + } + } + expected_type = mysqli_options_get_option_zval_type(mysql_option); + if (expected_type != Z_TYPE_PP(mysql_value)) { + switch (expected_type) { + case IS_STRING: + convert_to_string_ex(mysql_value); + break; + case IS_LONG: + convert_to_long_ex(mysql_value); + break; + default: + break; + } + } + switch (expected_type) { + case IS_STRING: + ret = mysql_options(mysql->mysql, mysql_option, Z_STRVAL_PP(mysql_value)); + break; + case IS_LONG: + l_value = Z_LVAL_PP(mysql_value); + ret = mysql_options(mysql->mysql, mysql_option, (char *)&l_value); + break; + default: + ret = 1; + break; + } + + RETURN_BOOL(!ret); +} +/* }}} */ + + +/* {{{ proto bool mysqli_ping(object link) + Ping a server connection or reconnect if there is no connection */ +PHP_FUNCTION(mysqli_ping) +{ + MY_MYSQL *mysql; + zval *mysql_link; + long rc; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + rc = mysql_ping(mysql->mysql); + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + + RETURN_BOOL(!rc); +} +/* }}} */ + +/* {{{ proto mixed mysqli_prepare(object link, string query) + Prepare a SQL statement for execution */ +PHP_FUNCTION(mysqli_prepare) +{ + MY_MYSQL *mysql; + MY_STMT *stmt; + char *query = NULL; + int query_len; + zval *mysql_link; + MYSQLI_RESOURCE *mysqli_resource; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os",&mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + +#if !defined(MYSQLI_USE_MYSQLND) + if (mysql->mysql->status == MYSQL_STATUS_GET_RESULT) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "All data must be fetched before a new statement prepare takes place"); + RETURN_FALSE; + } +#endif + + stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT)); + + if ((stmt->stmt = mysql_stmt_init(mysql->mysql))) { + if (mysql_stmt_prepare(stmt->stmt, query, query_len)) { + /* mysql_stmt_close() clears errors, so we have to store them temporarily */ +#if !defined(MYSQLI_USE_MYSQLND) + char last_error[MYSQL_ERRMSG_SIZE]; + char sqlstate[SQLSTATE_LENGTH+1]; + unsigned int last_errno; + + last_errno = stmt->stmt->last_errno; + memcpy(last_error, stmt->stmt->last_error, MYSQL_ERRMSG_SIZE); + memcpy(sqlstate, mysql->mysql->net.sqlstate, SQLSTATE_LENGTH+1); +#else + MYSQLND_ERROR_INFO error_info = *mysql->mysql->data->error_info; +#endif + mysqli_stmt_close(stmt->stmt, FALSE); + stmt->stmt = NULL; + + /* restore error messages */ +#if !defined(MYSQLI_USE_MYSQLND) + mysql->mysql->net.last_errno = last_errno; + memcpy(mysql->mysql->net.last_error, last_error, MYSQL_ERRMSG_SIZE); + memcpy(mysql->mysql->net.sqlstate, sqlstate, SQLSTATE_LENGTH+1); +#else + *mysql->mysql->data->error_info = error_info; +#endif + } + } + + /* don't initialize stmt->query with NULL, we ecalloc()-ed the memory */ + /* Get performance boost if reporting is switched off */ + if (stmt->stmt && query_len && (MyG(report_mode) & MYSQLI_REPORT_INDEX)) { + stmt->query = (char *)emalloc(query_len + 1); + memcpy(stmt->query, query, query_len); + stmt->query[query_len] = '\0'; + } + + /* don't join to the previous if because it won't work if mysql_stmt_prepare_fails */ + if (!stmt->stmt) { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + efree(stmt); + RETURN_FALSE; + } + + mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); + mysqli_resource->ptr = (void *)stmt; + + /* change status */ + mysqli_resource->status = MYSQLI_STATUS_VALID; + MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_stmt_class_entry); +} +/* }}} */ + + +/* {{{ proto bool mysqli_real_connect(object link [,string hostname [,string username [,string passwd [,string dbname [,int port [,string socket [,int flags]]]]]]]) + Open a connection to a mysql server */ +PHP_FUNCTION(mysqli_real_connect) +{ + mysqli_common_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, TRUE, FALSE); +} +/* }}} */ + + +/* {{{ proto bool mysqli_real_query(object link, string query) + Binary-safe version of mysql_query() */ +PHP_FUNCTION(mysqli_real_query) +{ + MY_MYSQL *mysql; + zval *mysql_link; + char *query = NULL; + int query_len; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + MYSQLI_DISABLE_MQ; /* disable multi statements/queries */ + + if (mysql_real_query(mysql->mysql, query, query_len)) { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + RETURN_FALSE; + } + + if (!mysql_field_count(mysql->mysql)) { + if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { + php_mysqli_report_index(query, mysqli_server_status(mysql->mysql) TSRMLS_CC); + } + } + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto string mysqli_real_escape_string(object link, string escapestr) + Escapes special characters in a string for use in a SQL statement, taking into account the current charset of the connection */ +PHP_FUNCTION(mysqli_real_escape_string) { + MY_MYSQL *mysql; + zval *mysql_link = NULL; + char *escapestr, *newstr; + int escapestr_len, newstr_len; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &escapestr, &escapestr_len) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + newstr = safe_emalloc(2, escapestr_len, 1); + newstr_len = mysql_real_escape_string(mysql->mysql, newstr, escapestr, escapestr_len); + newstr = erealloc(newstr, newstr_len + 1); + + RETURN_STRINGL(newstr, newstr_len, 0); +} +/* }}} */ + +/* {{{ proto bool mysqli_rollback(object link) + Undo actions from current transaction */ +PHP_FUNCTION(mysqli_rollback) +{ + MY_MYSQL *mysql; + zval *mysql_link; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + if (mysql_rollback(mysql->mysql)) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto bool mysqli_stmt_send_long_data(object stmt, int param_nr, string data) +*/ +PHP_FUNCTION(mysqli_stmt_send_long_data) +{ + MY_STMT *stmt; + zval *mysql_stmt; + char *data; + long param_nr; + int data_len; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ols", &mysql_stmt, mysqli_stmt_class_entry, ¶m_nr, &data, &data_len) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + if (param_nr < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter number"); + RETURN_FALSE; + } + if (mysql_stmt_send_long_data(stmt->stmt, param_nr, data, data_len)) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + + +/* {{{ proto mixed mysqli_stmt_affected_rows(object stmt) + Return the number of rows affected in the last query for the given link */ +PHP_FUNCTION(mysqli_stmt_affected_rows) +{ + MY_STMT *stmt; + zval *mysql_stmt; + my_ulonglong rc; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + rc = mysql_stmt_affected_rows(stmt->stmt); + if (rc == (my_ulonglong) -1) { + RETURN_LONG(-1); + } + MYSQLI_RETURN_LONG_LONG(rc) +} +/* }}} */ + +/* {{{ proto bool mysqli_stmt_close(object stmt) + Close statement */ +PHP_FUNCTION(mysqli_stmt_close) +{ + MY_STMT *stmt; + zval *mysql_stmt; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + mysqli_stmt_close(stmt->stmt, FALSE); + stmt->stmt = NULL; + php_clear_stmt_bind(stmt TSRMLS_CC); + MYSQLI_CLEAR_RESOURCE(&mysql_stmt); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto void mysqli_stmt_data_seek(object stmt, int offset) + Move internal result pointer */ +PHP_FUNCTION(mysqli_stmt_data_seek) +{ + MY_STMT *stmt; + zval *mysql_stmt; + long offset; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_stmt, mysqli_stmt_class_entry, &offset) == FAILURE) { + return; + } + if (offset < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset must be positive"); + RETURN_FALSE; + } + + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + mysql_stmt_data_seek(stmt->stmt, offset); +} +/* }}} */ + +/* {{{ proto int mysqli_stmt_field_count(object stmt) { + Return the number of result columns for the given statement */ +PHP_FUNCTION(mysqli_stmt_field_count) +{ + MY_STMT *stmt; + zval *mysql_stmt; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + RETURN_LONG(mysql_stmt_field_count(stmt->stmt)); +} +/* }}} */ + +/* {{{ proto void mysqli_stmt_free_result(object stmt) + Free stored result memory for the given statement handle */ +PHP_FUNCTION(mysqli_stmt_free_result) +{ + MY_STMT *stmt; + zval *mysql_stmt; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + mysql_stmt_free_result(stmt->stmt); +} +/* }}} */ + +/* {{{ proto mixed mysqli_stmt_insert_id(object stmt) + Get the ID generated from the previous INSERT operation */ +PHP_FUNCTION(mysqli_stmt_insert_id) +{ + MY_STMT *stmt; + my_ulonglong rc; + zval *mysql_stmt; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + rc = mysql_stmt_insert_id(stmt->stmt); + MYSQLI_RETURN_LONG_LONG(rc) +} +/* }}} */ + +/* {{{ proto int mysqli_stmt_param_count(object stmt) + Return the number of parameter for the given statement */ +PHP_FUNCTION(mysqli_stmt_param_count) +{ + MY_STMT *stmt; + zval *mysql_stmt; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + RETURN_LONG(mysql_stmt_param_count(stmt->stmt)); +} +/* }}} */ + +/* {{{ proto bool mysqli_stmt_reset(object stmt) + reset a prepared statement */ +PHP_FUNCTION(mysqli_stmt_reset) +{ + MY_STMT *stmt; + zval *mysql_stmt; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + if (mysql_stmt_reset(stmt->stmt)) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto mixed mysqli_stmt_num_rows(object stmt) + Return the number of rows in statements result set */ +PHP_FUNCTION(mysqli_stmt_num_rows) +{ + MY_STMT *stmt; + zval *mysql_stmt; + my_ulonglong rc; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + rc = mysql_stmt_num_rows(stmt->stmt); + MYSQLI_RETURN_LONG_LONG(rc) +} +/* }}} */ + +/* {{{ proto bool mysqli_select_db(object link, string dbname) + Select a MySQL database */ +PHP_FUNCTION(mysqli_select_db) +{ + MY_MYSQL *mysql; + zval *mysql_link; + char *dbname; + int dbname_len; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &dbname, &dbname_len) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + if (mysql_select_db(mysql->mysql, dbname)) { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto string mysqli_sqlstate(object link) + Returns the SQLSTATE error from previous MySQL operation */ +PHP_FUNCTION(mysqli_sqlstate) +{ + MY_MYSQL *mysql; + zval *mysql_link; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + RETURN_STRING((char *)mysql_sqlstate(mysql->mysql),1); +} +/* }}} */ + +/* {{{ proto bool mysqli_ssl_set(object link ,string key ,string cert ,string ca ,string capath ,string cipher]) U +*/ +PHP_FUNCTION(mysqli_ssl_set) +{ + MY_MYSQL *mysql; + zval *mysql_link; + char *ssl_parm[5]; + int ssl_parm_len[5], i; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osssss", &mysql_link, mysqli_link_class_entry, &ssl_parm[0], &ssl_parm_len[0], &ssl_parm[1], &ssl_parm_len[1], &ssl_parm[2], &ssl_parm_len[2], &ssl_parm[3], &ssl_parm_len[3], &ssl_parm[4], &ssl_parm_len[4]) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_INITIALIZED); + + for (i = 0; i < 5; i++) { + if (!ssl_parm_len[i]) { + ssl_parm[i] = NULL; + } + } + + mysql_ssl_set(mysql->mysql, ssl_parm[0], ssl_parm[1], ssl_parm[2], ssl_parm[3], ssl_parm[4]); + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto mixed mysqli_stat(object link) + Get current system status */ +PHP_FUNCTION(mysqli_stat) +{ + MY_MYSQL *mysql; + zval *mysql_link; + char *stat; +#if defined(MYSQLI_USE_MYSQLND) + uint stat_len; +#endif + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + +#if !defined(MYSQLI_USE_MYSQLND) + if ((stat = (char *)mysql_stat(mysql->mysql))) + { + RETURN_STRING(stat, 1); +#else + if (mysqlnd_stat(mysql->mysql, &stat, &stat_len) == PASS) + { + RETURN_STRINGL(stat, stat_len, 0); +#endif + } else { + RETURN_FALSE; + } +} + +/* }}} */ + +/* {{{ proto bool mysqli_refresh(object link, long options) + Flush tables or caches, or reset replication server information */ +PHP_FUNCTION(mysqli_refresh) +{ + MY_MYSQL *mysql; + zval *mysql_link = NULL; + long options; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_link, mysqli_link_class_entry, &options) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_INITIALIZED); +#ifdef MYSQLI_USE_MYSQLND + RETURN_BOOL(!mysql_refresh(mysql->mysql, (uint8_t) options)); +#else + RETURN_BOOL(!mysql_refresh(mysql->mysql, options)); +#endif +} +/* }}} */ + +/* {{{ proto int mysqli_stmt_attr_set(object stmt, long attr, long mode) +*/ +PHP_FUNCTION(mysqli_stmt_attr_set) +{ + MY_STMT *stmt; + zval *mysql_stmt; + long mode_in; +#if MYSQL_VERSION_ID >= 50107 + my_bool mode_b; +#endif + ulong mode; + ulong attr; + void *mode_p; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &mysql_stmt, mysqli_stmt_class_entry, &attr, &mode_in) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + if (mode_in < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "mode should be non-negative, %ld passed", mode_in); + RETURN_FALSE; + } + + switch (attr) { +#if MYSQL_VERSION_ID >= 50107 + case STMT_ATTR_UPDATE_MAX_LENGTH: + mode_b = (my_bool) mode_in; + mode_p = &mode_b; + break; +#endif + default: + mode = mode_in; + mode_p = &mode; + break; + } +#if !defined(MYSQLI_USE_MYSQLND) + if (mysql_stmt_attr_set(stmt->stmt, attr, mode_p)) { +#else + if (FAIL == mysql_stmt_attr_set(stmt->stmt, attr, mode_p)) { +#endif + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto int mysqli_stmt_attr_get(object stmt, long attr) +*/ +PHP_FUNCTION(mysqli_stmt_attr_get) +{ + MY_STMT *stmt; + zval *mysql_stmt; + ulong value = 0; + ulong attr; + int rc; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_stmt, mysqli_stmt_class_entry, &attr) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + if ((rc = mysql_stmt_attr_get(stmt->stmt, attr, &value))) { + RETURN_FALSE; + } + +#if MYSQL_VERSION_ID >= 50107 + if (attr == STMT_ATTR_UPDATE_MAX_LENGTH) + value = *((my_bool *)&value); +#endif + RETURN_LONG((long)value); +} +/* }}} */ + +/* {{{ proto int mysqli_stmt_errno(object stmt) +*/ +PHP_FUNCTION(mysqli_stmt_errno) +{ + MY_STMT *stmt; + zval *mysql_stmt; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_INITIALIZED); + + RETURN_LONG(mysql_stmt_errno(stmt->stmt)); +} +/* }}} */ + +/* {{{ proto string mysqli_stmt_error(object stmt) +*/ +PHP_FUNCTION(mysqli_stmt_error) +{ + MY_STMT *stmt; + zval *mysql_stmt; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_INITIALIZED); + + RETURN_STRING((char *)mysql_stmt_error(stmt->stmt),1); +} +/* }}} */ + +/* {{{ proto mixed mysqli_stmt_init(object link) + Initialize statement object +*/ +PHP_FUNCTION(mysqli_stmt_init) +{ + MY_MYSQL *mysql; + MY_STMT *stmt; + zval *mysql_link; + MYSQLI_RESOURCE *mysqli_resource; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",&mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT)); + + if (!(stmt->stmt = mysql_stmt_init(mysql->mysql))) { + efree(stmt); + RETURN_FALSE; + } + + mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); + mysqli_resource->status = MYSQLI_STATUS_INITIALIZED; + mysqli_resource->ptr = (void *)stmt; + MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_stmt_class_entry); +} +/* }}} */ + +/* {{{ proto bool mysqli_stmt_prepare(object stmt, string query) + prepare server side statement with query +*/ +PHP_FUNCTION(mysqli_stmt_prepare) +{ + MY_STMT *stmt; + zval *mysql_stmt; + char *query; + int query_len; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry, &query, &query_len) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_INITIALIZED); + + if (mysql_stmt_prepare(stmt->stmt, query, query_len)) { + MYSQLI_REPORT_STMT_ERROR(stmt->stmt); + RETURN_FALSE; + } + /* change status */ + MYSQLI_SET_STATUS(&mysql_stmt, MYSQLI_STATUS_VALID); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto mixed mysqli_stmt_result_metadata(object stmt) + return result set from statement */ +PHP_FUNCTION(mysqli_stmt_result_metadata) +{ + MY_STMT *stmt; + MYSQL_RES *result; + zval *mysql_stmt; + MYSQLI_RESOURCE *mysqli_resource; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + if (!(result = mysql_stmt_result_metadata(stmt->stmt))){ + MYSQLI_REPORT_STMT_ERROR(stmt->stmt); + RETURN_FALSE; + } + + mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); + mysqli_resource->ptr = (void *)result; + mysqli_resource->status = MYSQLI_STATUS_VALID; + MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry); +} +/* }}} */ + +/* {{{ proto bool mysqli_stmt_store_result(stmt) +*/ +PHP_FUNCTION(mysqli_stmt_store_result) +{ + MY_STMT *stmt; + zval *mysql_stmt; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + +#if !defined(MYSQLI_USE_MYSQLND) + { + /* + If the user wants to store the data and we have BLOBs/TEXTs we try to allocate + not the maximal length of the type (which is 16MB even for LONGBLOB) but + the maximal length of the field in the result set. If he/she has quite big + BLOB/TEXT columns after calling store_result() the memory usage of PHP will + double - but this is a known problem of the simple MySQL API ;) + */ + int i = 0; + + for (i = mysql_stmt_field_count(stmt->stmt) - 1; i >=0; --i) { + if (stmt->stmt->fields && (stmt->stmt->fields[i].type == MYSQL_TYPE_BLOB || + stmt->stmt->fields[i].type == MYSQL_TYPE_MEDIUM_BLOB || + stmt->stmt->fields[i].type == MYSQL_TYPE_LONG_BLOB || + stmt->stmt->fields[i].type == MYSQL_TYPE_GEOMETRY)) + { +#if MYSQL_VERSION_ID >= 50107 + my_bool tmp=1; +#else + uint tmp=1; +#endif + mysql_stmt_attr_set(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp); + break; + } + } + } +#endif + + if (mysql_stmt_store_result(stmt->stmt)){ + MYSQLI_REPORT_STMT_ERROR(stmt->stmt); + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto string mysqli_stmt_sqlstate(object stmt) +*/ +PHP_FUNCTION(mysqli_stmt_sqlstate) +{ + MY_STMT *stmt; + zval *mysql_stmt; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + RETURN_STRING((char *)mysql_stmt_sqlstate(stmt->stmt),1); +} +/* }}} */ + +/* {{{ proto object mysqli_store_result(object link) + Buffer result set on client */ +PHP_FUNCTION(mysqli_store_result) +{ + MY_MYSQL *mysql; + MYSQL_RES *result; + zval *mysql_link; + MYSQLI_RESOURCE *mysqli_resource; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + if (!(result = mysql_store_result(mysql->mysql))) { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + RETURN_FALSE; + } + if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { + php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql) TSRMLS_CC); + } + + mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); + mysqli_resource->ptr = (void *)result; + mysqli_resource->status = MYSQLI_STATUS_VALID; + MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry); +} +/* }}} */ + + +/* {{{ proto int mysqli_thread_id(object link) + Return the current thread ID */ +PHP_FUNCTION(mysqli_thread_id) +{ + MY_MYSQL *mysql; + zval *mysql_link; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + RETURN_LONG((long) mysql_thread_id(mysql->mysql)); +} +/* }}} */ + +/* {{{ proto bool mysqli_thread_safe(void) + Return whether thread safety is given or not */ +PHP_FUNCTION(mysqli_thread_safe) +{ + RETURN_BOOL(mysql_thread_safe()); +} +/* }}} */ + +/* {{{ proto mixed mysqli_use_result(object link) + Directly retrieve query results - do not buffer results on client side */ +PHP_FUNCTION(mysqli_use_result) +{ + MY_MYSQL *mysql; + MYSQL_RES *result; + zval *mysql_link; + MYSQLI_RESOURCE *mysqli_resource; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + if (!(result = mysql_use_result(mysql->mysql))) { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + RETURN_FALSE; + } + + if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { + php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql) TSRMLS_CC); + } + mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); + mysqli_resource->ptr = (void *)result; + mysqli_resource->status = MYSQLI_STATUS_VALID; + MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry); +} +/* }}} */ + +/* {{{ proto int mysqli_warning_count (object link) + Return number of warnings from the last query for the given link */ +PHP_FUNCTION(mysqli_warning_count) +{ + MY_MYSQL *mysql; + zval *mysql_link; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + RETURN_LONG(mysql_warning_count(mysql->mysql)); +} +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqli/mysqli_driver.c b/ext/mysqli/mysqli_driver.c new file mode 100644 index 0000000..8684edc --- /dev/null +++ b/ext/mysqli/mysqli_driver.c @@ -0,0 +1,185 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Georg Richter <georg@php.net> | + +----------------------------------------------------------------------+ + +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <signal.h> + +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +#include "php_mysqli_structs.h" +#include "zend_exceptions.h" +#include "mysqli_fe.h" + +#define MAP_PROPERTY_MYG_BOOL_READ(name, value) \ +static int name(mysqli_object *obj, zval **retval TSRMLS_DC) \ +{ \ + MAKE_STD_ZVAL(*retval); \ + ZVAL_BOOL(*retval, MyG(value)); \ + return SUCCESS; \ +} \ + +#define MAP_PROPERTY_MYG_BOOL_WRITE(name, value) \ +static int name(mysqli_object *obj, zval *value TSRMLS_DC) \ +{ \ + MyG(value) = Z_LVAL_P(value) > 0; \ + return SUCCESS; \ +} \ + +#define MAP_PROPERTY_MYG_LONG_READ(name, value) \ +static int name(mysqli_object *obj, zval **retval TSRMLS_DC) \ +{ \ + MAKE_STD_ZVAL(*retval); \ + ZVAL_LONG(*retval, MyG(value)); \ + return SUCCESS; \ +} \ + +#define MAP_PROPERTY_MYG_LONG_WRITE(name, value) \ +static int name(mysqli_object *obj, zval *value TSRMLS_DC) \ +{ \ + MyG(value) = Z_LVAL_P(value); \ + return SUCCESS; \ +} \ + +#define MAP_PROPERTY_MYG_STRING_READ(name, value) \ +static int name(mysqli_object *obj, zval **retval TSRMLS_DC) \ +{ \ + MAKE_STD_ZVAL(*retval); \ + ZVAL_STRING(*retval, MyG(value), 1); \ + return SUCCESS; \ +} \ + +#define MAP_PROPERTY_MYG_STRING_WRITE(name, value) \ +static int name(mysqli_object *obj, zval *value TSRMLS_DC) \ +{ \ + MyG(value) = Z_STRVAL_P(value); \ + return SUCCESS; \ +} \ + +/* {{{ property driver_report_write */ +static int driver_report_write(mysqli_object *obj, zval *value TSRMLS_DC) +{ + MyG(report_mode) = Z_LVAL_P(value); + /*FIXME*/ + /* zend_replace_error_handling(MyG(report_mode) & MYSQLI_REPORT_STRICT ? EH_THROW : EH_NORMAL, NULL, NULL TSRMLS_CC); */ + return SUCCESS; +} +/* }}} */ + +/* {{{ property driver_embedded_read */ +static int driver_embedded_read(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MAKE_STD_ZVAL(*retval); +#ifdef HAVE_EMBEDDED_MYSQLI + ZVAL_BOOL(*retval, 1); +#else + ZVAL_BOOL(*retval, 0); +#endif + return SUCCESS; +} +/* }}} */ + +/* {{{ property driver_client_version_read */ +static int driver_client_version_read(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MAKE_STD_ZVAL(*retval); + ZVAL_LONG(*retval, MYSQL_VERSION_ID); + return SUCCESS; +} +/* }}} */ + +/* {{{ property driver_client_info_read */ +static int driver_client_info_read(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MAKE_STD_ZVAL(*retval); + ZVAL_STRING(*retval, (char *)mysql_get_client_info(), 1); + return SUCCESS; +} +/* }}} */ + +/* {{{ property driver_driver_version_read */ +static int driver_driver_version_read(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MAKE_STD_ZVAL(*retval); + ZVAL_LONG(*retval, MYSQLI_VERSION_ID); + return SUCCESS; +} +/* }}} */ + +MAP_PROPERTY_MYG_BOOL_READ(driver_reconnect_read, reconnect) +MAP_PROPERTY_MYG_BOOL_WRITE(driver_reconnect_write, reconnect) +MAP_PROPERTY_MYG_LONG_READ(driver_report_read, report_mode) + +ZEND_FUNCTION(mysqli_driver_construct) +{ +#if G0 + MYSQLI_RESOURCE *mysqli_resource; + + mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); + mysqli_resource->ptr = 1; + mysqli_resource->status = (ZEND_NUM_ARGS() == 1) ? MYSQLI_STATUS_INITIALIZED : MYSQLI_STATUS_VALID; + ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr = mysqli_resource; +#endif +} + +const mysqli_property_entry mysqli_driver_property_entries[] = { + {"client_info", sizeof("client_info") - 1, driver_client_info_read, NULL}, + {"client_version", sizeof("client_version") - 1, driver_client_version_read, NULL}, + {"driver_version", sizeof("driver_version") - 1, driver_driver_version_read, NULL}, + {"embedded", sizeof("embedded") - 1, driver_embedded_read, NULL}, + {"reconnect", sizeof("reconnect") - 1, driver_reconnect_read, driver_reconnect_write}, + {"report_mode", sizeof("report_mode") - 1, driver_report_read, driver_report_write}, + {NULL, 0, NULL, NULL} +}; + +/* {{{ mysqli_warning_property_info_entries */ +const zend_property_info mysqli_driver_property_info_entries[] = { + {ZEND_ACC_PUBLIC, "client_info", sizeof("client_info") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "client_version", sizeof("client_version") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "driver_version", sizeof("driver_version") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "embedded", sizeof("embedded") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "reconnect", sizeof("reconnect") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "report_mode", sizeof("report_mode") - 1, -1, 0, NULL, 0, NULL}, + {0, NULL, 0, -1, 0, NULL, 0, NULL}, +}; +/* }}} */ + + +/* {{{ mysqli_driver_methods[] + */ +const zend_function_entry mysqli_driver_methods[] = { +#if defined(HAVE_EMBEDDED_MYSQLI) + PHP_FALIAS(embedded_server_start, mysqli_embedded_server_start, NULL) + PHP_FALIAS(embedded_server_end, mysqli_embedded_server_end, NULL) +#endif + {NULL, NULL, NULL} +}; +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * indent-tabs-mode: t + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqli/mysqli_embedded.c b/ext/mysqli/mysqli_embedded.c new file mode 100644 index 0000000..3693777 --- /dev/null +++ b/ext/mysqli/mysqli_embedded.c @@ -0,0 +1,131 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Georg Richter <georg@php.net> | + +----------------------------------------------------------------------+ + +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <signal.h> + +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +#include "php_mysqli_structs.h" + +/* {{{ proto bool mysqli_embedded_server_start(bool start, array arguments, array groups) + initialize and start embedded server */ +PHP_FUNCTION(mysqli_embedded_server_start) +{ +#ifdef HAVE_EMBEDDED_MYSQLI + long start; + zval *args; + zval *grps; + + int argc = 0; + char **arguments; + char **groups; + HashPosition pos; + int index, rc; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "laa", &start, &args, &grps) == FAILURE) { + return; + } + + if (!start) { + mysql_server_init(-1,NULL, NULL); + RETURN_TRUE; + } + /* get arguments */ + if ((argc = zend_hash_num_elements(HASH_OF(args)))) { + arguments = safe_emalloc(sizeof(char *), argc + 1, 0); + arguments[0] = NULL; + + zend_hash_internal_pointer_reset_ex(HASH_OF(args), &pos); + + for (index = 0;; zend_hash_move_forward_ex(HASH_OF(args), &pos)) { + zval **item; + + if (zend_hash_get_current_data_ex(HASH_OF(args), (void **) &item, &pos) == FAILURE) { + break; + } + + convert_to_string_ex(item); + + arguments[++index] = Z_STRVAL_PP(item); + } + argc++; + } + + /* get groups */ + if ((zend_hash_num_elements(HASH_OF(grps)))) { + groups = safe_emalloc(sizeof(char *), zend_hash_num_elements(HASH_OF(grps)) + 1, 0); + groups[0] = NULL; + + zend_hash_internal_pointer_reset_ex(HASH_OF(grps), &pos); + + for (index = 0;; zend_hash_move_forward_ex(HASH_OF(grps), &pos)) { + zval ** item; + + if (zend_hash_get_current_data_ex(HASH_OF(grps), (void **) &item, &pos) == FAILURE) { + break; + } + + convert_to_string_ex(item); + + groups[++index] = Z_STRVAL_PP(item); + } + groups[index] = NULL; + } else { + groups = safe_emalloc(sizeof(char *), 1, 0); + groups[0] = NULL; + } + + rc = mysql_server_init(argc, arguments, groups); + + if (argc) { + efree(arguments); + } + efree(groups); + + if (rc) { + RETURN_FALSE; + } + RETURN_TRUE; +#endif +} +/* }}} */ + +/* {{{ proto void mysqli_embedded_server_end(void) +*/ +PHP_FUNCTION(mysqli_embedded_server_end) +{ +#ifdef HAVE_MYSQLI_EMBEDDED + mysql_server_end(); +#endif +} +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * indent-tabs-mode: t + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqli/mysqli_exception.c b/ext/mysqli/mysqli_exception.c new file mode 100644 index 0000000..dafc309 --- /dev/null +++ b/ext/mysqli/mysqli_exception.c @@ -0,0 +1,85 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Georg Richter <georg@php.net> | + +----------------------------------------------------------------------+ + +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <signal.h> + +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +#include "php_mysqli_structs.h" +#include "mysqli_priv.h" +#include "zend_exceptions.h" + +/* {{{ mysqli_exception_methods[] + */ +const zend_function_entry mysqli_exception_methods[] = { + {NULL, NULL, NULL} +}; +/* }}} */ + +void php_mysqli_throw_sql_exception(char *sqlstate, int errorno TSRMLS_DC, char *format, ...) +{ + zval *sql_ex; + va_list arg; + char *message; + + va_start(arg, format); + vspprintf(&message, 0, format, arg); + va_end(arg);; + + if (!(MyG(report_mode) & MYSQLI_REPORT_STRICT)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "(%s/%d): %s", sqlstate, errorno, message); + efree(message); + return; + } + + MAKE_STD_ZVAL(sql_ex); + object_init_ex(sql_ex, mysqli_exception_class_entry); + + if (message) { + zend_update_property_string(mysqli_exception_class_entry, sql_ex, "message", sizeof("message") - 1, + message TSRMLS_CC); + } + + if (sqlstate) { + zend_update_property_string(mysqli_exception_class_entry, sql_ex, "sqlstate", sizeof("sqlstate") - 1, + sqlstate TSRMLS_CC); + } else { + zend_update_property_string(mysqli_exception_class_entry, sql_ex, "sqlstate", sizeof("sqlstate") - 1, + "00000" TSRMLS_CC); + } + + efree(message); + zend_update_property_long(mysqli_exception_class_entry, sql_ex, "code", sizeof("code") - 1, errorno TSRMLS_CC); + + zend_throw_exception_object(sql_ex TSRMLS_CC); +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * indent-tabs-mode: t + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqli/mysqli_fe.c b/ext/mysqli/mysqli_fe.c new file mode 100644 index 0000000..8bcb02f --- /dev/null +++ b/ext/mysqli/mysqli_fe.c @@ -0,0 +1,597 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Georg Richter <georg@php.net> | + | Andrey Hristov <andrey@php.net> | + | Ulf Wendel <uw@php.net> | + +----------------------------------------------------------------------+ + + $Id$ +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <signal.h> + +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +#include "php_mysqli_structs.h" +#include "mysqli_fe.h" +#include "mysqli_priv.h" + +#ifdef MYSQLI_USE_FULL_TYPED_ARGINFO_0 +#define MYSQLI_ZEND_ARG_OBJ_INFO_LINK() ZEND_ARG_OBJ_INFO(0, link, mysqli, 0) +#define MYSQLI_ZEND_ARG_OBJ_INFO_RESULT() ZEND_ARG_OBJ_INFO(0, result, mysqli_result, 0) +#define MYSQLI_ZEND_ARG_OBJ_INFO_STMT() ZEND_ARG_OBJ_INFO(0, stmt, mysqli_stmt, 0) +#else +#define MYSQLI_ZEND_ARG_OBJ_INFO_LINK() ZEND_ARG_INFO(0, link) +#define MYSQLI_ZEND_ARG_OBJ_INFO_RESULT() ZEND_ARG_INFO(0, result) +#define MYSQLI_ZEND_ARG_OBJ_INFO_STMT() ZEND_ARG_INFO(0, stmt) +#endif + +ZEND_BEGIN_ARG_INFO(arginfo_mysqli_stmt_bind_result, 1) + MYSQLI_ZEND_ARG_OBJ_INFO_STMT() +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_mysqli_stmt_bind_param, 1) + MYSQLI_ZEND_ARG_OBJ_INFO_STMT() + ZEND_ARG_INFO(0, types) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_class_mysqli_stmt_bind_result, 1) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_class_mysqli_stmt_bind_param, 1) + ZEND_ARG_INFO(0, types) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(all_args_force_by_ref, 1) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_poll, 0, 0, 4) + ZEND_ARG_ARRAY_INFO(1, read, 1) + ZEND_ARG_ARRAY_INFO(1, write, 1) + ZEND_ARG_ARRAY_INFO(1, error, 1) + ZEND_ARG_INFO(0, sec) + ZEND_ARG_INFO(0, usec) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_no_params, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_only_link, 0, 0, 1) + MYSQLI_ZEND_ARG_OBJ_INFO_LINK() +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_autocommit, 0, 0, 2) + MYSQLI_ZEND_ARG_OBJ_INFO_LINK() + ZEND_ARG_INFO(0, mode) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_autocommit, 0, 0, 1) + ZEND_ARG_INFO(0, mode) +ZEND_END_ARG_INFO() + + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_change_user, 0, 0, 4) + MYSQLI_ZEND_ARG_OBJ_INFO_LINK() + ZEND_ARG_INFO(0, user) + ZEND_ARG_INFO(0, password) + ZEND_ARG_INFO(0, database) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_change_user, 0, 0, 3) + ZEND_ARG_INFO(0, user) + ZEND_ARG_INFO(0, password) + ZEND_ARG_INFO(0, database) +ZEND_END_ARG_INFO() + + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_connect, 0, 0, 0) + ZEND_ARG_INFO(0, host) + ZEND_ARG_INFO(0, user) + ZEND_ARG_INFO(0, password) + ZEND_ARG_INFO(0, database) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, socket) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_real_connect, 0, 0, 1) + MYSQLI_ZEND_ARG_OBJ_INFO_LINK() + ZEND_ARG_INFO(0, host) + ZEND_ARG_INFO(0, user) + ZEND_ARG_INFO(0, password) + ZEND_ARG_INFO(0, database) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, socket) + ZEND_ARG_INFO(0, flags) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_real_connect, 0, 0, 0) + ZEND_ARG_INFO(0, host) + ZEND_ARG_INFO(0, user) + ZEND_ARG_INFO(0, password) + ZEND_ARG_INFO(0, database) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, socket) + ZEND_ARG_INFO(0, flags) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_only_result, 0, 0, 1) + MYSQLI_ZEND_ARG_OBJ_INFO_RESULT() +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_only_statement, 0, 0, 1) + MYSQLI_ZEND_ARG_OBJ_INFO_STMT() +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_data_seek, 0, 0, 2) + MYSQLI_ZEND_ARG_OBJ_INFO_RESULT() + ZEND_ARG_INFO(0, offset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_stmt_data_seek, 0, 0, 2) + MYSQLI_ZEND_ARG_OBJ_INFO_STMT() + ZEND_ARG_INFO(0, offset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_data_seek, 0, 0, 1) + ZEND_ARG_INFO(0, offset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_debug, 0, 0, 1) + ZEND_ARG_INFO(0, debug_options) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_result_and_fieldnr, 0, 0, 2) + MYSQLI_ZEND_ARG_OBJ_INFO_RESULT() + ZEND_ARG_INFO(0, field_nr) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_result_and_fieldnr, 0, 0, 1) + ZEND_ARG_INFO(0, field_nr) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_fetch_array, 0, 0, 1) + MYSQLI_ZEND_ARG_OBJ_INFO_RESULT() + ZEND_ARG_INFO(0, result_type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_fetch_array, 0, 0, 0) + ZEND_ARG_INFO(0, result_type) +ZEND_END_ARG_INFO() + + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_fetch_object, 0, 0, 1) +#if PHP_VERSION_ID > 50399 + MYSQLI_ZEND_ARG_OBJ_INFO_RESULT() + ZEND_ARG_INFO(0, class_name) + ZEND_ARG_ARRAY_INFO(0, params, 0) +#endif +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_fetch_object, 0, 0, 0) +#if PHP_VERSION_ID > 50399 + ZEND_ARG_INFO(0, class_name) + ZEND_ARG_ARRAY_INFO(0, params, 0) +#endif +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_kill, 0, 0, 2) + MYSQLI_ZEND_ARG_OBJ_INFO_LINK() + ZEND_ARG_INFO(0, connection_id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_kill, 0, 0, 1) + ZEND_ARG_INFO(0, connection_id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_set_local_infile_handler, 0, 0, 2) + MYSQLI_ZEND_ARG_OBJ_INFO_LINK() + ZEND_ARG_INFO(0, read_callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_set_local_infile_handler, 0, 0, 1) + MYSQLI_ZEND_ARG_OBJ_INFO_LINK() + ZEND_ARG_INFO(0, read_callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_query, 0, 0, 2) + MYSQLI_ZEND_ARG_OBJ_INFO_LINK() + ZEND_ARG_INFO(0, query) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_prepare, 0, 0, 2) + MYSQLI_ZEND_ARG_OBJ_INFO_LINK() + ZEND_ARG_INFO(0, query) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_stmt_prepare, 0, 0, 2) + MYSQLI_ZEND_ARG_OBJ_INFO_STMT() + ZEND_ARG_INFO(0, query) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_query, 0, 0, 1) + ZEND_ARG_INFO(0, query) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_options, 0, 0, 3) + MYSQLI_ZEND_ARG_OBJ_INFO_LINK() + ZEND_ARG_INFO(0, option) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_options, 0, 0, 2) + ZEND_ARG_INFO(0, option) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_report, 0, 0, 1) + ZEND_ARG_INFO(0, flags) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_real_escape_string, 0, 0, 2) + MYSQLI_ZEND_ARG_OBJ_INFO_LINK() + ZEND_ARG_INFO(0, string_to_escape) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_real_escape_string, 0, 0, 1) + ZEND_ARG_INFO(0, string_to_escape) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_select_db, 0, 0, 2) + MYSQLI_ZEND_ARG_OBJ_INFO_LINK() + ZEND_ARG_INFO(0, database) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_select_db, 0, 0, 1) + ZEND_ARG_INFO(0, database) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_set_charset, 0, 0, 2) + MYSQLI_ZEND_ARG_OBJ_INFO_LINK() + ZEND_ARG_INFO(0, charset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_set_charset, 0, 0, 1) + ZEND_ARG_INFO(0, charset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_stmt_attr_get, 0, 0, 2) + MYSQLI_ZEND_ARG_OBJ_INFO_STMT() + ZEND_ARG_INFO(0, attribute) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_stmt_attr_get, 0, 0, 1) + ZEND_ARG_INFO(0, attribute) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_stmt_attr_set, 0, 0, 3) + MYSQLI_ZEND_ARG_OBJ_INFO_STMT() + ZEND_ARG_INFO(0, attribute) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_stmt_attr_set, 0, 0, 2) + ZEND_ARG_INFO(0, attribute) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_stmt_send_long_data, 0, 0, 3) + MYSQLI_ZEND_ARG_OBJ_INFO_STMT() + ZEND_ARG_INFO(0, param_nr) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_stmt_send_long_data, 0, 0, 2) + ZEND_ARG_INFO(0, param_nr) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_ssl_set, 0, 0, 6) + MYSQLI_ZEND_ARG_OBJ_INFO_LINK() + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, cert) + ZEND_ARG_INFO(0, certificate_authority) + ZEND_ARG_INFO(0, certificate_authority_path) + ZEND_ARG_INFO(0, cipher) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_ssl_set, 0, 0, 5) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, cert) + ZEND_ARG_INFO(0, certificate_authority) + ZEND_ARG_INFO(0, certificate_authority_path) + ZEND_ARG_INFO(0, cipher) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_refresh, 0, 0, 2) + MYSQLI_ZEND_ARG_OBJ_INFO_LINK() + ZEND_ARG_INFO(0, options) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_refresh, 0, 0, 1) + ZEND_ARG_INFO(0, options) +ZEND_END_ARG_INFO() + + +/* {{{ mysqli_functions[] + * + * Every user visible function must have an entry in mysqli_functions[]. + */ +const zend_function_entry mysqli_functions[] = { + PHP_FE(mysqli_affected_rows, arginfo_mysqli_only_link) + PHP_FE(mysqli_autocommit, arginfo_mysqli_autocommit) + PHP_FE(mysqli_change_user, arginfo_mysqli_change_user) + PHP_FE(mysqli_character_set_name, arginfo_mysqli_only_link) + PHP_FE(mysqli_close, arginfo_mysqli_only_link) + PHP_FE(mysqli_commit, arginfo_mysqli_only_link) + PHP_FE(mysqli_connect, arginfo_mysqli_connect) + PHP_FE(mysqli_connect_errno, arginfo_mysqli_no_params) + PHP_FE(mysqli_connect_error, arginfo_mysqli_no_params) + PHP_FE(mysqli_data_seek, arginfo_mysqli_data_seek) + PHP_FE(mysqli_dump_debug_info, arginfo_mysqli_only_link) + PHP_FE(mysqli_debug, arginfo_mysqli_debug) +#if defined(HAVE_EMBEDDED_MYSQLI) + PHP_FE(mysqli_embedded_server_end, NULL) + PHP_FE(mysqli_embedded_server_start, NULL) +#endif + PHP_FE(mysqli_errno, arginfo_mysqli_only_link) + PHP_FE(mysqli_error, arginfo_mysqli_only_link) + PHP_FE(mysqli_error_list, arginfo_mysqli_only_link) + PHP_FE(mysqli_stmt_execute, arginfo_mysqli_only_statement) + PHP_FALIAS(mysqli_execute, mysqli_stmt_execute, arginfo_mysqli_only_statement) + PHP_FE(mysqli_fetch_field, arginfo_mysqli_only_result) + PHP_FE(mysqli_fetch_fields, arginfo_mysqli_only_result) + PHP_FE(mysqli_fetch_field_direct, arginfo_mysqli_result_and_fieldnr) + PHP_FE(mysqli_fetch_lengths, arginfo_mysqli_only_result) +#ifdef MYSQLI_USE_MYSQLND + PHP_FE(mysqli_fetch_all, arginfo_mysqli_only_result) +#endif + PHP_FE(mysqli_fetch_array, arginfo_mysqli_fetch_array) + PHP_FE(mysqli_fetch_assoc, arginfo_mysqli_only_result) + PHP_FE(mysqli_fetch_object, arginfo_mysqli_fetch_object) + PHP_FE(mysqli_fetch_row, arginfo_mysqli_only_result) + PHP_FE(mysqli_field_count, arginfo_mysqli_only_link) + PHP_FE(mysqli_field_seek, arginfo_mysqli_result_and_fieldnr) + PHP_FE(mysqli_field_tell, arginfo_mysqli_only_result) + PHP_FE(mysqli_free_result, arginfo_mysqli_only_result) +#if defined(MYSQLI_USE_MYSQLND) + PHP_FE(mysqli_get_connection_stats, arginfo_mysqli_only_link) + PHP_FE(mysqli_get_client_stats, arginfo_mysqli_no_params) +#endif +#ifdef HAVE_MYSQLI_GET_CHARSET + PHP_FE(mysqli_get_charset, arginfo_mysqli_only_link) +#endif + PHP_FE(mysqli_get_client_info, arginfo_mysqli_only_link) + PHP_FE(mysqli_get_client_version, arginfo_mysqli_only_link) + PHP_FE(mysqli_get_host_info, arginfo_mysqli_only_link) + PHP_FE(mysqli_get_proto_info, arginfo_mysqli_only_link) + PHP_FE(mysqli_get_server_info, arginfo_mysqli_only_link) + PHP_FE(mysqli_get_server_version, arginfo_mysqli_only_link) + PHP_FE(mysqli_get_warnings, arginfo_mysqli_only_link) + PHP_FE(mysqli_init, arginfo_mysqli_no_params) + PHP_FE(mysqli_info, arginfo_mysqli_only_link) + PHP_FE(mysqli_insert_id, arginfo_mysqli_only_link) + PHP_FE(mysqli_kill, arginfo_mysqli_kill) +#if !defined(MYSQLI_USE_MYSQLND) + PHP_FE(mysqli_set_local_infile_default, arginfo_mysqli_only_link) + PHP_FE(mysqli_set_local_infile_handler, arginfo_mysqli_set_local_infile_handler) +#endif + PHP_FE(mysqli_more_results, arginfo_mysqli_only_link) + PHP_FE(mysqli_multi_query, arginfo_mysqli_query) + PHP_FE(mysqli_next_result, arginfo_mysqli_only_link) + PHP_FE(mysqli_num_fields, arginfo_mysqli_only_result) + PHP_FE(mysqli_num_rows, arginfo_mysqli_only_result) + PHP_FE(mysqli_options, arginfo_mysqli_options) + PHP_FE(mysqli_ping, arginfo_mysqli_only_link) +#if defined(MYSQLI_USE_MYSQLND) + PHP_FE(mysqli_poll, arginfo_mysqli_poll) +#endif + PHP_FE(mysqli_prepare, arginfo_mysqli_prepare) + PHP_FE(mysqli_report, arginfo_mysqli_report) + PHP_FE(mysqli_query, arginfo_mysqli_query) + PHP_FE(mysqli_real_connect, arginfo_mysqli_real_connect) + PHP_FE(mysqli_real_escape_string, arginfo_mysqli_real_escape_string) + PHP_FE(mysqli_real_query, arginfo_mysqli_query) +#if defined(MYSQLI_USE_MYSQLND) + PHP_FE(mysqli_reap_async_query, arginfo_mysqli_only_link) +#endif + PHP_FE(mysqli_rollback, arginfo_mysqli_only_link) + PHP_FE(mysqli_select_db, arginfo_mysqli_select_db) +#ifdef HAVE_MYSQLI_SET_CHARSET + PHP_FE(mysqli_set_charset, arginfo_mysqli_set_charset) +#endif + PHP_FE(mysqli_stmt_affected_rows, arginfo_mysqli_only_statement) + PHP_FE(mysqli_stmt_attr_get, arginfo_mysqli_stmt_attr_get) + PHP_FE(mysqli_stmt_attr_set, arginfo_mysqli_stmt_attr_set) + PHP_FE(mysqli_stmt_bind_param, arginfo_mysqli_stmt_bind_param) + PHP_FE(mysqli_stmt_bind_result, arginfo_mysqli_stmt_bind_result) + PHP_FE(mysqli_stmt_close, arginfo_mysqli_only_statement) + PHP_FE(mysqli_stmt_data_seek, arginfo_mysqli_stmt_data_seek) + PHP_FE(mysqli_stmt_errno, arginfo_mysqli_only_statement) + PHP_FE(mysqli_stmt_error, arginfo_mysqli_only_statement) + PHP_FE(mysqli_stmt_error_list, arginfo_mysqli_only_statement) + PHP_FE(mysqli_stmt_fetch, arginfo_mysqli_only_statement) + PHP_FE(mysqli_stmt_field_count, arginfo_mysqli_only_statement) + PHP_FE(mysqli_stmt_free_result, arginfo_mysqli_only_statement) +#if defined(MYSQLI_USE_MYSQLND) + PHP_FE(mysqli_stmt_get_result, arginfo_mysqli_only_statement) +#endif + PHP_FE(mysqli_stmt_get_warnings, arginfo_mysqli_only_statement) + PHP_FE(mysqli_stmt_init, arginfo_mysqli_only_link) + PHP_FE(mysqli_stmt_insert_id, arginfo_mysqli_only_statement) +#if defined(MYSQLI_USE_MYSQLND) + PHP_FE(mysqli_stmt_more_results, arginfo_mysqli_only_statement) + PHP_FE(mysqli_stmt_next_result, arginfo_mysqli_only_statement) +#endif + PHP_FE(mysqli_stmt_num_rows, arginfo_mysqli_only_statement) + PHP_FE(mysqli_stmt_param_count, arginfo_mysqli_only_statement) + PHP_FE(mysqli_stmt_prepare, arginfo_mysqli_stmt_prepare) + PHP_FE(mysqli_stmt_reset, arginfo_mysqli_only_statement) + PHP_FE(mysqli_stmt_result_metadata, arginfo_mysqli_only_statement) + PHP_FE(mysqli_stmt_send_long_data, arginfo_mysqli_stmt_send_long_data) + PHP_FE(mysqli_stmt_store_result, arginfo_mysqli_only_statement) + PHP_FE(mysqli_stmt_sqlstate, arginfo_mysqli_only_statement) + PHP_FE(mysqli_sqlstate, arginfo_mysqli_only_link) + PHP_FE(mysqli_ssl_set, arginfo_mysqli_ssl_set) + PHP_FE(mysqli_stat, arginfo_mysqli_only_link) + PHP_FE(mysqli_store_result, arginfo_mysqli_only_link) + PHP_FE(mysqli_thread_id, arginfo_mysqli_only_link) + PHP_FE(mysqli_thread_safe, arginfo_mysqli_no_params) + PHP_FE(mysqli_use_result, arginfo_mysqli_only_link) + PHP_FE(mysqli_warning_count, arginfo_mysqli_only_link) + + PHP_FE(mysqli_refresh, arginfo_mysqli_refresh) + + /* Aliases */ + PHP_FALIAS(mysqli_escape_string, mysqli_real_escape_string, arginfo_mysqli_query) + PHP_FALIAS(mysqli_set_opt, mysqli_options, NULL) + + PHP_FE_END +}; +/* }}} */ + +/* {{{ mysqli_link_methods[] + * + * Every user visible function must have an entry in mysqli_functions[]. + */ +const zend_function_entry mysqli_link_methods[] = { + PHP_FALIAS(autocommit, mysqli_autocommit, arginfo_class_mysqli_autocommit) + PHP_FALIAS(change_user,mysqli_change_user, arginfo_class_mysqli_change_user) + PHP_FALIAS(character_set_name, mysqli_character_set_name, arginfo_mysqli_no_params) + PHP_FALIAS(close, mysqli_close, arginfo_mysqli_no_params) + PHP_FALIAS(commit, mysqli_commit, arginfo_mysqli_no_params) + PHP_FALIAS(connect, mysqli_connect, arginfo_mysqli_connect) + PHP_FALIAS(dump_debug_info, mysqli_dump_debug_info, arginfo_mysqli_no_params) + PHP_FALIAS(debug, mysqli_debug, arginfo_mysqli_debug) +#ifdef HAVE_MYSQLI_GET_CHARSET + PHP_FALIAS(get_charset, mysqli_get_charset, arginfo_mysqli_no_params) +#endif + PHP_FALIAS(get_client_info, mysqli_get_client_info, arginfo_mysqli_no_params) +#if defined(MYSQLI_USE_MYSQLND) + PHP_FALIAS(get_connection_stats, mysqli_get_connection_stats, arginfo_mysqli_no_params) +#endif + PHP_FALIAS(get_server_info, mysqli_get_server_info, arginfo_mysqli_no_params) + PHP_FALIAS(get_warnings, mysqli_get_warnings, arginfo_mysqli_no_params) + PHP_FALIAS(init,mysqli_init, arginfo_mysqli_no_params) + PHP_FALIAS(kill,mysqli_kill, arginfo_class_mysqli_kill) +#if !defined(MYSQLI_USE_MYSQLND) + PHP_FALIAS(set_local_infile_default, mysqli_set_local_infile_default, arginfo_mysqli_no_params) + PHP_FALIAS(set_local_infile_handler, mysqli_set_local_infile_handler, arginfo_class_mysqli_set_local_infile_handler) +#endif + PHP_FALIAS(multi_query, mysqli_multi_query, arginfo_class_mysqli_query) + PHP_FALIAS(mysqli, mysqli_link_construct, arginfo_mysqli_connect) + PHP_FALIAS(more_results, mysqli_more_results, arginfo_mysqli_no_params) + PHP_FALIAS(next_result, mysqli_next_result, arginfo_mysqli_no_params) + PHP_FALIAS(options, mysqli_options, arginfo_class_mysqli_options) + PHP_FALIAS(ping, mysqli_ping, arginfo_mysqli_no_params) +#if defined(MYSQLI_USE_MYSQLND) + ZEND_FENTRY(poll, ZEND_FN(mysqli_poll), arginfo_mysqli_poll, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) +#endif + PHP_FALIAS(prepare, mysqli_prepare, arginfo_class_mysqli_query) + PHP_FALIAS(query, mysqli_query, arginfo_class_mysqli_query) + PHP_FALIAS(real_connect, mysqli_real_connect, arginfo_class_mysqli_real_connect) + PHP_FALIAS(real_escape_string, mysqli_real_escape_string, arginfo_class_mysqli_real_escape_string) +#if defined(MYSQLI_USE_MYSQLND) + PHP_FALIAS(reap_async_query, mysqli_reap_async_query, arginfo_mysqli_no_params) +#endif + PHP_FALIAS(escape_string, mysqli_real_escape_string, arginfo_class_mysqli_real_escape_string) + PHP_FALIAS(real_query, mysqli_real_query, arginfo_class_mysqli_query) + PHP_FALIAS(rollback,mysqli_rollback, arginfo_mysqli_no_params) + PHP_FALIAS(select_db,mysqli_select_db, arginfo_class_mysqli_select_db) +#ifdef HAVE_MYSQLI_SET_CHARSET + PHP_FALIAS(set_charset, mysqli_set_charset, arginfo_class_mysqli_set_charset) +#endif + PHP_FALIAS(set_opt, mysqli_options, arginfo_class_mysqli_options) + PHP_FALIAS(ssl_set, mysqli_ssl_set, arginfo_class_mysqli_ssl_set) + PHP_FALIAS(stat, mysqli_stat, arginfo_mysqli_no_params) + PHP_FALIAS(stmt_init, mysqli_stmt_init, arginfo_mysqli_no_params) + PHP_FALIAS(store_result, mysqli_store_result, arginfo_mysqli_no_params) + PHP_FALIAS(thread_safe, mysqli_thread_safe, arginfo_mysqli_no_params) + PHP_FALIAS(use_result, mysqli_use_result, arginfo_mysqli_no_params) + PHP_FALIAS(refresh,mysqli_refresh, arginfo_class_mysqli_refresh) + {NULL, NULL, NULL} +}; +/* }}} */ + +/* {{{ mysqli_result_methods[] + * + * Every user visible function must have an entry in mysqli_result_functions[]. + */ +const zend_function_entry mysqli_result_methods[] = { + PHP_FALIAS(__construct, mysqli_result_construct, NULL) + PHP_FALIAS(close, mysqli_free_result, arginfo_mysqli_no_params) + PHP_FALIAS(free, mysqli_free_result, arginfo_mysqli_no_params) + PHP_FALIAS(data_seek, mysqli_data_seek, arginfo_class_mysqli_data_seek) + PHP_FALIAS(fetch_field, mysqli_fetch_field, arginfo_mysqli_no_params) + PHP_FALIAS(fetch_fields, mysqli_fetch_fields, arginfo_mysqli_no_params) + PHP_FALIAS(fetch_field_direct, mysqli_fetch_field_direct, arginfo_class_mysqli_result_and_fieldnr) +#if defined(MYSQLI_USE_MYSQLND) + PHP_FALIAS(fetch_all, mysqli_fetch_all, arginfo_mysqli_no_params) +#endif + PHP_FALIAS(fetch_array, mysqli_fetch_array, arginfo_class_mysqli_fetch_array) + PHP_FALIAS(fetch_assoc, mysqli_fetch_assoc, arginfo_mysqli_no_params) + PHP_FALIAS(fetch_object,mysqli_fetch_object, arginfo_class_mysqli_fetch_object) + PHP_FALIAS(fetch_row, mysqli_fetch_row, arginfo_mysqli_no_params) + PHP_FALIAS(field_seek, mysqli_field_seek, arginfo_class_mysqli_result_and_fieldnr) + PHP_FALIAS(free_result, mysqli_free_result, arginfo_mysqli_no_params) + {NULL, NULL, NULL} +}; +/* }}} */ + +/* {{{ mysqli_stmt_methods[] + * + * Every user visible function must have an entry in mysqli_stmt_functions[]. + */ +const zend_function_entry mysqli_stmt_methods[] = { + PHP_FALIAS(__construct, mysqli_stmt_construct, NULL) + PHP_FALIAS(attr_get, mysqli_stmt_attr_get, arginfo_class_mysqli_stmt_attr_get) + PHP_FALIAS(attr_set,mysqli_stmt_attr_set, arginfo_class_mysqli_stmt_attr_set) + PHP_FALIAS(bind_param,mysqli_stmt_bind_param, arginfo_class_mysqli_stmt_bind_param) + PHP_FALIAS(bind_result,mysqli_stmt_bind_result, arginfo_class_mysqli_stmt_bind_result) + PHP_FALIAS(close, mysqli_stmt_close, arginfo_mysqli_no_params) + PHP_FALIAS(data_seek, mysqli_stmt_data_seek, arginfo_class_mysqli_data_seek) + PHP_FALIAS(execute, mysqli_stmt_execute, arginfo_mysqli_no_params) + PHP_FALIAS(fetch, mysqli_stmt_fetch, arginfo_mysqli_no_params) + PHP_FALIAS(get_warnings, mysqli_stmt_get_warnings, arginfo_mysqli_no_params) + PHP_FALIAS(result_metadata, mysqli_stmt_result_metadata, arginfo_mysqli_no_params) +#if defined(MYSQLI_USE_MYSQLND) + PHP_FALIAS(more_results, mysqli_stmt_more_results, arginfo_mysqli_no_params) + PHP_FALIAS(next_result, mysqli_stmt_next_result, arginfo_mysqli_no_params) +#endif + PHP_FALIAS(num_rows, mysqli_stmt_num_rows, arginfo_mysqli_no_params) + PHP_FALIAS(send_long_data, mysqli_stmt_send_long_data, arginfo_class_mysqli_stmt_send_long_data) + PHP_FALIAS(free_result, mysqli_stmt_free_result, arginfo_mysqli_no_params) + PHP_FALIAS(reset, mysqli_stmt_reset, arginfo_mysqli_no_params) + PHP_FALIAS(prepare, mysqli_stmt_prepare, arginfo_class_mysqli_query) + PHP_FALIAS(store_result, mysqli_stmt_store_result, arginfo_mysqli_no_params) +#if defined(MYSQLI_USE_MYSQLND) + PHP_FALIAS(get_result, mysqli_stmt_get_result, arginfo_mysqli_no_params) +#endif + {NULL, NULL, NULL} +}; +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqli/mysqli_fe.h b/ext/mysqli/mysqli_fe.h new file mode 100644 index 0000000..d3e9000 --- /dev/null +++ b/ext/mysqli/mysqli_fe.h @@ -0,0 +1,139 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Georg Richter <georg@php.net> | + Andrey Hristov <andrey@php.net> | + +----------------------------------------------------------------------+ + + $Id: php_mysqli_structs.h 302179 2010-08-13 09:57:04Z andrey $ +*/ + +#ifndef MYSQLI_FE_H +#define MYSQLI_FE_H + +PHP_FUNCTION(mysqli); +PHP_FUNCTION(mysqli_affected_rows); +PHP_FUNCTION(mysqli_autocommit); +PHP_FUNCTION(mysqli_change_user); +PHP_FUNCTION(mysqli_character_set_name); +PHP_FUNCTION(mysqli_set_charset); +PHP_FUNCTION(mysqli_close); +PHP_FUNCTION(mysqli_commit); +PHP_FUNCTION(mysqli_connect); +PHP_FUNCTION(mysqli_connect_errno); +PHP_FUNCTION(mysqli_connect_error); +PHP_FUNCTION(mysqli_data_seek); +PHP_FUNCTION(mysqli_debug); +PHP_FUNCTION(mysqli_dump_debug_info); +PHP_FUNCTION(mysqli_errno); +PHP_FUNCTION(mysqli_error); +PHP_FUNCTION(mysqli_error_list); +PHP_FUNCTION(mysqli_fetch_all); +PHP_FUNCTION(mysqli_fetch_array); +PHP_FUNCTION(mysqli_fetch_assoc); +PHP_FUNCTION(mysqli_fetch_object); +PHP_FUNCTION(mysqli_fetch_field); +PHP_FUNCTION(mysqli_fetch_fields); +PHP_FUNCTION(mysqli_fetch_field_direct); +PHP_FUNCTION(mysqli_fetch_lengths); +PHP_FUNCTION(mysqli_fetch_row); +PHP_FUNCTION(mysqli_field_count); +PHP_FUNCTION(mysqli_field_seek); +PHP_FUNCTION(mysqli_field_tell); +PHP_FUNCTION(mysqli_free_result); +PHP_FUNCTION(mysqli_get_cache_stats); +PHP_FUNCTION(mysqli_get_client_stats); +PHP_FUNCTION(mysqli_get_connection_stats); +PHP_FUNCTION(mysqli_get_charset); +PHP_FUNCTION(mysqli_get_client_info); +PHP_FUNCTION(mysqli_get_client_version); +PHP_FUNCTION(mysqli_get_host_info); +PHP_FUNCTION(mysqli_get_proto_info); +PHP_FUNCTION(mysqli_get_server_info); +PHP_FUNCTION(mysqli_get_server_version); +PHP_FUNCTION(mysqli_get_warnings); +PHP_FUNCTION(mysqli_info); +PHP_FUNCTION(mysqli_insert_id); +PHP_FUNCTION(mysqli_init); +PHP_FUNCTION(mysqli_kill); +PHP_FUNCTION(mysqli_link_construct); +PHP_FUNCTION(mysqli_set_local_infile_default); +PHP_FUNCTION(mysqli_set_local_infile_handler); +PHP_FUNCTION(mysqli_more_results); +PHP_FUNCTION(mysqli_multi_query); +PHP_FUNCTION(mysqli_next_result); +PHP_FUNCTION(mysqli_num_fields); +PHP_FUNCTION(mysqli_num_rows); +PHP_FUNCTION(mysqli_options); +PHP_FUNCTION(mysqli_ping); +PHP_FUNCTION(mysqli_poll); +PHP_FUNCTION(mysqli_prepare); +PHP_FUNCTION(mysqli_query); +PHP_FUNCTION(mysqli_stmt_result_metadata); +PHP_FUNCTION(mysqli_report); +PHP_FUNCTION(mysqli_read_query_result); +PHP_FUNCTION(mysqli_real_connect); +PHP_FUNCTION(mysqli_real_query); +PHP_FUNCTION(mysqli_real_escape_string); +PHP_FUNCTION(mysqli_reap_async_query); +PHP_FUNCTION(mysqli_rollback); +PHP_FUNCTION(mysqli_row_seek); +PHP_FUNCTION(mysqli_select_db); +PHP_FUNCTION(mysqli_stmt_attr_get); +PHP_FUNCTION(mysqli_stmt_attr_set); +PHP_FUNCTION(mysqli_stmt_bind_param); +PHP_FUNCTION(mysqli_stmt_bind_result); +PHP_FUNCTION(mysqli_stmt_execute); +PHP_FUNCTION(mysqli_stmt_field_count); +PHP_FUNCTION(mysqli_stmt_init); +PHP_FUNCTION(mysqli_stmt_prepare); +PHP_FUNCTION(mysqli_stmt_fetch); +PHP_FUNCTION(mysqli_stmt_param_count); +PHP_FUNCTION(mysqli_stmt_send_long_data); +PHP_FUNCTION(mysqli_embedded_server_end); +PHP_FUNCTION(mysqli_embedded_server_start); +PHP_FUNCTION(mysqli_sqlstate); +PHP_FUNCTION(mysqli_ssl_set); +PHP_FUNCTION(mysqli_stat); +PHP_FUNCTION(mysqli_refresh); +PHP_FUNCTION(mysqli_stmt_affected_rows); +PHP_FUNCTION(mysqli_stmt_close); +PHP_FUNCTION(mysqli_stmt_data_seek); +PHP_FUNCTION(mysqli_stmt_errno); +PHP_FUNCTION(mysqli_stmt_error); +PHP_FUNCTION(mysqli_stmt_error_list); +PHP_FUNCTION(mysqli_stmt_free_result); +PHP_FUNCTION(mysqli_stmt_get_result); +PHP_FUNCTION(mysqli_stmt_get_warnings); +PHP_FUNCTION(mysqli_stmt_reset); +PHP_FUNCTION(mysqli_stmt_insert_id); +PHP_FUNCTION(mysqli_stmt_more_results); +PHP_FUNCTION(mysqli_stmt_next_result); +PHP_FUNCTION(mysqli_stmt_num_rows); +PHP_FUNCTION(mysqli_stmt_sqlstate); +PHP_FUNCTION(mysqli_stmt_store_result); +PHP_FUNCTION(mysqli_store_result); +PHP_FUNCTION(mysqli_thread_id); +PHP_FUNCTION(mysqli_thread_safe); +PHP_FUNCTION(mysqli_use_result); +PHP_FUNCTION(mysqli_warning_count); + +PHP_FUNCTION(mysqli_stmt_construct); +PHP_FUNCTION(mysqli_result_construct); +PHP_FUNCTION(mysqli_driver_construct); +PHP_METHOD(mysqli_warning,__construct); + +#endif /* MYSQLI_FE_H */ + + diff --git a/ext/mysqli/mysqli_libmysql.h b/ext/mysqli/mysqli_libmysql.h new file mode 100644 index 0000000..3a7b91b --- /dev/null +++ b/ext/mysqli/mysqli_libmysql.h @@ -0,0 +1,118 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Georg Richter <georg@php.net> | + | Andrey Hristov <andrey@php.net> | + | Ulf Wendel <uw@php.net> | + +----------------------------------------------------------------------+ +*/ + +#ifndef MYSQLI_LIBMYSQL_H +#define MYSQLI_LIBMYSQL_H + +/* These are unused */ +#define MYSQLI_CLOSE_EXPLICIT 0 +#define MYSQLI_CLOSE_IMPLICIT 1 +#define MYSQLI_CLOSE_DISCONNECTED 2 +#define MYSQLND_OPT_NUMERIC_AND_DATETIME_AS_UNICODE 200 +#define MYSQLND_OPT_INT_AND_YEAR_AS_INT 201 + +/* r->data should be always NULL, at least in recent libmysql versions, the status changes once data is read*/ +#define mysqli_result_is_unbuffered(r) ((r)->handle && (r)->handle->status == MYSQL_STATUS_USE_RESULT && (r)->data == NULL) +#define mysqli_result_is_unbuffered_and_not_everything_is_fetched(r) mysqli_result_is_unbuffered(r) +#define mysqli_server_status(c) (c)->server_status +#define mysqli_stmt_get_id(s) ((s)->stmt_id) +#define mysqli_stmt_warning_count(s) mysql_warning_count((s)->mysql) +#define mysqli_stmt_server_status(s) (s)->mysql->server_status +#define mysqli_stmt_get_connection(s) (s)->mysql +#define mysqli_close(c, is_forced) mysql_close((c)) +#define mysqli_stmt_close(c, implicit) mysql_stmt_close((c)) +#define mysqli_free_result(r, is_forced) mysql_free_result((r)) +#define mysqli_change_user_silent(c, u, p, d, p_len) mysql_change_user((c), (u), (p), (d)) + + +/* + These functions also reside in ext/mysqlnd/mysqlnd_portability.h but since it is only made + available if one wants to build mysqli against mysqlnd and they are useful for libmysql as + well, we check whether they're not defined [build with libmysql is desired] and define them. + + Bit values are sent in reverted order of bytes, compared to normal !!! +*/ + + +#ifndef uint1korr +#define uint1korr(A) (*(((uint8_t*)(A)))) +#endif + +#ifndef bit_uint2korr +#define bit_uint2korr(A) ((uint16_t) (((uint16_t) (((unsigned char*) (A))[1])) +\ + ((uint16_t) (((unsigned char*) (A))[0]) << 8))) +#endif + +#ifndef bit_uint3korr +#define bit_uint3korr(A) ((uint32_t) (((uint32_t) (((unsigned char*) (A))[2])) +\ + (((uint32_t) (((unsigned char*) (A))[1])) << 8) +\ + (((uint32_t) (((unsigned char*) (A))[0])) << 16))) +#endif + +#ifndef bit_uint4korr +#define bit_uint4korr(A) ((uint32_t) (((uint32_t) (((unsigned char*) (A))[3])) +\ + (((uint32_t) (((unsigned char*) (A))[2])) << 8) +\ + (((uint32_t) (((unsigned char*) (A))[1])) << 16) +\ + (((uint32_t) (((unsigned char*) (A))[0])) << 24))) +#endif + +#ifndef bit_uint5korr +#define bit_uint5korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[4])) +\ + (((uint32_t) (((unsigned char*) (A))[3])) << 8) +\ + (((uint32_t) (((unsigned char*) (A))[2])) << 16) +\ + (((uint32_t) (((unsigned char*) (A))[1])) << 24)) +\ + (((uint64_t) (((unsigned char*) (A))[0])) << 32)) +#endif + +#ifndef bit_uint6korr +#define bit_uint6korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[5])) +\ + (((uint32_t) (((unsigned char*) (A))[4])) << 8) +\ + (((uint32_t) (((unsigned char*) (A))[3])) << 16) +\ + (((uint32_t) (((unsigned char*) (A))[2])) << 24)) +\ + (((uint64_t) (((uint32_t) (((unsigned char*) (A))[1])) +\ + (((uint32_t) (((unsigned char*) (A))[0]) << 8)))) <<\ + 32)) +#endif + +#ifndef bit_uint7korr +#define bit_uint7korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[6])) +\ + (((uint32_t) (((unsigned char*) (A))[5])) << 8) +\ + (((uint32_t) (((unsigned char*) (A))[4])) << 16) +\ + (((uint32_t) (((unsigned char*) (A))[3])) << 24)) +\ + (((uint64_t) (((uint32_t) (((unsigned char*) (A))[2])) +\ + (((uint32_t) (((unsigned char*) (A))[1])) << 8) +\ + (((uint32_t) (((unsigned char*) (A))[0])) << 16))) <<\ + 32)) +#endif + +#ifndef bit_uint8korr +#define bit_uint8korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[7])) +\ + (((uint32_t) (((unsigned char*) (A))[6])) << 8) +\ + (((uint32_t) (((unsigned char*) (A))[5])) << 16) +\ + (((uint32_t) (((unsigned char*) (A))[4])) << 24)) +\ + (((uint64_t) (((uint32_t) (((unsigned char*) (A))[3])) +\ + (((uint32_t) (((unsigned char*) (A))[2])) << 8) +\ + (((uint32_t) (((unsigned char*) (A))[1])) << 16) +\ + (((uint32_t) (((unsigned char*) (A))[0])) << 24))) <<\ + 32)) +#endif + +#endif /* MYSQLI_LIBMYSQL_H */ + diff --git a/ext/mysqli/mysqli_mysqlnd.h b/ext/mysqli/mysqli_mysqlnd.h new file mode 100644 index 0000000..b6d23d9 --- /dev/null +++ b/ext/mysqli/mysqli_mysqlnd.h @@ -0,0 +1,48 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 2006-2009 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Georg Richter <georg@mysql.com> | + | Andrey Hristov <andrey@mysql.com> | + | Ulf Wendel <uwendel@mysql.com> | + +----------------------------------------------------------------------+ + +*/ + +#ifndef MYSQLI_MYSQLND_H +#define MYSQLI_MYSQLND_H + +#include "ext/mysqlnd/mysqlnd_libmysql_compat.h" +#include "ext/mysqlnd/mysqlnd_portability.h" + +/* Here comes non-libmysql API to have less ifdefs in mysqli*/ +#define MYSQLI_CLOSE_EXPLICIT MYSQLND_CLOSE_EXPLICIT +#define MYSQLI_CLOSE_IMPLICIT MYSQLND_CLOSE_IMPLICIT +#define MYSQLI_CLOSE_DISCONNECTED MYSQLND_CLOSE_DISCONNECTED + +#define mysqli_result_is_unbuffered(r) ((r)->unbuf) +#define mysqli_result_is_unbuffered_and_not_everything_is_fetched(r) ((r)->unbuf && !(r)->unbuf->eof_reached) +#define mysqli_server_status(c) mysqlnd_get_server_status((c)) +#define mysqli_stmt_get_id(s) ((s)->data->stmt_id) +#define mysqli_stmt_warning_count(s) mysqlnd_stmt_warning_count((s)) +#define mysqli_stmt_server_status(s) mysqlnd_stmt_server_status((s)) +#define mysqli_stmt_get_connection(s) (s)->data->conn +#define mysqli_close(c, how) mysqlnd_close((c), (how)) +#define mysqli_stmt_close(c, implicit) mysqlnd_stmt_close((c), (implicit)) +#define mysqli_free_result(r, implicit) mysqlnd_free_result((r), (implicit)) +#define mysqli_async_query(c, q, l) mysqlnd_async_query((c), (q), (l)) +#define mysqli_change_user_silent(c, u, p, d, p_len) mysqlnd_change_user_ex((c), (u), (p), (d), TRUE, (size_t)(p_len)) + +#define HAVE_STMT_NEXT_RESULT + +#endif diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c new file mode 100644 index 0000000..2ad1a20 --- /dev/null +++ b/ext/mysqli/mysqli_nonapi.c @@ -0,0 +1,1058 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Georg Richter <georg@php.net> | + | Andrey Hristov <andrey@php.net> | + | Ulf Wendel <uw@php.net> | + +----------------------------------------------------------------------+ + + $Id$ +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <signal.h> + +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +#include "php_mysqli_structs.h" +#include "mysqli_priv.h" + +#define SAFE_STR(a) ((a)?a:"") + +#ifndef zend_parse_parameters_none +#define zend_parse_parameters_none() \ + zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") +#endif + +/* {{{ php_mysqli_set_error + */ +static void php_mysqli_set_error(long mysql_errno, char *mysql_err TSRMLS_DC) +{ + MyG(error_no) = mysql_errno; + if (MyG(error_msg)) { + efree(MyG(error_msg)); + } + if(mysql_err && *mysql_err) { + MyG(error_msg) = estrdup(mysql_err); + } else { + MyG(error_msg) = NULL; + } +} +/* }}} */ + + +void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_real_connect, zend_bool in_ctor) +{ + MY_MYSQL *mysql = NULL; + MYSQLI_RESOURCE *mysqli_resource = NULL; + zval *object = getThis(); + char *hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL; + int hostname_len = 0, username_len = 0, passwd_len = 0, dbname_len = 0, socket_len = 0; + zend_bool persistent = FALSE; + long port = 0, flags = 0; + uint hash_len; + char *hash_key = NULL; + zend_bool new_connection = FALSE; + zend_rsrc_list_entry *le; + mysqli_plist_entry *plist = NULL; + zend_bool self_alloced = 0; + + +#if !defined(MYSQL_USE_MYSQLND) + if ((MYSQL_VERSION_ID / 100) != (mysql_get_client_version() / 100)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "Headers and client library minor version mismatch. Headers:%d Library:%ld", + MYSQL_VERSION_ID, mysql_get_client_version()); + } +#endif + + if (getThis() && !ZEND_NUM_ARGS() && in_ctor) { + php_mysqli_init(INTERNAL_FUNCTION_PARAM_PASSTHRU); + return; + } + hostname = username = dbname = passwd = socket = NULL; + + if (!is_real_connect) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ssssls", &hostname, &hostname_len, &username, &username_len, + &passwd, &passwd_len, &dbname, &dbname_len, &port, &socket, &socket_len) == FAILURE) { + return; + } + + if (object && instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry TSRMLS_CC)) { + mysqli_resource = ((mysqli_object *) zend_object_store_get_object(object TSRMLS_CC))->ptr; + if (mysqli_resource && mysqli_resource->ptr) { + mysql = (MY_MYSQL*) mysqli_resource->ptr; + } + } + if (!mysql) { + mysql = (MY_MYSQL *) ecalloc(1, sizeof(MY_MYSQL)); + self_alloced = 1; + } + flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */ + } else { + /* We have flags too */ + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sssslsl", &object, mysqli_link_class_entry, + &hostname, &hostname_len, &username, &username_len, &passwd, &passwd_len, &dbname, &dbname_len, &port, &socket, &socket_len, + &flags) == FAILURE) { + return; + } + + mysqli_resource = ((mysqli_object *) zend_object_store_get_object(object TSRMLS_CC))->ptr; + MYSQLI_FETCH_RESOURCE_CONN(mysql, &object, MYSQLI_STATUS_INITIALIZED); + + /* set some required options */ + flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */ + /* remove some insecure options */ + flags &= ~CLIENT_MULTI_STATEMENTS; /* don't allow multi_queries via connect parameter */ + if (PG(open_basedir) && PG(open_basedir)[0] != '\0') { + flags &= ~CLIENT_LOCAL_FILES; + } + } + + if (!socket_len || !socket) { + socket = MyG(default_socket); + } + if (!port){ + port = MyG(default_port); + } + if (!passwd) { + passwd = MyG(default_pw); + passwd_len = strlen(SAFE_STR(passwd)); + } + if (!username){ + username = MyG(default_user); + } + if (!hostname || !hostname_len) { + hostname = MyG(default_host); + } + + if (mysql->mysql && mysqli_resource && + (mysqli_resource->status > MYSQLI_STATUS_INITIALIZED)) + { + /* already connected, we should close the connection */ + php_mysqli_close(mysql, MYSQLI_CLOSE_IMPLICIT, mysqli_resource->status TSRMLS_CC); + } + + if (strlen(SAFE_STR(hostname)) > 2 && !strncasecmp(hostname, "p:", 2)) { + hostname += 2; + if (!MyG(allow_persistent)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Persistent connections are disabled. Downgrading to normal"); + } else { + mysql->persistent = persistent = TRUE; + + hash_len = spprintf(&hash_key, 0, "mysqli_%s_%s%ld%s%s%s", SAFE_STR(hostname), SAFE_STR(socket), + port, SAFE_STR(username), SAFE_STR(dbname), + SAFE_STR(passwd)); + + mysql->hash_key = hash_key; + + /* check if we can reuse exisiting connection ... */ + if (zend_hash_find(&EG(persistent_list), hash_key, hash_len + 1, (void **)&le) == SUCCESS) { + if (Z_TYPE_P(le) == php_le_pmysqli()) { + plist = (mysqli_plist_entry *) le->ptr; + + do { + if (zend_ptr_stack_num_elements(&plist->free_links)) { + mysql->mysql = zend_ptr_stack_pop(&plist->free_links); + + MyG(num_inactive_persistent)--; + /* reset variables */ + +#ifndef MYSQLI_NO_CHANGE_USER_ON_PCONNECT + if (!mysqli_change_user_silent(mysql->mysql, username, passwd, dbname, passwd_len)) { +#else + if (!mysql_ping(mysql->mysql)) { +#endif +#ifdef MYSQLI_USE_MYSQLND + mysqlnd_restart_psession(mysql->mysql); +#endif + MyG(num_active_persistent)++; + goto end; + } else { + mysqli_close(mysql->mysql, MYSQLI_CLOSE_IMPLICIT); + mysql->mysql = NULL; + } + } + } while (0); + } + } else { + zend_rsrc_list_entry le; + le.type = php_le_pmysqli(); + le.ptr = plist = calloc(1, sizeof(mysqli_plist_entry)); + + zend_ptr_stack_init_ex(&plist->free_links, 1); + zend_hash_update(&EG(persistent_list), hash_key, hash_len + 1, (void *)&le, sizeof(le), NULL); + } + } + } + if (MyG(max_links) != -1 && MyG(num_links) >= MyG(max_links)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MyG(num_links)); + goto err; + } + + if (persistent && MyG(max_persistent) != -1 && + (MyG(num_active_persistent) + MyG(num_inactive_persistent))>= MyG(max_persistent)) + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open persistent links (%ld)", + MyG(num_active_persistent) + MyG(num_inactive_persistent)); + goto err; + } + if (!mysql->mysql) { +#if !defined(MYSQLI_USE_MYSQLND) + if (!(mysql->mysql = mysql_init(NULL))) { +#else + if (!(mysql->mysql = mysqlnd_init(persistent))) { +#endif + goto err; + } + new_connection = TRUE; + } + +#ifdef HAVE_EMBEDDED_MYSQLI + if (hostname_len) { + unsigned int external=1; + mysql_options(mysql->mysql, MYSQL_OPT_USE_REMOTE_CONNECTION, (char *)&external); + } else { + mysql_options(mysql->mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, 0); + } +#endif + +#if !defined(MYSQLI_USE_MYSQLND) + /* BC for prior to bug fix #53425 */ + flags |= CLIENT_MULTI_RESULTS; + + if (mysql_real_connect(mysql->mysql, hostname, username, passwd, dbname, port, socket, flags) == NULL) +#else + if (mysqlnd_connect(mysql->mysql, hostname, username, passwd, passwd_len, dbname, dbname_len, + port, socket, flags TSRMLS_CC) == NULL) +#endif + { + /* Save error messages - for mysqli_connect_error() & mysqli_connect_errno() */ + php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC); + php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql) TSRMLS_CC, + "%s", mysql_error(mysql->mysql)); + if (!is_real_connect) { + /* free mysql structure */ + mysqli_close(mysql->mysql, MYSQLI_CLOSE_DISCONNECTED); + mysql->mysql = NULL; + } + goto err; + } + + /* clear error */ + php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC); + +#if !defined(MYSQLI_USE_MYSQLND) + mysql->mysql->reconnect = MyG(reconnect); + + /* set our own local_infile handler */ + php_set_local_infile_handler_default(mysql); +#endif + + mysql_options(mysql->mysql, MYSQL_OPT_LOCAL_INFILE, (char *)&MyG(allow_local_infile)); + +end: + if (!mysqli_resource) { + mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); + mysqli_resource->ptr = (void *)mysql; + } + mysqli_resource->status = MYSQLI_STATUS_VALID; + + /* store persistent connection */ + if (persistent && (new_connection || is_real_connect)) { + MyG(num_active_persistent)++; + } + + MyG(num_links)++; + + mysql->multi_query = 0; + + if (!object || !instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry TSRMLS_CC)) { + MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_link_class_entry); + } else { + ((mysqli_object *) zend_object_store_get_object(object TSRMLS_CC))->ptr = mysqli_resource; + } + if (!is_real_connect) { + return; + } else { + RETURN_TRUE; + } + +err: + if (mysql->hash_key) { + efree(mysql->hash_key); + mysql->hash_key = NULL; + mysql->persistent = FALSE; + } + if (!is_real_connect && self_alloced) { + efree(mysql); + } + RETVAL_FALSE; +} + + +/* {{{ proto object mysqli_connect([string hostname [,string username [,string passwd [,string dbname [,int port [,string socket]]]]]]) + Open a connection to a mysql server */ +PHP_FUNCTION(mysqli_connect) +{ + mysqli_common_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, FALSE, FALSE); +} +/* }}} */ + + +/* {{{ proto object mysqli_link_construct() + */ +PHP_FUNCTION(mysqli_link_construct) +{ + mysqli_common_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, FALSE, TRUE); +} +/* }}} */ + + +/* {{{ proto int mysqli_connect_errno(void) + Returns the numerical value of the error message from last connect command */ +PHP_FUNCTION(mysqli_connect_errno) +{ + RETURN_LONG(MyG(error_no)); +} +/* }}} */ + +/* {{{ proto string mysqli_connect_error(void) + Returns the text of the error message from previous MySQL operation */ +PHP_FUNCTION(mysqli_connect_error) +{ + if (MyG(error_msg)) { + RETURN_STRING(MyG(error_msg),1); + } else { + RETURN_NULL(); + } +} +/* }}} */ + + +/* {{{ proto mixed mysqli_fetch_array (object result [,int resulttype]) + Fetch a result row as an associative array, a numeric array, or both */ +PHP_FUNCTION(mysqli_fetch_array) +{ + php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0); +} +/* }}} */ + +/* {{{ proto mixed mysqli_fetch_assoc (object result) + Fetch a result row as an associative array */ +PHP_FUNCTION(mysqli_fetch_assoc) +{ + php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC, 0); +} +/* }}} */ + + +/* {{{ proto mixed mysqli_fetch_all (object result [,int resulttype]) + Fetches all result rows as an associative array, a numeric array, or both */ +#if defined(MYSQLI_USE_MYSQLND) +PHP_FUNCTION(mysqli_fetch_all) +{ + MYSQL_RES *result; + zval *mysql_result; + long mode = MYSQLND_FETCH_NUM; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &mode) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + + if (!mode || (mode & ~MYSQLND_FETCH_BOTH)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Mode can be only MYSQLI_FETCH_NUM, " + "MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH"); + RETURN_FALSE; + } + + mysqlnd_fetch_all(result, mode, return_value); +} +/* }}} */ + + + +/* {{{ proto array mysqli_get_client_stats(void) + Returns statistics about the zval cache */ +PHP_FUNCTION(mysqli_get_client_stats) +{ + if (zend_parse_parameters_none() == FAILURE) { + return; + } + mysqlnd_get_client_stats(return_value); +} +/* }}} */ + + +/* {{{ proto array mysqli_get_connection_stats(void) + Returns statistics about the zval cache */ +PHP_FUNCTION(mysqli_get_connection_stats) +{ + MY_MYSQL *mysql; + zval *mysql_link; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", + &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + mysqlnd_get_connection_stats(mysql->mysql, return_value); +} +#endif +/* }}} */ + +/* {{{ proto mixed mysqli_error_list (object connection) + Fetches all client errors */ +PHP_FUNCTION(mysqli_error_list) +{ + MY_MYSQL *mysql; + zval *mysql_link; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + array_init(return_value); +#if defined(MYSQLI_USE_MYSQLND) + if (mysql->mysql->data->error_info->error_list) { + MYSQLND_ERROR_LIST_ELEMENT * message; + zend_llist_position pos; + for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(mysql->mysql->data->error_info->error_list, &pos); + message; + message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(mysql->mysql->data->error_info->error_list, &pos)) + { + zval * single_error; + MAKE_STD_ZVAL(single_error); + array_init(single_error); + add_assoc_long_ex(single_error, "errno", sizeof("errno"), message->error_no); + add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), message->sqlstate, 1); + add_assoc_string_ex(single_error, "error", sizeof("error"), message->error, 1); + add_next_index_zval(return_value, single_error); + } + } +#else + if (mysql_errno(mysql->mysql)) { + zval * single_error; + MAKE_STD_ZVAL(single_error); + array_init(single_error); + add_assoc_long_ex(single_error, "errno", sizeof("errno"), mysql_errno(mysql->mysql)); + add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), mysql_sqlstate(mysql->mysql), 1); + add_assoc_string_ex(single_error, "error", sizeof("error"), mysql_error(mysql->mysql), 1); + add_next_index_zval(return_value, single_error); + } +#endif +} +/* }}} */ + + +/* {{{ proto string mysqli_stmt_error_list(object stmt) +*/ +PHP_FUNCTION(mysqli_stmt_error_list) +{ + MY_STMT *stmt; + zval *mysql_stmt; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_INITIALIZED); + array_init(return_value); +#if defined(MYSQLI_USE_MYSQLND) + if (stmt->stmt && stmt->stmt->data && stmt->stmt->data->error_info->error_list) { + MYSQLND_ERROR_LIST_ELEMENT * message; + zend_llist_position pos; + for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(stmt->stmt->data->error_info->error_list, &pos); + message; + message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(stmt->stmt->data->error_info->error_list, &pos)) + { + zval * single_error; + MAKE_STD_ZVAL(single_error); + array_init(single_error); + add_assoc_long_ex(single_error, "errno", sizeof("errno"), message->error_no); + add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), message->sqlstate, 1); + add_assoc_string_ex(single_error, "error", sizeof("error"), message->error, 1); + add_next_index_zval(return_value, single_error); + } + } +#else + if (mysql_stmt_errno(stmt->stmt)) { + zval * single_error; + MAKE_STD_ZVAL(single_error); + array_init(single_error); + add_assoc_long_ex(single_error, "errno", sizeof("errno"), mysql_stmt_errno(stmt->stmt)); + add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), mysql_stmt_sqlstate(stmt->stmt), 1); + add_assoc_string_ex(single_error, "error", sizeof("error"), mysql_stmt_error(stmt->stmt), 1); + add_next_index_zval(return_value, single_error); + } +#endif +} +/* }}} */ + + +/* {{{ proto mixed mysqli_fetch_object (object result [, string class_name [, NULL|array ctor_params]]) + Fetch a result row as an object */ +PHP_FUNCTION(mysqli_fetch_object) +{ + php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC, 1); +} +/* }}} */ + +/* {{{ proto bool mysqli_multi_query(object link, string query) + allows to execute multiple queries */ +PHP_FUNCTION(mysqli_multi_query) +{ + MY_MYSQL *mysql; + zval *mysql_link; + char *query = NULL; + int query_len; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + MYSQLI_ENABLE_MQ; + if (mysql_real_query(mysql->mysql, query, query_len)) { +#ifndef MYSQLI_USE_MYSQLND + char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1]; + unsigned int s_errno; + /* we have to save error information, cause + MYSQLI_DISABLE_MQ will reset error information */ + strcpy(s_error, mysql_error(mysql->mysql)); + strcpy(s_sqlstate, mysql_sqlstate(mysql->mysql)); + s_errno = mysql_errno(mysql->mysql); +#else + MYSQLND_ERROR_INFO error_info = *mysql->mysql->data->error_info; +#endif + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + MYSQLI_DISABLE_MQ; + +#ifndef MYSQLI_USE_MYSQLND + /* restore error information */ + strcpy(mysql->mysql->net.last_error, s_error); + strcpy(mysql->mysql->net.sqlstate, s_sqlstate); + mysql->mysql->net.last_errno = s_errno; +#else + *mysql->mysql->data->error_info = error_info; +#endif + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto mixed mysqli_query(object link, string query [,int resultmode]) */ +PHP_FUNCTION(mysqli_query) +{ + MY_MYSQL *mysql; + zval *mysql_link; + MYSQLI_RESOURCE *mysqli_resource; + MYSQL_RES *result; + char *query = NULL; + int query_len; + long resultmode = MYSQLI_STORE_RESULT; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|l", &mysql_link, mysqli_link_class_entry, &query, &query_len, &resultmode) == FAILURE) { + return; + } + + if (!query_len) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty query"); + RETURN_FALSE; + } + if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && (resultmode & ~MYSQLI_ASYNC) != MYSQLI_STORE_RESULT) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for resultmode"); + RETURN_FALSE; + } + + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + MYSQLI_DISABLE_MQ; + + +#ifdef MYSQLI_USE_MYSQLND + if (resultmode & MYSQLI_ASYNC) { + if (mysqli_async_query(mysql->mysql, query, query_len)) { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + RETURN_FALSE; + } + mysql->async_result_fetch_type = resultmode & ~MYSQLI_ASYNC; + RETURN_TRUE; + } +#endif + + if (mysql_real_query(mysql->mysql, query, query_len)) { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + RETURN_FALSE; + } + + if (!mysql_field_count(mysql->mysql)) { + /* no result set - not a SELECT */ + if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { + php_mysqli_report_index(query, mysqli_server_status(mysql->mysql) TSRMLS_CC); + } + RETURN_TRUE; + } + + switch (resultmode) { + case MYSQLI_STORE_RESULT: + result = mysql_store_result(mysql->mysql); + break; + case MYSQLI_USE_RESULT: + result = mysql_use_result(mysql->mysql); + break; + } + if (!result) { + php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql) TSRMLS_CC, + "%s", mysql_error(mysql->mysql)); + RETURN_FALSE; + } + + if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { + php_mysqli_report_index(query, mysqli_server_status(mysql->mysql) TSRMLS_CC); + } + + mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); + mysqli_resource->ptr = (void *)result; + mysqli_resource->status = MYSQLI_STATUS_VALID; + MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry); +} +/* }}} */ + + +#if defined(MYSQLI_USE_MYSQLND) +#include "php_network.h" +/* {{{ mysqlnd_zval_array_to_mysqlnd_array functions */ +static int mysqlnd_zval_array_to_mysqlnd_array(zval *in_array, MYSQLND ***out_array TSRMLS_DC) +{ + zval **elem; + int i = 0, current = 0; + + if (Z_TYPE_P(in_array) != IS_ARRAY) { + return 0; + } + *out_array = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(in_array)) + 1, sizeof(MYSQLND *)); + for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(in_array)); + zend_hash_get_current_data(Z_ARRVAL_P(in_array), (void **) &elem) == SUCCESS; + zend_hash_move_forward(Z_ARRVAL_P(in_array))) { + i++; + if (Z_TYPE_PP(elem) != IS_OBJECT || + !instanceof_function(Z_OBJCE_PP(elem), mysqli_link_class_entry TSRMLS_CC)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter %d not a mysqli object", i); + } else { + MY_MYSQL *mysql; + MYSQLI_RESOURCE *my_res; + mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*elem TSRMLS_CC); + if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "[%d] Couldn't fetch %s", i, intern->zo.ce->name); + continue; + } + mysql = (MY_MYSQL*) my_res->ptr; + if (MYSQLI_STATUS_VALID && my_res->status < MYSQLI_STATUS_VALID) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid object %d or resource %s", i, intern->zo.ce->name); + continue; + } + (*out_array)[current++] = mysql->mysql; + } + } + return 0; +} +/* }}} */ + + +/* {{{ mysqlnd_zval_array_from_mysqlnd_array */ +static int mysqlnd_zval_array_from_mysqlnd_array(MYSQLND **in_array, zval *out_array TSRMLS_DC) +{ + MYSQLND **p = in_array; + HashTable *new_hash; + zval **elem, **dest_elem; + int ret = 0, i = 0; + + ALLOC_HASHTABLE(new_hash); + zend_hash_init(new_hash, zend_hash_num_elements(Z_ARRVAL_P(out_array)), NULL, ZVAL_PTR_DTOR, 0); + + for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(out_array)); + zend_hash_get_current_data(Z_ARRVAL_P(out_array), (void **) &elem) == SUCCESS; + zend_hash_move_forward(Z_ARRVAL_P(out_array))) + { + i++; + if (Z_TYPE_PP(elem) != IS_OBJECT || !instanceof_function(Z_OBJCE_PP(elem), mysqli_link_class_entry TSRMLS_CC)) { + continue; + } + { + MY_MYSQL *mysql; + MYSQLI_RESOURCE *my_res; + mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*elem TSRMLS_CC); + if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "[%d] Couldn't fetch %s", i, intern->zo.ce->name); + continue; + } + mysql = (MY_MYSQL *) my_res->ptr; + if (mysql->mysql == *p) { + zend_hash_next_index_insert(new_hash, (void *)elem, sizeof(zval *), (void **)&dest_elem); + if (dest_elem) { + zval_add_ref(dest_elem); + } + ret++; + p++; + } + } + } + + /* destroy old array and add new one */ + zend_hash_destroy(Z_ARRVAL_P(out_array)); + efree(Z_ARRVAL_P(out_array)); + + zend_hash_internal_pointer_reset(new_hash); + Z_ARRVAL_P(out_array) = new_hash; + + return 0; +} +/* }}} */ + + +/* {{{ mysqlnd_dont_poll_zval_array_from_mysqlnd_array */ +static int mysqlnd_dont_poll_zval_array_from_mysqlnd_array(MYSQLND **in_array, zval *in_zval_array, zval *out_array TSRMLS_DC) +{ + MYSQLND **p = in_array; + HashTable *new_hash; + zval **elem, **dest_elem; + int ret = 0; + + ALLOC_HASHTABLE(new_hash); + zend_hash_init(new_hash, zend_hash_num_elements(Z_ARRVAL_P(in_zval_array)), NULL, ZVAL_PTR_DTOR, 0); + if (in_array) { + for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(in_zval_array)); + zend_hash_get_current_data(Z_ARRVAL_P(in_zval_array), (void **) &elem) == SUCCESS; + zend_hash_move_forward(Z_ARRVAL_P(in_zval_array))) + { + MY_MYSQL *mysql; + mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*elem TSRMLS_CC); + mysql = (MY_MYSQL *) ((MYSQLI_RESOURCE *)intern->ptr)->ptr; + if (mysql->mysql == *p) { + zend_hash_next_index_insert(new_hash, (void *)elem, sizeof(zval *), (void **)&dest_elem); + if (dest_elem) { + zval_add_ref(dest_elem); + } + ret++; + p++; + } + } + } + + /* destroy old array and add new one */ + zend_hash_destroy(Z_ARRVAL_P(out_array)); + efree(Z_ARRVAL_P(out_array)); + + zend_hash_internal_pointer_reset(new_hash); + Z_ARRVAL_P(out_array) = new_hash; + + return 0; +} +/* }}} */ + + +/* {{{ proto int mysqli_poll(array read, array write, array error, long sec [, long usec]) U + Poll connections */ +PHP_FUNCTION(mysqli_poll) +{ + zval *r_array, *e_array, *dont_poll_array; + MYSQLND **new_r_array = NULL, **new_e_array = NULL, **new_dont_poll_array = NULL; + long sec = 0, usec = 0; + enum_func_status ret; + uint desc_num; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!a!al|l", &r_array, &e_array, &dont_poll_array, &sec, &usec) == FAILURE) { + return; + } + if (sec < 0 || usec < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Negative values passed for sec and/or usec"); + RETURN_FALSE; + } + + if (!r_array && !e_array) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "No stream arrays were passed"); + RETURN_FALSE; + } + + if (r_array != NULL) { + mysqlnd_zval_array_to_mysqlnd_array(r_array, &new_r_array TSRMLS_CC); + } + if (e_array != NULL) { + mysqlnd_zval_array_to_mysqlnd_array(e_array, &new_e_array TSRMLS_CC); + } + + ret = mysqlnd_poll(new_r_array, new_e_array, &new_dont_poll_array, sec, usec, &desc_num); + + mysqlnd_dont_poll_zval_array_from_mysqlnd_array(r_array != NULL ? new_dont_poll_array:NULL, r_array, dont_poll_array TSRMLS_CC); + + if (r_array != NULL) { + mysqlnd_zval_array_from_mysqlnd_array(new_r_array, r_array TSRMLS_CC); + } + if (e_array != NULL) { + mysqlnd_zval_array_from_mysqlnd_array(new_e_array, e_array TSRMLS_CC); + } + + if (new_dont_poll_array) { + efree(new_dont_poll_array); + } + if (new_r_array) { + efree(new_r_array); + } + if (new_e_array) { + efree(new_e_array); + } + if (ret == PASS) { + RETURN_LONG(desc_num); + } else { + RETURN_FALSE; + } +} +/* }}} */ + + +/* {{{ proto int mysqli_reap_async_query(object link) U + Poll connections */ +PHP_FUNCTION(mysqli_reap_async_query) +{ + MY_MYSQL *mysql; + zval *mysql_link; + MYSQLI_RESOURCE *mysqli_resource; + MYSQL_RES *result; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + if (FAIL == mysqlnd_reap_async_query(mysql->mysql)) { + RETURN_FALSE; + } + + if (!mysql_field_count(mysql->mysql)) { + /* no result set - not a SELECT */ + if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { +/* php_mysqli_report_index("n/a", mysqli_server_status(mysql->mysql) TSRMLS_CC); */ + } + RETURN_TRUE; + } + + switch (mysql->async_result_fetch_type) { + case MYSQLI_STORE_RESULT: + result = mysql_store_result(mysql->mysql); + break; + case MYSQLI_USE_RESULT: + result = mysql_use_result(mysql->mysql); + break; + } + + if (!result) { + php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql) TSRMLS_CC, + "%s", mysql_error(mysql->mysql)); + RETURN_FALSE; + } + + if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { +/* php_mysqli_report_index("n/a", mysqli_server_status(mysql->mysql) TSRMLS_CC); */ + } + + mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); + mysqli_resource->ptr = (void *)result; + mysqli_resource->status = MYSQLI_STATUS_VALID; + MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry); +} +/* }}} */ + + +/* {{{ proto object mysqli_stmt_get_result(object link) U + Buffer result set on client */ +PHP_FUNCTION(mysqli_stmt_get_result) +{ + MYSQL_RES *result; + MYSQLI_RESOURCE *mysqli_resource; + MY_STMT *stmt; + zval *mysql_stmt; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID); + + if (!(result = mysqlnd_stmt_get_result(stmt->stmt))) { + MYSQLI_REPORT_STMT_ERROR(stmt->stmt); + RETURN_FALSE; + } + + mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); + mysqli_resource->ptr = (void *)result; + mysqli_resource->status = MYSQLI_STATUS_VALID; + MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry); +} +/* }}} */ +#endif + + +/* {{{ proto object mysqli_get_warnings(object link) */ +PHP_FUNCTION(mysqli_get_warnings) +{ + MY_MYSQL *mysql; + zval *mysql_link; + MYSQLI_RESOURCE *mysqli_resource; + MYSQLI_WARNING *w; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + if (mysql_warning_count(mysql->mysql)) { +#ifdef MYSQLI_USE_MYSQLND + w = php_get_warnings(mysql->mysql->data TSRMLS_CC); +#else + w = php_get_warnings(mysql->mysql TSRMLS_CC); +#endif + } else { + RETURN_FALSE; + } + mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); + mysqli_resource->ptr = mysqli_resource->info = (void *)w; + mysqli_resource->status = MYSQLI_STATUS_VALID; + MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry); +} +/* }}} */ + + +/* {{{ proto object mysqli_stmt_get_warnings(object link) */ +PHP_FUNCTION(mysqli_stmt_get_warnings) +{ + MY_STMT *stmt; + zval *stmt_link; + MYSQLI_RESOURCE *mysqli_resource; + MYSQLI_WARNING *w; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &stmt_link, mysqli_stmt_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_STMT(stmt, &stmt_link, MYSQLI_STATUS_VALID); + + if (mysqli_stmt_warning_count(stmt->stmt)) { + w = php_get_warnings(mysqli_stmt_get_connection(stmt->stmt) TSRMLS_CC); + } else { + RETURN_FALSE; + } + mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); + mysqli_resource->ptr = mysqli_resource->info = (void *)w; + mysqli_resource->status = MYSQLI_STATUS_VALID; + MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry); +} +/* }}} */ + + +#ifdef HAVE_MYSQLI_SET_CHARSET +/* {{{ proto bool mysqli_set_charset(object link, string csname) + sets client character set */ +PHP_FUNCTION(mysqli_set_charset) +{ + MY_MYSQL *mysql; + zval *mysql_link; + char *cs_name; + int csname_len; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &cs_name, &csname_len) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + if (mysql_set_character_set(mysql->mysql, cs_name)) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ +#endif + +#ifdef HAVE_MYSQLI_GET_CHARSET +/* {{{ proto object mysqli_get_charset(object link) U + returns a character set object */ +PHP_FUNCTION(mysqli_get_charset) +{ + MY_MYSQL *mysql; + zval *mysql_link; + const char *name = NULL, *collation = NULL, *dir = NULL, *comment = NULL; + uint minlength, maxlength, number, state; +#if !defined(MYSQLI_USE_MYSQLND) + MY_CHARSET_INFO cs; +#else + const MYSQLND_CHARSET *cs; +#endif + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { + return; + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); + + +#if !defined(MYSQLI_USE_MYSQLND) + mysql_get_character_set_info(mysql->mysql, &cs); + name = (char *)cs.csname; + collation = (char *)cs.name; + dir = (char *)cs.dir; + minlength = cs.mbminlen; + maxlength = cs.mbmaxlen; + number = cs.number; + state = cs.state; + comment = cs.comment; +#else + cs = mysql->mysql->data->charset; + if (!cs) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The connection has no charset associated"); + RETURN_NULL(); + } + name = cs->name; + collation = cs->collation; + minlength = cs->char_minlen; + maxlength = cs->char_maxlen; + number = cs->nr; + comment = cs->comment; + state = 1; /* all charsets are compiled in */ +#endif + object_init(return_value); + + add_property_string(return_value, "charset", (name) ? (char *)name : "", 1); + add_property_string(return_value, "collation",(collation) ? (char *)collation : "", 1); + add_property_string(return_value, "dir", (dir) ? (char *)dir : "", 1); + add_property_long(return_value, "min_length", minlength); + add_property_long(return_value, "max_length", maxlength); + add_property_long(return_value, "number", number); + add_property_long(return_value, "state", state); + add_property_string(return_value, "comment", (comment) ? (char *)comment : "", 1); +} +/* }}} */ +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqli/mysqli_priv.h b/ext/mysqli/mysqli_priv.h new file mode 100644 index 0000000..f85f029 --- /dev/null +++ b/ext/mysqli/mysqli_priv.h @@ -0,0 +1,154 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Georg Richter <georg@php.net> | + +----------------------------------------------------------------------+ + + $Id: php_mysqli_structs.h 302179 2010-08-13 09:57:04Z andrey $ +*/ + +#ifndef MYSQLI_PRIV_H +#define MYSQLI_PRIV_H + +#ifdef PHP_MYSQL_UNIX_SOCK_ADDR +#ifdef MYSQL_UNIX_ADDR +#undef MYSQL_UNIX_ADDR +#endif +#define MYSQL_UNIX_ADDR PHP_MYSQL_UNIX_SOCK_ADDR +#endif + +/* character set support */ +#if defined(MYSQLND_VERSION_ID) || MYSQL_VERSION_ID > 50009 +#define HAVE_MYSQLI_GET_CHARSET +#endif + +#if defined(MYSQLND_VERSION_ID) || (MYSQL_VERSION_ID > 40112 && MYSQL_VERSION_ID < 50000) || MYSQL_VERSION_ID > 50005 +#define HAVE_MYSQLI_SET_CHARSET +#endif + + +extern const zend_function_entry mysqli_functions[]; +extern const zend_function_entry mysqli_link_methods[]; +extern const zend_function_entry mysqli_stmt_methods[]; +extern const zend_function_entry mysqli_result_methods[]; +extern const zend_function_entry mysqli_driver_methods[]; +extern const zend_function_entry mysqli_warning_methods[]; +extern const zend_function_entry mysqli_exception_methods[]; + +extern const mysqli_property_entry mysqli_link_property_entries[]; +extern const mysqli_property_entry mysqli_result_property_entries[]; +extern const mysqli_property_entry mysqli_stmt_property_entries[]; +extern const mysqli_property_entry mysqli_driver_property_entries[]; +extern const mysqli_property_entry mysqli_warning_property_entries[]; + +extern const zend_property_info mysqli_link_property_info_entries[]; +extern const zend_property_info mysqli_result_property_info_entries[]; +extern const zend_property_info mysqli_stmt_property_info_entries[]; +extern const zend_property_info mysqli_driver_property_info_entries[]; +extern const zend_property_info mysqli_warning_property_info_entries[]; + +extern int php_le_pmysqli(void); +extern void php_mysqli_dtor_p_elements(void *data); + +extern void php_mysqli_close(MY_MYSQL * mysql, int close_type, int resource_status TSRMLS_DC); + +extern void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flag, int into_object); +extern void php_clear_stmt_bind(MY_STMT *stmt TSRMLS_DC); +extern void php_clear_mysql(MY_MYSQL *); +#ifdef MYSQLI_USE_MYSQLND +extern MYSQLI_WARNING *php_get_warnings(MYSQLND_CONN_DATA * mysql TSRMLS_DC); +#else +extern MYSQLI_WARNING *php_get_warnings(MYSQL * mysql TSRMLS_DC); +#endif + +extern void php_clear_warnings(MYSQLI_WARNING *w); +extern void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type); +extern void php_mysqli_report_error(const char *sqlstate, int errorno, const char *error TSRMLS_DC); +extern void php_mysqli_report_index(const char *query, unsigned int status TSRMLS_DC); +extern void php_set_local_infile_handler_default(MY_MYSQL *); +extern void php_mysqli_throw_sql_exception(char *sqlstate, int errorno TSRMLS_DC, char *format, ...); + +#ifdef HAVE_SPL +extern PHPAPI zend_class_entry *spl_ce_RuntimeException; +#endif + +#define PHP_MYSQLI_EXPORT(__type) PHP_MYSQLI_API __type + +PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry * TSRMLS_DC); + + +#define MYSQLI_DISABLE_MQ if (mysql->multi_query) { \ + mysql_set_server_option(mysql->mysql, MYSQL_OPTION_MULTI_STATEMENTS_OFF); \ + mysql->multi_query = 0; \ +} + +#define MYSQLI_ENABLE_MQ if (!mysql->multi_query) { \ + mysql_set_server_option(mysql->mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON); \ + mysql->multi_query = 1; \ +} + + +#define MYSQLI_RETURN_LONG_LONG(__val) \ +{ \ + if ((__val) < LONG_MAX) { \ + RETURN_LONG((long) (__val)); \ + } else { \ + char *ret; \ + /* always used with my_ulonglong -> %llu */ \ + int l = spprintf(&ret, 0, MYSQLI_LLU_SPEC, (__val)); \ + RETURN_STRINGL(ret, l, 0); \ + } \ +} + +#define MYSQLI_STORE_RESULT 0 +#define MYSQLI_USE_RESULT 1 +#ifdef MYSQLI_USE_MYSQLND +#define MYSQLI_ASYNC 8 +#else +/* libmysql */ +#define MYSQLI_ASYNC 0 +#endif + +/* for mysqli_fetch_assoc */ +#define MYSQLI_ASSOC 1 +#define MYSQLI_NUM 2 +#define MYSQLI_BOTH 3 + +/* fetch types */ +#define FETCH_SIMPLE 1 +#define FETCH_RESULT 2 + +/*** REPORT MODES ***/ +#define MYSQLI_REPORT_OFF 0 +#define MYSQLI_REPORT_ERROR 1 +#define MYSQLI_REPORT_STRICT 2 +#define MYSQLI_REPORT_INDEX 4 +#define MYSQLI_REPORT_CLOSE 8 +#define MYSQLI_REPORT_ALL 255 + +#define MYSQLI_REPORT_MYSQL_ERROR(mysql) \ +if ((MyG(report_mode) & MYSQLI_REPORT_ERROR) && mysql_errno(mysql)) { \ + php_mysqli_report_error(mysql_sqlstate(mysql), mysql_errno(mysql), mysql_error(mysql) TSRMLS_CC); \ +} + +#define MYSQLI_REPORT_STMT_ERROR(stmt) \ +if ((MyG(report_mode) & MYSQLI_REPORT_ERROR) && mysql_stmt_errno(stmt)) { \ + php_mysqli_report_error(mysql_stmt_sqlstate(stmt), mysql_stmt_errno(stmt), mysql_stmt_error(stmt) TSRMLS_CC); \ +} + +void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_real_connect, zend_bool in_ctor); + +void php_mysqli_init(INTERNAL_FUNCTION_PARAMETERS); + +#endif /* MYSQLI_PRIV_H */ diff --git a/ext/mysqli/mysqli_prop.c b/ext/mysqli/mysqli_prop.c new file mode 100644 index 0000000..f50371b --- /dev/null +++ b/ext/mysqli/mysqli_prop.c @@ -0,0 +1,549 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Georg Richter <georg@php.net> | + | Andrey Hristov <andrey@php.net> | + +----------------------------------------------------------------------+ + + $Id$ +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <signal.h> + +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +#include "php_mysqli_structs.h" +#include "mysqli_priv.h" + +#define CHECK_STATUS(value) \ + if (!obj->ptr || ((MYSQLI_RESOURCE *)obj->ptr)->status < value ) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Property access is not allowed yet"); \ + ZVAL_NULL(*retval); \ + return SUCCESS; \ + } \ + +#define MYSQLI_GET_MYSQL(statusval) \ +MYSQL *p; \ +MAKE_STD_ZVAL(*retval);\ +if (!obj->ptr || !(MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", obj->zo.ce->name);\ + ZVAL_NULL(*retval);\ + return SUCCESS; \ +} else { \ + CHECK_STATUS(statusval);\ + p = (MYSQL *)((MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr)->mysql;\ +} + +#define MYSQLI_GET_RESULT(statusval) \ +MYSQL_RES *p; \ +MAKE_STD_ZVAL(*retval);\ +if (!obj->ptr) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", obj->zo.ce->name);\ + ZVAL_NULL(*retval);\ + return SUCCESS; \ +} else { \ + CHECK_STATUS(statusval);\ + p = (MYSQL_RES *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; \ +} + + +#define MYSQLI_GET_STMT(statusval) \ +MYSQL_STMT *p; \ +MAKE_STD_ZVAL(*retval);\ +if (!obj->ptr) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", obj->zo.ce->name);\ + ZVAL_NULL(*retval);\ + return SUCCESS; \ +} else { \ + CHECK_STATUS(statusval);\ + p = (MYSQL_STMT *)((MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr)->stmt;\ +} + +#define MYSQLI_MAP_PROPERTY_FUNC_LONG( __func, __int_func, __get_type, __ret_type, __ret_type_sprint_mod)\ +static int __func(mysqli_object *obj, zval **retval TSRMLS_DC) \ +{\ + __ret_type l;\ + __get_type;\ + if (!p) {\ + ZVAL_NULL(*retval);\ + } else {\ + l = (__ret_type)__int_func(p);\ + if (l < LONG_MAX) {\ + ZVAL_LONG(*retval, (long) l);\ + } else { \ + char *ret; \ + int ret_len = spprintf(&ret, 0, __ret_type_sprint_mod, l); \ + ZVAL_STRINGL(*retval, ret, ret_len, 0); \ + } \ + }\ + return SUCCESS;\ +} + +#define MYSQLI_MAP_PROPERTY_FUNC_STRING(__func, __int_func, __get_type)\ +static int __func(mysqli_object *obj, zval **retval TSRMLS_DC)\ +{\ + char *c;\ + __get_type;\ + if (!p) {\ + ZVAL_NULL(*retval);\ + } else {\ + c = (char *)__int_func(p);\ + if (!c) {\ + ZVAL_NULL(*retval);\ + } else {\ + ZVAL_STRING(*retval, c, 1);\ + }\ + }\ + return SUCCESS;\ +} + +/* {{{ property link_client_version_read */ +static int link_client_version_read(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MAKE_STD_ZVAL(*retval); + ZVAL_LONG(*retval, MYSQL_VERSION_ID); + return SUCCESS; +} +/* }}} */ + +/* {{{ property link_client_info_read */ +static int link_client_info_read(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MAKE_STD_ZVAL(*retval); + CHECK_STATUS(MYSQLI_STATUS_INITIALIZED); + ZVAL_STRING(*retval, MYSQL_SERVER_VERSION, 1); + return SUCCESS; +} +/* }}} */ + +/* {{{ property link_connect_errno_read */ +static int link_connect_errno_read(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MAKE_STD_ZVAL(*retval); + ZVAL_LONG(*retval, (long)MyG(error_no)); + return SUCCESS; +} +/* }}} */ + +/* {{{ property link_connect_error_read */ +static int link_connect_error_read(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MAKE_STD_ZVAL(*retval); + if (MyG(error_msg)) { + ZVAL_STRING(*retval, MyG(error_msg), 1); + } else { + ZVAL_NULL(*retval); + } + return SUCCESS; +} +/* }}} */ + +/* {{{ property link_affected_rows_read */ +static int link_affected_rows_read(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MY_MYSQL *mysql; + my_ulonglong rc; + + MAKE_STD_ZVAL(*retval); + + CHECK_STATUS(MYSQLI_STATUS_INITIALIZED); + + mysql = (MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; + + if (!mysql) { + ZVAL_NULL(*retval); + } else { + CHECK_STATUS(MYSQLI_STATUS_VALID); + + rc = mysql_affected_rows(mysql->mysql); + + if (rc == (my_ulonglong) -1) { + ZVAL_LONG(*retval, -1); + return SUCCESS; + } + + if (rc < LONG_MAX) { + ZVAL_LONG(*retval, (long) rc); + } else { + char *ret; + int l = spprintf(&ret, 0, MYSQLI_LLU_SPEC, rc); + ZVAL_STRINGL(*retval, ret, l, 0); + } + } + return SUCCESS; +} +/* }}} */ + + +/* {{{ property link_error_list_read */ +static int link_error_list_read(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MY_MYSQL *mysql; + + MAKE_STD_ZVAL(*retval); + + CHECK_STATUS(MYSQLI_STATUS_VALID); + + mysql = (MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; + + array_init(*retval); + if (mysql) { +#if defined(MYSQLI_USE_MYSQLND) + if (mysql->mysql->data->error_info->error_list) { + MYSQLND_ERROR_LIST_ELEMENT * message; + zend_llist_position pos; + for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(mysql->mysql->data->error_info->error_list, &pos); + message; + message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(mysql->mysql->data->error_info->error_list, &pos)) + { + zval * single_error; + MAKE_STD_ZVAL(single_error); + array_init(single_error); + add_assoc_long_ex(single_error, "errno", sizeof("errno"), message->error_no); + add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), message->sqlstate, 1); + add_assoc_string_ex(single_error, "error", sizeof("error"), message->error, 1); + add_next_index_zval(*retval, single_error); + } + } +#else + if (mysql_errno(mysql->mysql)) { + zval * single_error; + MAKE_STD_ZVAL(single_error); + array_init(single_error); + add_assoc_long_ex(single_error, "errno", sizeof("errno"), mysql_errno(mysql->mysql)); + add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), mysql_sqlstate(mysql->mysql), 1); + add_assoc_string_ex(single_error, "error", sizeof("error"), mysql_error(mysql->mysql), 1); + add_next_index_zval(*retval, single_error); + } +#endif + } + return SUCCESS; +} +/* }}} */ + + +/* link properties */ +MYSQLI_MAP_PROPERTY_FUNC_LONG(link_errno_read, mysql_errno, MYSQLI_GET_MYSQL(MYSQLI_STATUS_INITIALIZED), ulong, "%lu") +MYSQLI_MAP_PROPERTY_FUNC_STRING(link_error_read, mysql_error, MYSQLI_GET_MYSQL(MYSQLI_STATUS_INITIALIZED)) +MYSQLI_MAP_PROPERTY_FUNC_LONG(link_field_count_read, mysql_field_count, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), ulong, "%lu") +MYSQLI_MAP_PROPERTY_FUNC_STRING(link_host_info_read, mysql_get_host_info, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID)) +MYSQLI_MAP_PROPERTY_FUNC_STRING(link_info_read, mysql_info, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID)) +MYSQLI_MAP_PROPERTY_FUNC_LONG(link_insert_id_read, mysql_insert_id, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), my_ulonglong, MYSQLI_LLU_SPEC) +MYSQLI_MAP_PROPERTY_FUNC_LONG(link_protocol_version_read, mysql_get_proto_info, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), ulong, "%lu") +MYSQLI_MAP_PROPERTY_FUNC_STRING(link_server_info_read, mysql_get_server_info, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID)) +MYSQLI_MAP_PROPERTY_FUNC_LONG(link_server_version_read, mysql_get_server_version, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), ulong, "%lu") +MYSQLI_MAP_PROPERTY_FUNC_STRING(link_sqlstate_read, mysql_sqlstate, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID)) +MYSQLI_MAP_PROPERTY_FUNC_LONG(link_thread_id_read, mysql_thread_id, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), ulong, "%lu") +MYSQLI_MAP_PROPERTY_FUNC_LONG(link_warning_count_read, mysql_warning_count, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), ulong, "%lu") + +/* {{{ property link_stat_read */ +static int link_stat_read(mysqli_object *obj, zval **retval TSRMLS_DC)\ +{\ + MY_MYSQL *mysql; + + MAKE_STD_ZVAL(*retval); + ZVAL_NULL(*retval); + +#if defined(MYSQLI_USE_MYSQLND) + CHECK_STATUS(MYSQLI_STATUS_INITIALIZED); +#else + CHECK_STATUS(MYSQLI_STATUS_VALID); +#endif + + mysql = (MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; + + if (mysql) { + char * stat_msg; +#if defined(MYSQLI_USE_MYSQLND) + uint stat_msg_len; + if (mysqlnd_stat(mysql->mysql, &stat_msg, &stat_msg_len) == PASS) { + ZVAL_STRINGL(*retval, stat_msg, stat_msg_len, 0); + } +#else + if ((stat_msg = (char *) mysql_stat(mysql->mysql))) { + ZVAL_STRING(*retval, stat_msg, 1); + } +#endif + } + return SUCCESS; +} +/* }}} */ + + +/* result properties */ + +/* {{{ property result_type_read */ +static int result_type_read(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MYSQL_RES *p; + + MAKE_STD_ZVAL(*retval); + CHECK_STATUS(MYSQLI_STATUS_VALID); + p = (MYSQL_RES *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; + + if (!p) { + ZVAL_NULL(*retval); + } else { + ZVAL_LONG(*retval, mysqli_result_is_unbuffered(p) ? MYSQLI_USE_RESULT:MYSQLI_STORE_RESULT); + } + return SUCCESS; +} +/* }}} */ + +/* {{{ property result_lengths_read */ +static int result_lengths_read(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MYSQL_RES *p; + ulong *ret; + + MAKE_STD_ZVAL(*retval); + + CHECK_STATUS(MYSQLI_STATUS_VALID); + p = (MYSQL_RES *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; + if (!p || !p->field_count || !(ret = mysql_fetch_lengths(p))) { + ZVAL_NULL(*retval); + } else { + ulong i; + + array_init(*retval); + + for (i = 0; i < p->field_count; i++) { + add_index_long(*retval, i, ret[i]); + } + } + return SUCCESS; +} +/* }}} */ + + +MYSQLI_MAP_PROPERTY_FUNC_LONG(result_current_field_read, mysql_field_tell, MYSQLI_GET_RESULT(MYSQLI_STATUS_VALID), ulong, "%lu") +MYSQLI_MAP_PROPERTY_FUNC_LONG(result_field_count_read, mysql_num_fields, MYSQLI_GET_RESULT(MYSQLI_STATUS_VALID), ulong, "%lu") +MYSQLI_MAP_PROPERTY_FUNC_LONG(result_num_rows_read, mysql_num_rows, MYSQLI_GET_RESULT(MYSQLI_STATUS_VALID), my_ulonglong, MYSQLI_LLU_SPEC) + +/* statement properties */ + +/* {{{ property stmt_id_read */ +static int stmt_id_read(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MY_STMT *p; + + MAKE_STD_ZVAL(*retval); + CHECK_STATUS(MYSQLI_STATUS_VALID); + + p = (MY_STMT*)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; + + if (!p) { + ZVAL_NULL(*retval); + } else { + ZVAL_LONG(*retval, mysqli_stmt_get_id(p->stmt)); + } + return SUCCESS; +} +/* }}} */ + +/* {{{ property stmt_affected_rows_read */ +static int stmt_affected_rows_read(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MY_STMT *p; + my_ulonglong rc; + + MAKE_STD_ZVAL(*retval); + CHECK_STATUS(MYSQLI_STATUS_VALID); + + p = (MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; + + if (!p) { + ZVAL_NULL(*retval); + } else { + rc = mysql_stmt_affected_rows(p->stmt); + + if (rc == (my_ulonglong) -1) { + ZVAL_LONG(*retval, -1); + return SUCCESS; + } + + if (rc < LONG_MAX) { + ZVAL_LONG(*retval, (long) rc); + } else { + char *ret; + int l = spprintf(&ret, 0, MYSQLI_LLU_SPEC, rc); + ZVAL_STRINGL(*retval, ret, l, 0); + } + } + return SUCCESS; +} +/* }}} */ + +/* {{{ property stmt_error_list_read */ +static int stmt_error_list_read(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MY_STMT * stmt; + + MAKE_STD_ZVAL(*retval); + CHECK_STATUS(MYSQLI_STATUS_INITIALIZED); + + stmt = (MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; + array_init(*retval); + if (stmt && stmt->stmt) { +#if defined(MYSQLI_USE_MYSQLND) + if (stmt->stmt->data && stmt->stmt->data->error_info->error_list) { + MYSQLND_ERROR_LIST_ELEMENT * message; + zend_llist_position pos; + for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(stmt->stmt->data->error_info->error_list, &pos); + message; + message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(stmt->stmt->data->error_info->error_list, &pos)) + { + zval * single_error; + MAKE_STD_ZVAL(single_error); + array_init(single_error); + add_assoc_long_ex(single_error, "errno", sizeof("errno"), message->error_no); + add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), message->sqlstate, 1); + add_assoc_string_ex(single_error, "error", sizeof("error"), message->error, 1); + add_next_index_zval(*retval, single_error); + } + } +#else + if (mysql_stmt_errno(stmt->stmt)) { + zval * single_error; + MAKE_STD_ZVAL(single_error); + array_init(single_error); + add_assoc_long_ex(single_error, "errno", sizeof("errno"), mysql_stmt_errno(stmt->stmt)); + add_assoc_string_ex(single_error, "sqlstate", sizeof("sqlstate"), mysql_stmt_sqlstate(stmt->stmt), 1); + add_assoc_string_ex(single_error, "error", sizeof("error"), mysql_stmt_error(stmt->stmt), 1); + add_next_index_zval(*retval, single_error); + } +#endif + } + return SUCCESS; +} +/* }}} */ + + +MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_insert_id_read, mysql_stmt_insert_id, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), my_ulonglong, MYSQLI_LLU_SPEC) +MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_num_rows_read, mysql_stmt_num_rows, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), my_ulonglong, MYSQLI_LLU_SPEC) +MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_param_count_read, mysql_stmt_param_count, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), ulong, "%lu") +MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_field_count_read, mysql_stmt_field_count, MYSQLI_GET_STMT(MYSQLI_STATUS_VALID), ulong, "%lu") +MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_errno_read, mysql_stmt_errno, MYSQLI_GET_STMT(MYSQLI_STATUS_INITIALIZED), ulong, "%lu") +MYSQLI_MAP_PROPERTY_FUNC_STRING(stmt_error_read, mysql_stmt_error, MYSQLI_GET_STMT(MYSQLI_STATUS_INITIALIZED)) +MYSQLI_MAP_PROPERTY_FUNC_STRING(stmt_sqlstate_read, mysql_stmt_sqlstate, MYSQLI_GET_STMT(MYSQLI_STATUS_INITIALIZED)) + +/* }}} */ +const mysqli_property_entry mysqli_link_property_entries[] = { + {"affected_rows", sizeof("affected_rows") - 1, link_affected_rows_read, NULL}, + {"client_info", sizeof("client_info") - 1, link_client_info_read, NULL}, + {"client_version", sizeof("client_version") - 1, link_client_version_read, NULL}, + {"connect_errno", sizeof("connect_errno") - 1, link_connect_errno_read, NULL}, + {"connect_error", sizeof("connect_error") - 1, link_connect_error_read, NULL}, + {"errno", sizeof("errno") - 1, link_errno_read, NULL}, + {"error", sizeof("error") - 1, link_error_read, NULL}, + {"error_list", sizeof("error_list") - 1, link_error_list_read, NULL}, + {"field_count", sizeof("field_count") - 1, link_field_count_read, NULL}, + {"host_info", sizeof("host_info") - 1, link_host_info_read, NULL}, + {"info", sizeof("info") - 1, link_info_read, NULL}, + {"insert_id", sizeof("insert_id") - 1, link_insert_id_read, NULL}, + {"server_info", sizeof("server_info") - 1, link_server_info_read, NULL}, + {"server_version", sizeof("server_version") - 1, link_server_version_read, NULL}, + {"stat", sizeof("stat") - 1, link_stat_read, NULL}, + {"sqlstate", sizeof("sqlstate") - 1, link_sqlstate_read, NULL}, + {"protocol_version",sizeof("protocol_version") - 1, link_protocol_version_read, NULL}, + {"thread_id", sizeof("thread_id") - 1, link_thread_id_read, NULL}, + {"warning_count", sizeof("warning_count") - 1, link_warning_count_read, NULL}, + {NULL, 0, NULL, NULL} +}; + + +const zend_property_info mysqli_link_property_info_entries[] = { + {ZEND_ACC_PUBLIC, "affected_rows", sizeof("affected_rows") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "client_info", sizeof("client_info") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "client_version", sizeof("client_version") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "connect_errno", sizeof("connect_errno") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "connect_error", sizeof("connect_error") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "errno", sizeof("errno") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "error", sizeof("error") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "error_list", sizeof("error_list") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "field_count", sizeof("field_count") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "host_info", sizeof("host_info") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "info", sizeof("info") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "insert_id", sizeof("insert_id") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "server_info", sizeof("server_info") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "server_version", sizeof("server_version") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "stat", sizeof("stat") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "sqlstate", sizeof("sqlstate") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "protocol_version", sizeof("protocol_version")-1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "thread_id", sizeof("thread_id") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "warning_count", sizeof("warning_count") - 1, -1, 0, NULL, 0, NULL}, + {0, NULL, 0, -1, 0, NULL, 0, NULL} +}; + + +const mysqli_property_entry mysqli_result_property_entries[] = { + {"current_field",sizeof("current_field")-1, result_current_field_read, NULL}, + {"field_count", sizeof("field_count") - 1, result_field_count_read, NULL}, + {"lengths", sizeof("lengths") - 1, result_lengths_read, NULL}, + {"num_rows", sizeof("num_rows") - 1, result_num_rows_read, NULL}, + {"type", sizeof("type") - 1, result_type_read, NULL}, + {NULL, 0, NULL, NULL} +}; + +const zend_property_info mysqli_result_property_info_entries[] = { + {ZEND_ACC_PUBLIC, "current_field", sizeof("current_field")-1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "field_count", sizeof("field_count") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "lengths", sizeof("lengths") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "num_rows", sizeof("num_rows") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "type", sizeof("type") - 1, -1, 0, NULL, 0, NULL}, + {0, NULL, 0, -1, 0, NULL, 0, NULL} +}; + +const mysqli_property_entry mysqli_stmt_property_entries[] = { + {"affected_rows", sizeof("affected_rows")-1,stmt_affected_rows_read, NULL}, + {"insert_id", sizeof("insert_id") - 1, stmt_insert_id_read, NULL}, + {"num_rows", sizeof("num_rows") - 1, stmt_num_rows_read, NULL}, + {"param_count", sizeof("param_count") - 1, stmt_param_count_read, NULL}, + {"field_count", sizeof("field_count") - 1, stmt_field_count_read, NULL}, + {"errno", sizeof("errno") - 1, stmt_errno_read, NULL}, + {"error", sizeof("error") - 1, stmt_error_read, NULL}, + {"error_list", sizeof("error_list") - 1, stmt_error_list_read, NULL}, + {"sqlstate", sizeof("sqlstate") - 1, stmt_sqlstate_read, NULL}, + {"id", sizeof("id") - 1, stmt_id_read, NULL}, + {NULL, 0, NULL, NULL} +}; + + +const zend_property_info mysqli_stmt_property_info_entries[] = { + {ZEND_ACC_PUBLIC, "affected_rows", sizeof("affected_rows") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "insert_id", sizeof("insert_id") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "num_rows", sizeof("num_rows") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "param_count",sizeof("param_count") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "field_count",sizeof("field_count") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "errno", sizeof("errno") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "error", sizeof("error") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "error_list", sizeof("error_list") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "sqlstate", sizeof("sqlstate") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "id", sizeof("id") - 1, -1, 0, NULL, 0, NULL}, + {0, NULL, 0, -1, 0, NULL, 0, NULL} +}; + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqli/mysqli_report.c b/ext/mysqli/mysqli_report.c new file mode 100644 index 0000000..52135ce --- /dev/null +++ b/ext/mysqli/mysqli_report.c @@ -0,0 +1,78 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Georg Richter <georg@php.net> | + +----------------------------------------------------------------------+ + + $Id$ +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +#include "php_mysqli_structs.h" + +extern void php_mysqli_throw_sql_exception(char *sqlstate, int errorno TSRMLS_DC, char *format, ...); + +/* {{{ proto bool mysqli_report(int flags) + sets report level */ +PHP_FUNCTION(mysqli_report) +{ + long flags; + + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &flags) == FAILURE) { + return; + } + + MyG(report_mode) = flags; + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ void php_mysqli_report_error(char *sqlstate, int errorno, char *error) */ +void php_mysqli_report_error(const char *sqlstate, int errorno, const char *error TSRMLS_DC) +{ + php_mysqli_throw_sql_exception((char *)sqlstate, errorno TSRMLS_CC, "%s", error); +} +/* }}} */ + +/* {{{ void php_mysqli_report_index() */ +void php_mysqli_report_index(const char *query, unsigned int status TSRMLS_DC) { + char index[15]; + + if (status & SERVER_QUERY_NO_GOOD_INDEX_USED) { + strcpy(index, "Bad index"); + } else if (status & SERVER_QUERY_NO_INDEX_USED) { + strcpy(index, "No index"); + } else { + return; + } + php_mysqli_throw_sql_exception("00000", 0 TSRMLS_CC, "%s used in query/prepared statement %s", index, query); +} +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqli/mysqli_report.h b/ext/mysqli/mysqli_report.h new file mode 100644 index 0000000..34d0a66 --- /dev/null +++ b/ext/mysqli/mysqli_report.h @@ -0,0 +1,64 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Georg Richter <georg@php.net> | + +----------------------------------------------------------------------+ + + $Id$ +*/ + +#ifndef __HAVE_MYSQLI_PROFILER_H__ +#define __HAVE_MYSQLI_PROFILER_H__ + +#ifdef PHP_WIN32 +#include <process.h> +#include <direct.h> +#include "win32/time.h" +#else +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <sys/time.h> +#endif + +typedef struct { + struct timeval starttime, + endtime; /* execution time */ +} PR_TIME_INFO; + + +#define MYSQLI_PR_REPORT_STDERR 1 +#define MYSQLI_PR_REPORT_PORT 2 + + + +/*** PROFILER MACROS ***/ +#define MYSQLI_PROFILER_STARTTIME(ptr) if (MyG(profiler.mode)) gettimeofday(&ptr.starttime, NULL) +#define MYSQLI_PROFILER_ENDTIME(ptr) if (MyG(profiler.mode)) gettimeofday(&ptr.endtime, NULL) +#define MYSQLI_PROFILER_REPORT(_type, _time, ptr) if (MyG(profiler.mode)) php_mysqli_profiler_report(_type, _time, (void *)ptr) + + + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * indent-tabs-mode: t + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqli/mysqli_result_iterator.c b/ext/mysqli/mysqli_result_iterator.c new file mode 100644 index 0000000..0f5ccdd --- /dev/null +++ b/ext/mysqli/mysqli_result_iterator.c @@ -0,0 +1,182 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Georg Richter <georg@php.net> | + | Andrey Hristov <andrey@php.net> | + | Ulf Wendel <uw@php.net> | + +----------------------------------------------------------------------+ + + $Id: mysqli.c 299335 2010-05-13 11:05:09Z andrey $ +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <signal.h> + +#include "php.h" +#include "php_ini.h" +#include "php_mysqli_structs.h" +#include "mysqli_priv.h" +#include "zend_interfaces.h" + + +extern zend_object_iterator_funcs php_mysqli_result_iterator_funcs; + +typedef struct { + zend_object_iterator intern; + mysqli_object *result; + zval *current_row; + my_longlong row_num; +} php_mysqli_result_iterator; + + +/* {{{ */ +zend_object_iterator *php_mysqli_result_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) +{ + php_mysqli_result_iterator *iterator; + + if (by_ref) { + zend_error(E_ERROR, "An iterator cannot be used with foreach by reference"); + } + iterator = ecalloc(1, sizeof(php_mysqli_result_iterator)); + + Z_ADDREF_P(object); + iterator->intern.data = (void*)object; + iterator->intern.funcs = &php_mysqli_result_iterator_funcs; + iterator->result = (mysqli_object *) zend_object_store_get_object(object TSRMLS_CC); + iterator->row_num = -1; + + return (zend_object_iterator*)iterator; +} +/* }}} */ + + +/* {{{ */ +static void php_mysqli_result_iterator_dtor(zend_object_iterator *iter TSRMLS_DC) +{ + php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; + + /* cleanup handled in sxe_object_dtor as we dont always have an iterator wrapper */ + if (iterator->intern.data) { + zval_ptr_dtor((zval**)&iterator->intern.data); + } + if (iterator->current_row) { + zval_ptr_dtor(&iterator->current_row); + } + efree(iterator); +} +/* }}} */ + + +/* {{{ */ +static int php_mysqli_result_iterator_valid(zend_object_iterator *iter TSRMLS_DC) +{ + php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; + + return iterator->current_row && Z_TYPE_P(iterator->current_row) == IS_ARRAY ? SUCCESS : FAILURE; +} +/* }}} */ + + +/* {{{ */ +static void php_mysqli_result_iterator_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) +{ + php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; + + *data = &iterator->current_row; +} +/* }}} */ + + +/* {{{ */ +static void php_mysqli_result_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC) +{ + + php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; + mysqli_object *intern = iterator->result; + MYSQL_RES *result; + + MYSQLI_FETCH_RESOURCE_BY_OBJ(result, MYSQL_RES *, intern, "mysqli_result", MYSQLI_STATUS_VALID); + if (iterator->current_row) { + zval_ptr_dtor(&iterator->current_row); + } + MAKE_STD_ZVAL(iterator->current_row); + php_mysqli_fetch_into_hash_aux(iterator->current_row, result, MYSQLI_ASSOC TSRMLS_CC); + if (Z_TYPE_P(iterator->current_row) == IS_ARRAY) { + iterator->row_num++; + } +} +/* }}} */ + + +/* {{{ */ +static void php_mysqli_result_iterator_rewind(zend_object_iterator *iter TSRMLS_DC) +{ + php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; + mysqli_object *intern = iterator->result; + MYSQL_RES *result; + + MYSQLI_FETCH_RESOURCE_BY_OBJ(result, MYSQL_RES *, intern, "mysqli_result", MYSQLI_STATUS_VALID); + + if (mysqli_result_is_unbuffered(result)) { +#if MYSQLI_USE_MYSQLND + if (result->unbuf->eof_reached) { +#else + if (result->eof) { +#endif + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Data fetched with MYSQLI_USE_RESULT can be iterated only once"); + return; + } + } else { + mysql_data_seek(result, 0); + } + iterator->row_num = -1; + php_mysqli_result_iterator_move_forward(iter TSRMLS_CC); +} +/* }}} */ + + +/* {{{ php_mysqli_result_iterator_current_key */ +static int php_mysqli_result_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) +{ + php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; + + *int_key = (ulong) iterator->row_num; + return HASH_KEY_IS_LONG; +} +/* }}} */ + + +/* {{{ php_mysqli_result_iterator_funcs */ +zend_object_iterator_funcs php_mysqli_result_iterator_funcs = { + php_mysqli_result_iterator_dtor, + php_mysqli_result_iterator_valid, + php_mysqli_result_iterator_current_data, + php_mysqli_result_iterator_current_key, + php_mysqli_result_iterator_move_forward, + php_mysqli_result_iterator_rewind, +}; +/* }}} */ + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqli/mysqli_warning.c b/ext/mysqli/mysqli_warning.c new file mode 100644 index 0000000..25653e3 --- /dev/null +++ b/ext/mysqli/mysqli_warning.c @@ -0,0 +1,365 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Georg Richter <georg@php.net> | + +----------------------------------------------------------------------+ + +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <signal.h> + +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +#include "php_mysqli_structs.h" +#include "mysqli_priv.h" + +/* Define these in the PHP5 tree to make merging easy process */ +#define ZSTR_DUPLICATE (1<<0) +#define ZSTR_AUTOFREE (1<<1) + +#define ZVAL_UTF8_STRING(z, s, flags) ZVAL_STRING((z), (char*)(s), ((flags) & ZSTR_DUPLICATE)) +#define ZVAL_UTF8_STRINGL(z, s, l, flags) ZVAL_STRINGL((z), (char*)(s), (l), ((flags) & ZSTR_DUPLICATE)) + + +/* {{{ void php_clear_warnings() */ +void php_clear_warnings(MYSQLI_WARNING *w) +{ + MYSQLI_WARNING *n; + + while (w) { + n = w; + zval_dtor(&(w->reason)); + zval_dtor(&(w->sqlstate)); + w = w->next; + efree(n); + } +} +/* }}} */ + + +#ifndef MYSQLI_USE_MYSQLND +/* {{{ MYSQLI_WARNING *php_new_warning */ +static +MYSQLI_WARNING *php_new_warning(const char *reason, int errorno TSRMLS_DC) +{ + MYSQLI_WARNING *w; + + w = (MYSQLI_WARNING *)ecalloc(1, sizeof(MYSQLI_WARNING)); + + ZVAL_UTF8_STRING(&(w->reason), reason, ZSTR_DUPLICATE); + + ZVAL_UTF8_STRINGL(&(w->sqlstate), "HY000", sizeof("HY000") - 1, ZSTR_DUPLICATE); + + w->errorno = errorno; + + return w; +} +/* }}} */ + + +/* {{{ MYSQLI_WARNING *php_get_warnings(MYSQL *mysql TSRMLS_DC) */ +MYSQLI_WARNING *php_get_warnings(MYSQL *mysql TSRMLS_DC) +{ + MYSQLI_WARNING *w, *first = NULL, *prev = NULL; + MYSQL_RES *result; + MYSQL_ROW row; + + if (mysql_real_query(mysql, "SHOW WARNINGS", 13)) { + return NULL; + } + + result = mysql_store_result(mysql); + + while ((row = mysql_fetch_row(result))) { + w = php_new_warning(row[2], atoi(row[1]) TSRMLS_CC); + if (!first) { + first = w; + } + if (prev) { + prev->next = w; + } + prev = w; + } + mysql_free_result(result); + return first; +} +/* }}} */ +#else +/* {{{ MYSQLI_WARNING *php_new_warning */ +static +MYSQLI_WARNING *php_new_warning(const zval * reason, int errorno TSRMLS_DC) +{ + MYSQLI_WARNING *w; + + w = (MYSQLI_WARNING *)ecalloc(1, sizeof(MYSQLI_WARNING)); + + w->reason = *reason; + zval_copy_ctor(&(w->reason)); + + ZVAL_UTF8_STRINGL(&(w->reason), Z_STRVAL(w->reason), Z_STRLEN(w->reason), ZSTR_AUTOFREE); + + ZVAL_UTF8_STRINGL(&(w->sqlstate), "HY000", sizeof("HY000") - 1, ZSTR_DUPLICATE); + + w->errorno = errorno; + + return w; +} +/* }}} */ + + +/* {{{ MYSQLI_WARNING *php_get_warnings(MYSQL *mysql TSRMLS_DC) */ +MYSQLI_WARNING * php_get_warnings(MYSQLND_CONN_DATA * mysql TSRMLS_DC) +{ + MYSQLI_WARNING *w, *first = NULL, *prev = NULL; + MYSQL_RES *result; + zval *row; + + if (mysql->m->query(mysql, "SHOW WARNINGS", 13 TSRMLS_CC)) { + return NULL; + } + + result = mysql->m->use_result(mysql TSRMLS_CC); + + for (;;) { + zval **entry; + int errno; + + MAKE_STD_ZVAL(row); + mysqlnd_fetch_into(result, MYSQLND_FETCH_NUM, row, MYSQLND_MYSQLI); + if (Z_TYPE_P(row) != IS_ARRAY) { + zval_ptr_dtor(&row); + break; + } + zend_hash_internal_pointer_reset(Z_ARRVAL_P(row)); + /* 0. we don't care about the first */ + zend_hash_move_forward(Z_ARRVAL_P(row)); + + /* 1. Here comes the error no */ + zend_hash_get_current_data(Z_ARRVAL_P(row), (void **)&entry); + convert_to_long_ex(entry); + errno = Z_LVAL_PP(entry); + zend_hash_move_forward(Z_ARRVAL_P(row)); + + /* 2. Here comes the reason */ + zend_hash_get_current_data(Z_ARRVAL_P(row), (void **)&entry); + + w = php_new_warning(*entry, errno TSRMLS_CC); + /* + Don't destroy entry, because the row destroy will decrease + the refcounter. Decreased twice then mysqlnd_free_result() + will crash, because it will try to access already freed memory. + */ + if (!first) { + first = w; + } + if (prev) { + prev->next = (void *)w; + } + prev = w; + + zval_ptr_dtor(&row); + } + + mysql_free_result(result); + return first; +} +/* }}} */ +#endif + + +/* {{{ bool mysqli_warning::next() */ +PHP_METHOD(mysqli_warning, next) +{ + MYSQLI_WARNING *w; + zval *mysqli_warning; + mysqli_object *obj = (mysqli_object *)zend_objects_get_address(getThis() TSRMLS_CC); + + if (obj->ptr) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", + &mysqli_warning, mysqli_warning_class_entry) == FAILURE) { + return; + } + + MYSQLI_FETCH_RESOURCE(w, MYSQLI_WARNING *, &mysqli_warning, "mysqli_warning", MYSQLI_STATUS_VALID); + + if (w && w->next) { + w = w->next; + ((MYSQLI_RESOURCE *)(obj->ptr))->ptr = w; + RETURN_TRUE; + } + } + RETURN_FALSE; +} +/* }}} */ + + +/* {{{ property mysqli_warning_message */ +static +int mysqli_warning_message(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MYSQLI_WARNING *w; + + if (!obj->ptr || !((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { + return FAILURE; + } + + w = (MYSQLI_WARNING *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; + MAKE_STD_ZVAL(*retval); + **retval = w->reason; + zval_copy_ctor(*retval); + return SUCCESS; +} +/* }}} */ + + +/* {{{ property mysqli_warning_sqlstate */ +static +int mysqli_warning_sqlstate(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MYSQLI_WARNING *w; + + if (!obj->ptr || !((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { + return FAILURE; + } + + w = (MYSQLI_WARNING *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; + MAKE_STD_ZVAL(*retval); + **retval = w->sqlstate; + zval_copy_ctor(*retval); + return SUCCESS; +} +/* }}} */ + + +/* {{{ property mysqli_warning_error */ +static +int mysqli_warning_errno(mysqli_object *obj, zval **retval TSRMLS_DC) +{ + MYSQLI_WARNING *w; + + if (!obj->ptr || !((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { + return FAILURE; + } + w = (MYSQLI_WARNING *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; + MAKE_STD_ZVAL(*retval); + ZVAL_LONG(*retval, w->errorno); + return SUCCESS; +} +/* }}} */ + +/* {{{ mysqli_warning_construct(object obj) */ +PHP_METHOD(mysqli_warning, __construct) +{ + zval *z; + mysqli_object *obj; +#ifndef MYSQLI_USE_MYSQLND + MYSQL *hdl; +#endif + MYSQLI_WARNING *w; + MYSQLI_RESOURCE *mysqli_resource; + + if (ZEND_NUM_ARGS() != 1) { + WRONG_PARAM_COUNT; + } + if (zend_parse_parameters(1 TSRMLS_CC, "o", &z)==FAILURE) { + return; + } + obj = (mysqli_object *)zend_object_store_get_object(z TSRMLS_CC);\ + + if (obj->zo.ce == mysqli_link_class_entry) { + MY_MYSQL *mysql; + MYSQLI_FETCH_RESOURCE_CONN(mysql, &z, MYSQLI_STATUS_VALID); + if (mysql_warning_count(mysql->mysql)) { +#ifndef MYSQLI_USE_MYSQLND + w = php_get_warnings(mysql->mysql TSRMLS_CC); +#else + w = php_get_warnings(mysql->mysql->data TSRMLS_CC); +#endif + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "No warnings found"); + RETURN_FALSE; + } + } else if (obj->zo.ce == mysqli_stmt_class_entry) { + MY_STMT *stmt; + MYSQLI_FETCH_RESOURCE_STMT(stmt, &z, MYSQLI_STATUS_VALID); +#ifndef MYSQLI_USE_MYSQLND + hdl = mysqli_stmt_get_connection(stmt->stmt); + if (mysql_warning_count(hdl)) { + w = php_get_warnings(hdl TSRMLS_CC); +#else + if (mysqlnd_stmt_warning_count(stmt->stmt)) { + w = php_get_warnings(mysqli_stmt_get_connection(stmt->stmt) TSRMLS_CC); +#endif + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "No warnings found"); + RETURN_FALSE; + } + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid class argument"); + RETURN_FALSE; + } + + mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); + mysqli_resource->ptr = mysqli_resource->info = (void *)w; + mysqli_resource->status = MYSQLI_STATUS_VALID; + + if (!getThis() || !instanceof_function(Z_OBJCE_P(getThis()), mysqli_warning_class_entry TSRMLS_CC)) { + MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry); + } else { + ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr = mysqli_resource; + } + +} +/* }}} */ + +/* {{{ mysqli_warning_methods */ +const zend_function_entry mysqli_warning_methods[] = { + PHP_ME(mysqli_warning, __construct, NULL, ZEND_ACC_PROTECTED) + PHP_ME(mysqli_warning, next, NULL, ZEND_ACC_PUBLIC) + {NULL, NULL, NULL} +}; +/* }}} */ + +/* {{{ mysqli_warning_property_entries */ +const mysqli_property_entry mysqli_warning_property_entries[] = { + {"message", sizeof("message") - 1, mysqli_warning_message, NULL}, + {"sqlstate", sizeof("sqlstate") - 1, mysqli_warning_sqlstate, NULL}, + {"errno", sizeof("errno") - 1, mysqli_warning_errno, NULL}, + {NULL, 0, NULL, NULL} +}; +/* }}} */ + +/* {{{ mysqli_warning_property_info_entries */ +const zend_property_info mysqli_warning_property_info_entries[] = { + {ZEND_ACC_PUBLIC, "message", sizeof("message") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "sqlstate", sizeof("sqlstate") - 1, -1, 0, NULL, 0, NULL}, + {ZEND_ACC_PUBLIC, "errno", sizeof("errno") - 1, -1, 0, NULL, 0, NULL}, + {0, NULL, 0, -1, 0, NULL, 0, NULL} +}; +/* }}} */ + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * indent-tabs-mode: t + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqli/package.xml b/ext/mysqli/package.xml new file mode 100644 index 0000000..6de81d7 --- /dev/null +++ b/ext/mysqli/package.xml @@ -0,0 +1,118 @@ +<?xml version="1.0" encoding="ISO-8859-1" ?> +<!DOCTYPE package SYSTEM "../pear/package.dtd"> +<package> + <name>mysqli</name> + <summary>MySQLi - new MySQL interface for PHP 5 and MySQL 4.1+</summary> + <maintainers> + <maintainer> + <user>georg</user> + <name>Georg Richter</name> + <email>georg@php.net</email> + <role>lead</role> + </maintainer> + <maintainer> + <user>zak</user> + <name>Zak Greant</name> + <email>zak@php.net</email> + <role>lead</role> + </maintainer> + </maintainers> + <description> +MySQLi is a rewrite of the original MySQL extension ... + </description> + <license>PHP</license> + <release> + <state>beta</state> + <version>5.0.0rc1</version> + <date>2004-03-19</date> + <notes> +package.xml added to support installation using pear installer + </notes> + <configureoptions> + <configureoption name="with-mysqli" default="autodetect" prompt="path to mysql_config tool?"/> + <configureoption name="enable-embedded-mysqli" default="no" prompt="embedd mysql server into PHP?"/> + </configureoptions> + <filelist> + <file role="src" name="config.m4"/> + <file role="src" name="config.w32"/> + <file role="src" name="mysqli.dsp"/> + <file role="src" name="mysqli.c"/> + <file role="src" name="mysqli_api.c"/> + <file role="src" name="mysqli_fe.c"/> + <file role="src" name="mysqli_nonapi.c"/> + <file role="src" name="mysqli_prop.c"/> + <file role="src" name="mysqli_repl.c"/> + <file role="src" name="mysqli_report.c"/> + <file role="src" name="mysqli_report.h"/> + <file role="src" name="php_mysqli.h"/> + <file role="doc" name="CREDITS"/> + <file role="test" name="tests/001.phpt"/> + <file role="test" name="tests/002.phpt"/> + <file role="test" name="tests/003.phpt"/> + <file role="test" name="tests/004.phpt"/> + <file role="test" name="tests/005.phpt"/> + <file role="test" name="tests/006.phpt"/> + <file role="test" name="tests/007.phpt"/> + <file role="test" name="tests/008.phpt"/> + <file role="test" name="tests/009.phpt"/> + <file role="test" name="tests/010.phpt"/> + <file role="test" name="tests/011.phpt"/> + <file role="test" name="tests/012.phpt"/> + <file role="test" name="tests/013.phpt"/> + <file role="test" name="tests/014.phpt"/> + <file role="test" name="tests/015.phpt"/> + <file role="test" name="tests/016.phpt"/> + <file role="test" name="tests/017.phpt"/> + <file role="test" name="tests/018.phpt"/> + <file role="test" name="tests/019.phpt"/> + <file role="test" name="tests/020.phpt"/> + <file role="test" name="tests/021.phpt"/> + <file role="test" name="tests/022.phpt"/> + <file role="test" name="tests/023.phpt"/> + <file role="test" name="tests/024.phpt"/> + <file role="test" name="tests/025.phpt"/> + <file role="test" name="tests/026.phpt"/> + <file role="test" name="tests/027.phpt"/> + <file role="test" name="tests/028.phpt"/> + <file role="test" name="tests/029.phpt"/> + <file role="test" name="tests/030.phpt"/> + <file role="test" name="tests/031.phpt"/> + <file role="test" name="tests/032.phpt"/> + <file role="test" name="tests/033.phpt"/> + <file role="test" name="tests/034.phpt"/> + <file role="test" name="tests/035.phpt"/> + <file role="test" name="tests/036.phpt"/> + <file role="test" name="tests/037.phpt"/> + <file role="test" name="tests/038.phpt"/> + <file role="test" name="tests/039.phpt"/> + <file role="test" name="tests/040.phpt"/> + <file role="test" name="tests/041.phpt"/> + <file role="test" name="tests/042.phpt"/> + <file role="test" name="tests/043.phpt"/> + <file role="test" name="tests/044.phpt"/> + <file role="test" name="tests/045.phpt"/> + <file role="test" name="tests/046.phpt"/> + <file role="test" name="tests/047.phpt"/> + <file role="test" name="tests/048.phpt"/> + <file role="test" name="tests/049.phpt"/> + <file role="test" name="tests/050.phpt"/> + <file role="test" name="tests/051.phpt"/> + <file role="test" name="tests/052.phpt"/> + <file role="test" name="tests/053.phpt"/> + <file role="test" name="tests/054.phpt"/> + <file role="test" name="tests/055.phpt"/> + <file role="test" name="tests/056.phpt"/> + <file role="test" name="tests/057.phpt"/> + <file role="test" name="tests/058.phpt"/> + <file role="test" name="tests/059.phpt"/> + <file role="test" name="tests/060.phpt"/> + <file role="test" name="tests/connect.inc"/> + </filelist> + <deps> + <dep type="php" rel="ge" version="5" /> + </deps> + </release> +</package> +<!-- +vim:et:ts=1:sw=1 +--> diff --git a/ext/mysqli/php_mysqli.h b/ext/mysqli/php_mysqli.h new file mode 100644 index 0000000..6dac3f0 --- /dev/null +++ b/ext/mysqli/php_mysqli.h @@ -0,0 +1,39 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Georg Richter <georg@php.net> | + | Andrey Hristov <andrey@php.net> | + | Ulf Wendel <uw@php.net> | + +----------------------------------------------------------------------+ + + $Id$ +*/ + +#ifndef PHP_MYSQLI_H +#define PHP_MYSQLI_H + +#define phpext_mysqli_ptr &mysqli_module_entry +extern zend_module_entry mysqli_module_entry; + +#endif /* PHP_MYSQLI.H */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * indent-tabs-mode: t + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqli/php_mysqli_structs.h b/ext/mysqli/php_mysqli_structs.h new file mode 100644 index 0000000..1f7e761 --- /dev/null +++ b/ext/mysqli/php_mysqli_structs.h @@ -0,0 +1,374 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Georg Richter <georg@php.net> | + | Andrey Hristov <andrey@php.net> | + | Ulf Wendel <uw@php.net> | + +----------------------------------------------------------------------+ + + $Id$ +*/ + +#ifndef PHP_MYSQLI_STRUCTS_H +#define PHP_MYSQLI_STRUCTS_H + +/* A little hack to prevent build break, when mysql is used together with + * c-client, which also defines LIST. + */ +#ifdef LIST +#undef LIST +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifdef MYSQLI_USE_MYSQLND +#include "ext/mysqlnd/mysqlnd.h" +#include "mysqli_mysqlnd.h" +#else + +/* + The libmysql headers (a PITA) also define it and there will be an warning. + Undef it and later we might need to define it again. +*/ +#ifdef HAVE_MBRLEN +#undef HAVE_MBRLEN +#define WE_HAD_MBRLEN +#endif +#ifdef HAVE_MBSTATE_T +#undef HAVE_MBSTATE_T +#define WE_HAD_MBSTATE_T +#endif + +#if defined(ulong) && !defined(HAVE_ULONG) +#define HAVE_ULONG +#endif + +#include <my_global.h> + +#if !defined(HAVE_MBRLEN) && defined(WE_HAD_MBRLEN) +#define HAVE_MBRLEN 1 +#endif + +#if !defined(HAVE_MBSTATE_T) && defined(WE_HAD_MBSTATE_T) +#define HAVE_MBSTATE_T 1 +#endif + +/* + We need more than mysql.h because we need CHARSET_INFO in one place. + This order has been borrowed from the ODBC driver. Nothing can be removed + from the list of headers :( +*/ + +#include <my_sys.h> +#include <mysql.h> +#include <errmsg.h> +#include <my_list.h> +#include <m_string.h> +#include <mysqld_error.h> +#include <my_list.h> +#include <m_ctype.h> +#include "mysqli_libmysql.h" +#endif /* MYSQLI_USE_MYSQLND */ + + +#define MYSQLI_VERSION_ID 101009 + +enum mysqli_status { + MYSQLI_STATUS_UNKNOWN=0, + MYSQLI_STATUS_CLEARED, + MYSQLI_STATUS_INITIALIZED, + MYSQLI_STATUS_VALID +}; + +typedef struct { + char *val; + ulong buflen; + ulong output_len; + ulong type; +} VAR_BUFFER; + +typedef struct { + unsigned int var_cnt; + VAR_BUFFER *buf; + zval **vars; + char *is_null; +} BIND_BUFFER; + +typedef struct { + MYSQL_STMT *stmt; + BIND_BUFFER param; + BIND_BUFFER result; + char *query; +} MY_STMT; + +typedef struct { + MYSQL *mysql; + char *hash_key; + zval *li_read; + php_stream *li_stream; + unsigned int multi_query; + zend_bool persistent; +#if defined(MYSQLI_USE_MYSQLND) + int async_result_fetch_type; +#endif +} MY_MYSQL; + +typedef struct { + int mode; + int socket; + FILE *fp; +} PROFILER; + +typedef struct { + void *ptr; /* resource: (mysql, result, stmt) */ + void *info; /* additional buffer */ + enum mysqli_status status; /* object status */ +} MYSQLI_RESOURCE; + +typedef struct _mysqli_object { + zend_object zo; + void *ptr; + HashTable *prop_handler; +} mysqli_object; /* extends zend_object */ + +typedef struct st_mysqli_warning MYSQLI_WARNING; + +struct st_mysqli_warning { + zval reason; + zval sqlstate; + int errorno; + MYSQLI_WARNING *next; +}; + +typedef struct _mysqli_property_entry { + const char *pname; + size_t pname_length; + int (*r_func)(mysqli_object *obj, zval **retval TSRMLS_DC); + int (*w_func)(mysqli_object *obj, zval *value TSRMLS_DC); +} mysqli_property_entry; + +#if !defined(MYSQLI_USE_MYSQLND) +typedef struct { + char error_msg[LOCAL_INFILE_ERROR_LEN]; + void *userdata; +} mysqli_local_infile; +#endif + +typedef struct { + zend_ptr_stack free_links; +} mysqli_plist_entry; + +#ifdef PHP_WIN32 +#define PHP_MYSQLI_API __declspec(dllexport) +#define MYSQLI_LLU_SPEC "%I64u" +#define MYSQLI_LL_SPEC "%I64d" +#ifndef L64 +#define L64(x) x##i64 +#endif +typedef __int64 my_longlong; +#else +# if defined(__GNUC__) && __GNUC__ >= 4 +# define PHP_MYSQLI_API __attribute__ ((visibility("default"))) +# else +# define PHP_MYSQLI_API +# endif +/* we need this for PRIu64 and PRId64 */ +#include <inttypes.h> +#define MYSQLI_LLU_SPEC "%" PRIu64 +#define MYSQLI_LL_SPEC "%" PRId64 +#ifndef L64 +#define L64(x) x##LL +#endif +typedef int64_t my_longlong; +#endif + +#ifdef ZTS +#include "TSRM.h" +#endif + +extern zend_class_entry *mysqli_link_class_entry; +extern zend_class_entry *mysqli_stmt_class_entry; +extern zend_class_entry *mysqli_result_class_entry; +extern zend_class_entry *mysqli_driver_class_entry; +extern zend_class_entry *mysqli_warning_class_entry; +extern zend_class_entry *mysqli_exception_class_entry; +extern int php_le_pmysqli(void); +extern void php_mysqli_dtor_p_elements(void *data); + +extern void php_mysqli_close(MY_MYSQL * mysql, int close_type, int resource_status TSRMLS_DC); + +extern zend_object_iterator_funcs php_mysqli_result_iterator_funcs; +extern zend_object_iterator *php_mysqli_result_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC); + +extern void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * result, long fetchtype TSRMLS_DC); + +#ifdef HAVE_SPL +extern PHPAPI zend_class_entry *spl_ce_RuntimeException; +#endif + +#define MYSQLI_DISABLE_MQ if (mysql->multi_query) { \ + mysql_set_server_option(mysql->mysql, MYSQL_OPTION_MULTI_STATEMENTS_OFF); \ + mysql->multi_query = 0; \ +} + +#define MYSQLI_ENABLE_MQ if (!mysql->multi_query) { \ + mysql_set_server_option(mysql->mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON); \ + mysql->multi_query = 1; \ +} + +#define REGISTER_MYSQLI_CLASS_ENTRY(name, mysqli_entry, class_functions) { \ + zend_class_entry ce; \ + INIT_CLASS_ENTRY(ce, name,class_functions); \ + ce.create_object = mysqli_objects_new; \ + mysqli_entry = zend_register_internal_class(&ce TSRMLS_CC); \ +} \ + +#define MYSQLI_REGISTER_RESOURCE_EX(__ptr, __zval) \ + ((mysqli_object *) zend_object_store_get_object(__zval TSRMLS_CC))->ptr = __ptr; + +#define MYSQLI_RETURN_RESOURCE(__ptr, __ce) \ + Z_TYPE_P(return_value) = IS_OBJECT; \ + (return_value)->value.obj = mysqli_objects_new(__ce TSRMLS_CC); \ + MYSQLI_REGISTER_RESOURCE_EX(__ptr, return_value) + +#define MYSQLI_REGISTER_RESOURCE(__ptr, __ce) \ +{\ + zval *object = getThis();\ + if (!object || !instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry TSRMLS_CC)) {\ + object = return_value;\ + Z_TYPE_P(object) = IS_OBJECT;\ + (object)->value.obj = mysqli_objects_new(__ce TSRMLS_CC);\ + }\ + MYSQLI_REGISTER_RESOURCE_EX(__ptr, object)\ +} + +#define MYSQLI_FETCH_RESOURCE(__ptr, __type, __id, __name, __check) \ +{ \ + MYSQLI_RESOURCE *my_res; \ + mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*(__id) TSRMLS_CC);\ + if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {\ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", intern->zo.ce->name);\ + RETURN_NULL();\ + }\ + __ptr = (__type)my_res->ptr; \ + if (__check && my_res->status < __check) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid object or resource %s\n", intern->zo.ce->name); \ + RETURN_NULL();\ + }\ +} + +#define MYSQLI_FETCH_RESOURCE_BY_OBJ(__ptr, __type, __obj, __name, __check) \ +{ \ + MYSQLI_RESOURCE *my_res; \ + if (!(my_res = (MYSQLI_RESOURCE *)(__obj->ptr))) {\ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", intern->zo.ce->name);\ + return;\ + }\ + __ptr = (__type)my_res->ptr; \ + if (__check && my_res->status < __check) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid object or resource %s\n", intern->zo.ce->name); \ + return;\ + }\ +} + + +#define MYSQLI_FETCH_RESOURCE_CONN(__ptr, __id, __check) \ +{ \ + MYSQLI_FETCH_RESOURCE((__ptr), MY_MYSQL *, (__id), "mysqli_link", (__check)); \ + if (!(__ptr)->mysql) { \ + mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*(__id) TSRMLS_CC);\ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid object or resource %s\n", intern->zo.ce->name); \ + RETURN_NULL();\ + } \ +} + +#define MYSQLI_FETCH_RESOURCE_STMT(__ptr, __id, __check) \ +{ \ + MYSQLI_FETCH_RESOURCE((__ptr), MY_STMT *, (__id), "mysqli_stmt", (__check)); \ + if (!(__ptr)->stmt) { \ + mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*(__id) TSRMLS_CC);\ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid object or resource %s\n", intern->zo.ce->name); \ + RETURN_NULL();\ + } \ +} + + +#define MYSQLI_SET_STATUS(__id, __value) \ +{ \ + mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*(__id) TSRMLS_CC);\ + ((MYSQLI_RESOURCE *)intern->ptr)->status = __value; \ +} \ + +#define MYSQLI_CLEAR_RESOURCE(__id) \ +{ \ + mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*(__id) TSRMLS_CC);\ + efree(intern->ptr); \ + intern->ptr = NULL; \ +} + + +ZEND_BEGIN_MODULE_GLOBALS(mysqli) + long default_link; + long num_links; + long max_links; + long num_active_persistent; + long num_inactive_persistent; + long max_persistent; + long allow_persistent; + unsigned long default_port; + char *default_host; + char *default_user; + char *default_socket; + char *default_pw; + long reconnect; + long allow_local_infile; + long strict; + long error_no; + char *error_msg; + long report_mode; + HashTable *report_ht; + unsigned long multi_query; + unsigned long embedded; +ZEND_END_MODULE_GLOBALS(mysqli) + + +#ifdef ZTS +#define MyG(v) TSRMG(mysqli_globals_id, zend_mysqli_globals *, v) +#else +#define MyG(v) (mysqli_globals.v) +#endif + +#define my_estrdup(x) (x) ? estrdup(x) : NULL +#define my_efree(x) if (x) efree(x) + +ZEND_EXTERN_MODULE_GLOBALS(mysqli) + +#endif /* PHP_MYSQLI_STRUCTS.H */ + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * indent-tabs-mode: t + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqli/tests/001.phpt b/ext/mysqli/tests/001.phpt new file mode 100644 index 0000000..ed09b2e --- /dev/null +++ b/ext/mysqli/tests/001.phpt @@ -0,0 +1,63 @@ +--TEST-- +mysqli connect +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $test = ""; + + /*** test mysqli_connect localhost:port ***/ + $link = my_mysqli_connect($host, $user, $passwd, "", $port, $socket); + $test .= ($link) ? "1" : "0"; + mysqli_close($link); + + /*** test mysqli_real_connect ***/ + $link = mysqli_init(); + $test.= (my_mysqli_real_connect($link, $host, $user, $passwd, "", $port, $socket) ) + ? "1" : "0"; + mysqli_close($link); + + /*** test mysqli_real_connect with db ***/ + $link = mysqli_init(); + $test .= (my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) + ? "1" : "0"; + mysqli_close($link); + + /*** test mysqli_real_connect with port ***/ + $link = mysqli_init(); + $test .= (my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) + ? "1":"0"; + mysqli_close($link); + + /* temporary addition for Kent's setup, Win32 box */ + for ($i = 0; $i < 10; $i++) { + if (!$link = mysqli_init()) + printf("[001 + %d] mysqli_init() failed, [%d] %s\n", $i, mysqli_connect_errno(), mysqli_connect_error()); + + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) + printf("[002 + %d] mysqli_real_connect() failed, [%d] %s\n", $i, mysqli_connect_errno(), mysqli_connect_error()); + + mysqli_close($link); + } + + /*** test mysqli_real_connect compressed ***/ + /* + $link = mysqli_init(); + $test .= (my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket, MYSQLI_CLIENT_COMPRESS)) + ? "1" : "0"; + mysqli_close($link); + */ + /* todo ssl connections */ + + var_dump($test); + print "done!"; +?> +--EXPECTF-- +%s(4) "1111" +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/002.phpt b/ext/mysqli/tests/002.phpt new file mode 100644 index 0000000..522c99e --- /dev/null +++ b/ext/mysqli/tests/002.phpt @@ -0,0 +1,85 @@ +--TEST-- +mysqli bind_result 1 +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test_fetch_null")) + printf("[002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $rc = mysqli_query($link,"CREATE TABLE test_fetch_null(col1 tinyint, col2 smallint, + col3 int, col4 bigint, + col5 float, col6 double, + col7 date, col8 time, + col9 varbinary(10), + col10 varchar(50), + col11 char(20)) ENGINE=" . $engine); + + if (!$rc) + printf("[003] Cannot create table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $rc = mysqli_query($link, "INSERT INTO test_fetch_null(col1,col10, col11) VALUES(1,'foo1', 1000),(2,'foo2', 88),(3,'foo3', 389789)"); + if (!$rc) + printf("[004] Cannot insert records, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $stmt = mysqli_prepare($link, "SELECT col1, col2, col3, col4, col5, col6, col7, col8, col9, col10, col11 from test_fetch_null ORDER BY col1"); + mysqli_stmt_bind_result($stmt, $c1, $c2, $c3, $c4, $c5, $c6, $c7, $c8, $c9, $c10, $c11); + mysqli_stmt_execute($stmt); + + mysqli_stmt_fetch($stmt); + + $test = array($c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$c10,$c11); + + var_dump($test); + + mysqli_stmt_close($stmt); + @mysqli_query($link, "DROP TABLE IF EXISTS test_fetch_null"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_fetch_null")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +array(11) { + [0]=> + int(1) + [1]=> + NULL + [2]=> + NULL + [3]=> + NULL + [4]=> + NULL + [5]=> + NULL + [6]=> + NULL + [7]=> + NULL + [8]=> + NULL + [9]=> + %unicode|string%(4) "foo1" + [10]=> + %unicode|string%(4) "1000" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/003.phpt b/ext/mysqli/tests/003.phpt new file mode 100644 index 0000000..9374763 --- /dev/null +++ b/ext/mysqli/tests/003.phpt @@ -0,0 +1,103 @@ +--TEST-- +mysqli connect +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_query($link, "SET sql_mode=''"); + + if (!mysqli_query($link,"DROP TABLE IF EXISTS test_bind_result")) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $rc = @mysqli_query($link,"CREATE TABLE test_bind_result( + c1 date, + c2 time, + c3 timestamp(14), + c4 year, + c5 datetime, + c6 timestamp(4), + c7 timestamp(6)) ENGINE=" . $engine); + + /* + Seems that not all MySQL 6.0 installations use defaults that ignore the display widths. + From the manual: + From MySQL 4.1.0 on, TIMESTAMP display format differs from that of earlier MySQL releases: + [...] + Display widths (used as described in the preceding section) are no longer supported. + In other words, for declarations such as TIMESTAMP(2), TIMESTAMP(4), and so on, + the display width is ignored. + [...] + */ + if (!$rc) + $rc = @mysqli_query($link,"CREATE TABLE test_bind_result( + c1 date, + c2 time, + c3 timestamp, + c4 year, + c5 datetime, + c6 timestamp, + c7 timestamp) ENGINE=" . $engine); + + if (!$rc) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $rc = mysqli_query($link, "INSERT INTO test_bind_result VALUES( + '2002-01-02', + '12:49:00', + '2002-01-02 17:46:59', + 2010, + '2010-07-10', + '2020','1999-12-29')"); + if (!$rc) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $stmt = mysqli_prepare($link, "SELECT c1, c2, c3, c4, c5, c6, c7 FROM test_bind_result"); + mysqli_stmt_bind_result($stmt, $c1, $c2, $c3, $c4, $c5, $c6, $c7); + mysqli_stmt_execute($stmt); + mysqli_stmt_fetch($stmt); + + $test = array($c1,$c2,$c3,$c4,$c5,$c6,$c7); + + var_dump($test); + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_result"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_result")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +array(7) { + [0]=> + %unicode|string%(10) "2002-01-02" + [1]=> + %unicode|string%(8) "12:49:00" + [2]=> + %unicode|string%(19) "2002-01-02 17:46:59" + [3]=> + int(2010) + [4]=> + %unicode|string%(19) "2010-07-10 00:00:00" + [5]=> + %unicode|string%(19) "0000-00-00 00:00:00" + [6]=> + %unicode|string%(19) "1999-12-29 00:00:00" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/004.phpt b/ext/mysqli/tests/004.phpt new file mode 100644 index 0000000..010d6e1 --- /dev/null +++ b/ext/mysqli/tests/004.phpt @@ -0,0 +1,89 @@ +--TEST-- +mysqli fetch char/text +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + include ("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + + if (!mysqli_query($link,"DROP TABLE IF EXISTS test_bind_fetch")) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link,"CREATE TABLE test_bind_fetch(c1 char(10), c2 text) ENGINE=" . $engine)) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "INSERT INTO test_bind_fetch VALUES ('1234567890', 'this is a test0')")) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "INSERT INTO test_bind_fetch VALUES ('1234567891', 'this is a test1')")) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "INSERT INTO test_bind_fetch VALUES ('1234567892', 'this is a test2')")) + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "INSERT INTO test_bind_fetch VALUES ('1234567893', 'this is a test3')")) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$stmt = mysqli_prepare($link, "SELECT * FROM test_bind_fetch ORDER BY c1")) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $c1 = $c2 = NULL; + mysqli_stmt_bind_result($stmt, $c1, $c2); + mysqli_stmt_execute($stmt); + $i = 4; + while ($i--) { + mysqli_stmt_fetch($stmt); + $test = array($c1, $c2); + var_dump($test); + } + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +array(2) { + [0]=> + %unicode|string%(10) "1234567890" + [1]=> + %unicode|string%(15) "this is a test0" +} +array(2) { + [0]=> + %unicode|string%(10) "1234567891" + [1]=> + %unicode|string%(15) "this is a test1" +} +array(2) { + [0]=> + %unicode|string%(10) "1234567892" + [1]=> + %unicode|string%(15) "this is a test2" +} +array(2) { + [0]=> + %unicode|string%(10) "1234567893" + [1]=> + %unicode|string%(15) "this is a test3" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/005.phpt b/ext/mysqli/tests/005.phpt new file mode 100644 index 0000000..07292a1 --- /dev/null +++ b/ext/mysqli/tests/005.phpt @@ -0,0 +1,61 @@ +--TEST-- +mysqli fetch char/text long +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "CREATE TABLE test_bind_fetch(c1 char(10), c2 text) ENGINE=" . $engine)) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $a = str_repeat("A1", 32000); + + mysqli_query($link, "INSERT INTO test_bind_fetch VALUES ('1234567890', '$a')"); + + $stmt = mysqli_prepare($link, "SELECT * FROM test_bind_fetch"); + mysqli_stmt_bind_result($stmt, $c1, $c2); + mysqli_stmt_execute($stmt); + mysqli_stmt_fetch($stmt); + + $test[] = $c1; + $test[] = ($a == $c2) ? "32K String ok" : "32K String failed"; + + var_dump($test); + + /* this will crash with libmysql from PHP 5.0.6 (or earlier) to 5.3.0 */ + mysqli_stmt_fetch($stmt); + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +array(2) { + [0]=> + %unicode|string%(10) "1234567890" + [1]=> + %unicode|string%(13) "32K String ok" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/006.phpt b/ext/mysqli/tests/006.phpt new file mode 100644 index 0000000..2043cc5 --- /dev/null +++ b/ext/mysqli/tests/006.phpt @@ -0,0 +1,76 @@ +--TEST-- +mysqli fetch long values +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + if (!mysqli_query($link, "SET sql_mode=''")) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link,"DROP TABLE IF EXISTS test_bind_fetch")) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $rc = mysqli_query($link,"CREATE TABLE test_bind_fetch(c1 int unsigned, + c2 int unsigned, + c3 int, + c4 int, + c5 int, + c6 int unsigned, + c7 int) ENGINE=" . $engine); + if (!$rc) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "INSERT INTO test_bind_fetch VALUES (-23,35999,NULL,-500,-9999999,-0,0)")) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $stmt = mysqli_prepare($link, "SELECT * FROM test_bind_fetch"); + mysqli_stmt_bind_result($stmt, $c1, $c2, $c3, $c4, $c5, $c6, $c7); + mysqli_stmt_execute($stmt); + mysqli_stmt_fetch($stmt); + + $test = array($c1,$c2,$c3,$c4,$c5,$c6,$c7); + + var_dump($test); + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECT-- +array(7) { + [0]=> + int(0) + [1]=> + int(35999) + [2]=> + NULL + [3]=> + int(-500) + [4]=> + int(-9999999) + [5]=> + int(0) + [6]=> + int(0) +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/007.phpt b/ext/mysqli/tests/007.phpt new file mode 100644 index 0000000..26b5763 --- /dev/null +++ b/ext/mysqli/tests/007.phpt @@ -0,0 +1,76 @@ +--TEST-- +mysqli fetch short values +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + if (!mysqli_query($link, "SET sql_mode=''")) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $rc = mysqli_query($link, "CREATE TABLE test_bind_fetch(c1 smallint unsigned, + c2 smallint unsigned, + c3 smallint, + c4 smallint, + c5 smallint, + c6 smallint unsigned, + c7 smallint) ENGINE=" . $engine); + if (!$rc) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "INSERT INTO test_bind_fetch VALUES (-23,35999,NULL,-500,-9999999,+30,0)")) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $stmt = mysqli_prepare($link, "SELECT * FROM test_bind_fetch"); + mysqli_stmt_bind_result($stmt, $c1, $c2, $c3, $c4, $c5, $c6, $c7); + mysqli_stmt_execute($stmt); + mysqli_stmt_fetch($stmt); + + $test = array($c1,$c2,$c3,$c4,$c5,$c6,$c7); + + var_dump($test); + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECT-- +array(7) { + [0]=> + int(0) + [1]=> + int(35999) + [2]=> + NULL + [3]=> + int(-500) + [4]=> + int(-32768) + [5]=> + int(30) + [6]=> + int(0) +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/008.phpt b/ext/mysqli/tests/008.phpt new file mode 100644 index 0000000..0ae09df --- /dev/null +++ b/ext/mysqli/tests/008.phpt @@ -0,0 +1,76 @@ +--TEST-- +mysqli fetch tinyint values +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + if (!mysqli_query($link, "SET sql_mode=''")) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $rc = mysqli_query($link, "CREATE TABLE test_bind_fetch(c1 tinyint, + c2 tinyint unsigned, + c3 tinyint not NULL, + c4 tinyint, + c5 tinyint, + c6 tinyint unsigned, + c7 tinyint) ENGINE=" . $engine); + if (!$rc) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "INSERT INTO test_bind_fetch VALUES (-23,300,0,-100,-127,+30,0)")) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $stmt = mysqli_prepare($link, "SELECT * FROM test_bind_fetch"); + mysqli_stmt_bind_result($stmt, $c1, $c2, $c3, $c4, $c5, $c6, $c7); + mysqli_stmt_execute($stmt); + mysqli_stmt_fetch($stmt); + + $test = array($c1,$c2,$c3,$c4,$c5,$c6,$c7); + + var_dump($test); + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECT-- +array(7) { + [0]=> + int(-23) + [1]=> + int(255) + [2]=> + int(0) + [3]=> + int(-100) + [4]=> + int(-127) + [5]=> + int(30) + [6]=> + int(0) +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/009.phpt b/ext/mysqli/tests/009.phpt new file mode 100644 index 0000000..30d42c3 --- /dev/null +++ b/ext/mysqli/tests/009.phpt @@ -0,0 +1,116 @@ +--TEST-- +mysqli fetch bigint values (ok to fail with 4.1.x) +--SKIPIF-- +<?php + if (PHP_INT_SIZE == 8) { + echo 'skip test valid only for 32bit systems'; + exit; + } + require_once('skipif.inc'); + require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + if (!mysqli_query($link, "SET sql_mode=''")) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $rc = mysqli_query($link,"CREATE TABLE test_bind_fetch(c1 bigint default 5, + c2 bigint, + c3 bigint not NULL, + c4 bigint unsigned, + c5 bigint unsigned, + c6 bigint unsigned, + c7 bigint unsigned, + c8 bigint unsigned) ENGINE=" . $engine); + if (!$rc) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $rc = mysqli_query($link, "INSERT INTO test_bind_fetch (c2,c3,c4,c5,c6,c7,c8) ". + "VALUES (-23,4.0,33333333333333,0,-333333333333,99.9,1234)"); + if (!$rc) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $stmt = mysqli_prepare($link, "SELECT * FROM test_bind_fetch"); + mysqli_stmt_bind_result($stmt, $c1, $c2, $c3, $c4, $c5, $c6, $c7, $c8); + mysqli_stmt_execute($stmt); + $rc = mysqli_stmt_fetch($stmt); + + if (mysqli_get_server_version($link) < 50000) { + // 4.1 is faulty and will return big number for $c6 + if ($c6 == "18446743740376218283") { + $c6 = 0; + } + } + $c8 = 4567;// change this to test how mysqli/mysqlnd handles is_ref changing + $test = array($c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8); + + var_dump($test); + + mysqli_stmt_close($stmt); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch_uint")) + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $rc = mysqli_query($link, "CREATE TABLE test_bind_fetch_uint(c1 integer unsigned, c2 integer unsigned) ENGINE=" . $engine); + if (!$rc) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "INSERT INTO test_bind_fetch_uint (c1,c2) VALUES (20123456, 3123456789)")) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $stmt = mysqli_prepare($link, "SELECT * FROM test_bind_fetch_uint"); + mysqli_stmt_bind_result($stmt, $c1, $c2); + mysqli_stmt_execute($stmt); + $rc = mysqli_stmt_fetch($stmt); + + echo $c1, "\n", $c2, "\n"; + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch_uint"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch_uint")) + printf("[002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +array(8) { + [0]=> + int(5) + [1]=> + int(-23) + [2]=> + int(4) + [3]=> + %unicode|string%(14) "33333333333333" + [4]=> + int(0) + [5]=> + int(0) + [6]=> + int(100) + [7]=> + int(4567) +} +20123456 +3123456789 +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/010.phpt b/ext/mysqli/tests/010.phpt new file mode 100644 index 0000000..60ff8ea --- /dev/null +++ b/ext/mysqli/tests/010.phpt @@ -0,0 +1,79 @@ +--TEST-- +mysqli fetch float values +--INI-- +precision=12 +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + if (!mysqli_query($link, "SET sql_mode=''")) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $rc = mysqli_query($link, "CREATE TABLE test_bind_fetch(c1 float(3), + c2 float, + c3 float unsigned, + c4 float, + c5 float, + c6 float, + c7 float(10) unsigned) ENGINE=" . $engine); + if (!$rc) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + + mysqli_query($link, "INSERT INTO test_bind_fetch (c1,c2,c3,c4,c5,c6,c7) VALUES (3.1415926535,-0.000001, -5, 999999999999, + sin(0.6), 1.00000000000001, 888888888888888)"); + + $stmt = mysqli_prepare($link, "SELECT * FROM test_bind_fetch"); + mysqli_stmt_bind_result($stmt, $c1, $c2, $c3, $c4, $c5, $c6, $c7); + mysqli_stmt_execute($stmt); + mysqli_stmt_fetch($stmt); + + $test = array($c1,$c2,$c3,$c4,$c5,$c6,$c7); + + var_dump($test); + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECT-- +array(7) { + [0]=> + float(3.14159274101) + [1]=> + float(-9.99999997475E-7) + [2]=> + float(0) + [3]=> + float(999999995904) + [4]=> + float(0.564642488956) + [5]=> + float(1) + [6]=> + float(8.88888914608E+14) +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/011.phpt b/ext/mysqli/tests/011.phpt new file mode 100644 index 0000000..db03aba --- /dev/null +++ b/ext/mysqli/tests/011.phpt @@ -0,0 +1,78 @@ +--TEST-- +mysqli fetch mixed values +--INI-- +precision=12 +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_result")) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $rc = mysqli_query($link, "CREATE TABLE test_bind_result(c1 tinyint, c2 smallint, + c3 int, c4 bigint, + c5 float, c6 double, + c7 varbinary(10), + c8 varchar(50)) ENGINE=" . $engine); + if (!$rc) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $rc = mysqli_query($link,"INSERT INTO test_bind_result VALUES(19,2999,3999,4999999, + 2345.6,5678.89563, + 'foobar','mysql rulez')"); + if (!$rc) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $stmt = mysqli_prepare($link, "SELECT * FROM test_bind_result"); + mysqli_stmt_bind_result($stmt, $c1, $c2, $c3, $c4, $c5, $c6, $c7, $c8); + mysqli_stmt_execute($stmt); + mysqli_stmt_fetch($stmt); + + $test = array($c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8); + + var_dump($test); + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_result"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_result")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +array(8) { + [0]=> + int(19) + [1]=> + int(2999) + [2]=> + int(3999) + [3]=> + int(4999999) + [4]=> + float(2345.60009766) + [5]=> + float(5678.89563) + [6]=> + string(6) "foobar" + [7]=> + %unicode|string%(11) "mysql rulez" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/012.phpt b/ext/mysqli/tests/012.phpt new file mode 100644 index 0000000..7cc34b0 --- /dev/null +++ b/ext/mysqli/tests/012.phpt @@ -0,0 +1,77 @@ +--TEST-- +mysqli fetch mixed values 2 +--INI-- +precision=12 +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_result")) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $rc = mysqli_query($link, "CREATE TABLE test_bind_result(c1 tinyint, c2 smallint, + c3 int, c4 bigint, + c5 float, c6 double, + c7 varbinary(10), + c8 varchar(10)) ENGINE=" . $engine); + if (!$rc) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "INSERT INTO test_bind_result VALUES(120,2999,3999,54, + 2.6,58.89, + '206','6.7')")) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $stmt = mysqli_prepare($link, "SELECT * FROM test_bind_result"); + mysqli_stmt_bind_result($stmt, $c1, $c2, $c3, $c4, $c5, $c6, $c7, $c8); + mysqli_stmt_execute($stmt); + mysqli_stmt_fetch($stmt); + + $test = array($c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8); + + var_dump($test); + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_result"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_result")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +array(8) { + [0]=> + int(120) + [1]=> + int(2999) + [2]=> + int(3999) + [3]=> + int(54) + [4]=> + float(2.59999990463) + [5]=> + float(58.89) + [6]=> + string(3) "206" + [7]=> + %unicode|string%(3) "6.7" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/013.phpt b/ext/mysqli/tests/013.phpt new file mode 100644 index 0000000..6d75bde --- /dev/null +++ b/ext/mysqli/tests/013.phpt @@ -0,0 +1,72 @@ +--TEST-- +mysqli fetch mixed / mysql_query (may fail when using 4.1 library with 5.x server) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_result")) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $rc = mysqli_query($link, "CREATE TABLE test_bind_result(c1 tinyint, c2 smallint, + c3 int, c4 bigint, + c5 decimal(4,2), c6 double, + c7 varbinary(10), + c8 varchar(10)) ENGINE=" . $engine); + if (!$rc) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "INSERT INTO test_bind_result VALUES(120,2999,3999,54, + 2.6,58.89, + '206','6.7')")) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $stmt = mysqli_prepare($link, "SELECT * FROM test_bind_result"); + + $c = array(0,0,0,0,0,0,0,0); + $b_res= mysqli_stmt_bind_result($stmt, $c[0], $c[1], $c[2], $c[3], $c[4], $c[5], $c[6], $c[7]); + mysqli_stmt_execute($stmt); + mysqli_stmt_fetch($stmt); + mysqli_stmt_fetch($stmt); + mysqli_stmt_close($stmt); + + $result = mysqli_query($link, "select * from test_bind_result"); + $d = mysqli_fetch_row($result); + mysqli_free_result($result); + + $test = ""; + for ($i=0; $i < count($c); $i++) + $test .= ($c[$i] == $d[$i]) ? "1" : "0"; + if ($test == "11111111") + echo "ok\n"; + else if ($b_res == FALSE && mysqli_get_client_version() > 40100 && mysqli_get_client_version() < 50000 && + mysqli_get_server_version($link) > 50000) + echo "error (4.1 library with 5.x server)"; + else + echo "error"; + + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_result"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_result")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +ok +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/014.phpt b/ext/mysqli/tests/014.phpt new file mode 100644 index 0000000..da6a005 --- /dev/null +++ b/ext/mysqli/tests/014.phpt @@ -0,0 +1,97 @@ +--TEST-- +mysqli autocommit/commit/rollback +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifconnectfailure.inc'); + require_once("connect.inc"); + + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + if (!$link) + die(sprintf("Cannot connect, [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); + + if (!have_innodb($link)) + die(sprintf("Needs InnoDB support, [%d] %s", $link->errno, $link->error)); +?> +--FILE-- +<?php + require_once("connect.inc"); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + if (!mysqli_autocommit($link, TRUE)) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "CREATE TABLE test(a int, b varchar(10)) engine=InnoDB")) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "INSERT INTO test VALUES (1, 'foobar')")) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_autocommit($link, FALSE)) + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "DELETE FROM test")) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "INSERT INTO test VALUES (2, 'egon')")) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_rollback($link)) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$result = mysqli_query($link, "SELECT * FROM test")) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + printf("Num_of_rows=%d\n", mysqli_num_rows($result)); + if (!$row = mysqli_fetch_row($result)) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($result); + + var_dump($row); + + if (!mysqli_query($link, "DELETE FROM test")) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "INSERT INTO test VALUES (2, 'egon')")) + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_commit($link)) + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$result = mysqli_query($link, "SELECT * FROM test")) + printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_row($result)) + printf("[014] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($result); + + var_dump($row); + + mysqli_query($link, "DROP TABLE IF EXISTS test"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Num_of_rows=1 +array(2) { + [0]=> + %unicode|string%(1) "1" + [1]=> + %unicode|string%(6) "foobar" +} +array(2) { + [0]=> + %unicode|string%(1) "2" + [1]=> + %unicode|string%(4) "egon" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/015.phpt b/ext/mysqli/tests/015.phpt new file mode 100644 index 0000000..c671ad6 --- /dev/null +++ b/ext/mysqli/tests/015.phpt @@ -0,0 +1,94 @@ +--TEST-- +mysqli autocommit/commit/rollback with innodb +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifconnectfailure.inc'); + + require_once('connect.inc'); + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die(sprintf("Cannot connect, [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); + + if (!have_innodb($link)) + die(sprintf("Needs InnoDB support, [%d] %s", $link->errno, $link->error)); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + if (!$link) + printf("[001] Cannot connect, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (!mysqli_select_db($link, $db)) + printf("[002] Cannot select DB '%s', [%d] %s\n", $db, + mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_autocommit($link, TRUE)) + printf("[003] Cannot turn on autocommit mode, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link,"DROP TABLE IF EXISTS test") || + !mysqli_query($link,"CREATE TABLE test(a int, b varchar(10)) Engine=InnoDB") || + !mysqli_query($link, "INSERT INTO test VALUES (1, 'foobar')")) + printf("[004] Cannot create test data, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_autocommit($link, FALSE)) + printf("[005] Cannot turn off autocommit mode, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "DELETE FROM test") || + !mysqli_query($link, "INSERT INTO test VALUES (2, 'egon')")) + printf("[006] Cannot modify test data, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_rollback($link)) + printf("[007] Cannot call rollback, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + $result = mysqli_query($link, "SELECT SQL_NO_CACHE * FROM test"); + if (!$result) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $row = mysqli_fetch_row($result); + mysqli_free_result($result); + + var_dump($row); + + if (!mysqli_query($link, "DELETE FROM test") || + !mysqli_query($link, "INSERT INTO test VALUES (2, 'egon')")) + printf("[009] Cannot modify test data, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + mysqli_commit($link); + + $result = mysqli_query($link, "SELECT * FROM test"); + if (!$result) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $row = mysqli_fetch_row($result); + mysqli_free_result($result); + + var_dump($row); + + mysqli_query($link, "DROP TABLE IF EXISTS test"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +array(2) { + [0]=> + %unicode|string%(1) "1" + [1]=> + %unicode|string%(6) "foobar" +} +array(2) { + [0]=> + %unicode|string%(1) "2" + [1]=> + %unicode|string%(4) "egon" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/016.phpt b/ext/mysqli/tests/016.phpt new file mode 100644 index 0000000..8e1ffe6 --- /dev/null +++ b/ext/mysqli/tests/016.phpt @@ -0,0 +1,33 @@ +--TEST-- +mysqli fetch user variable +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + if (!mysqli_query($link, "SET @dummy='foobar'")) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$stmt = mysqli_prepare($link, "SELECT @dummy")) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_stmt_bind_result($stmt, $dummy); + mysqli_stmt_execute($stmt); + mysqli_stmt_fetch($stmt); + + var_dump($dummy); + + mysqli_stmt_close($stmt); + mysqli_close($link); + print "done!"; +?> +--EXPECTF-- +%unicode|string%(6) "foobar" +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/017.phpt b/ext/mysqli/tests/017.phpt new file mode 100644 index 0000000..082202f --- /dev/null +++ b/ext/mysqli/tests/017.phpt @@ -0,0 +1,43 @@ +--TEST-- +mysqli fetch functions +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + if (!$stmt = mysqli_prepare($link, "SELECT md5('bar'), database(), 'foo'")) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_stmt_bind_result($stmt, $c0, $c1, $c2); + mysqli_stmt_execute($stmt); + + mysqli_stmt_fetch($stmt); + mysqli_stmt_close($stmt); + + $test = array($c0, $c1, $c2); + if ($c1 !== $db) { + echo "Different data\n"; + } + + var_dump($test); + mysqli_close($link); + print "done!"; +?> +--EXPECTF-- +array(3) { + [0]=> + string(32) "37b51d194a7513e45b56f6524f2d51f2" + [1]=> + %unicode|string%(%d) "%s" + [2]=> + %unicode|string%(3) "foo" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/018.phpt b/ext/mysqli/tests/018.phpt new file mode 100644 index 0000000..d5466e2 --- /dev/null +++ b/ext/mysqli/tests/018.phpt @@ -0,0 +1,33 @@ +--TEST-- +mysqli fetch system variables +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + if (!mysqli_query($link, "SET AUTOCOMMIT=0")) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$stmt = mysqli_prepare($link, "SELECT @@autocommit")) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_stmt_bind_result($stmt, $c0); + mysqli_stmt_execute($stmt); + + mysqli_stmt_fetch($stmt); + + var_dump($c0); + + mysqli_close($link); + print "done!"; +?> +--EXPECT-- +int(0) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/019.phpt b/ext/mysqli/tests/019.phpt new file mode 100644 index 0000000..5e6aac0 --- /dev/null +++ b/ext/mysqli/tests/019.phpt @@ -0,0 +1,94 @@ +--TEST-- +mysqli fetch (bind_param + bind_result) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS insert_read")) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $rc = mysqli_query($link,"CREATE TABLE insert_read(col1 tinyint, col2 smallint, + col3 int, col4 bigint, + col5 float, col6 double, + col7 date, col8 time, + col9 varbinary(10), + col10 varchar(50), + col11 char(20)) ENGINE=" . $engine); + if (!$rc) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$stmt = mysqli_prepare($link, "INSERT INTO insert_read(col1,col10, col11, col6) VALUES (?,?,?,?)")) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_stmt_bind_param($stmt, "issd", $c1, $c2, $c3, $c4); + + $c1 = 1; + $c2 = "foo"; + $c3 = "foobar"; + $c4 = 3.14; + + mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + + if (!$stmt = mysqli_prepare($link, "SELECT col1, col2, col3, col4, col5, col6, col7, col8, col9, col10, col11 FROM insert_read")) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_stmt_bind_result($stmt, $c1, $c2, $c3, $c4, $c5, $c6, $c7, $c8, $c9, $c10, $c11); + mysqli_stmt_execute($stmt); + + mysqli_stmt_fetch($stmt); + + $test = array($c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$c10,$c11); + + var_dump($test); + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS insert_read"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS insert_read")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +array(11) { + [0]=> + int(1) + [1]=> + NULL + [2]=> + NULL + [3]=> + NULL + [4]=> + NULL + [5]=> + float(3.14) + [6]=> + NULL + [7]=> + NULL + [8]=> + NULL + [9]=> + %unicode|string%(3) "foo" + [10]=> + %unicode|string%(6) "foobar" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/020.phpt b/ext/mysqli/tests/020.phpt new file mode 100644 index 0000000..6512cd8 --- /dev/null +++ b/ext/mysqli/tests/020.phpt @@ -0,0 +1,98 @@ +--TEST-- +mysqli bind_param/bind_result date +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + mysqli_query($link, "SET sql_mode=''"); + + mysqli_query($link,"DROP TABLE IF EXISTS test_bind_result"); + + $rc = @mysqli_query($link,"CREATE TABLE test_bind_result( + c1 date, + c2 time, + c3 timestamp(14), + c4 year, + c5 datetime, + c6 timestamp(4), + c7 timestamp(6))"); + + if (!$rc) + $rc = mysqli_query($link,"CREATE TABLE test_bind_result( + c1 date, + c2 time, + c3 timestamp, + c4 year, + c5 datetime, + c6 timestamp, + c7 timestamp)"); + + $stmt = mysqli_prepare($link, "INSERT INTO test_bind_result VALUES (?,?,?,?,?,?,?)"); + mysqli_stmt_bind_param($stmt, "sssssss", $d1, $d2, $d3, $d4, $d5, $d6, $d7); + + $d1 = "2002-01-02"; + $d2 = "12:49:00"; + $d3 = "2002-01-02 17:46:59"; + $d4 = "2010"; + $d5 = "2010-07-10"; + $d6 = "2020"; + $d7 = "1999-12-29"; + + mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + + $stmt = mysqli_prepare($link, "SELECT c1, c2, c3, c4, c5, c6, c7 FROM test_bind_result"); + + mysqli_stmt_bind_result($stmt,$c1, $c2, $c3, $c4, $c5, $c6, $c7); + + mysqli_stmt_execute($stmt); + mysqli_stmt_fetch($stmt); + + $test = array($c1,$c2,$c3,$c4,$c5,$c6,$c7); + + var_dump($test); + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_result"); + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_result")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +array(7) { + [0]=> + %s(10) "2002-01-02" + [1]=> + %s(8) "12:49:00" + [2]=> + %s(19) "2002-01-02 17:46:59" + [3]=> + int(2010) + [4]=> + %s(19) "2010-07-10 00:00:00" + [5]=> + %s(19) "0000-00-00 00:00:00" + [6]=> + %s(19) "1999-12-29 00:00:00" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/021.phpt b/ext/mysqli/tests/021.phpt new file mode 100644 index 0000000..5ff58c0 --- /dev/null +++ b/ext/mysqli/tests/021.phpt @@ -0,0 +1,59 @@ +--TEST-- +mysqli bind_param+bind_result char/text +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + + mysqli_query($link,"DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_query($link,"CREATE TABLE test_bind_fetch(c1 char(10), c2 text)"); + + $stmt = mysqli_prepare($link, "INSERT INTO test_bind_fetch VALUES (?,?)"); + mysqli_stmt_bind_param($stmt, "ss", $q1, $q2); + $q1 = "1234567890"; + $q2 = "this is a test"; + mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + + $stmt = mysqli_prepare($link, "SELECT * FROM test_bind_fetch"); + mysqli_stmt_bind_result($stmt, $c1, $c2); + mysqli_stmt_execute($stmt); + mysqli_stmt_fetch($stmt); + + $test = array($c1,$c2); + + var_dump($test); + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +array(2) { + [0]=> + %unicode|string%(10) "1234567890" + [1]=> + %unicode|string%(14) "this is a test" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/022.phpt b/ext/mysqli/tests/022.phpt new file mode 100644 index 0000000..9cb71c0 --- /dev/null +++ b/ext/mysqli/tests/022.phpt @@ -0,0 +1,64 @@ +--TEST-- +mysqli bind_param/bind_result char/text long +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + + mysqli_query($link,"DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_query($link,"CREATE TABLE test_bind_fetch(c1 char(10), c2 text)"); + + + $stmt = mysqli_prepare($link, "INSERT INTO test_bind_fetch VALUES (?,?)"); + mysqli_stmt_bind_param($stmt, "ss", $a1, $a2); + + $a1 = "1234567890"; + $a2 = str_repeat("A1", 32000); + + mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + + $stmt = mysqli_prepare($link, "SELECT * FROM test_bind_fetch"); + mysqli_stmt_bind_result($stmt, $c1, $c2); + mysqli_stmt_execute($stmt); + mysqli_stmt_fetch($stmt); + + $test[] = $c1; + $test[] = ($a2 == $c2) ? "32K String ok" : "32K String failed"; + + var_dump($test); + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +array(2) { + [0]=> + %unicode|string%(10) "1234567890" + [1]=> + %s(13) "32K String ok" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/023.phpt b/ext/mysqli/tests/023.phpt new file mode 100644 index 0000000..2528519 --- /dev/null +++ b/ext/mysqli/tests/023.phpt @@ -0,0 +1,83 @@ +--TEST-- +mysqli bind_param/bind_prepare fetch long values +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + mysqli_query($link, "SET sql_mode=''"); + + mysqli_query($link,"DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_query($link,"CREATE TABLE test_bind_fetch(c1 int unsigned, + c2 int unsigned, + c3 int, + c4 int, + c5 int, + c6 int unsigned, + c7 int)"); + + $stmt = mysqli_prepare($link, "INSERT INTO test_bind_fetch VALUES (?,?,?,?,?,?,?)"); + mysqli_stmt_bind_param($stmt, "iiiiiii", $c1,$c2,$c3,$c4,$c5,$c6,$c7); + $c1 = -23; + $c2 = 35999; + $c3 = NULL; + $c4 = -500; + $c5 = -9999999; + $c6 = -0; + $c7 = 0; + + mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + + $stmt = mysqli_prepare($link, "SELECT * FROM test_bind_fetch"); + mysqli_stmt_bind_result($stmt, $c1, $c2, $c3, $c4, $c5, $c6, $c7); + mysqli_stmt_execute($stmt); + mysqli_stmt_fetch($stmt); + + $test = array($c1,$c2,$c3,$c4,$c5,$c6,$c7); + + var_dump($test); + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECT-- +array(7) { + [0]=> + int(0) + [1]=> + int(35999) + [2]=> + NULL + [3]=> + int(-500) + [4]=> + int(-9999999) + [5]=> + int(0) + [6]=> + int(0) +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/024.phpt b/ext/mysqli/tests/024.phpt new file mode 100644 index 0000000..893ca0d --- /dev/null +++ b/ext/mysqli/tests/024.phpt @@ -0,0 +1,83 @@ +--TEST-- +mysqli bind_param/bind_result short values +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + mysqli_query($link, "SET sql_mode=''"); + + mysqli_query($link,"DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_query($link,"CREATE TABLE test_bind_fetch(c1 smallint unsigned, + c2 smallint unsigned, + c3 smallint, + c4 smallint, + c5 smallint, + c6 smallint unsigned, + c7 smallint)"); + + $stmt = mysqli_prepare($link, "INSERT INTO test_bind_fetch VALUES (?,?,?,?,?,?,?)"); + mysqli_stmt_bind_param($stmt, "iiiiiii", $c1,$c2,$c3,$c4,$c5,$c6,$c7); + + $c1 = -23; + $c2 = 35999; + $c3 = NULL; + $c4 = -500; + $c5 = -9999999; + $c6 = -0; + $c7 = 0; + + mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + + $stmt = mysqli_prepare($link, "SELECT * FROM test_bind_fetch"); + mysqli_stmt_bind_result($stmt, $c1, $c2, $c3, $c4, $c5, $c6, $c7); + mysqli_stmt_execute($stmt); + mysqli_stmt_fetch($stmt); + + $test = array($c1,$c2,$c3,$c4,$c5,$c6,$c7); + + var_dump($test); + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECT-- +array(7) { + [0]=> + int(0) + [1]=> + int(35999) + [2]=> + NULL + [3]=> + int(-500) + [4]=> + int(-32768) + [5]=> + int(0) + [6]=> + int(0) +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/025.phpt b/ext/mysqli/tests/025.phpt new file mode 100644 index 0000000..937d624 --- /dev/null +++ b/ext/mysqli/tests/025.phpt @@ -0,0 +1,88 @@ +--TEST-- +mysqli bind_param/bind_result tinyint values +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + mysqli_query($link, "SET sql_mode=''"); + + mysqli_query($link,"DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_query($link,"CREATE TABLE test_bind_fetch(c1 tinyint, + c2 tinyint unsigned, + c3 tinyint not NULL, + c4 tinyint, + c5 tinyint, + c6 tinyint unsigned, + c7 tinyint)"); + + $stmt = mysqli_prepare ($link, "INSERT INTO test_bind_fetch VALUES(?,?,?,?,?,?,?)"); + mysqli_stmt_bind_param($stmt, "iiiiiii", $c1,$c2,$c3,$c4,$c5,$c6,$c7); + + $c1 = -23; + $c2 = 300; + $c3 = 0; + $c4 = -100; + $c5 = -127; + $c6 = 30; + $c7 = 0; + + mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + + mysqli_query($link, "INSERT INTO test_bind_fetch VALUES (-23,300,0,-100,-127,+30,0)"); + + $c1 = $c2 = $c3 = $c4 = $c5 = $c6 = $c7 = NULL; + + $stmt = mysqli_prepare($link, "SELECT * FROM test_bind_fetch"); + mysqli_stmt_bind_result($stmt, $c1, $c2, $c3, $c4, $c5, $c6, $c7); + mysqli_stmt_execute($stmt); + mysqli_stmt_fetch($stmt); + + $test = array($c1,$c2,$c3,$c4,$c5,$c6,$c7); + + var_dump($test); + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECT-- +array(7) { + [0]=> + int(-23) + [1]=> + int(255) + [2]=> + int(0) + [3]=> + int(-100) + [4]=> + int(-127) + [5]=> + int(30) + [6]=> + int(0) +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/026.phpt b/ext/mysqli/tests/026.phpt new file mode 100644 index 0000000..47d763a --- /dev/null +++ b/ext/mysqli/tests/026.phpt @@ -0,0 +1,65 @@ +--TEST-- +mysqli bind_param/bind_result with send_long_data +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + mysqli_query($link, "SET sql_mode=''"); + + mysqli_query($link,"DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_query($link,"CREATE TABLE test_bind_fetch(c1 varchar(10), c2 text)"); + + $stmt = mysqli_prepare ($link, "INSERT INTO test_bind_fetch VALUES (?,?)"); + mysqli_stmt_bind_param($stmt, "sb", $c1, $c2); + + $c1 = "Hello World"; + + mysqli_stmt_send_long_data($stmt, 1, "This is the first sentence."); + mysqli_stmt_send_long_data($stmt, 1, " And this is the second sentence."); + mysqli_stmt_send_long_data($stmt, 1, " And finally this is the last sentence."); + + mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + + $stmt = mysqli_prepare($link, "SELECT * FROM test_bind_fetch"); + mysqli_stmt_bind_result($stmt, $d1, $d2); + mysqli_stmt_execute($stmt); + mysqli_stmt_fetch($stmt); + + $test = array($d1,$d2); + + var_dump($test); + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +array(2) { + [0]=> + %unicode|string%(10) "Hello Worl" + [1]=> + %unicode|string%(99) "This is the first sentence. And this is the second sentence. And finally this is the last sentence." +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/027.phpt b/ext/mysqli/tests/027.phpt new file mode 100644 index 0000000..69233d6 --- /dev/null +++ b/ext/mysqli/tests/027.phpt @@ -0,0 +1,24 @@ +--TEST-- +function test: mysqli_stat +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + $status = mysqli_stat($link); + + var_dump(strlen($status) > 0); + + mysqli_close($link); + print "done!"; +?> +--EXPECT-- +bool(true) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/028.phpt b/ext/mysqli/tests/028.phpt new file mode 100644 index 0000000..af453dd --- /dev/null +++ b/ext/mysqli/tests/028.phpt @@ -0,0 +1,24 @@ +--TEST-- +function test: mysqli_character_set_name +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + $cset = substr(mysqli_character_set_name($link),0,6); + + var_dump($cset); + + mysqli_close($link); + print "done!"; +?> +--EXPECTF-- +%unicode|string%(%d) "%s" +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/029.phpt b/ext/mysqli/tests/029.phpt new file mode 100644 index 0000000..9364206 --- /dev/null +++ b/ext/mysqli/tests/029.phpt @@ -0,0 +1,42 @@ +--TEST-- +function test: mysqli_affected_rows +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + + mysqli_query($link, "DROP TABLE IF EXISTS general_test"); + mysqli_query($link, "CREATE TABLE general_test (a INT)"); + mysqli_query($link, "INSERT INTO general_test VALUES (1),(2),(3)"); + + $afc = mysqli_affected_rows($link); + + var_dump($afc); + + mysqli_query($link, "DROP TABLE IF EXISTS general_test"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS general_test")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECT-- +int(3) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/030.phpt b/ext/mysqli/tests/030.phpt new file mode 100644 index 0000000..c4b1710 --- /dev/null +++ b/ext/mysqli/tests/030.phpt @@ -0,0 +1,30 @@ +--TEST-- +function test: mysqli_errno +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $errno = mysqli_errno($link); + var_dump($errno); + + mysqli_select_db($link, $db); + + mysqli_query($link, "SELECT * FROM non_exisiting_table"); + $errno = mysqli_errno($link); + + var_dump($errno); + + mysqli_close($link); + print "done!"; +?> +--EXPECT-- +int(0) +int(1146) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/031.phpt b/ext/mysqli/tests/031.phpt new file mode 100644 index 0000000..9b8c720 --- /dev/null +++ b/ext/mysqli/tests/031.phpt @@ -0,0 +1,30 @@ +--TEST-- +function test: mysqli_error +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $error = mysqli_error($link); + var_dump($error); + + mysqli_select_db($link, $db); + + mysqli_query($link, "SELECT * FROM non_exisiting_table"); + $error = mysqli_error($link); + + var_dump($error); + + mysqli_close($link); + print "done!"; +?> +--EXPECTF-- +%unicode|string%(0) "" +%unicode|string%(%d) "%s" +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/032.phpt b/ext/mysqli/tests/032.phpt new file mode 100644 index 0000000..5fcd548 --- /dev/null +++ b/ext/mysqli/tests/032.phpt @@ -0,0 +1,42 @@ +--TEST-- +function test: mysqli_info +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + + mysqli_query($link, "DROP TABLE IF EXISTS general_test"); + mysqli_query($link, "CREATE TABLE general_test (a INT)"); + mysqli_query($link, "INSERT INTO general_test VALUES (1),(2),(3)"); + + $afc = mysqli_info($link); + + var_dump($afc); + + mysqli_query($link, "DROP TABLE IF EXISTS general_test"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS general_test")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +%unicode|string%(38) "Records: 3 Duplicates: 0 Warnings: 0" +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/033.phpt b/ext/mysqli/tests/033.phpt new file mode 100644 index 0000000..b499bd7 --- /dev/null +++ b/ext/mysqli/tests/033.phpt @@ -0,0 +1,25 @@ +--TEST-- +function test: mysqli_get_host_info +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + $hinfo = mysqli_get_host_info($link); + + var_dump(str_replace('/','', $hinfo)); + + mysqli_close($link); + print "done!"; +?> +--EXPECTF-- +%unicode|string%(%d) "%s via %s" +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/034.phpt b/ext/mysqli/tests/034.phpt new file mode 100644 index 0000000..3fda560 --- /dev/null +++ b/ext/mysqli/tests/034.phpt @@ -0,0 +1,25 @@ +--TEST-- +function test: mysqli_get_proto_info +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + $pinfo = mysqli_get_proto_info($link); + + var_dump($pinfo); + + mysqli_close($link); + print "done!"; +?> +--EXPECT-- +int(10) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/035.phpt b/ext/mysqli/tests/035.phpt new file mode 100644 index 0000000..7b18e02 --- /dev/null +++ b/ext/mysqli/tests/035.phpt @@ -0,0 +1,24 @@ +--TEST-- +function test: mysqli_get_server_info +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + $sinfo = substr(mysqli_get_server_info($link),0,1); + + var_dump(strlen($sinfo)); + + mysqli_close($link); + print "done!"; +?> +--EXPECT-- +int(1) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/036.phpt b/ext/mysqli/tests/036.phpt new file mode 100644 index 0000000..b0d259c --- /dev/null +++ b/ext/mysqli/tests/036.phpt @@ -0,0 +1,63 @@ +--TEST-- +function test: mysqli_insert_id() +--SKIPIF-- +<?php + if (PHP_INT_SIZE == 8) { + echo 'skip test valid only for 32bit systems'; + exit; + } + require_once('skipif.inc'); + require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + + mysqli_query($link, "DROP TABLE IF EXISTS t036"); + mysqli_query($link, "CREATE TABLE t036 (a bigint not null auto_increment primary key, b varchar(10)) ENGINE = " . $engine); + + mysqli_query($link, "INSERT INTO t036 (b) VALUES ('foo1')"); + $test[] = mysqli_insert_id($link); + + /* we have to insert more values, cause lexer sets auto_increment to max_int + see mysql bug #54. So we don't check for the value, only for type (which must + be type string) + */ + + mysqli_query($link, "ALTER TABLE t036 AUTO_INCREMENT=9999999999999998"); + mysqli_query($link, "INSERT INTO t036 (b) VALUES ('foo2')"); + mysqli_query($link, "INSERT INTO t036 (b) VALUES ('foo3')"); + mysqli_query($link, "INSERT INTO t036 (b) VALUES ('foo4')"); + $x = mysqli_insert_id($link); + $test[] = is_string($x); + + var_dump($test); + + mysqli_query($link, "DROP TABLE IF EXISTS t036"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS t036")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECT-- +array(2) { + [0]=> + int(1) + [1]=> + bool(true) +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/037.phpt b/ext/mysqli/tests/037.phpt new file mode 100644 index 0000000..03d5d55 --- /dev/null +++ b/ext/mysqli/tests/037.phpt @@ -0,0 +1,53 @@ +--TEST-- +function test: mysqli_field_count() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + + mysqli_query($link, "DROP TABLE IF EXISTS test_result"); + + mysqli_query($link, "CREATE TABLE test_result (a int, b varchar(10)) ENGINE = " . $engine); + + mysqli_query($link, "INSERT INTO test_result VALUES (1, 'foo')"); + $ir[] = mysqli_field_count($link); + + mysqli_real_query($link, "SELECT * FROM test_result"); + $ir[] = mysqli_field_count($link); + + + var_dump($ir); + + mysqli_query($link, "DROP TABLE IF EXISTS test_result"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_result")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECT-- +array(2) { + [0]=> + int(0) + [1]=> + int(2) +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/038.phpt b/ext/mysqli/tests/038.phpt new file mode 100644 index 0000000..45b724c --- /dev/null +++ b/ext/mysqli/tests/038.phpt @@ -0,0 +1,47 @@ +--TEST-- +function test: mysqli_num_fields() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + + mysqli_query($link, "DROP TABLE IF EXISTS test_result"); + + mysqli_query($link, "CREATE TABLE test_result (a int, b varchar(10)) ENGINE = " . $engine); + + mysqli_query($link, "INSERT INTO test_result VALUES (1, 'foo')"); + + mysqli_real_query($link, "SELECT * FROM test_result"); + if (mysqli_field_count($link)) { + $result = mysqli_store_result($link); + $num = mysqli_num_fields($result); + mysqli_free_result($result); + } + + var_dump($num); + + mysqli_query($link, "DROP TABLE IF EXISTS test_result"); + mysqli_close($link); +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_result")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECT-- +int(2) diff --git a/ext/mysqli/tests/039.phpt b/ext/mysqli/tests/039.phpt new file mode 100644 index 0000000..ae881e1 --- /dev/null +++ b/ext/mysqli/tests/039.phpt @@ -0,0 +1,30 @@ +--TEST-- +function test: mysqli_num_fields() 2 +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_real_query($link, "SHOW VARIABLES"); + + if (mysqli_field_count($link)) { + $result = mysqli_store_result($link); + $num = mysqli_num_fields($result); + mysqli_free_result($result); + } + + var_dump($num); + + mysqli_close($link); + print "done!"; +?> +--EXPECT-- +int(2) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/040.phpt b/ext/mysqli/tests/040.phpt new file mode 100644 index 0000000..3e28883 --- /dev/null +++ b/ext/mysqli/tests/040.phpt @@ -0,0 +1,47 @@ +--TEST-- +function test: mysqli_num_rows() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + + mysqli_query($link, "DROP TABLE IF EXISTS test_result"); + mysqli_query($link, "CREATE TABLE test_result (a int, b varchar(10)) ENGINE=" . $engine); + mysqli_query($link, "INSERT INTO test_result VALUES (1, 'foo')"); + + mysqli_real_query($link, "SELECT * FROM test_result"); + if (mysqli_field_count($link)) { + $result = mysqli_store_result($link); + $num = mysqli_num_rows($result); + mysqli_free_result($result); + } + + var_dump($num); + + mysqli_query($link, "DROP TABLE IF EXISTS test_result"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_result")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECT-- +int(1) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/041.phpt b/ext/mysqli/tests/041.phpt new file mode 100644 index 0000000..ec67e47 --- /dev/null +++ b/ext/mysqli/tests/041.phpt @@ -0,0 +1,38 @@ +--TEST-- +function test: mysqli_warning_count() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + mysqli_select_db($link, $db); + + mysqli_query($link, "DROP TABLE IF EXISTS test_warnings"); + mysqli_query($link, "DROP TABLE IF EXISTS test_warnings"); + + var_dump(mysqli_warning_count($link)); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_warnings")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECT-- +int(1) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/042.phpt b/ext/mysqli/tests/042.phpt new file mode 100644 index 0000000..31f38f7 --- /dev/null +++ b/ext/mysqli/tests/042.phpt @@ -0,0 +1,79 @@ +--TEST-- +mysqli_fetch_object +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + mysqli_query($link, "SET sql_mode=''"); + + mysqli_query($link,"DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_query($link,"CREATE TABLE test_bind_fetch(c1 smallint unsigned, + c2 smallint unsigned, + c3 smallint, + c4 smallint, + c5 smallint, + c6 smallint unsigned, + c7 smallint) ENGINE=" . $engine); + + $stmt = mysqli_prepare($link, "INSERT INTO test_bind_fetch VALUES (?,?,?,?,?,?,?)"); + mysqli_stmt_bind_param($stmt, "iiiiiii", $c1,$c2,$c3,$c4,$c5,$c6,$c7); + + $c1 = -23; + $c2 = 35999; + $c3 = NULL; + $c4 = -500; + $c5 = -9999999; + $c6 = -0; + $c7 = 0; + + mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + + $result = mysqli_query($link, "SELECT * FROM test_bind_fetch"); + $test = mysqli_fetch_object($result); + mysqli_free_result($result); + + var_dump($test); + + mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch"); + mysqli_close($link); + print "done!" +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +object(stdClass)#%d (7) { + [%u|b%"c1"]=> + %unicode|string%(1) "0" + [%u|b%"c2"]=> + %unicode|string%(5) "35999" + [%u|b%"c3"]=> + NULL + [%u|b%"c4"]=> + %unicode|string%(4) "-500" + [%u|b%"c5"]=> + %unicode|string%(6) "-32768" + [%u|b%"c6"]=> + %unicode|string%(1) "0" + [%u|b%"c7"]=> + %unicode|string%(1) "0" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/043.phpt b/ext/mysqli/tests/043.phpt new file mode 100644 index 0000000..c3a9901 --- /dev/null +++ b/ext/mysqli/tests/043.phpt @@ -0,0 +1,59 @@ +--TEST-- +mysqli_stmt_bind_param (UPDATE) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + + mysqli_query($link,"DROP TABLE IF EXISTS test_update"); + mysqli_query($link,"CREATE TABLE test_update(a varchar(10), + b int) ENGINE=" . $engine); + + mysqli_query($link, "INSERT INTO test_update VALUES ('foo', 2)"); + + $stmt = mysqli_prepare($link, "UPDATE test_update SET a=?,b=? WHERE b=?"); + mysqli_stmt_bind_param($stmt, "sii", $c1, $c2, $c3); + + $c1 = "Rasmus"; + $c2 = 1; + $c3 = 2; + + mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + + $result = mysqli_query($link, "SELECT concat(a, ' is No. ', b) FROM test_update"); + $test = mysqli_fetch_row($result); + mysqli_free_result($result); + + var_dump($test); + + mysqli_query($link, "DROP TABLE IF EXISTS test_update"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_update")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +array(1) { + [0]=> + string(15) "Rasmus is No. 1" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/044.phpt b/ext/mysqli/tests/044.phpt new file mode 100644 index 0000000..3ddae3e --- /dev/null +++ b/ext/mysqli/tests/044.phpt @@ -0,0 +1,26 @@ +--TEST-- +mysqli_get_server_version +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + $i = mysqli_get_server_version($link); + + $test = $i / $i; + + var_dump($test); + + mysqli_close($link); + print "done!"; +?> +--EXPECT-- +int(1) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/045.phpt b/ext/mysqli/tests/045.phpt new file mode 100644 index 0000000..d11c166 --- /dev/null +++ b/ext/mysqli/tests/045.phpt @@ -0,0 +1,53 @@ +--TEST-- +mysqli_stmt_bind_result (SHOW) +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifemb.inc'); + require_once('skipifconnectfailure.inc'); + + require_once("connect.inc"); + $link = my_mysqli_connect($host, $user, $passwd); + + $stmt = mysqli_prepare($link, "SHOW VARIABLES LIKE 'port'"); + mysqli_stmt_execute($stmt); + + if (!$stmt->field_count) { + printf("skip SHOW command is not supported in prepared statements."); + } + $stmt->close(); + mysqli_close($link); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + $stmt = mysqli_prepare($link, "SHOW VARIABLES LIKE 'port'"); + mysqli_stmt_execute($stmt); + + mysqli_stmt_bind_result($stmt, $c1, $c2); + mysqli_stmt_fetch($stmt); + mysqli_stmt_close($stmt); + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && mysqli_get_server_version($link) < 50000) { + /* variables are binary */ + settype($c1, "unicode"); + settype($c2, "unicode"); + } + $test = array ($c1,$c2); + + var_dump($test); + + mysqli_close($link); + print "done!"; +?> +--EXPECTF-- +array(2) { + [0]=> + %unicode|string%(4) "port" + [1]=> + %unicode|string%(%d) "%s" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/046.phpt b/ext/mysqli/tests/046.phpt new file mode 100644 index 0000000..1abc5e7 --- /dev/null +++ b/ext/mysqli/tests/046.phpt @@ -0,0 +1,50 @@ +--TEST-- +mysqli_stmt_affected_rows (delete) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + + mysqli_query($link, "DROP TABLE IF EXISTS test_affected"); + mysqli_query($link, "CREATE TABLE test_affected (foo int) ENGINE=" . $engine); + + mysqli_query($link, "INSERT INTO test_affected VALUES (1),(2),(3),(4),(5)"); + + $stmt = mysqli_prepare($link, "DELETE FROM test_affected WHERE foo=?"); + mysqli_stmt_bind_param($stmt, "i", $c1); + + $c1 = 2; + + mysqli_stmt_execute($stmt); + $x = mysqli_stmt_affected_rows($stmt); + + mysqli_stmt_close($stmt); + var_dump($x==1); + + mysqli_query($link, "DROP TABLE IF EXISTS test_affected"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_affected")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECT-- +bool(true) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/047.phpt b/ext/mysqli/tests/047.phpt new file mode 100644 index 0000000..178a1ae --- /dev/null +++ b/ext/mysqli/tests/047.phpt @@ -0,0 +1,237 @@ +--TEST-- +mysqli_stmt_result_metadata +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + + mysqli_query($link, "DROP TABLE IF EXISTS test_affected"); + mysqli_query($link, "CREATE TABLE test_affected (foo int, bar varchar(10) character set latin1) ENGINE=" . $engine); + + mysqli_query($link, "INSERT INTO test_affected VALUES (1, 'Zak'),(2, 'Greant')"); + + $stmt = mysqli_prepare($link, "SELECT * FROM test_affected"); + mysqli_stmt_execute($stmt); + $result = mysqli_stmt_result_metadata($stmt); + + echo "\n=== fetch_fields ===\n"; + var_dump(mysqli_fetch_fields($result)); + + echo "\n=== fetch_field_direct ===\n"; + var_dump(mysqli_fetch_field_direct($result, 0)); + var_dump(mysqli_fetch_field_direct($result, 1)); + + echo "\n=== fetch_field ===\n"; + while ($field = mysqli_fetch_field($result)) { + var_dump($field); + } + + print_r(mysqli_fetch_lengths($result)); + + mysqli_free_result($result); + + + mysqli_stmt_close($stmt); + mysqli_query($link, "DROP TABLE IF EXISTS test_affected"); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_affected")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +=== fetch_fields === +array(2) { + [0]=> + object(stdClass)#5 (13) { + [%u|b%"name"]=> + %unicode|string%(3) "foo" + [%u|b%"orgname"]=> + %unicode|string%(3) "foo" + [%u|b%"table"]=> + %unicode|string%(13) "test_affected" + [%u|b%"orgtable"]=> + %unicode|string%(13) "test_affected" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(0) + [%u|b%"length"]=> + int(%d) + [%u|b%"charsetnr"]=> + int(%d) + [%u|b%"flags"]=> + int(32768) + [%u|b%"type"]=> + int(3) + [%u|b%"decimals"]=> + int(0) + } + [1]=> + object(stdClass)#6 (13) { + [%u|b%"name"]=> + %unicode|string%(3) "bar" + [%u|b%"orgname"]=> + %unicode|string%(3) "bar" + [%u|b%"table"]=> + %unicode|string%(13) "test_affected" + [%u|b%"orgtable"]=> + %unicode|string%(13) "test_affected" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(0) + [%u|b%"length"]=> + int(%d) + [%u|b%"charsetnr"]=> + int(%d) + [%u|b%"flags"]=> + int(0) + [%u|b%"type"]=> + int(253) + [%u|b%"decimals"]=> + int(0) + } +} + +=== fetch_field_direct === +object(stdClass)#6 (13) { + [%u|b%"name"]=> + %unicode|string%(3) "foo" + [%u|b%"orgname"]=> + %unicode|string%(3) "foo" + [%u|b%"table"]=> + %unicode|string%(13) "test_affected" + [%u|b%"orgtable"]=> + %unicode|string%(13) "test_affected" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(0) + [%u|b%"length"]=> + int(%d) + [%u|b%"charsetnr"]=> + int(%d) + [%u|b%"flags"]=> + int(32768) + [%u|b%"type"]=> + int(3) + [%u|b%"decimals"]=> + int(0) +} +object(stdClass)#6 (13) { + [%u|b%"name"]=> + %unicode|string%(3) "bar" + [%u|b%"orgname"]=> + %unicode|string%(3) "bar" + [%u|b%"table"]=> + %unicode|string%(13) "test_affected" + [%u|b%"orgtable"]=> + %unicode|string%(13) "test_affected" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(0) + [%u|b%"length"]=> + int(%d) + [%u|b%"charsetnr"]=> + int(%d) + [%u|b%"flags"]=> + int(0) + [%u|b%"type"]=> + int(253) + [%u|b%"decimals"]=> + int(0) +} + +=== fetch_field === +object(stdClass)#6 (13) { + [%u|b%"name"]=> + %unicode|string%(3) "foo" + [%u|b%"orgname"]=> + %unicode|string%(3) "foo" + [%u|b%"table"]=> + %unicode|string%(13) "test_affected" + [%u|b%"orgtable"]=> + %unicode|string%(13) "test_affected" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(0) + [%u|b%"length"]=> + int(%d) + [%u|b%"charsetnr"]=> + int(%d) + [%u|b%"flags"]=> + int(32768) + [%u|b%"type"]=> + int(3) + [%u|b%"decimals"]=> + int(0) +} +object(stdClass)#5 (13) { + [%u|b%"name"]=> + %unicode|string%(3) "bar" + [%u|b%"orgname"]=> + %unicode|string%(3) "bar" + [%u|b%"table"]=> + %unicode|string%(13) "test_affected" + [%u|b%"orgtable"]=> + %unicode|string%(13) "test_affected" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(0) + [%u|b%"length"]=> + int(%d) + [%u|b%"charsetnr"]=> + int(%d) + [%u|b%"flags"]=> + int(0) + [%u|b%"type"]=> + int(253) + [%u|b%"decimals"]=> + int(0) +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/048.phpt b/ext/mysqli/tests/048.phpt new file mode 100644 index 0000000..afc0923 --- /dev/null +++ b/ext/mysqli/tests/048.phpt @@ -0,0 +1,79 @@ +--TEST-- +mysqli bind_result (OO-Style) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $mysql = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + $mysql->select_db($db); + $mysql->query("DROP TABLE IF EXISTS test_fetch_null"); + + $mysql->query("CREATE TABLE test_fetch_null(col1 tinyint, col2 smallint, + col3 int, col4 bigint, + col5 float, col6 double, + col7 date, col8 time, + col9 varbinary(10), + col10 varchar(50), + col11 char(20)) ENGINE=" . $engine); + + $mysql->query("INSERT INTO test_fetch_null(col1,col10, col11) VALUES(1,'foo1', 1000),(2,'foo2', 88),(3,'foo3', 389789)"); + + $stmt = $mysql->prepare("SELECT col1, col2, col3, col4, col5, col6, col7, col8, col9, col10, col11 from test_fetch_null"); + $stmt->bind_result($c1, $c2, $c3, $c4, $c5, $c6, $c7, $c8, $c9, $c10, $c11); + $stmt->execute(); + + $stmt->fetch(); + + $test = array($c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$c10,$c11); + + var_dump($test); + + $stmt->close(); + $mysql->query("DROP TABLE IF EXISTS test_fetch_null"); + $mysql->close(); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_fetch_null")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +array(11) { + [0]=> + int(1) + [1]=> + NULL + [2]=> + NULL + [3]=> + NULL + [4]=> + NULL + [5]=> + NULL + [6]=> + NULL + [7]=> + NULL + [8]=> + NULL + [9]=> + %unicode|string%(4) "foo1" + [10]=> + %unicode|string%(4) "1000" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/049.phpt b/ext/mysqli/tests/049.phpt new file mode 100644 index 0000000..c87f369 --- /dev/null +++ b/ext/mysqli/tests/049.phpt @@ -0,0 +1,33 @@ +--TEST-- +mysql_fetch_row (OO-Style) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $mysql = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + $mysql->select_db($db); + $result = $mysql->query("SELECT DATABASE()"); + $row = $result->fetch_row(); + $result->close(); + + var_dump($row); + if ($row[0] != $db) + printf("[001] Expecting '%s' got '%s'\n", $db, $row[0]); + + $mysql->close(); + print "done!"; +?> +--EXPECTF-- +array(1) { + [0]=> + %unicode|string%(%d) "%s" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/050.phpt b/ext/mysqli/tests/050.phpt new file mode 100644 index 0000000..448f164 --- /dev/null +++ b/ext/mysqli/tests/050.phpt @@ -0,0 +1,24 @@ +--TEST-- +non freed statement test +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /************************ + * non freed stamement + ************************/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + $stmt = mysqli_prepare($link, "SELECT CURRENT_USER()"); + mysqli_stmt_execute($stmt); + + mysqli_close($link); + printf("Ok\n"); +?> +--EXPECT-- +Ok diff --git a/ext/mysqli/tests/051.phpt b/ext/mysqli/tests/051.phpt new file mode 100644 index 0000000..4a766fb --- /dev/null +++ b/ext/mysqli/tests/051.phpt @@ -0,0 +1,25 @@ +--TEST-- +free statement after close +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /************************ + * free statement after close + ************************/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + $stmt1 = mysqli_prepare($link, "SELECT CURRENT_USER()"); + mysqli_stmt_execute($stmt1); + + mysqli_close($link); + @mysqli_stmt_close($stmt1); + printf("Ok\n"); +?> +--EXPECT-- +Ok diff --git a/ext/mysqli/tests/052.phpt b/ext/mysqli/tests/052.phpt new file mode 100644 index 0000000..1d131f1 --- /dev/null +++ b/ext/mysqli/tests/052.phpt @@ -0,0 +1,25 @@ +--TEST-- +call statement after close +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /************************ + * statement call after close + ************************/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + $stmt2 = mysqli_prepare($link, "SELECT CURRENT_USER()"); + + mysqli_close($link); + @mysqli_stmt_execute($stmt2); + @mysqli_stmt_close($stmt2); + printf("Ok\n"); +?> +--EXPECT-- +Ok diff --git a/ext/mysqli/tests/053.phpt b/ext/mysqli/tests/053.phpt new file mode 100644 index 0000000..a1840c9 --- /dev/null +++ b/ext/mysqli/tests/053.phpt @@ -0,0 +1,23 @@ +--TEST-- +not freed resultset +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /************************ + * non freed resultset + ************************/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + $result = mysqli_query($link, "SELECT CURRENT_USER()"); + mysqli_close($link); + printf("Ok\n"); + +?> +--EXPECT-- +Ok diff --git a/ext/mysqli/tests/054.phpt b/ext/mysqli/tests/054.phpt new file mode 100644 index 0000000..6bd45a7 --- /dev/null +++ b/ext/mysqli/tests/054.phpt @@ -0,0 +1,23 @@ +--TEST-- +free resultset after close +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /************************ + * free resultset after close + ************************/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + $result1 = mysqli_query($link, "SELECT CURRENT_USER()"); + mysqli_close($link); + mysqli_free_result($result1); + printf("Ok\n"); +?> +--EXPECT-- +Ok diff --git a/ext/mysqli/tests/055.phpt b/ext/mysqli/tests/055.phpt new file mode 100644 index 0000000..c73266e --- /dev/null +++ b/ext/mysqli/tests/055.phpt @@ -0,0 +1,22 @@ +--TEST-- +free nothing +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /************************ + * don't free anything + ************************/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + $result2 = mysqli_query($link, "SELECT CURRENT_USER()"); + $stmt2 = mysqli_prepare($link, "SELECT CURRENT_USER()"); + printf("Ok\n"); +?> +--EXPECT-- +Ok diff --git a/ext/mysqli/tests/056.phpt b/ext/mysqli/tests/056.phpt new file mode 100644 index 0000000..413e678 --- /dev/null +++ b/ext/mysqli/tests/056.phpt @@ -0,0 +1,24 @@ +--TEST-- +extend mysqli +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + class foobar extends mysqli { + function test () { + return ("I do not like MySQL 4.1"); + } + } + + $foo = new foobar(); + $foo->connect($host, $user, $passwd, $db, $port, $socket); + $foo->close(); + printf("%s\n", $foo->test()); +?> +--EXPECT-- +I do not like MySQL 4.1 diff --git a/ext/mysqli/tests/057.phpt b/ext/mysqli/tests/057.phpt new file mode 100644 index 0000000..2cb8875 --- /dev/null +++ b/ext/mysqli/tests/057.phpt @@ -0,0 +1,113 @@ +--TEST-- +mysqli_stmt_result_metadata +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + + mysqli_query($link,"DROP TABLE IF EXISTS test_store_result"); + mysqli_query($link,"CREATE TABLE test_store_result (a int)"); + + mysqli_query($link, "INSERT INTO test_store_result VALUES (1),(2),(3)"); + + $stmt = mysqli_prepare($link, "SELECT * FROM test_store_result"); + mysqli_stmt_execute($stmt); + + /* this should produce an out of sync error */ + if ($result = mysqli_query($link, "SELECT * FROM test_store_result")) { + mysqli_free_result($result); + printf ("Query ok\n"); + } + mysqli_stmt_close($stmt); + + /* now we should try mysqli_stmt_reset() */ + $stmt = mysqli_prepare($link, "SELECT * FROM test_store_result"); + var_dump(mysqli_stmt_execute($stmt)); + var_dump(mysqli_stmt_reset($stmt)); + + var_dump($stmt = mysqli_prepare($link, "SELECT * FROM test_store_result")); + if ($IS_MYSQLND && $stmt->affected_rows !== -1) + printf("[001] Expecting -1, got %d\n", $stmt->affected_rows); + + var_dump(mysqli_stmt_execute($stmt)); + var_dump($stmt = @mysqli_prepare($link, "SELECT * FROM test_store_result"), mysqli_error($link)); + var_dump(mysqli_stmt_reset($stmt)); + + $stmt = mysqli_prepare($link, "SELECT * FROM test_store_result"); + mysqli_stmt_execute($stmt); + $result1 = mysqli_stmt_result_metadata($stmt); + mysqli_stmt_store_result($stmt); + + printf ("Rows: %d\n", mysqli_stmt_affected_rows($stmt)); + + /* this should show an error, cause results are not buffered */ + if ($result = mysqli_query($link, "SELECT * FROM test_store_result")) { + $row = mysqli_fetch_row($result); + mysqli_free_result($result); + } + + var_dump($row); + + mysqli_free_result($result1); + mysqli_stmt_close($stmt); + mysqli_close($link); + echo "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_store_result")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +bool(true) +bool(true) +object(mysqli_stmt)#%d (%d) { + [%u|b%"affected_rows"]=> + int(%i) + [%u|b%"insert_id"]=> + int(0) + [%u|b%"num_rows"]=> + int(0) + [%u|b%"param_count"]=> + int(0) + [%u|b%"field_count"]=> + int(1) + [%u|b%"errno"]=> + int(0) + [%u|b%"error"]=> + %unicode|string%(0) "" + [%u|b%"error_list"]=> + array(0) { + } + [%u|b%"sqlstate"]=> + %unicode|string%(5) "00000" + [%u|b%"id"]=> + int(3) +} +bool(true) +bool(false) +%unicode|string%(0) "" + +Warning: mysqli_stmt_reset() expects parameter 1 to be mysqli_stmt, boolean given in %s on line %d +NULL +Rows: 3 +array(1) { + [0]=> + %unicode|string%(1) "1" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/058.phpt b/ext/mysqli/tests/058.phpt new file mode 100644 index 0000000..3d2eed7 --- /dev/null +++ b/ext/mysqli/tests/058.phpt @@ -0,0 +1,73 @@ +--TEST-- +multiple binds +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + + mysqli_query($link,"DROP TABLE IF EXISTS mbind"); + mysqli_query($link,"CREATE TABLE mbind (a int, b varchar(10))"); + + $stmt = mysqli_prepare($link, "INSERT INTO mbind VALUES (?,?)"); + + mysqli_stmt_bind_param($stmt, "is", $a, $b); + + $a = 1; + $b = "foo"; + + mysqli_stmt_execute($stmt); + + mysqli_stmt_bind_param($stmt, "is", $c, $d); + + $c = 2; + $d = "bar"; + + mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + + $stmt = mysqli_prepare($link, "SELECT * FROM mbind"); + mysqli_stmt_execute($stmt); + + mysqli_stmt_bind_result($stmt, $e, $f); + mysqli_stmt_fetch($stmt); + + mysqli_stmt_bind_result($stmt, $g, $h); + mysqli_stmt_fetch($stmt); + + var_dump((array($e,$f,$g,$h))); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS mbind")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +array(4) { + [0]=> + int(1) + [1]=> + %unicode|string%(3) "foo" + [2]=> + int(2) + [3]=> + %unicode|string%(3) "bar" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/059.phpt b/ext/mysqli/tests/059.phpt new file mode 100644 index 0000000..e4b6a0b --- /dev/null +++ b/ext/mysqli/tests/059.phpt @@ -0,0 +1,57 @@ +--TEST-- +sqlmode + bind +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + + mysqli_query($link, "SET SQL_MODE='PIPES_AS_CONCAT'"); + + mysqli_query($link,"DROP TABLE IF EXISTS mbind"); + mysqli_query($link,"CREATE TABLE mbind (b varchar(25))"); + + $stmt = mysqli_prepare($link, "INSERT INTO mbind VALUES (?||?)"); + + mysqli_stmt_bind_param($stmt, "ss", $a, $b); + + $a = "foo"; + $b = "bar"; + + mysqli_stmt_execute($stmt); + + mysqli_stmt_close($stmt); + + $stmt = mysqli_prepare($link, "SELECT * FROM mbind"); + mysqli_stmt_execute($stmt); + + mysqli_stmt_bind_result($stmt, $e); + mysqli_stmt_fetch($stmt); + + var_dump($e); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS mbind")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +%unicode|string%(6) "foobar" +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/060.phpt b/ext/mysqli/tests/060.phpt new file mode 100644 index 0000000..5d17f8f --- /dev/null +++ b/ext/mysqli/tests/060.phpt @@ -0,0 +1,74 @@ +--TEST-- +mysqli_fetch_object with classes +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + class test_class { + function __construct($arg1, $arg2) { + echo __METHOD__ . "($arg1,$arg2)\n"; + } + } + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + mysqli_select_db($link, $db); + mysqli_query($link, "SET sql_mode=''"); + + mysqli_query($link,"DROP TABLE IF EXISTS test_fetch"); + mysqli_query($link,"CREATE TABLE test_fetch(c1 smallint unsigned, + c2 smallint unsigned, + c3 smallint, + c4 smallint, + c5 smallint, + c6 smallint unsigned, + c7 smallint)"); + + mysqli_query($link, "INSERT INTO test_fetch VALUES ( -23, 35999, NULL, -500, -9999999, -0, 0)"); + + $result = mysqli_query($link, "SELECT * FROM test_fetch"); + $test = mysqli_fetch_object($result, 'test_class', array(1, 2)); + mysqli_free_result($result); + + var_dump($test); + + mysqli_close($link); + + echo "Done\n"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_fetch")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +test_class::__construct(1,2) +object(test_class)#%d (7) { + [%u|b%"c1"]=> + %unicode|string%(1) "0" + [%u|b%"c2"]=> + %unicode|string%(5) "35999" + [%u|b%"c3"]=> + NULL + [%u|b%"c4"]=> + %unicode|string%(4) "-500" + [%u|b%"c5"]=> + %unicode|string%(6) "-32768" + [%u|b%"c6"]=> + %unicode|string%(1) "0" + [%u|b%"c7"]=> + %unicode|string%(1) "0" +} +Done
\ No newline at end of file diff --git a/ext/mysqli/tests/061.phpt b/ext/mysqli/tests/061.phpt new file mode 100644 index 0000000..5817d82 --- /dev/null +++ b/ext/mysqli/tests/061.phpt @@ -0,0 +1,78 @@ +--TEST-- +local infile handler +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +if (!function_exists('mysqli_set_local_infile_handler')) + die("skip - function not available."); + +$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); +if (!$link) + die(sprintf("skip Can't connect [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--FILE-- +<?php + require_once("connect.inc"); + + function my_read($fp, &$buffer, $buflen, &$error) { + $buffer = strrev(fread($fp, $buflen)); + return(strlen($buffer)); + } + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + /* create temporary file */ + $filename = dirname(__FILE__) . "061.csv"; + $fp = fopen($filename, "w"); + fwrite($fp, b"foo;bar"); + fclose($fp); + + if (!mysqli_query($link,"DROP TABLE IF EXISTS t_061")) + printf("Cannot drop table: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + if (!mysqli_query($link,"CREATE TABLE t_061 (c1 varchar(10), c2 varchar(10))")) + printf("Cannot create table: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, sprintf("LOAD DATA LOCAL INFILE '%s' INTO TABLE t_061 FIELDS TERMINATED BY ';'", mysqli_real_escape_string($link, $filename)))) + printf("Cannot load data: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_set_local_infile_handler($link, "my_read"); + if (!mysqli_query($link, sprintf("LOAD DATA LOCAL INFILE '%s' INTO TABLE t_061 FIELDS TERMINATED BY ';'", mysqli_real_escape_string($link, $filename)))) + printf("Cannot load data using infile handler: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ($result = mysqli_query($link, "SELECT c1,c2 FROM t_061")) { + while (($row = mysqli_fetch_row($result))) { + printf("%s-%s\n", $row[0], $row[1]); + printf("%s-%s\n", gettype($row[0]), gettype($row[1])); + } + mysqli_free_result($result); + } + + mysqli_close($link); + unlink($filename); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS t_061")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +foo-bar +%unicode|string%-%unicode|string% +rab-oof +%unicode|string%-%unicode|string% +done! diff --git a/ext/mysqli/tests/062.phpt b/ext/mysqli/tests/062.phpt new file mode 100644 index 0000000..bc6198c --- /dev/null +++ b/ext/mysqli/tests/062.phpt @@ -0,0 +1,30 @@ +--TEST-- +resultset constructor +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + + $mysql->real_query("SELECT 'foo' FROM DUAL"); + + $myresult = new mysqli_result($mysql); + + $row = $myresult->fetch_row(); + $myresult->close(); + $mysql->close(); + + var_dump($row); + print "done!"; +?> +--EXPECTF-- +array(1) { + [0]=> + %unicode|string%(3) "foo" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/063.phpt b/ext/mysqli/tests/063.phpt new file mode 100644 index 0000000..b184d72 --- /dev/null +++ b/ext/mysqli/tests/063.phpt @@ -0,0 +1,24 @@ +--TEST-- +resultset constructor +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + + $stmt = new mysqli_stmt($mysql, "SELECT 'foo' FROM DUAL"); + $stmt->execute(); + $stmt->bind_result($foo); + $stmt->fetch(); + $stmt->close(); + $mysql->close(); + + var_dump($foo); +?> +--EXPECTF-- +%unicode|string%(3) "foo"
\ No newline at end of file diff --git a/ext/mysqli/tests/064.phpt b/ext/mysqli/tests/064.phpt new file mode 100644 index 0000000..46af7a6 --- /dev/null +++ b/ext/mysqli/tests/064.phpt @@ -0,0 +1,24 @@ +--TEST-- +NULL binding +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + + $stmt = new mysqli_stmt($mysql, "SELECT NULL FROM DUAL"); + $stmt->execute(); + $stmt->bind_result($foo); + $stmt->fetch(); + $stmt->close(); + $mysql->close(); + + var_dump($foo); +?> +--EXPECT-- +NULL diff --git a/ext/mysqli/tests/065.phpt b/ext/mysqli/tests/065.phpt new file mode 100644 index 0000000..9426644 --- /dev/null +++ b/ext/mysqli/tests/065.phpt @@ -0,0 +1,55 @@ +--TEST-- +set character set +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_set_charset')) { + die('skip mysqli_set_charset() not available'); +} +if (version_compare(PHP_VERSION, '5.9.9', '>') == 1) { + die('skip set character set not functional with PHP 6 (fomerly PHP 6 && unicode.semantics=On)'); +} +?> +--FILE-- +<?php + require_once("connect.inc"); + + if (!$mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (!mysqli_query($mysql, "SET sql_mode=''")) + printf("[002] Cannot set SQL-Mode, [%d] %s\n", mysqli_errno($mysql), mysqli_error($mysql)); + + $esc_str = chr(0xbf) . chr(0x5c); + $len = $charset = array(); + $tmp = null; + + if ($mysql->set_charset("latin1")) { + /* 5C should be escaped */ + if (3 !== ($tmp = strlen($mysql->real_escape_string($esc_str)))) + printf("[003] Expecting 3/int got %s/%s\n", gettype($tmp), $tmp); + + if ('latin1' !== ($tmp = $mysql->character_set_name())) + printf("[004] Expecting latin1/string got %s/%s\n", gettype($tmp), $tmp); + } + + if ($res = $mysql->query("SHOW CHARACTER SET LIKE 'gbk'")) { + $res->free_result(); + if ($mysql->set_charset("gbk")) { + /* nothing should be escaped, it's a valid gbk character */ + + if (2 !== ($tmp = strlen($mysql->real_escape_string($esc_str)))) + printf("[005] Expecting 2/int got %s/%s\n", gettype($tmp), $tmp); + + if ('gbk' !== ($tmp = $mysql->character_set_name())) + printf("[005] Expecting gbk/string got %s/%s\n", gettype($tmp), $tmp);; + } + } + $mysql->close(); + + print "done!"; +?> +--EXPECT-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/066.phpt b/ext/mysqli/tests/066.phpt new file mode 100644 index 0000000..91dfce5 --- /dev/null +++ b/ext/mysqli/tests/066.phpt @@ -0,0 +1,43 @@ +--TEST-- +function test: mysqli_warning object +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + + $mysql->query("DROP TABLE IF EXISTS test_warnings"); + + $mysql->query("CREATE TABLE test_warnings (a int not null) ENGINE=myisam"); + + $mysql->query("INSERT INTO test_warnings VALUES (1),(2),(NULL)"); + + if (($warning = $mysql->get_warnings())) { + do { + printf("Warning\n"); + } while ($warning->next()); + } + + $mysql->close(); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_warnings")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECT-- +Warning +done! diff --git a/ext/mysqli/tests/067.phpt b/ext/mysqli/tests/067.phpt new file mode 100644 index 0000000..d5795bd --- /dev/null +++ b/ext/mysqli/tests/067.phpt @@ -0,0 +1,81 @@ +--TEST-- +function test: nested selects (cursors) +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifconnectfailure.inc'); + require_once("connect.inc"); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die("skip Cannot connect to check required version"); + + /* skip cursor test for versions < 50004 */ + if ((!$IS_MYSQLND && (mysqli_get_client_version() < 50009)) || + (mysqli_get_server_version($link) < 50009)) { + die(sprintf("skip Client library doesn't support cursors (%s/%s)", + mysqli_get_client_version(), mysqli_get_server_version($link))); + } + mysqli_close($link); +?> +--FILE-- +<?php + function open_cursor($mysql, $query) { + if (!is_object($stmt = $mysql->prepare($query))) { + printf("[001] Cannot create statement object for '%s', [%d] %s\n", + $query, $mysql->errno, $mysql->error); + } + + $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_READ_ONLY); + return $stmt; + } + + require_once("connect.inc"); + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + + if ((!$IS_MYSQLND && mysqli_get_client_version() < 50009) || + (mysqli_get_server_version($mysql) < 50009)) { + /* we really want to skip it... */ + die(var_dump(63)); + } + + $a = array(); + + for ($i=0;$i < 3; $i++) { + $mysql->query("DROP TABLE IF EXISTS cursor$i"); + $mysql->query("CREATE TABLE cursor$i (a int not null) ENGINE=" . $engine); + $mysql->query("INSERT INTO cursor$i VALUES (1),(2),(3),(4),(5),(6)"); + $stmt[$i] = open_cursor($mysql, "SELECT a FROM cursor$i"); + $stmt[$i]->execute(); + $stmt[$i]->bind_result($a[$i]); + } + + + $cnt = 0; + while ($stmt[0]->fetch()) { + $stmt[1]->fetch(); + $stmt[2]->fetch(); + $cnt += $a[0] + $a[1] + $a[2]; + } + + for ($i=0; $i < 3; $i++) { + $stmt[$i]->close(); + } + + $mysql->close(); + var_dump($cnt); +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +for ($i =0; $i < 3; $i++) { + if (!mysqli_query($link, sprintf("DROP TABLE IF EXISTS cursor%d", $i))) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); +} + +mysqli_close($link); +?> +--EXPECT-- +int(63)
\ No newline at end of file diff --git a/ext/mysqli/tests/068.phpt b/ext/mysqli/tests/068.phpt new file mode 100644 index 0000000..57a4a25 --- /dev/null +++ b/ext/mysqli/tests/068.phpt @@ -0,0 +1,11 @@ +--TEST-- +mysqli get_client_info +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + $s = mysqli_get_client_info(); + echo gettype($s); +?> +--EXPECTF-- +%unicode|string%
\ No newline at end of file diff --git a/ext/mysqli/tests/069.phpt b/ext/mysqli/tests/069.phpt new file mode 100644 index 0000000..ee76ca5 --- /dev/null +++ b/ext/mysqli/tests/069.phpt @@ -0,0 +1,38 @@ +--TEST-- +mysqli multi_query, next_result, more_results +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + $mysql->multi_query('SELECT 1;SELECT 2'); + do { + $res = $mysql->store_result(); + if ($mysql->errno == 0) { + while ($arr = $res->fetch_assoc()) { + var_dump($arr); + } + $res->free(); + } + if (!$mysql->more_results()) { + break; + } + } while (@$mysql->next_result()); + $mysql->close(); + print "done!"; +?> +--EXPECTF-- +array(1) { + [1]=> + %unicode|string%(1) "1" +} +array(1) { + [2]=> + %unicode|string%(1) "2" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/070.phpt b/ext/mysqli/tests/070.phpt new file mode 100644 index 0000000..b71d9b2 --- /dev/null +++ b/ext/mysqli/tests/070.phpt @@ -0,0 +1,19 @@ +--TEST-- +mysqli ping +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + var_dump($mysql->ping()); + $mysql->close(); + print "done!"; +?> +--EXPECT-- +bool(true) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/071.phpt b/ext/mysqli/tests/071.phpt new file mode 100644 index 0000000..6f45777 --- /dev/null +++ b/ext/mysqli/tests/071.phpt @@ -0,0 +1,74 @@ +--TEST-- +mysqli thread_id & kill +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + $version = $mysql->server_version; + + var_dump($mysql->ping()); + + $ret = $mysql->kill($mysql->thread_id); + if ($IS_MYSQLND) { + if ($ret !== true){ + printf("[001] Expecting boolean/true got %s/%s\n", gettype($ret), var_export($ret, true)); + } + } else { + /* libmysql return value seems to depend on server version */ + if ((($version >= 50123) || ($version <= 40200)) && $version != 50200) { + /* TODO: find exact version */ + if ($ret !== true){ + printf("[001] Expecting boolean/true got %s/%s @\n", gettype($ret), var_export($ret, true), $version); + } + } else { + if ($ret !== false){ + printf("[001] Expecting boolean/false got %s/%s @\n", gettype($ret), var_export($ret, true), $version); + } + } + } + + var_dump($mysql->ping()); + + $mysql->close(); + + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + + var_dump(mysqli_ping($mysql)); + + $ret = $mysql->kill($mysql->thread_id); + if ($IS_MYSQLND) { + if ($ret !== true){ + printf("[002] Expecting boolean/true got %s/%s\n", gettype($ret), var_export($ret, true)); + } + } else { + /* libmysql return value seems to depend on server version */ + if ((($version >= 50123) || ($version <= 40200)) && $version != 50200) { + /* TODO: find exact version */ + if ($ret !== true){ + printf("[002] Expecting boolean/true got %s/%s @\n", gettype($ret), var_export($ret, true), $version); + } + } else { + if ($ret !== false){ + printf("[002] Expecting boolean/false got %s/%s @\n", gettype($ret), var_export($ret, true), $version); + } + } + } + + var_dump(mysqli_ping($mysql)); + + $mysql->close(); + print "done!"; +?> +--EXPECT-- +bool(true) +bool(false) +bool(true) +bool(false) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/072.phpt b/ext/mysqli/tests/072.phpt new file mode 100644 index 0000000..a1e9983 --- /dev/null +++ b/ext/mysqli/tests/072.phpt @@ -0,0 +1,32 @@ +--TEST-- +mysqli warning_count, get_warnings +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + + $mysql->query("DROP TABLE IF EXISTS not_exists"); + + var_dump($mysql->warning_count); + + $w = $mysql->get_warnings(); + + var_dump($w->errno); + var_dump($w->message); + var_dump($w->sqlstate); + + $mysql->close(); + echo "done!" +?> +--EXPECTF-- +int(1) +int(1051) +%unicode|string%(%d) "Unknown table %snot_exists%s" +%unicode|string%(5) "HY000" +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/073.phpt b/ext/mysqli/tests/073.phpt new file mode 100644 index 0000000..c70f7d9 --- /dev/null +++ b/ext/mysqli/tests/073.phpt @@ -0,0 +1,24 @@ +--TEST-- +mysqli_driver properties +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + require_once("connect.inc"); + + var_dump($driver->embedded); + var_dump($driver->client_version); + var_dump($driver->client_info); + var_dump($driver->driver_version); + var_dump($driver->reconnect); + var_dump($driver->report_mode); + print "done!"; +?> +--EXPECTF-- +bool(%s) +int(%d) +%unicode|string%(%d) "%s" +int(%d) +bool(%s) +int(%d) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/074.phpt b/ext/mysqli/tests/074.phpt new file mode 100644 index 0000000..7d9d01b --- /dev/null +++ b/ext/mysqli/tests/074.phpt @@ -0,0 +1,34 @@ +--TEST-- +mysqli_autocommit() tests +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + + require_once("connect.inc"); + + $mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + + var_dump($mysqli->autocommit(false)); + $result = $mysqli->query("SELECT @@autocommit"); + var_dump($result->fetch_row()); + + var_dump($mysqli->autocommit(true)); + $result = $mysqli->query("SELECT @@autocommit"); + var_dump($result->fetch_row()); + +?> +--EXPECTF-- +bool(true) +array(1) { + [0]=> + %unicode|string%(1) "0" +} +bool(true) +array(1) { + [0]=> + %unicode|string%(1) "1" +}
\ No newline at end of file diff --git a/ext/mysqli/tests/bug28817.phpt b/ext/mysqli/tests/bug28817.phpt new file mode 100644 index 0000000..254c0e5 --- /dev/null +++ b/ext/mysqli/tests/bug28817.phpt @@ -0,0 +1,42 @@ +--TEST-- +Bug #28817 (problems with properties declared in the class extending MySQLi) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + class my_mysql extends mysqli { + public $p_test; + + function __construct() { + $this->p_test[] = "foo"; + $this->p_test[] = "bar"; + } + } + + + $mysql = new my_mysql(); + + var_dump($mysql->p_test); + @var_dump($mysql->errno); + + $mysql->connect($host, $user, $passwd, $db, $port, $socket); + $mysql->select_db("nonexistingdb"); + + var_dump($mysql->errno > 0); + + $mysql->close(); +?> +--EXPECTF-- +array(2) { + [0]=> + %s(3) "foo" + [1]=> + %s(3) "bar" +} +NULL +bool(true)
\ No newline at end of file diff --git a/ext/mysqli/tests/bug29311.phpt b/ext/mysqli/tests/bug29311.phpt new file mode 100644 index 0000000..cd7b9ef --- /dev/null +++ b/ext/mysqli/tests/bug29311.phpt @@ -0,0 +1,51 @@ +--TEST-- +Bug #29311 (Cannot override mysqli constructor) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /* class 1 calls parent constructor */ + class mysql1 extends mysqli { + function __construct() { + global $host, $user, $passwd, $db, $port, $socket; + parent::__construct($host, $user, $passwd, $db, $port, $socket); + } + } + + /* class 2 has an own constructor */ + class mysql2 extends mysqli { + + function __construct() { + global $host, $user, $passwd, $db, $port, $socket; + $this->connect($host, $user, $passwd, $db, $port, $socket); + } + } + + /* class 3 has no constructor */ + class mysql3 extends mysqli { + + } + + $foo[0] = new mysql1(); + $foo[1] = new mysql2(); + $foo[2] = new mysql3($host, $user, $passwd, $db, $port, $socket); + + + for ($i=0; $i < 3; $i++) { + if (($result = $foo[$i]->query("SELECT DATABASE()"))) { + $row = $result->fetch_row(); + if ($row[0] != $db) + printf("%d: %s\n", $i, $row[0]); + $result->close(); + } + $foo[$i]->close(); + } + print "done!"; +?> +--EXPECTF-- +done! diff --git a/ext/mysqli/tests/bug30967.phpt b/ext/mysqli/tests/bug30967.phpt new file mode 100644 index 0000000..48007ce --- /dev/null +++ b/ext/mysqli/tests/bug30967.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #30967 (problems with properties declared in the class extending the class extending MySQLi) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + class mysql1 extends mysqli { + } + + class mysql2 extends mysql1 { + } + + $mysql = new mysql2($host, $user, $passwd, $db, $port, $socket); + + $mysql->query("THIS DOES NOT WORK"); + printf("%d\n", $mysql->errno); + + $mysql->close(); +?> +--EXPECTF-- +1064 diff --git a/ext/mysqli/tests/bug31141.phpt b/ext/mysqli/tests/bug31141.phpt new file mode 100644 index 0000000..7183474 --- /dev/null +++ b/ext/mysqli/tests/bug31141.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #31141 (properties declared in the class extending MySQLi are not available) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +class Test extends mysqli +{ + public $test = array(); + + function foo() + { + $ar_test = array("foo", "bar"); + $this->test = &$ar_test; + } +} + +$my_test = new Test; +$my_test->foo(); +var_dump($my_test->test); +?> +--EXPECTF-- +array(2) { + [0]=> + %s(3) "foo" + [1]=> + %s(3) "bar" +} diff --git a/ext/mysqli/tests/bug31668.phpt b/ext/mysqli/tests/bug31668.phpt new file mode 100644 index 0000000..9b769a1 --- /dev/null +++ b/ext/mysqli/tests/bug31668.phpt @@ -0,0 +1,61 @@ +--TEST-- +Bug #31668 (multi_query works exactly every other time (multi_query was global, now per connection)) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +error_reporting = E_ALL & ~E_STRICT +--FILE-- +<?php + require_once("connect.inc"); + + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + $mysql->multi_query('SELECT 1;SELECT 2'); + do { + $res = $mysql->store_result(); + if ($mysql->errno == 0) { + while ($arr = $res->fetch_assoc()) { + var_dump($arr); + } + $res->free(); + } + } while ($mysql->next_result()); + var_dump($mysql->error, __LINE__); + $mysql->close(); + + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + $mysql->multi_query('SELECT 1;SELECT 2'); + do { + $res = $mysql->store_result(); + if ($mysql->errno == 0) { + while ($arr = $res->fetch_assoc()) { + var_dump($arr); + } + $res->free(); + } + } while ($mysql->next_result()); + var_dump($mysql->error, __LINE__); +?> +--EXPECTF-- +array(1) { + [1]=> + %s(1) "1" +} +array(1) { + [2]=> + %s(1) "2" +} +%s(0) "" +int(%d) +array(1) { + [1]=> + %s(1) "1" +} +array(1) { + [2]=> + %s(1) "2" +} +%s(0) "" +int(%d) diff --git a/ext/mysqli/tests/bug32405.phpt b/ext/mysqli/tests/bug32405.phpt new file mode 100644 index 0000000..0b3cad5 --- /dev/null +++ b/ext/mysqli/tests/bug32405.phpt @@ -0,0 +1,53 @@ +--TEST-- +Bug #32405 (mysqli->fetch() is returning bad data) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + mysqli_select_db($link, "test"); + mysqli_query($link, "SET sql_mode=''"); + + /* two fields are needed. the problem does not occur with 1 field only selected. */ + $link->query("CREATE TABLE test_users(user_id int(10) unsigned NOT NULL auto_increment, login varchar(50) default '', PRIMARY KEY (user_id))"); + $link->query('INSERT INTO test_users VALUES (NULL, "user1"), (NULL, "user2"), (NULL, "user3"), (NULL, "user4")'); + + + if ($stmt = $link->prepare("SELECT SQL_NO_CACHE user_id, login FROM test_users")) { + $stmt->execute(); + $stmt->bind_result($col1, $col2); + while ($stmt->fetch()) { + var_dump($col1, $col2); + } + $stmt->close(); + } + + mysqli_query($link,"DROP TABLE test_users"); + mysqli_close($link); +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_users")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +int(1) +%s(5) "user1" +int(2) +%s(5) "user2" +int(3) +%s(5) "user3" +int(4) +%s(5) "user4" diff --git a/ext/mysqli/tests/bug33090.phpt b/ext/mysqli/tests/bug33090.phpt new file mode 100644 index 0000000..c95043c --- /dev/null +++ b/ext/mysqli/tests/bug33090.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #33090 (mysql_prepare doesn't return an error) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + include ("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, null, $port, $socket); + mysqli_select_db($link, $db); + + if (!($link->prepare("this makes no sense"))) { + printf("%d\n", $link->errno); + printf("%s\n", $link->sqlstate); + } + $link->close(); +?> +--EXPECT-- +1064 +42000 diff --git a/ext/mysqli/tests/bug33263.phpt b/ext/mysqli/tests/bug33263.phpt new file mode 100644 index 0000000..ac2de19 --- /dev/null +++ b/ext/mysqli/tests/bug33263.phpt @@ -0,0 +1,37 @@ +--TEST-- +Bug #33263 (mysqli_real_connect in __construct) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + class test extends mysqli + { + public function __construct($host, $user, $passwd, $db, $port, $socket) { + parent::init(); + parent::real_connect($host, $user, $passwd, $db, $port, $socket); + } + } + + $mysql = new test($host, $user, $passwd, $db, $port, $socket); + + $stmt = $mysql->prepare("SELECT DATABASE()"); + $stmt->execute(); + $stmt->bind_result($database); + $stmt->fetch(); + $stmt->close(); + + if ($database != $db) + printf("[001] Expecting '%s' got %s/'%s'.\n", + gettype($database), $database); + + $mysql->close(); + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/bug33491.phpt b/ext/mysqli/tests/bug33491.phpt new file mode 100644 index 0000000..168ecb0 --- /dev/null +++ b/ext/mysqli/tests/bug33491.phpt @@ -0,0 +1,29 @@ +--TEST-- +Bug #33491 (extended mysqli class crashes when result is not object) +--INI-- +error_reporting=4095 +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + +class DB extends mysqli +{ + public function query_single($query) { + $result = parent::query($query); + $result->fetch_row(); // <- Here be crash + } +} + +require_once("connect.inc"); + +// Segfault when using the DB class which extends mysqli +$DB = new DB($host, $user, $passwd, $db, $port, $socket); +$DB->query_single('SELECT DATE()'); + +?> +--EXPECTF-- +Fatal error: Call to a member function fetch_row() on a non-object in %sbug33491.php on line %d diff --git a/ext/mysqli/tests/bug34785.phpt b/ext/mysqli/tests/bug34785.phpt new file mode 100644 index 0000000..18dd4c3 --- /dev/null +++ b/ext/mysqli/tests/bug34785.phpt @@ -0,0 +1,50 @@ +--TEST-- +Bug #34785 (Can not properly subclass mysqli_stmt) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + include ("connect.inc"); + + class my_stmt extends mysqli_stmt + { + public function __construct($link, $query) { + parent::__construct($link, $query); + } + } + + class my_result extends mysqli_result + { + public function __construct($link, $query) { + parent::__construct($link, $query); + } + } + + /*** test mysqli_connect 127.0.0.1 ***/ + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + mysqli_query($link, "SET sql_mode=''"); + + $stmt = new my_stmt($link, "SELECT 'foo' FROM DUAL"); + + $stmt->execute(); + $stmt->bind_result($var); + $stmt->fetch(); + + $stmt->close(); + var_dump($var); + + mysqli_real_query($link, "SELECT 'bar' FROM DUAL"); + $result = new my_result($link, MYSQLI_STORE_RESULT); + $row = $result->fetch_row(); + $result->close(); + + var_dump($row[0]); + + mysqli_close($link); +?> +--EXPECTF-- +%s(3) "foo" +%s(3) "bar" diff --git a/ext/mysqli/tests/bug34810.phpt b/ext/mysqli/tests/bug34810.phpt new file mode 100644 index 0000000..1ea89d9 --- /dev/null +++ b/ext/mysqli/tests/bug34810.phpt @@ -0,0 +1,146 @@ +--TEST-- +Bug #34810 (mysqli::init() and others use wrong $this pointer without checks) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + +class DbConnection { + public function connect() { + require_once("connect.inc"); + + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + var_dump($link); + + $link = mysqli_init(); + /* @ is to supress 'Property access is not allowed yet' */ + @var_dump($link); + + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + $mysql->query("DROP TABLE IF EXISTS test_warnings"); + $mysql->query("CREATE TABLE test_warnings (a int not null)"); + $mysql->query("SET sql_mode=''"); + $mysql->query("INSERT INTO test_warnings VALUES (1),(2),(NULL)"); + + $warning = $mysql->get_warnings(); + if (!$warning) + printf("[001] No warning!\n"); + + if ($warning->errno == 1048 || $warning->errno == 1253) { + /* 1048 - Column 'a' cannot be null, 1263 - Data truncated; NULL supplied to NOT NULL column 'a' at row */ + if ("HY000" != $warning->sqlstate) + printf("[003] Wrong sql state code: %s\n", $warning->sqlstate); + + if ("" == $warning->message) + printf("[004] Message string must not be empty\n"); + + + } else { + printf("[002] Empty error message!\n"); + var_dump($warning); + } + } +} + +$db = new DbConnection(); +$db->connect(); + +echo "Done\n"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_warnings")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +object(mysqli)#%d (%d) { + [%u|b%"affected_rows"]=> + int(0) + [%u|b%"client_info"]=> + %unicode|string%(%d) "%s" + [%u|b%"client_version"]=> + int(%d) + [%u|b%"connect_errno"]=> + int(0) + [%u|b%"connect_error"]=> + NULL + [%u|b%"errno"]=> + int(0) + [%u|b%"error"]=> + %unicode|string%(0) "" + [%u|b%"error_list"]=> + array(0) { + } + [%u|b%"field_count"]=> + int(0) + [%u|b%"host_info"]=> + %unicode|string%(%d) "%s" + [%u|b%"info"]=> + NULL + [%u|b%"insert_id"]=> + int(0) + [%u|b%"server_info"]=> + %unicode|string%(%d) "%s" + [%u|b%"server_version"]=> + int(%d) + [%u|b%"stat"]=> + string(%d) "Uptime: %d Threads: %d Questions: %d Slow queries: %d Opens: %d Flush tables: %d Open tables: %d Queries per second avg: %d.%d" + [%u|b%"sqlstate"]=> + %unicode|string%(5) "00000" + [%u|b%"protocol_version"]=> + int(10) + [%u|b%"thread_id"]=> + int(%d) + [%u|b%"warning_count"]=> + int(0) +} +object(mysqli)#%d (%d) { + [%u|b%"affected_rows"]=> + NULL + [%u|b%"client_info"]=> + %unicode|string%(%d) "%s" + [%u|b%"client_version"]=> + int(%d) + [%u|b%"connect_errno"]=> + int(0) + [%u|b%"connect_error"]=> + NULL + [%u|b%"errno"]=> + int(0) + [%u|b%"error"]=> + %unicode|string%(0) "" + [%u|b%"error_list"]=> + NULL + [%u|b%"field_count"]=> + NULL + [%u|b%"host_info"]=> + NULL + [%u|b%"info"]=> + NULL + [%u|b%"insert_id"]=> + NULL + [%u|b%"server_info"]=> + NULL + [%u|b%"server_version"]=> + NULL + [%u|b%"stat"]=> + NULL + [%u|b%"sqlstate"]=> + NULL + [%u|b%"protocol_version"]=> + NULL + [%u|b%"thread_id"]=> + NULL + [%u|b%"warning_count"]=> + NULL +} +Done diff --git a/ext/mysqli/tests/bug35103.phpt b/ext/mysqli/tests/bug35103.phpt new file mode 100644 index 0000000..fc3cad0 --- /dev/null +++ b/ext/mysqli/tests/bug35103.phpt @@ -0,0 +1,82 @@ +--TEST-- +Bug #35103 (Bad handling of unsigned bigint) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + +$drop = <<<EOSQL +DROP TABLE test_bint; +DROP TABLE test_buint; +EOSQL; + require_once("connect.inc"); + + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + $mysql->query("DROP TABLE IF EXISTS test_bint"); + $mysql->query("CREATE TABLE test_bint (a bigint(20) default NULL) ENGINE=MYISAM"); + $mysql->query("INSERT INTO test_bint VALUES (9223372036854775807),(-9223372036854775808),(-2147483648),(-2147483649),(-2147483647),(2147483647),(2147483648),(2147483649)"); + + $mysql->query("DROP TABLE IF EXISTS test_buint"); + $mysql->query("CREATE TABLE test_buint (a bigint(20) unsigned default NULL)"); + $mysql->query("INSERT INTO test_buint VALUES (18446744073709551615),(9223372036854775807),(9223372036854775808),(2147483647),(2147483649),(4294967295)"); + + $stmt = $mysql->prepare("SELECT a FROM test_bint ORDER BY a"); + $stmt->bind_result($v); + $stmt->execute(); + $i=0; + echo "BIG INT SIGNED, TEST\n"; + while ($i++ < 8) { + $stmt->fetch(); + echo $v, "\n"; + } + $stmt->close(); + + echo str_repeat("-", 20), "\n"; + + $stmt = $mysql->prepare("SELECT a FROM test_buint ORDER BY a"); + $stmt->bind_result($v2); + $stmt->execute(); + $j=0; + echo "BIG INT UNSIGNED TEST\n"; + while ($j++ < 6) { + $stmt->fetch(); + echo $v2, "\n"; + } + $stmt->close(); + + $mysql->multi_query($drop); + + $mysql->close(); +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bint") || !mysqli_query($link, "DROP TABLE IF EXISTS test_buint")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECT-- +BIG INT SIGNED, TEST +-9223372036854775808 +-2147483649 +-2147483648 +-2147483647 +2147483647 +2147483648 +2147483649 +9223372036854775807 +-------------------- +BIG INT UNSIGNED TEST +2147483647 +2147483649 +4294967295 +9223372036854775807 +9223372036854775808 +18446744073709551615 diff --git a/ext/mysqli/tests/bug35517.phpt b/ext/mysqli/tests/bug35517.phpt new file mode 100644 index 0000000..746251f --- /dev/null +++ b/ext/mysqli/tests/bug35517.phpt @@ -0,0 +1,56 @@ +--TEST-- +Bug #35517 (mysqli_stmt_fetch returns NULL) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + + $mysql->query("CREATE TABLE temp (id INT UNSIGNED NOT NULL)"); + $mysql->query("INSERT INTO temp (id) VALUES (3000000897),(3800001532),(3900002281),(3100059612)"); + $stmt = $mysql->prepare("SELECT id FROM temp"); + $stmt->execute(); + $stmt->bind_result($id); + while ($stmt->fetch()) { + if (PHP_INT_SIZE == 8) { + if ((gettype($id) !== 'int') && (gettype($id) != 'integer')) + printf("[001] Expecting integer on 64bit got %s/%s\n", gettype($id), var_export($id, true)); + } else { + if (gettype($id) !== 'string') { + printf("[002] Expecting string on 32bit got %s/%s\n", gettype($id), var_export($id, true)); + } + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($id)) { + printf("[003] Expecting unicode string\n"); + } + } + print $id; + print "\n"; + } + $stmt->close(); + + $mysql->query("DROP TABLE temp"); + $mysql->close(); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS temp")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +3000000897 +3800001532 +3900002281 +3100059612 +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/bug35759.phpt b/ext/mysqli/tests/bug35759.phpt new file mode 100644 index 0000000..99c1380 --- /dev/null +++ b/ext/mysqli/tests/bug35759.phpt @@ -0,0 +1,58 @@ +--TEST-- +Bug #35759 (mysqli_stmt_bind_result() makes huge allocation when column empty) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + + require_once("connect.inc"); + $col_num= 1000; + + $mysql = new mysqli($host, $user, $passwd, $db, $port, $socket); + $mysql->query("DROP TABLE IF EXISTS test"); + $create = "CREATE TABLE test (a0 MEDIUMBLOB NOT NULL DEFAULT ''"; + $i= 0; + while (++$i < $col_num) { + $create .= ", a$i MEDIUMBLOB NOT NULL DEFAULT ''"; + } + $create .= ") ENGINE=MyISAM"; // doesn't work with InnoDB, which is default in 5.5 + + if (!$mysql->query($create)) { + if (1101 == $mysql->errno) { + /* SQL strict mode - [1101] BLOB/TEXT column 'a0' can't have a default value */ + print "done!"; + exit(0); + } + printf("[001] [%d] %s\n", $mysql->errno, $mysql->error); + } + + if (!$mysql->query("INSERT INTO test (a0) VALUES ('')")) + printf("[002] [%d] %s\n", $mysql->errno, $mysql->error); + + $stmt = $mysql->prepare("SELECT * FROM test"); + if ($stmt) { + + $stmt->execute(); + $stmt->store_result(); + for ($i = 0; $i < $col_num; $i++) { + $params[] = &$col_num; + } + call_user_func_array(array($stmt, "bind_result"), $params); + $stmt->fetch(); + + $stmt->close(); + } else { + printf("[003] [%d] %s\n", $mysql->errno, $mysql->error); + } + + $mysql->close(); + + echo "done!"; +?> +--CLEAN-- +<?php require("clean_table.inc"); ?> +--EXPECT-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/bug36420.phpt b/ext/mysqli/tests/bug36420.phpt new file mode 100644 index 0000000..6dd03b3 --- /dev/null +++ b/ext/mysqli/tests/bug36420.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #36420 (segfault when access result->num_rows after calling result->close()) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + +require_once("connect.inc"); +$mysqli = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + +$result = $mysqli->query('select 1'); + +$result->close(); +echo $result->num_rows; + +$mysqli->close(); +echo $result->num_rows; + +echo "Done\n"; +?> +--EXPECTF-- +Warning: main(): Couldn't fetch mysqli_result in %s on line %d + +Warning: main(): Couldn't fetch mysqli_result in %s on line %d +Done diff --git a/ext/mysqli/tests/bug36745.phpt b/ext/mysqli/tests/bug36745.phpt new file mode 100644 index 0000000..5e203e1 --- /dev/null +++ b/ext/mysqli/tests/bug36745.phpt @@ -0,0 +1,37 @@ +--TEST-- +Bug #36745 (LOAD DATA LOCAL INFILE doesn't return correct error message) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + /*** test mysqli_connect 127.0.0.1 ***/ + $mysql = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + $mysql->query("DROP TABLE IF EXISTS litest"); + $mysql->query("CREATE TABLE litest (a VARCHAR(20))"); + + $mysql->query("LOAD DATA LOCAL INFILE 'filenotfound' INTO TABLE litest"); + var_dump($mysql->error); + + $mysql->close(); + printf("Done"); +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS litest")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +%s(%d) "%s" +Done diff --git a/ext/mysqli/tests/bug36802.phpt b/ext/mysqli/tests/bug36802.phpt new file mode 100644 index 0000000..3694a26 --- /dev/null +++ b/ext/mysqli/tests/bug36802.phpt @@ -0,0 +1,41 @@ +--TEST-- +Bug #36802 (crashes with with mysqli_set_charset()) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + class really_my_mysqli extends mysqli { + function __construct() + { + } + } + + require_once("connect.inc"); + $mysql = mysqli_init(); + + /* following operations should not work */ + if (method_exists($mysql, 'set_charset')) { + $x[0] = @$mysql->set_charset('utf8'); + } else { + $x[0] = NULL; + } + $x[1] = @$mysql->query("SELECT 'foo' FROM DUAL"); + + /* following operations should work */ + $x[2] = ($mysql->client_version > 0); + $x[3] = $mysql->errno; + $mysql->close(); + + var_dump($x); +?> +--EXPECT-- +array(4) { + [0]=> + NULL + [1]=> + NULL + [2]=> + bool(true) + [3]=> + int(0) +} diff --git a/ext/mysqli/tests/bug36949.phpt b/ext/mysqli/tests/bug36949.phpt new file mode 100644 index 0000000..2b3cc49 --- /dev/null +++ b/ext/mysqli/tests/bug36949.phpt @@ -0,0 +1,63 @@ +--TEST-- +Bug #36949 (invalid internal mysqli objects dtor) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +require_once("connect.inc"); +class A { + + private $mysqli; + + public function __construct() { + global $user, $host, $passwd, $db, $port, $socket; + $this->mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket); + $result = $this->mysqli->query("SELECT NOW() AS my_time FROM DUAL"); + $row = $result->fetch_object(); + echo $row->my_time."<br>\n"; + $result->close(); + } + + public function __destruct() { + $this->mysqli->close(); + } +} + +class B { + + private $mysqli; + + public function __construct() { + global $user, $host, $passwd, $db, $port, $socket; + $this->mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket); + $result = $this->mysqli->query("SELECT NOW() AS my_time FROM DUAL"); + $row = $result->fetch_object(); + echo $row->my_time."<br>\n"; + $result->close(); + } + + public function __destruct() { + $this->mysqli->close(); + } +} + +$A = new A(); +$B = new B(); +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS my_time")) + printf("[002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +%d%d%d%d-%d%d-%d%d %d%d:%d%d:%d%d<br> +%d%d%d%d-%d%d-%d%d %d%d:%d%d:%d%d<br> diff --git a/ext/mysqli/tests/bug37090.phpt b/ext/mysqli/tests/bug37090.phpt new file mode 100644 index 0000000..839081d --- /dev/null +++ b/ext/mysqli/tests/bug37090.phpt @@ -0,0 +1,48 @@ +--TEST-- +Bug #37090 (mysqli_set_charset return code) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +if (!function_exists('mysqli_set_charset')) { + die('skip mysqli_set_charset() not available'); +} +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1)) { + die("skip Functionality not available in unicode mode"); +} +?> +--FILE-- +<?php + require_once("connect.inc"); + + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + + $cs = array(); + $cs[] = $mysql->set_charset("latin1"); + $cs[] = $mysql->character_set_name(); + + $cs[] = $mysql->set_charset("utf8"); + $cs[] = $mysql->character_set_name(); + + $cs[] = $mysql->set_charset("notdefined"); + $cs[] = $mysql->character_set_name(); + + var_dump($cs); + print "done!"; +?> +--EXPECT-- +array(6) { + [0]=> + bool(true) + [1]=> + string(6) "latin1" + [2]=> + bool(true) + [3]=> + string(4) "utf8" + [4]=> + bool(false) + [5]=> + string(4) "utf8" +} +done! diff --git a/ext/mysqli/tests/bug38003.phpt b/ext/mysqli/tests/bug38003.phpt new file mode 100644 index 0000000..af71f85 --- /dev/null +++ b/ext/mysqli/tests/bug38003.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #38003 (in classes inherited from MySQLi it's possible to call private constructors from invalid context) +--SKIPIF-- +<?php if (!extension_loaded("mysqli")) print "skip"; ?> +--FILE-- +<?php + +class DB extends mysqli { + + private function __construct($hostname, $username, $password, $database) { + var_dump("DB::__construct() called"); + } +} + +$DB = new DB(); + +echo "Done\n"; +?> +--EXPECTF-- +Fatal error: Call to private DB::__construct() from invalid context in %s on line %d diff --git a/ext/mysqli/tests/bug38710.phpt b/ext/mysqli/tests/bug38710.phpt new file mode 100644 index 0000000..c3bb728 --- /dev/null +++ b/ext/mysqli/tests/bug38710.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #38710 (data leakage because of nonexisting boundary checking in statements) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +require_once("connect.inc"); + +$db = new my_mysqli($host, $user, $passwd, $db, $port, $socket); +$qry=$db->stmt_init(); +$qry->prepare("SELECT REPEAT('a',100000)"); +$qry->execute(); +$qry->bind_result($text); +$qry->fetch(); +if ($text !== str_repeat('a', ($IS_MYSQLND || mysqli_get_server_version($db) > 50110)? 100000:(mysqli_get_server_version($db)>=50000? 8193:8191))) { + var_dump(strlen($text)); +} +echo "Done"; +?> +--EXPECTF-- +Done
\ No newline at end of file diff --git a/ext/mysqli/tests/bug39457.phpt b/ext/mysqli/tests/bug39457.phpt new file mode 100644 index 0000000..ec9239b --- /dev/null +++ b/ext/mysqli/tests/bug39457.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #39457 (Multiple invoked OO connections never close) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $mysql = mysqli_init(); + $mysql->connect($host, $user, $passwd, $db, $port, $socket); + + $mysql->connect($host, $user, $passwd, $db, $port, $socket); + + $mysql->close(); + echo "OK\n"; +?> +--EXPECT-- +OK diff --git a/ext/mysqli/tests/bug42378.phpt b/ext/mysqli/tests/bug42378.phpt new file mode 100644 index 0000000..b3fd7ca --- /dev/null +++ b/ext/mysqli/tests/bug42378.phpt @@ -0,0 +1,197 @@ +--TEST-- +Bug #42378 (bind_result memory exhaustion, SELECT column, FORMAT(...) AS _format) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +memory_limit=83886080 +--FILE-- +<?php + require_once("connect.inc"); + + function create_table($link, $column, $min, $max, $engine, $offset) { + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { + printf("[%03d] Cannot drop table test, [%d] %s\n", + $offset, + mysqli_errno($link), mysqli_error($link)); + return array(); + } + print "$column\n"; + + $sql = sprintf("CREATE TABLE test(id INT AUTO_INCREMENT PRIMARY KEY, col1 %s) ENGINE=%s", + $column, $engine); + if (!mysqli_query($link, $sql)) { + printf("[%03d] Cannot create table test, [%d] %s\n", + $offset + 1, + mysqli_errno($link), mysqli_error($link)); + return array(); + } + + $values = array(); + for ($i = 1; $i <= 100; $i++) { + $col1 = mt_rand($min, $max); + $values[$i] = $col1; + $sql = sprintf("INSERT INTO test(id, col1) VALUES (%d, %f)", + $i, $col1); + if (!mysqli_query($link, $sql)) { + printf("[%03d] Cannot insert data, [%d] %s\n", + $offset + 2, + mysqli_errno($link), mysqli_error($link)); + return array(); + } + } + + return $values; + } + + function test_format($link, $format, $from, $order_by, $expected, $offset) { + + if (!$stmt = mysqli_stmt_init($link)) { + printf("[%03d] Cannot create PS, [%d] %s\n", + $offset, + mysqli_errno($link), mysqli_error($link)); + return false; + } + print "$format\n"; + + if ($order_by) + $sql = sprintf('SELECT %s AS _format FROM %s ORDER BY %s', $format, $from, $order_by); + else + $sql = sprintf('SELECT %s AS _format FROM %s', $format, $from); + + if (!mysqli_stmt_prepare($stmt, $sql)) { + printf("[%03d] Cannot prepare PS, [%d] %s\n", + $offset + 1, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if (!mysqli_stmt_execute($stmt)) { + printf("[%03d] Cannot execute PS, [%d] %s\n", + $offset + 2, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if (!mysqli_stmt_store_result($stmt)) { + printf("[%03d] Cannot store result set, [%d] %s\n", + $offset + 3, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if (!is_array($expected)) { + + $result = null; + if (!mysqli_stmt_bind_result($stmt, $result)) { + printf("[%03d] Cannot bind result, [%d] %s\n", + $offset + 4, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if (!mysqli_stmt_fetch($stmt)) { + printf("[%03d] Cannot fetch result,, [%d] %s\n", + $offset + 5, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if ($result !== $expected) { + printf("[%03d] Expecting %s/%s got %s/%s with %s - %s.\n", + $offset + 6, + gettype($expected), $expected, + gettype($result), $result, + $format, $sql); + } + + } else { + + $order_by_col = $result = null; + if (!is_null($order_by)) { + if (!mysqli_stmt_bind_result($stmt, $order_by_col, $result)) { + printf("[%03d] Cannot bind result, [%d] %s\n", + $offset + 7, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + } else { + if (!mysqli_stmt_bind_result($stmt, $result)) { + printf("[%03d] Cannot bind result, [%d] %s\n", + $offset + 7, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + } + + if (!empty($expected)) + reset($expected); + while ((list($k, $v) = each($expected)) && mysqli_stmt_fetch($stmt)) { + if (!empty($expected)) { + if ($result !== $v) { + printf("[%03d] Row %d - expecting %s/%s got %s/%s [%s] with %s - %s.\n", + $offset + 8, + $k, + gettype($v), $v, + gettype($result), $result, + $order_by_col, + $format, $sql); + } + } + } + + } + + mysqli_stmt_free_result($stmt); + mysqli_stmt_close($stmt); + + return true; + } + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect - [%d] %s\n", + mysqli_connect_errno(), + mysqli_connect_error()); + + /* create new table and select from it */ + $expected = create_table($link, 'FLOAT', -10000, 10000, $engine, 90); + foreach ($expected as $k => $v) + $expected[$k] = number_format(round($v), 0, '.', ','); + test_format($link, 'FORMAT(col1, 0)', 'test', NULL, array(), 100); + + $expected = create_table($link, 'FLOAT', -10000, 10000, $engine, 110); + foreach ($expected as $k => $v) + $expected[$k] = number_format(round($v), 0, '.', ','); + test_format($link, 'id AS order_by_col, FORMAT(col1, 0)', 'test', 'id', $expected, 120); + + $expected = create_table($link, 'FLOAT UNSIGNED', 0, 10000, $engine, 130); + foreach ($expected as $k => $v) + $expected[$k] = number_format(round($v), 0, '.', ','); + test_format($link, 'id AS order_by_col, FORMAT(col1, 0)', 'test', 'id', $expected, 140); + + $expected = create_table($link, 'DECIMAL(5,0)', -1000, 1000, $engine, 150); + foreach ($expected as $k => $v) + $expected[$k] = number_format(round($v), 0, '.', ','); + test_format($link, 'id AS order_by_col, FORMAT(col1, 0)', 'test', 'id', $expected, 160); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +FLOAT +FORMAT(col1, 0) +FLOAT +id AS order_by_col, FORMAT(col1, 0) +FLOAT UNSIGNED +id AS order_by_col, FORMAT(col1, 0) +DECIMAL(5,0) +id AS order_by_col, FORMAT(col1, 0) +done! diff --git a/ext/mysqli/tests/bug42548.phpt b/ext/mysqli/tests/bug42548.phpt new file mode 100644 index 0000000..ef0c831 --- /dev/null +++ b/ext/mysqli/tests/bug42548.phpt @@ -0,0 +1,75 @@ +--TEST-- +Bug #42548 PROCEDURE xxx can't return a result set in the given context (works in 5.2.3!!) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf('skip Cannot connect to MySQL, [%d] %s.', mysqli_connect_errno(), mysqli_connect_error())); +} +if (mysqli_get_server_version($link) <= 50000) { + die(sprintf('skip Needs MySQL 5.0+, found version %d.', mysqli_get_server_version($link))); +} +?> +--FILE-- +<?php +require_once('connect.inc'); + +$mysqli = mysqli_init(); +$mysqli->real_connect($host, $user, $passwd, $db, $port, $socket); +if (mysqli_connect_errno()) { + printf("Connect failed: %s\n", mysqli_connect_error()); + exit(); +} + +$mysqli->query("DROP PROCEDURE IF EXISTS p1") or die($mysqli->error); +$mysqli->query("CREATE PROCEDURE p1() BEGIN SELECT 23; SELECT 42; END") or die($mysqli->error); + +if ($mysqli->multi_query("CALL p1();")) +{ + do + { + if ($objResult = $mysqli->store_result()) { + while ($row = $objResult->fetch_assoc()) { + print_r($row); + } + $objResult->close(); + if ($mysqli->more_results()) { + print "----- next result -----------\n"; + } + } else { + print "no results found\n"; + } + } while ($mysqli->more_results() && $mysqli->next_result()); +} else { + print $mysqli->error; +} + +$mysqli->query("DROP PROCEDURE p1") or die($mysqli->error); +$mysqli->close(); +print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +mysqli_query($link, "DROP PROCEDURE IF EXISTS p1"); + +mysqli_close($link); +?> +--EXPECT-- +Array +( + [23] => 23 +) +----- next result ----------- +Array +( + [42] => 42 +) +----- next result ----------- +no results found +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/bug44897.phpt b/ext/mysqli/tests/bug44897.phpt new file mode 100644 index 0000000..84c245d --- /dev/null +++ b/ext/mysqli/tests/bug44897.phpt @@ -0,0 +1,89 @@ +--TEST-- +Bug #44879 (failed to prepare statement) +--SKIPIF-- +<?php +require_once('skipif.inc'); + +if (!stristr(mysqli_get_client_info(), 'mysqlnd')) + die("skip: only available in mysqlnd"); + +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf('skip Cannot connect to MySQL, [%d] %s.', mysqli_connect_errno(), mysqli_connect_error())); +} +if (mysqli_get_server_version($link) <= 50000) { + die(sprintf('skip Needs MySQL 5.0+, found version %d.', mysqli_get_server_version($link))); +} +?> +--FILE-- +<?php + require_once("table.inc"); + + if (!$link->query('DROP PROCEDURE IF EXISTS p')) + printf("[001] [%d] %s\n", $link->errno, $link->error); + + if (!$link->query('CREATE PROCEDURE p(IN new_id INT, IN new_label CHAR(1)) BEGIN INSERT INTO test(id, label) VALUES (new_id, new_label); SELECT new_label; END;')) + printf("[002] [%d] %s\n", $link->errno, $link->error); + + $new_id = 100; + $new_label = 'z'; + + if (!$stmt = $link->prepare('CALL p(?, ?)')) + printf("[003] [%d] %s\n", $link->errno, $link->error); + + if (!$stmt->bind_param('is', $new_id, $new_label) || !$stmt->execute()) + printf("[004] [%d] %s\n", $stmt->errno, $stmt->error); + + $out_new_label = null; + if (!$stmt->bind_result($out_new_label) || !$stmt->fetch()) + printf("[005] [%d] %s\n", $stmt->errno, $stmt->error); + + if ($out_new_label != $new_label) + printf("[006] IN value and returned value differ. Expecting %s/%s got %s/%s\n", + $new_label, gettype($new_label), $out_new_label, gettype($out_new_label)); + + $stmt->close(); + + $stmt2 = $link->prepare('SELECT label FROM test WHERE id = ?'); + if (!is_object($stmt2)) { + + printf("[007] Failed to create new statement object, [%d] %s\n", + $link->errno, $link->error); + + } else { + + if (!$stmt2->bind_param("i", $new_id) || !$stmt2->execute()) + printf("[008] [%d] %s\n", $stmt2->errno, $stmt2->error); + + $out_new_label = null; + if (!$stmt2->bind_result($out_new_label) || !$stmt2->fetch()) + printf("[009] [%d] %s\n", $stmt2->errno, $stmt2->error); + + if ($out_new_label != $new_label) + printf("[010] IN value and returned value differ. Expecting %s/%s got %s/%s\n", + $new_label, gettype($new_label), $out_new_label, gettype($out_new_label)); + + } + + $link->close(); + + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_query($link, "DROP PROCEDURE IF EXISTS p"); + +mysqli_close($link); +?> + +--EXPECTF-- +done! diff --git a/ext/mysqli/tests/bug45019.phpt b/ext/mysqli/tests/bug45019.phpt new file mode 100644 index 0000000..b8828c7 --- /dev/null +++ b/ext/mysqli/tests/bug45019.phpt @@ -0,0 +1,59 @@ +--TEST-- +Bug #45019 (Segmentation fault with SELECT ? and UNION) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + require_once("table.inc"); + + // Regular (non-prepared) queries + print "Using CAST('somestring' AS CHAR)...\n"; + if (!($res = $link->query("SELECT CAST('one' AS CHAR) AS column1 UNION SELECT CAST('three' AS CHAR) UNION SELECT CAST('two' AS CHAR)"))) + printf("[001] [%d] %s\n", $link->errno, $link->error); + + $data = array(); + while ($row = $res->fetch_assoc()) { + $data[] = $row['column1']; + var_dump($row['column1']); + } + $res->free(); + + // Prepared Statements + if (!($stmt = $link->prepare("SELECT CAST('one' AS CHAR) AS column1 UNION SELECT CAST('three' AS CHAR) UNION SELECT CAST('two' AS CHAR)"))) + printf("[002] [%d] %s\n", $link->errno, $link->error); + + $column1 = null; + if (!$stmt->bind_result($column1) || !$stmt->execute()) + printf("[003] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + while ($stmt->fetch()) { + /* NOTE: libmysql - http://bugs.mysql.com/bug.php?id=47483 */ + if ($data[$index] != $column1) { + if ($IS_MYSQLND || $index != 1) { + printf("[004] Row %d, expecting %s/%s got %s/%s\n", + $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + } else { + if ($column1 != "thre") + printf("[005] Got '%s'. Please check if http://bugs.mysql.com/bug.php?id=47483 has been fixed and adapt tests bug45019.phpt/mysqli_ps_select_union.phpt", $column1); + } + } + $index++; + } + $stmt->close(); + + $link->close(); + + print "done!"; +?> +--EXPECTF-- +Using CAST('somestring' AS CHAR)... +%unicode|string%(3) "one" +%unicode|string%(5) "three" +%unicode|string%(3) "two" +done! diff --git a/ext/mysqli/tests/bug45289.phpt b/ext/mysqli/tests/bug45289.phpt new file mode 100644 index 0000000..2ddacf4 --- /dev/null +++ b/ext/mysqli/tests/bug45289.phpt @@ -0,0 +1,40 @@ +--TEST-- +Bug #45289 (Bogus store_result on PS) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require('table.inc'); + + $link->close(); + + $link = mysqli_init(); + if (!($link->real_connect($host, $user, $passwd, $db, $port, $socket))) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + $id = 1; + if (!($stmt = $link->prepare('SELECT id, label FROM test WHERE id=? LIMIT 1'))) + printf("[002] [%d] %s\n", $link->errno, $link->error); + + if (!$stmt->bind_param('i', $id) || !$stmt->execute()) + printf("[003] [%d] %s\n", $stmt->errno, $stmt->error); + + if ($res = $link->store_result()) { + if ($IS_MYSQLND) + printf("[004] Can store result!\n"); + else + printf("[004] [007] http://bugs.mysql.com/bug.php?id=47485\n"); + } else { + printf("[004] [%d] %s\n", $link->errno, $link->error); + } +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +[004] [%s diff --git a/ext/mysqli/tests/bug46109.phpt b/ext/mysqli/tests/bug46109.phpt new file mode 100644 index 0000000..c377171 --- /dev/null +++ b/ext/mysqli/tests/bug46109.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #46109 (MySQLi::init - Memory leaks) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $mysqli = new mysqli(); + $mysqli->init(); + $mysqli->init(); + echo "done"; +?> +--EXPECTF-- +done diff --git a/ext/mysqli/tests/bug46614.phpt b/ext/mysqli/tests/bug46614.phpt new file mode 100644 index 0000000..9e78222 --- /dev/null +++ b/ext/mysqli/tests/bug46614.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #46614 (Extended MySQLi class gives incorrect empty() result) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +if (!defined("MYSQLI_ASYNC")) { + die("skip mysqlnd only"); +} +?> +--FILE-- +<?php +class MySQL_Ext extends mysqli{ + protected $fooData = array(); + + public function isEmpty() + { + $this->extData[] = 'Bar'; + return empty($this->extData); + } +} + +include ("connect.inc"); +$MySQL_Ext = new MySQL_Ext($host, $user, $passwd, $db, $port, $socket); + +$isEmpty = $MySQL_Ext->isEmpty(); +var_dump($isEmpty); +?> +--EXPECT-- +bool(false) diff --git a/ext/mysqli/tests/bug47050.phpt b/ext/mysqli/tests/bug47050.phpt new file mode 100644 index 0000000..0358802 --- /dev/null +++ b/ext/mysqli/tests/bug47050.phpt @@ -0,0 +1,34 @@ +--TEST-- +Bug #47050 (mysqli_poll() modifies improper variables) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +if (!defined("MYSQLI_ASYNC")) { + die("skip mysqlnd only"); +} +?> +--FILE-- +<?php + include ("connect.inc"); + + $link1 = my_mysqli_connect($host, $user, $passwd, null, $port, $socket); + mysqli_select_db($link1, $db); + + $link1->query("SELECT 'test'", MYSQLI_ASYNC); + $all_links = array($link1); + $links = $errors = $reject = $all_links; + mysqli_poll($links, $errors, $reject, 1); + + echo "links: ", sizeof($links), "\n"; + echo "errors: ", sizeof($errors), "\n"; + echo "reject: ", sizeof($reject), "\n"; + echo "all_links: ", sizeof($all_links), "\n"; + + $link1->close(); +?> +--EXPECT-- +links: 1 +errors: 0 +reject: 0 +all_links: 1 diff --git a/ext/mysqli/tests/bug48909.phpt b/ext/mysqli/tests/bug48909.phpt new file mode 100644 index 0000000..7690139 --- /dev/null +++ b/ext/mysqli/tests/bug48909.phpt @@ -0,0 +1,46 @@ +--TEST-- +Bug #48909 (Segmentation fault in mysqli_stmt_execute) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + if (!($link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!$link->query("DROP TABLE IF EXISTS test") || + !$link->query(sprintf("CREATE TABLE test(id INT, label varchar(255)) ENGINE = %s", $engine))) + printf("[002] [%d] %s\n", $link->errno, $link->error); + + if (!$stmt = $link->prepare("INSERT INTO test(id, label) VALUES (?, ?)")) + printf("[003] [%d] %s\n", $link->errno, $link->error); + + if (!$stmt->bind_param("bb",$bvar, $bvar)) + printf("[004] [%d] %s\n", $stmt->errno, $stmt->error); + + if (!$stmt->execute()) { + if ($stmt->errno != 1366) { + /* + $bvar is null, b is for BLOB - any error like this should be OK: + 1366 - Incorrect integer value: '' for column 'id' at row 1 + */ + printf("[005] [%d] %s\n", $stmt->errno, $stmt->error); + } + } + + $stmt->close(); + $link->close(); + + echo "done"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done
\ No newline at end of file diff --git a/ext/mysqli/tests/bug49027.phpt b/ext/mysqli/tests/bug49027.phpt new file mode 100644 index 0000000..35434bd --- /dev/null +++ b/ext/mysqli/tests/bug49027.phpt @@ -0,0 +1,62 @@ +--TEST-- +Bug #49027 (mysqli_options() doesn't work when using mysqlnd) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + include ("connect.inc"); + + $link = mysqli_init(); + if (!mysqli_options($link, MYSQLI_INIT_COMMAND, "SELECT 1")) { + printf("[001] Cannot set INIT_COMMAND\n"); + } + + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) { + printf("[002] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + } + + var_dump($link->query("SELECT 42")->fetch_row()); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test") || + !mysqli_query($link, sprintf("CREATE TABLE test(id INT) ENGINE=%s", $engine))) { + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + mysqli_close($link); + + $link = mysqli_init(); + if (!mysqli_options($link, MYSQLI_INIT_COMMAND, "INSERT INTO test(id) VALUES(1)")) { + printf("[004] Cannot set INIT_COMMAND\n"); + } + + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) { + printf("[005] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + } + + if (!$res = mysqli_query($link, "SELECT id FROM test")) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + var_dump(mysqli_fetch_assoc($res)); + + mysqli_free_result($res); + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +array(1) { + [0]=> + %unicode|string%(2) "42" +} +array(1) { + [%u|b%"id"]=> + %unicode|string%(1) "1" +} +done! diff --git a/ext/mysqli/tests/bug49442.phpt b/ext/mysqli/tests/bug49442.phpt new file mode 100644 index 0000000..5426745 --- /dev/null +++ b/ext/mysqli/tests/bug49442.phpt @@ -0,0 +1,130 @@ +--TEST-- +Bug #49422 (mysqlnd: mysqli_real_connect() and LOAD DATA INFILE crash) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); + +$link = mysqli_init(); +if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) { + die(sprintf("skip Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error())); +} + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--INI-- +mysqli.allow_local_infile=1 +mysqli.allow_persistent=1 +mysqli.max_persistent=1 +--FILE-- +<?php + include ("connect.inc"); + + $link = mysqli_init(); + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) { + printf("[001] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + } + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { + printf("[002] Failed to drop old test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + if (!mysqli_query($link, 'CREATE TABLE test(id INT, label CHAR(1), PRIMARY KEY(id)) ENGINE=' . $engine)) { + printf("[003] Failed to create test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + include("local_infile_tools.inc"); + $file = create_standard_csv(4); + + if (!@mysqli_query($link, sprintf("LOAD DATA LOCAL INFILE '%s' + INTO TABLE test + FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '\'' + LINES TERMINATED BY '\n'", + mysqli_real_escape_string($link, $file)))) { + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id")) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $rows = array(); + while ($row = mysqli_fetch_assoc($res)) { + var_dump($row); + $rows[] = $row; + } + + mysqli_free_result($res); + + mysqli_query($link, "DELETE FROM test"); + mysqli_close($link); + + if ($IS_MYSQLND) { + /* + mysqlnd makes a connection created through mysql_init()/mysqli_real_connect() always a 'persistent' one. + At this point 'persistent' is not to be confused with what a user calls a 'persistent' - in this case + 'persistent' means that mysqlnd uses malloc() instead of emalloc(). nothing else. ext/mysqli will + not consider it as a 'persistent' connection in a user sense, ext/mysqli will not appy max_persistent etc. + Its only about malloc() vs. emalloc(). + + However, the bug is about malloc() and efree(). You can make make mysqlnd use malloc() by either using + pconnect or mysql_init() - so we should test pconnect as well.. + */ + $host = 'p:' . $host; + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[007] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + } + + /* bug happened during query processing */ + if (!@mysqli_query($link, sprintf("LOAD DATA LOCAL INFILE '%s' + INTO TABLE test + FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '\'' + LINES TERMINATED BY '\n'", + mysqli_real_escape_string($link, $file)))) { + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + /* we survived? that's good enough... */ + + if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id")) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $i = 0; + while ($row = mysqli_fetch_assoc($res)) { + if (($row['id'] != $rows[$i]['id']) || ($row['label'] != $rows[$i]['label'])) { + printf("[010] Wrong values, check manually!\n"); + } + $i++; + } + mysqli_close($link); + } + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +array(2) { + [%u|b%"id"]=> + %unicode|string%(2) "97" + [%u|b%"label"]=> + %unicode|string%(1) "x" +} +array(2) { + [%u|b%"id"]=> + %unicode|string%(2) "98" + [%u|b%"label"]=> + %unicode|string%(1) "y" +} +array(2) { + [%u|b%"id"]=> + %unicode|string%(2) "99" + [%u|b%"label"]=> + %unicode|string%(1) "z" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/bug50772.phpt b/ext/mysqli/tests/bug50772.phpt new file mode 100644 index 0000000..eecef84 --- /dev/null +++ b/ext/mysqli/tests/bug50772.phpt @@ -0,0 +1,36 @@ +--TEST-- +Bug #50772 (mysqli constructor without parameters does not return a working mysqli object) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + include "connect.inc"; + $db1 = new mysqli(); + + // These calls fail + $db1->options(MYSQLI_OPT_CONNECT_TIMEOUT, 3); + my_mysqli_real_connect($db1, $host, $user, $passwd, $db, $port, $socket); + if(mysqli_connect_error()) { + echo "error 1\n"; + } else { + echo "ok 1\n"; + } + + $db2 = mysqli_init(); + + $db2->options(MYSQLI_OPT_CONNECT_TIMEOUT, 3); + my_mysqli_real_connect($db2, $host, $user, $passwd, $db, $port, $socket); + if(mysqli_connect_error()) { + echo "error 2\n"; + } else { + echo "ok 2\n"; + } + echo "done\n"; +?> +--EXPECTF-- +ok 1 +ok 2 +done
\ No newline at end of file diff --git a/ext/mysqli/tests/bug51605.phpt b/ext/mysqli/tests/bug51605.phpt new file mode 100644 index 0000000..02328a5 --- /dev/null +++ b/ext/mysqli/tests/bug51605.phpt @@ -0,0 +1,44 @@ +--TEST-- +Bug #51605 Mysqli - zombie links +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +mysqli.max_links = 1 +mysqli.allow_persistent = Off +mysqli.max_persistent = 0 +mysqli.reconnect = Off +--FILE-- +<?php + include ("connect.inc"); + + $link = mysqli_init(); + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) { + printf("[002] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + } + mysqli_close($link); + echo "closed once\n"; + + $link = mysqli_init(); + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) { + printf("[002] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + } + mysqli_close($link); + echo "closed twice\n"; + + $link = mysqli_init(); + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) { + printf("[003] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + } + mysqli_close($link); + echo "closed for third time\n"; + + print "done!"; +?> +--EXPECTF-- +closed once +closed twice +closed for third time +done! diff --git a/ext/mysqli/tests/bug51647.phpt b/ext/mysqli/tests/bug51647.phpt new file mode 100644 index 0000000..78540f1 --- /dev/null +++ b/ext/mysqli/tests/bug51647.phpt @@ -0,0 +1,81 @@ +--TEST-- +Bug #51647 (Certificate file without private key (pk in another file) doesn't work) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +require_once("connect.inc"); + +if ($IS_MYSQLND && !extension_loaded("openssl")) + die("skip PHP streams lack support for SSL. mysqli is compiled to use mysqlnd which uses PHP streams in turn."); + +if (!($link = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))) + die(sprintf("skip Connect failed, [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); + +$row = NULL; +if ($res = $link->query('SHOW VARIABLES LIKE "have_ssl"')) { + $row = $res->fetch_row(); +} else { + if ($link->errno == 1064 && ($res = $link->query("SHOW VARIABLES"))) { + while ($row = $res->fetch_row()) + if ($row[0] == 'have_ssl') + break; + } else { + die(sprintf("skip Failed to test for MySQL SSL support, [%d] %s", $link->errno, $link->error)); + } +} + + +if (empty($row)) + die(sprintf("skip Failed to test for MySQL SSL support, [%d] %s", $link->errno, $link->error)); + +if (($row[1] == 'NO') || ($row[1] == 'DISABLED')) + die(sprintf("skip MySQL has no SSL support, [%d] %s", $link->errno, $link->error)); + +$link->close(); +?> +--FILE-- +<?php + include ("connect.inc"); + + if (!is_object($link = mysqli_init())) + printf("[001] Cannot create link\n"); + + $path_to_pems = !$IS_MYSQLND? "ext/mysqli/tests/" : ""; + if (!$link->ssl_set("{$path_to_pems}client-key.pem", "{$path_to_pems}client-cert.pem", "{$path_to_pems}cacert.pem","","")) + printf("[002] [%d] %s\n", $link->errno, $link->error); + + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) { + printf("[003] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + } + + if (!$res = $link->query('SHOW STATUS like "Ssl_cipher"')) { + if (1064 == $link->errno) { + /* ERROR 1064 (42000): You have an error in your SQL syntax; = sql strict mode */ + if ($res = $link->query("SHOW STATUS")) { + while ($row = $res->fetch_assoc()) + if ($row['Variable_name'] == 'Ssl_cipher') + break; + } else { + printf("[005] [%d] %s\n", $link->errno, $link->error); + } + } else { + printf("[004] [%d] %s\n", $link->errno, $link->error); + } + } else { + if (!$row = $res->fetch_assoc()) + printf("[006] [%d] %s\n", $link->errno, $link->error); + } + + var_dump($row); + + print "done!"; +?> +--EXPECTF-- +array(2) { + ["Variable_name"]=> + string(10) "Ssl_cipher" + ["Value"]=> + string(%d) "%S" +} +done! diff --git a/ext/mysqli/tests/bug52082.phpt b/ext/mysqli/tests/bug52082.phpt new file mode 100644 index 0000000..8e3bd59 --- /dev/null +++ b/ext/mysqli/tests/bug52082.phpt @@ -0,0 +1,50 @@ +--TEST-- +Bug #52082 (character_set_client & character_set_connection reset after mysqli_change_user) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + $link = mysqli_init(); + $link->options(MYSQLI_SET_CHARSET_NAME, "latin2"); + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) { + die("can't connect"); + } + var_dump($link->query("show variables like 'character_set_client'")->fetch_row()); + var_dump($link->query("show variables like 'character_set_connection'")->fetch_row()); + $link->change_user($user, $passwd, $db); + var_dump($link->query("show variables like 'character_set_client'")->fetch_row()); + var_dump($link->query("show variables like 'character_set_connection'")->fetch_row()); + + print "done!"; +?> +--EXPECTF-- +array(2) { + [0]=> + string(20) "character_set_client" + [1]=> + string(6) "latin2" +} +array(2) { + [0]=> + string(24) "character_set_connection" + [1]=> + string(6) "latin2" +} +array(2) { + [0]=> + string(20) "character_set_client" + [1]=> + string(6) "latin2" +} +array(2) { + [0]=> + string(24) "character_set_connection" + [1]=> + string(6) "latin2" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/bug52891.phpt b/ext/mysqli/tests/bug52891.phpt new file mode 100644 index 0000000..463efd6 --- /dev/null +++ b/ext/mysqli/tests/bug52891.phpt @@ -0,0 +1,160 @@ +--TEST-- +Bug #52891 (Wrong data inserted with mysqli/mysqlnd when using bind_param,value > LONG_MAX) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +if (!$IS_MYSQLND) { + die("skip: test applies only to mysqlnd"); +} +?> +--FILE-- +<?php + require_once("connect.inc"); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[001] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + } + + if (!$link->query("DROP TABLE IF EXISTS tuint") || + !$link->query("DROP TABLE IF EXISTS tsint")) { + printf("[002] [%d] %s\n", $link->errno, $link->error); + } + + if (!$link->query("CREATE TABLE tuint(a BIGINT UNSIGNED) ENGINE=" . $engine) || + !$link->query("CREATE TABLE tsint(a BIGINT) ENGINE=" . $engine)) { + printf("[003] [%d] %s\n", $link->errno, $link->error); + } + + + if (!$stmt1 = $link->prepare("INSERT INTO tuint VALUES(?)")) + printf("[004] [%d] %s\n", $link->errno, $link->error); + + if (!$stmt2 = $link->prepare("INSERT INTO tsint VALUES(?)")) + printf("[005] [%d] %s\n", $link->errno, $link->error); + + $param = 42; + + if (!$stmt1->bind_param("i", $param)) + printf("[006] [%d] %s\n", $stmt1->errno, $stmt1->error); + + if (!$stmt2->bind_param("i", $param)) + printf("[007] [%d] %s\n", $stmt2->errno, $stmt2->error); + + /* first insert normal value to force initial send of types */ + if (!$stmt1->execute()) + printf("[008] [%d] %s\n", $stmt1->errno, $stmt1->error); + + if (!$stmt2->execute()) + printf("[009] [%d] %s\n", $stmt2->errno, $stmt2->error); + + /* now try values that don't fit in long, on 32bit, new types should be sent or 0 will be inserted */ + $param = -4294967297; + if (!$stmt2->execute()) + printf("[010] [%d] %s\n", $stmt2->errno, $stmt2->error); + + /* again normal value */ + $param = 43; + + if (!$stmt1->execute()) + printf("[011] [%d] %s\n", $stmt1->errno, $stmt1->error); + + if (!$stmt2->execute()) + printf("[012] [%d] %s\n", $stmt2->errno, $stmt2->error); + + /* again conversion */ + $param = -4294967295; + if (!$stmt2->execute()) + printf("[013] [%d] %s\n", $stmt2->errno, $stmt2->error); + + $param = 4294967295; + if (!$stmt1->execute()) + printf("[014] [%d] %s\n", $stmt1->errno, $stmt1->error); + + if (!$stmt2->execute()) + printf("[015] [%d] %s\n", $stmt2->errno, $stmt2->error); + + $param = 4294967297; + if (!$stmt1->execute()) + printf("[016] [%d] %s\n", $stmt1->errno, $stmt1->error); + + if (!$stmt2->execute()) + printf("[017] [%d] %s\n", $stmt2->errno, $stmt2->error); + + $result = $link->query("SELECT * FROM tsint ORDER BY a ASC"); + $result2 = $link->query("SELECT * FROM tuint ORDER BY a ASC"); + + echo "tsint:\n"; + while ($row = $result->fetch_assoc()) { + var_dump($row); + } + echo "tuint:\n"; + while ($row = $result2->fetch_assoc()) { + var_dump($row); + } + + echo "done"; +?> +--CLEAN-- +<?php +require_once('connect.inc'); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[clean] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); +} + +if (!mysqli_query($link, 'DROP TABLE IF EXISTS tuint')) { + printf("[clean] Failed to drop old test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); +} + +if (!mysqli_query($link, 'DROP TABLE IF EXISTS tsint')) { + printf("[clean] Failed to drop old test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); +} + +mysqli_close($link); +?> +--EXPECTF-- +tsint: +array(1) { + ["a"]=> + string(11) "-4294967297" +} +array(1) { + ["a"]=> + string(11) "-4294967295" +} +array(1) { + ["a"]=> + string(2) "42" +} +array(1) { + ["a"]=> + string(2) "43" +} +array(1) { + ["a"]=> + string(10) "4294967295" +} +array(1) { + ["a"]=> + string(10) "4294967297" +} +tuint: +array(1) { + ["a"]=> + string(2) "42" +} +array(1) { + ["a"]=> + string(2) "43" +} +array(1) { + ["a"]=> + string(10) "4294967295" +} +array(1) { + ["a"]=> + string(10) "4294967297" +} +done
\ No newline at end of file diff --git a/ext/mysqli/tests/bug53503.phpt b/ext/mysqli/tests/bug53503.phpt new file mode 100644 index 0000000..339fce7 --- /dev/null +++ b/ext/mysqli/tests/bug53503.phpt @@ -0,0 +1,66 @@ +--TEST--
+Bug #53503 (mysqli::query returns false after successful LOAD DATA query)
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifconnectfailure.inc');
+
+if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
+ die("skip Cannot connect to MySQL");
+
+include_once("local_infile_tools.inc");
+if ($msg = check_local_infile_support($link, $engine))
+ die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
+
+mysqli_close($link);
+
+?>
+--FILE--
+<?php
+ require_once("connect.inc");
+
+ if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
+ printf("[001] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
+ }
+
+ if (!$link->query("DROP TABLE IF EXISTS test")) {
+ printf("[002] [%d] %s\n", $link->errno, $link->error);
+ }
+
+ if (!$link->query("CREATE TABLE test (dump1 INT UNSIGNED NOT NULL PRIMARY KEY) ENGINE=" . $engine)) {
+ printf("[003] [%d] %s\n", $link->errno, $link->error);
+ }
+
+ if (FALSE == file_put_contents('bug53503.data', "1\n2\n3\n"))
+ printf("[004] Failed to create CVS file\n");
+
+ if (!$link->query("SELECT 1 FROM DUAL"))
+ printf("[005] [%d] %s\n", $link->errno, $link->error);
+
+ if (!$link->query("LOAD DATA LOCAL INFILE 'bug53503.data' INTO TABLE test")) {
+ printf("[006] [%d] %s\n", $link->errno, $link->error);
+ echo "bug";
+ } else {
+ echo "done";
+ }
+ $link->close();
+?>
+--CLEAN--
+<?php
+require_once('connect.inc');
+
+if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
+ printf("[clean] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+ $host, $user, $db, $port, $socket);
+}
+
+if (!$link->query($link, 'DROP TABLE IF EXISTS test')) {
+ printf("[clean] Failed to drop old test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+}
+
+$link->close();
+
+unlink('bug53503.data');
+?>
+--EXPECT--
+done
\ No newline at end of file diff --git a/ext/mysqli/tests/bug54221.phpt b/ext/mysqli/tests/bug54221.phpt new file mode 100644 index 0000000..78c9a2c --- /dev/null +++ b/ext/mysqli/tests/bug54221.phpt @@ -0,0 +1,47 @@ +--TEST-- +Bug #54221 mysqli::get_warnings segfault when used in multi queries +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +mysqli.max_links = 1 +mysqli.allow_persistent = Off +mysqli.max_persistent = 0 +mysqli.reconnect = Off +--FILE-- +<?php + include ("connect.inc"); + + $link = mysqli_init(); + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) { + printf("[002] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + } + + $create = "CREATE TEMPORARY TABLE IF NOT EXISTS t54221(a int)"; + + $query = "$create;$create;$create;"; + if ($link->multi_query($query)) { + do { + $sth = $link->store_result(); + + if ($link->warning_count) { + $warnings = $link->get_warnings(); + if ($warnings) { + do { + echo "Warning: ".$warnings->errno.": ".$warnings->message."\n"; + } while ($warnings->next()); + } + } + } while ($link->more_results() && $link->next_result()); + } + + mysqli_close($link); + + print "done!"; +?> +--EXPECTF-- +Warning: : +Warning: 1050: Table 't54221' already exists +done! diff --git a/ext/mysqli/tests/bug54674.phpt b/ext/mysqli/tests/bug54674.phpt new file mode 100644 index 0000000..efc6730 --- /dev/null +++ b/ext/mysqli/tests/bug54674.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #54674 mysqlnd valid_sjis_(head|tail) is using invalid operator and range. +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +mysqli.max_links = 1 +mysqli.allow_persistent = Off +mysqli.max_persistent = 0 +mysqli.reconnect = Off +--FILE-- +<?php + include ("connect.inc"); + + $link = mysqli_init(); + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) { + printf("[002] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + } + + $japanese_so = pack('H4', '835c'); + $link->set_charset('sjis'); + var_dump($link->real_escape_string($japanese_so) === $japanese_so); + mysqli_close($link); + + print "done!"; +?> +--EXPECTF-- +bool(true) +done! diff --git a/ext/mysqli/tests/bug55283.phpt b/ext/mysqli/tests/bug55283.phpt new file mode 100644 index 0000000..d03daae --- /dev/null +++ b/ext/mysqli/tests/bug55283.phpt @@ -0,0 +1,75 @@ +--TEST-- +Bug #55283 (SSL options set by mysqli_ssl_set ignored for MySQLi persistent connections) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +require_once("connect.inc"); + +if ($IS_MYSQLND && !extension_loaded("openssl")) + die("skip PHP streams lack support for SSL. mysqli is compiled to use mysqlnd which uses PHP streams in turn."); + +if (!($link = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))) + die(sprintf("skip Connect failed, [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); + +$row = NULL; +if ($res = $link->query('SHOW VARIABLES LIKE "have_ssl"')) { + $row = $res->fetch_row(); +} else { + if ($link->errno == 1064 && ($res = $link->query("SHOW VARIABLES"))) { + while ($row = $res->fetch_row()) + if ($row[0] == 'have_ssl') + break; + } else { + die(sprintf("skip Failed to test for MySQL SSL support, [%d] %s", $link->errno, $link->error)); + } +} + + +if (empty($row)) + die(sprintf("skip Failed to test for MySQL SSL support, [%d] %s", $link->errno, $link->error)); + +if (($row[1] == 'NO') || ($row[1] == 'DISABLED')) + die(sprintf("skip MySQL has no SSL support, [%d] %s", $link->errno, $link->error)); + +$link->close(); +?> +--FILE-- +<?php + include "connect.inc"; + $db1 = new mysqli(); + + + $flags = MYSQLI_CLIENT_SSL; + + $link = mysqli_init(); + mysqli_ssl_set($link, null, null, null, null, "RC4-MD5"); + if (my_mysqli_real_connect($link, 'p:' . $host, $user, $passwd, $db, $port, null, $flags)) { + $r = $link->query("SHOW STATUS LIKE 'Ssl_cipher'"); + var_dump($r->fetch_row()); + } + + /* non-persistent connection */ + $link2 = mysqli_init(); + mysqli_ssl_set($link2, null, null, null, null, "RC4-MD5"); + if (my_mysqli_real_connect($link2, $host, $user, $passwd, $db, $port, null, $flags)) { + $r2 = $link2->query("SHOW STATUS LIKE 'Ssl_cipher'"); + var_dump($r2->fetch_row()); + } + + echo "done\n"; +?> +--EXPECTF-- +array(2) { + [0]=> + string(10) "Ssl_cipher" + [1]=> + string(7) "RC4-MD5" +} +array(2) { + [0]=> + string(10) "Ssl_cipher" + [1]=> + string(7) "RC4-MD5" +} +done
\ No newline at end of file diff --git a/ext/mysqli/tests/bug55582.phpt b/ext/mysqli/tests/bug55582.phpt new file mode 100644 index 0000000..3933845 --- /dev/null +++ b/ext/mysqli/tests/bug55582.phpt @@ -0,0 +1,41 @@ +--TEST-- +Bug #55582 mysqli_num_rows() returns always 0 for unbuffered, when mysqlnd is used +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +require_once("connect.inc"); +?> +--FILE-- +<?php + include "connect.inc"; + if (!($link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))) { + printf("[001] Cannot connect to the server"); + } + + var_dump($link->real_query("SELECT 1")); + $res = $link->use_result(); + var_dump(mysqli_num_rows($res)); + var_dump($res->fetch_assoc()); + var_dump(mysqli_num_rows($res)); + var_dump($res->fetch_assoc()); + var_dump(mysqli_num_rows($res)); + + $link->close(); + echo "done\n"; +?> +--EXPECTF-- +bool(true) + +Warning: mysqli_num_rows(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d +int(0) +array(1) { + [1]=> + string(1) "1" +} + +Warning: mysqli_num_rows(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d +int(0) +NULL +int(1) +done diff --git a/ext/mysqli/tests/bug55653.phpt b/ext/mysqli/tests/bug55653.phpt new file mode 100644 index 0000000..f9cd297 --- /dev/null +++ b/ext/mysqli/tests/bug55653.phpt @@ -0,0 +1,36 @@ +--TEST--
+Bug #55653 PS crash with libmysql when binding same variable as param and out
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ require_once("connect.inc");
+
+ if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
+ printf("[001] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
+ }
+
+ $in_and_out = "a";
+
+ if (!($stmt = $link->stmt_init()))
+ printf("[002] [%d] %s\n", $link->errno, $link->error);
+
+ if (!($stmt->prepare("SELECT ?")) ||
+ !($stmt->bind_param("s", $in_and_out)) ||
+ !($stmt->execute()) ||
+ !($stmt->bind_result($in_and_out)))
+ printf("[003] [%d] %s\n", $stmt->errno, $stmt->error);
+
+ if (!$stmt->fetch())
+ printf("[004] [%d] %s\n", $stmt->errno, $stmt->error);
+
+ if ("a" !== $in_and_out)
+ printf("[005] Wrong result: '%s'\n", $in_and_out);
+
+ echo "done!";
+?>
+--EXPECT--
+done!
\ No newline at end of file diff --git a/ext/mysqli/tests/bug55859.phpt b/ext/mysqli/tests/bug55859.phpt new file mode 100644 index 0000000..ba6e990 --- /dev/null +++ b/ext/mysqli/tests/bug55859.phpt @@ -0,0 +1,20 @@ +--TEST--
+Bug #55859 mysqli->stat property access gives error
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ require_once("connect.inc");
+
+ if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
+ printf("[001] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
+ }
+ var_dump(soundex(mysqli_stat($link)) === soundex($link->stat));
+ echo "done!";
+?>
+--EXPECT--
+bool(true)
+done!
diff --git a/ext/mysqli/tests/bug62046.phpt b/ext/mysqli/tests/bug62046.phpt new file mode 100644 index 0000000..31a7328 --- /dev/null +++ b/ext/mysqli/tests/bug62046.phpt @@ -0,0 +1,40 @@ +--TEST--
+Bug #62046 mysqli@mysqlnd can't iterate over stored sets after call to mysqli_stmt_reset()
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ require_once("connect.inc");
+
+ if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
+ printf("[001] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
+ }
+ if (FALSE === ($stmt = $link->prepare('SELECT 42'))) {
+ printf("[002] Prepare failed, [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ }
+ if (FALSE === $stmt->execute()) {
+ printf("[003] Execute failed, [%d] %s\n", $stmt->errorno, $stmt->error);
+ }
+ if (FALSE === $stmt->store_result()) {
+ printf("[004] store_result failed, [%d] %s\n", $stmt->errorno, $stmt->error);
+ }
+ $one = NULL;
+ if (FALSE === $stmt->bind_result($one)) {
+ printf("[005] bind_result failed, [%d] %s\n", $stmt->errorno, $stmt->error);
+ }
+ if (FALSE === $stmt->reset()) {
+ printf("[006] bind_result failed, [%d] %s\n", $stmt->errorno, $stmt->error);
+ }
+ while ($stmt->fetch()) {
+ var_dump($one);
+ }
+ $stmt->close();
+ $link->close();
+ echo "done!";
+?>
+--EXPECT--
+int(42)
+done!
\ No newline at end of file diff --git a/ext/mysqli/tests/bug62885.phpt b/ext/mysqli/tests/bug62885.phpt new file mode 100644 index 0000000..9fb0aa0 --- /dev/null +++ b/ext/mysqli/tests/bug62885.phpt @@ -0,0 +1,26 @@ +--TEST--
+Bug #62885 (mysqli_poll - Segmentation fault)
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once("connect.inc");
+if (!$IS_MYSQLND) {
+ die("skip mysqlnd only test");
+}
+?>
+--FILE--
+<?php
+error_reporting(E_ALL);
+$tablica = array();
+$test1 = mysqli_poll($test2, $test3, $tablica, null);
+
+$test2 = array();
+$test2 = array();
+$test1 = mysqli_poll($test2, $test3, $tablica, null);
+echo "okey";
+?>
+--EXPECTF--
+Warning: mysqli_poll(): No stream arrays were passed in %sbug62885.php on line %d
+
+Warning: mysqli_poll(): No stream arrays were passed in %sbug62885.php on line %d
+okey
diff --git a/ext/mysqli/tests/bug63398.phpt b/ext/mysqli/tests/bug63398.phpt new file mode 100644 index 0000000..b6e6c25 --- /dev/null +++ b/ext/mysqli/tests/bug63398.phpt @@ -0,0 +1,36 @@ +--TEST-- +Bug #63398 (Segfault when polling closed link) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once("connect.inc"); +if (!$IS_MYSQLND) { + die("skip mysqlnd only test"); +} +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +require 'connect.inc'; +$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + +mysqli_close($link); + +$read = $error = $reject = array(); +$read[] = $error[] = $reject[] = $link; + +mysqli_poll($read, $error, $reject, 1); + +echo "okey"; +?> +--EXPECTF-- +Warning: mysqli_poll(): [1] Couldn't fetch mysqli in %sbug63398.php on line %d + +Warning: mysqli_poll(): [1] Couldn't fetch mysqli in %sbug63398.php on line %d + +Warning: mysqli_poll(): No stream arrays were passed in %sbug63398.php on line %d + +Warning: mysqli_poll(): [1] Couldn't fetch mysqli in %sbug63398.php on line %d + +Warning: mysqli_poll(): [1] Couldn't fetch mysqli in %sbug63398.php on line %d +okey diff --git a/ext/mysqli/tests/bug_mysql_49406.phpt b/ext/mysqli/tests/bug_mysql_49406.phpt new file mode 100644 index 0000000..7ed7b44 --- /dev/null +++ b/ext/mysqli/tests/bug_mysql_49406.phpt @@ -0,0 +1,107 @@ +--TEST-- +MySQL Bug #49406 (Binding params doesn't work when selecting a date inside a CASE-WHEN, http://bugs.mysql.com/bug.php?id=49406) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + if (!($link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + $query = "SELECT CASE WHEN 0 THEN CAST('2009-12-03' AS DATE) ELSE CAST('2009-12-03' AS DATE) END"; + + if (!$res = $link->query($query)) + printf("[002] [%d] %s\n", $link->errno, $link->error); + + if (!$row = $res->fetch_row()) + printf("[003] No result, [%d] %s\n", $link->errno, $link->error); + + $res->free(); + + if ($row[0] != '2009-12-03') { + printf("[004] Expecting '2009-12-03' got '%s'\n", $row[0]); + } + + if (!$stmt = $link->prepare($query)) + printf("[005] [%d] %s\n", $link->errno, $link->error); + + if (!$stmt->execute() || !$stmt->store_result()) + printf("[006] [%d] %s\n", $stmt->errno, $stmt->error); + + + $datatypes = array( + MYSQLI_TYPE_TINY => "TINY", + MYSQLI_TYPE_SHORT => "SHORT", + MYSQLI_TYPE_LONG => "LONG", + MYSQLI_TYPE_FLOAT => "FLOAT", + MYSQLI_TYPE_DOUBLE => "DOUBLE", + MYSQLI_TYPE_TIMESTAMP => "TIMESTAMP", + MYSQLI_TYPE_LONGLONG => "LONGLONG", + MYSQLI_TYPE_INT24 => "INT24", + MYSQLI_TYPE_DATE => "DATE", + MYSQLI_TYPE_TIME => "TIME", + MYSQLI_TYPE_DATETIME => "DATETIME", + MYSQLI_TYPE_YEAR => "YEAR", + MYSQLI_TYPE_ENUM => "ENUM", + MYSQLI_TYPE_SET => "SET", + MYSQLI_TYPE_TINY_BLOB => "TINYBLOB", + MYSQLI_TYPE_MEDIUM_BLOB => "MEDIUMBLOB", + MYSQLI_TYPE_LONG_BLOB => "LONGBLOB", + MYSQLI_TYPE_BLOB => "BLOB", + MYSQLI_TYPE_VAR_STRING => "VAR_STRING", + MYSQLI_TYPE_STRING => "STRING", + MYSQLI_TYPE_NULL => "NULL", + MYSQLI_TYPE_NEWDATE => "NEWDATE", + MYSQLI_TYPE_INTERVAL => "INTERVAL", + MYSQLI_TYPE_GEOMETRY => "GEOMETRY", + ); + + $meta_res = $stmt->result_metadata(); + for ($field_idx = 0; $field_idx < $meta_res->field_count; $field_idx++) { + $field = $meta_res->fetch_field(); + printf("Field : %d\n", $field_idx); + printf("Name : %s\n", $field->name); + printf("Orgname : %s\n", $field->orgname); + printf("Table : %s\n", $field->table); + printf("Orgtable : %s\n", $field->orgtable); + printf("Maxlength : %d\n", $field->max_length); + printf("Length : %d\n", $field->length); + printf("Charsetnr : %d\n", $field->charsetnr); + printf("Flags : %d\n", $field->flags); + printf("Type : %d (%s)\n", $field->type, (isset($datatypes[$field->type])) ? $datatypes[$field->type] : 'unknown'); + printf("Decimals : %d\n", $field->decimals); + } + + $row_stmt = null; + if (!$stmt->bind_result($row_stmt) || !$stmt->fetch()) + printf("[007] [%d] %s\n", $stmt->errno, $stmt->error); + + if ($row[0] != $row_stmt) { + printf("[008] PS and non-PS results differ, dumping data\n"); + var_dump($row[0]); + var_dump($row_stmt); + } + + $stmt->close(); + $link->close(); + + echo "done"; +?> +--EXPECTF-- +Field : %s +Name : %s +Orgname :%s +Table :%s +Orgtable :%s +Maxlength : %d +Length : %d +Charsetnr : %d +Flags : %d +Type : %d (%s) +Decimals : %d +done
\ No newline at end of file diff --git a/ext/mysqli/tests/cacert.pem b/ext/mysqli/tests/cacert.pem new file mode 100644 index 0000000..e443413 --- /dev/null +++ b/ext/mysqli/tests/cacert.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICrTCCAhagAwIBAgIJAMI7xZKjhrDbMA0GCSqGSIb3DQEBBAUAMEQxCzAJBgNV +BAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxhMREwDwYD +VQQKEwhNeVNRTCBBQjAeFw0xMDAxMjkxMTQ3MTBaFw0xNTAxMjgxMTQ3MTBaMEQx +CzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxh +MREwDwYDVQQKEwhNeVNRTCBBQjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA +wQYsOEfrN4ESP3FjsI8cghE+tZVuyK2gck61lwieVxjgFMtBd65mI5a1y9pmlOI1 +yM4SB2Ppqcuw7/e1CdV1y7lvHrGNt5yqEHbN4QX1gvsN8TQauP/2WILturk4R4Hq +rKg0ZySu7f1Xhl0ed9a48LpaEHD17IcxWEGMMJwAxF0CAwEAAaOBpjCBozAMBgNV +HRMEBTADAQH/MB0GA1UdDgQWBBSvktYQ0ahLnyxyVKqty+WpBbBrDTB0BgNVHSME +bTBrgBSvktYQ0ahLnyxyVKqty+WpBbBrDaFIpEYwRDELMAkGA1UEBhMCU0UxEDAO +BgNVBAgTB1VwcHNhbGExEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FM +IEFCggkAwjvFkqOGsNswDQYJKoZIhvcNAQEEBQADgYEAdKN1PjwMHAKG2Ww1145g +JQGBnKxSFOUaoSvkBi/4ntTM+ysnViWh7WvxyWjR9zU9arfr7aqsDeQxm0XDOqzj +AQ/cQIla2/Li8tXyfc06bisH/IHRaSc2zWqioTKbEwMdVOdrvq4a8V8ic3xYyIWn +7F4WeS07J8LKardSvM0+hOA= +-----END CERTIFICATE----- diff --git a/ext/mysqli/tests/clean_table.inc b/ext/mysqli/tests/clean_table.inc new file mode 100644 index 0000000..716cc84 --- /dev/null +++ b/ext/mysqli/tests/clean_table.inc @@ -0,0 +1,14 @@ +<?PHP +require_once('connect.inc'); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[clean] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); +} + +if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { + printf("[clean] Failed to drop old test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); +} + +mysqli_close($link); +?>
\ No newline at end of file diff --git a/ext/mysqli/tests/client-cert.pem b/ext/mysqli/tests/client-cert.pem new file mode 100644 index 0000000..ee7f2ab --- /dev/null +++ b/ext/mysqli/tests/client-cert.pem @@ -0,0 +1,46 @@ +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 1048577 (0x100001) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB + Validity + Not Before: Jan 29 11:50:22 2010 GMT + Not After : Jan 28 11:50:22 2015 GMT + Subject: C=SE, ST=Uppsala, O=MySQL AB + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: + 00:cc:9a:37:49:13:66:dc:cf:e3:0b:13:a1:23:ed: + 78:db:4e:bd:11:f6:8c:0d:76:f9:a3:32:56:9a:f8: + a1:21:6a:55:4e:4d:3f:e6:67:9d:26:99:b2:cd:a4: + 9a:d2:2b:59:5c:d7:8a:d3:60:68:f8:18:bd:c5:be: + 15:e1:2a:3c:a3:d4:61:cb:f5:11:94:17:81:81:f7: + 87:8c:f6:6a:d2:ee:d8:e6:77:f6:62:66:4d:2e:16: + 8d:08:81:4a:c9:c6:4b:31:e5:b9:c7:8a:84:96:48: + a7:47:8c:0d:26:90:56:4e:e6:a5:6e:8c:b3:f2:9f: + fc:3d:78:9b:49:6e:86:83:77 + Exponent: 65537 (0x10001) + Signature Algorithm: md5WithRSAEncryption + 5e:1f:a3:53:5f:24:13:1c:f8:28:32:b0:7f:69:69:f3:0e:c0: + 34:87:10:03:7d:da:15:8b:bd:19:b8:1a:56:31:e7:85:49:81: + c9:7f:45:20:74:3e:89:c0:e0:26:84:51:cc:04:16:ce:69:99: + 01:e1:26:99:b3:e3:f5:bd:ec:5f:a0:84:e4:38:da:75:78:7b: + 89:9c:d2:cd:60:95:20:ba:8e:e3:7c:e6:df:76:3a:7c:89:77: + 02:94:86:11:3a:c4:61:7d:6f:71:83:21:8a:17:fb:17:e2:ee: + 02:6b:61:c1:b4:52:63:d7:d8:46:b2:c5:9c:6f:38:91:8a:35: + 32:0b +-----BEGIN CERTIFICATE----- +MIIB5zCCAVACAxAAATANBgkqhkiG9w0BAQQFADBEMQswCQYDVQQGEwJTRTEQMA4G +A1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwg +QUIwHhcNMTAwMTI5MTE1MDIyWhcNMTUwMTI4MTE1MDIyWjAyMQswCQYDVQQGEwJT +RTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIwgZ8wDQYJKoZI +hvcNAQEBBQADgY0AMIGJAoGBAMyaN0kTZtzP4wsToSPteNtOvRH2jA12+aMyVpr4 +oSFqVU5NP+ZnnSaZss2kmtIrWVzXitNgaPgYvcW+FeEqPKPUYcv1EZQXgYH3h4z2 +atLu2OZ39mJmTS4WjQiBSsnGSzHluceKhJZIp0eMDSaQVk7mpW6Ms/Kf/D14m0lu +hoN3AgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAXh+jU18kExz4KDKwf2lp8w7ANIcQ +A33aFYu9GbgaVjHnhUmByX9FIHQ+icDgJoRRzAQWzmmZAeEmmbPj9b3sX6CE5Dja +dXh7iZzSzWCVILqO43zm33Y6fIl3ApSGETrEYX1vcYMhihf7F+LuAmthwbRSY9fY +RrLFnG84kYo1Mgs= +-----END CERTIFICATE----- diff --git a/ext/mysqli/tests/client-key.pem b/ext/mysqli/tests/client-key.pem new file mode 100644 index 0000000..205b5f3 --- /dev/null +++ b/ext/mysqli/tests/client-key.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDMmjdJE2bcz+MLE6Ej7XjbTr0R9owNdvmjMlaa+KEhalVOTT/m +Z50mmbLNpJrSK1lc14rTYGj4GL3FvhXhKjyj1GHL9RGUF4GB94eM9mrS7tjmd/Zi +Zk0uFo0IgUrJxksx5bnHioSWSKdHjA0mkFZO5qVujLPyn/w9eJtJboaDdwIDAQAB +AoGASqk/4We2En+93y3jkIO4pXafIe3w/3zZ7caRue1ehx4RUQh5d+95djuB9u7J +HEZ7TpjM7QNyao5EueL6gvbxt0LXFvqAMni7yM9tt/HUYtHHPqYiRtUny9bKYFTm +l8szCCMal/wD9GZU9ByHDNHm7tHUMyMhARNTYSgx+SERFmECQQD/6jJocC4SXf6f +T3LqimWR02lbJ7qCoDgRglsUXh0zjrG+IIiAyE+QOCCx1GMe3Uw6bsIuYwdHT6as +WcdPs04xAkEAzKulvEvLVvN5zfa/DTYRTV7jh6aDleOxjsD5oN/oJXoACnPzVuUL +qQQMNtuAXm6Q1QItrRxpQsSKbY0UQka6JwJBAOSgoNoG5lIIYTKIMvzwGV+XBLeo +HYsXgh+6Wo4uql3mLErUG78ZtWL9kc/tE4R+ZdyKGLaCR/1gXmH5bwN4B/ECQEBb +uUH8k3REG4kojesZlVc+/00ojzgS4UKCa/yqa9VdB6ZBz8MDQydinnShkTwgiGpy +xOoqhO753o2UT0qH8wECQQC99IEJWUnwvExVMkLaZH5NjAFJkb22sjkmuT11tAgU +RQgOMoDOm6driojnOnDWOkx1r1Gy9NgMLooduja4v6cx +-----END RSA PRIVATE KEY----- diff --git a/ext/mysqli/tests/connect.inc b/ext/mysqli/tests/connect.inc new file mode 100644 index 0000000..3a9d8ec --- /dev/null +++ b/ext/mysqli/tests/connect.inc @@ -0,0 +1,273 @@ +<?php + /* + Default values are "localhost", "root", + database "stest" and empty password. + Change the MYSQL_TEST environment values + if you want to use another configuration + */ + + $driver = new mysqli_driver; + + $host = getenv("MYSQL_TEST_HOST") ? getenv("MYSQL_TEST_HOST") : "localhost"; + $port = getenv("MYSQL_TEST_PORT") ? getenv("MYSQL_TEST_PORT") : 3306; + $user = getenv("MYSQL_TEST_USER") ? getenv("MYSQL_TEST_USER") : "root"; + $passwd = getenv("MYSQL_TEST_PASSWD") ? getenv("MYSQL_TEST_PASSWD") : ""; + $db = getenv("MYSQL_TEST_DB") ? getenv("MYSQL_TEST_DB") : "test"; + $engine = getenv("MYSQL_TEST_ENGINE") ? getenv("MYSQL_TEST_ENGINE") : "MyISAM"; + $socket = getenv("MYSQL_TEST_SOCKET") ? getenv("MYSQL_TEST_SOCKET") : null; + $skip_on_connect_failure = getenv("MYSQL_TEST_SKIP_CONNECT_FAILURE") ? getenv("MYSQL_TEST_SKIP_CONNECT_FAILURE") : true; + $connect_flags = getenv("MYSQL_TEST_CONNECT_FLAGS") ? (int)getenv("MYSQL_TEST_CONNECT_FLAGS") : 0; + if ($socket) { + ini_set('mysqli.default_socket', $socket); + } + + /* Development setting: test experimal features and/or feature requests that never worked before? */ + $TEST_EXPERIMENTAL = (in_array(getenv("MYSQL_TEST_EXPERIMENTAL"), array(0, 1))) ? + ((1 == getenv("MYSQL_TEST_EXPERIMENTAL")) ? true : false) : + false; + + $IS_MYSQLND = stristr(mysqli_get_client_info(), "mysqlnd"); + if (!$IS_MYSQLND) { + $MYSQLND_VERSION = NULL; + } else { + /* + The formatting of the version reported by mysqli_get_client_info() + has changed significantly in the past. To get tests working properly + with PHP 5.3.0 and up, we set everything that looks like prior to + PHP 5.3.0 to version 5.0.4 = 5 * 10000 + 0 * 100 + 4 = 50004. + PHP 5.3.0 reports mysqlnd 5.0.5 dev (= 5 * 10000 + 0 * 100 + 5 = 50005. + */ + if (preg_match('@Revision:\s+(\d+)\s*\$@ism', mysqli_get_client_info(), $matches)) { + /* something prior to PHP 5.3.0 */ + $MYSQLND_VERSION = 50004; + } else if (preg_match('@^mysqlnd (\d+)\.(\d+)\.(\d+).*@ism', mysqli_get_client_info(), $matches)) { + /* formatting schema used by PHP 5.3.0 */ + $MYSQLND_VERSION = (int)$matches[1] * 10000 + (int)$matches[2] * 100 + (int)$matches[3]; + } else if (preg_match('@^mysqlnd/PHP 6.0.0-dev@ism', mysqli_get_client_info(), $matches)) { + /* + PHP 6.0 at the time of the first PHP 5.3.0 release. + HEAD and 5.3 have been in sync when 5.3.0 was released. + It is at least 5.0.5-dev. + */ + $MYSQLND_VERSION = 50005; + } else { + /* unknown */ + $MYSQLND_VERSION = -1; + } + + } + + if (!function_exists('sys_get_temp_dir')) { + function sys_get_temp_dir() { + + if (!empty($_ENV['TMP'])) + return realpath( $_ENV['TMP'] ); + if (!empty($_ENV['TMPDIR'])) + return realpath( $_ENV['TMPDIR'] ); + if (!empty($_ENV['TEMP'])) + return realpath( $_ENV['TEMP'] ); + + $temp_file = tempnam(md5(uniqid(rand(), TRUE)), ''); + if ($temp_file) { + $temp_dir = realpath(dirname($temp_file)); + unlink($temp_file); + return $temp_dir; + } + return FALSE; + } + } + + if (!function_exists('my_mysqli_connect')) { + + /** + * Whenever possible, please use this wrapper to make testing ot MYSQLI_CLIENT_COMPRESS (and potentially SSL) possible + * + * @param enable_env_flags Enable setting of connection flags through env(MYSQL_TEST_CONNECT_FLAGS)? + */ + function my_mysqli_connect($host, $user, $passwd, $db, $port, $socket, $enable_env_flags = true) { + global $connect_flags; + + $flags = ($enable_env_flags) ? $connect_flags : false; + + if ($flags !== false) { + $link = mysqli_init(); + if (!mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket, $flags)) + $link = false; + } else { + $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + } + + return $link; + } + + /** + * Whenever possible, please use this wrapper to make testing ot MYSQLI_CLIENT_COMPRESS (and potentially SSL) possible + * + * @param enable_env_flags Enable setting of connection flags through env(MYSQL_TEST_CONNECT_FLAGS) + */ + function my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket, $flags = 0, $enable_env_flags = true) { + global $connect_flags; + + if ($enable_env_flags) + $flags & $connect_flags; + + return mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket, $flags); + } + + class my_mysqli extends mysqli { + public function __construct($host, $user, $passwd, $db, $port, $socket, $enable_env_flags = true) { + global $connect_flags; + + $flags = ($enable_env_flags) ? $connect_flags : false; + + if ($flags !== false) { + parent::init(); + $this->real_connect($host, $user, $passwd, $db, $port, $socket, $flags); + } else { + parent::__construct($host, $user, $passwd, $db, $port, $socket); + } + } + } + + function my_get_charsets($link) { + + /* Those tree are set by SET NAMES */ + $charsets = array( + 'client' => NULL, + 'results' => NULL, + 'connection' => NULL, + ); + + if (!($res = mysqli_query($link, "SHOW VARIABLES LIKE '%character%'"))) { + printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link)); + return $charsets; + } + + $names = array(); + while ($row = mysqli_fetch_assoc($res)) { + $names[$row['Variable_name']] = $row['Value']; + } + mysqli_free_result($res); + + if (!($res = mysqli_query($link, sprintf("SHOW CHARACTER SET LIKE '%s'", $names['character_set_client']))) || + !($details = mysqli_fetch_assoc($res))) { + printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link)); + return $charsets; + } + mysqli_free_result($res); + + $charsets['client'] = array( + 'charset' => $details['Charset'], + 'desc' => $details['Description'], + 'collation' => $details['Default collation'], + 'maxlen' => $details['Maxlen'], + 'nr' => NULL, + ); + + if (!($res = mysqli_query($link, sprintf("SHOW COLLATION LIKE '%s'", $details['Default collation']))) || + !($collation = mysqli_fetch_assoc($res))) { + printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link)); + return $charsets; + } + mysqli_free_result($res); + $charsets['client']['nr'] = $collation['Id']; + + if (!($res = mysqli_query($link, sprintf("SHOW CHARACTER SET LIKE '%s'", $names['character_set_results']))) || + !($details = mysqli_fetch_assoc($res))) { + printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link)); + return $charsets; + } + mysqli_free_result($res); + + $charsets['results'] = array( + 'charset' => $details['Charset'], + 'desc' => $details['Description'], + 'collation' => $details['Default collation'], + 'maxlen' => $details['Maxlen'], + 'nr' => NULL, + ); + + if (!($res = mysqli_query($link, sprintf("SHOW COLLATION LIKE '%s'", $details['Default collation']))) || + !($collation = mysqli_fetch_assoc($res))) { + printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link)); + return $charsets; + } + mysqli_free_result($res); + $charsets['results']['nr'] = $collation['Id']; + + + if (!($res = mysqli_query($link, sprintf("SHOW CHARACTER SET LIKE '%s'", $names['character_set_connection']))) || + !($details = mysqli_fetch_assoc($res))) { + printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link)); + return $charsets; + } + mysqli_free_result($res); + + $charsets['connection'] = array( + 'charset' => $details['Charset'], + 'desc' => $details['Description'], + 'collation' => $details['Default collation'], + 'maxlen' => $details['Maxlen'], + 'nr' => NULL, + ); + + if (!($res = mysqli_query($link, sprintf("SHOW COLLATION LIKE '%s'", $details['Default collation']))) || + !($collation = mysqli_fetch_assoc($res))) { + printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link)); + return $charsets; + } + mysqli_free_result($res); + $charsets['connection']['nr'] = $collation['Id']; + + return $charsets; + } + + function have_innodb($link) { + if (($res = $link->query("SHOW VARIABLES LIKE 'have_innodb'")) && + ($row = $res->fetch_row()) && + !empty($row)) { + if ($row[1] == "DISABLED" || $row[1] == "NO") { + return false; + } + return true; + } else { + /* MySQL 5.6.1+ */ + if ($res = $link->query("SHOW ENGINES")) { + while ($row = $res->fetch_assoc()) { + if (!isset($row['Engine']) || !isset($row['Support'])) + return false; + + if (('InnoDB' == $row['Engine']) && + (('YES' == $row['Support']) || ('DEFAULT' == $row['Support'])) + ) { + return true; + } + } + return false; + } else { + return false; + } + } + return false; + } + + } else { + printf("skip Eeeek/BUG/FIXME - connect.inc included twice! skipif bug?\n"); + } + + function handle_catchable_fatal($errno, $error, $file, $line) { + static $errcodes = array(); + if (empty($errcodes)) { + $constants = get_defined_constants(); + foreach ($constants as $name => $value) { + if (substr($name, 0, 2) == "E_") + $errcodes[$value] = $name; + } + } + printf("[%s] %s in %s on line %s\n", + (isset($errcodes[$errno])) ? $errcodes[$errno] : $errno, + $error, $file, $line); + + return true; + } +?> diff --git a/ext/mysqli/tests/local_infile_tools.inc b/ext/mysqli/tests/local_infile_tools.inc new file mode 100644 index 0000000..bb9872f --- /dev/null +++ b/ext/mysqli/tests/local_infile_tools.inc @@ -0,0 +1,156 @@ +<?php + /* Utility function for mysqli_set_local_infile*.phpt tests */ + function shutdown_clean($file) { + if ($file) { + unlink($file); + } + } + + function check_local_infile_support($link, $engine, $table_name = 'test') { + + if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) + return "Cannot check if Server variable 'local_infile' is set to 'ON'"; + + $row = mysqli_fetch_assoc($res); + mysqli_free_result($res); + if ('ON' != $row['Value']) + return sprintf("Server variable 'local_infile' seems not set to 'ON', found '%s'", $row['Value']); + + if (!mysqli_query($link, sprintf('DROP TABLE IF EXISTS %s', $table_name))) { + return "Failed to drop old test table"; + } + + if (!mysqli_query($link, $sql = sprintf('CREATE TABLE %s(id INT, label CHAR(1), PRIMARY KEY(id)) ENGINE=%s', + $table_name, $engine))) + return "Failed to create test table: $sql"; + + $file = create_standard_csv(1, false); + if (!$file) { + mysqli_query($link, sprintf('DROP TABLE IF EXISTS %s', $table_name)); + return "Cannot create CSV file"; + } + + if (!@mysqli_query($link, sprintf("LOAD DATA LOCAL INFILE '%s' + INTO TABLE %s + FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '\'' + LINES TERMINATED BY '\n'", + mysqli_real_escape_string($link, $file), + $table_name))) { + if (1148 == mysqli_errno($link)) { + mysqli_query($link, sprintf('DROP TABLE IF EXISTS %s', $table_name)); + return "Cannot test LOAD DATA LOCAL INFILE, [1148] The used command is not allowed with this MySQL version"; + } else if ($link->errno) { + return $link->error; + } + } + mysqli_query($link, sprintf('DROP TABLE IF EXISTS %s', $table_name)); + return ""; + } + + function create_standard_csv($offset, $verbose = true) { + // create a CVS file + $file = tempnam(sys_get_temp_dir(), 'mysqli_test'); + if (!$fp = fopen($file, 'w')) { + if ($verbose) + printf("[%03d + 1] Cannot create CVS file '%s'\n", $offset, $file); + return NULL; + } else { + /* Looks ugly? No, handy if you have crashes... */ + register_shutdown_function("shutdown_clean", $file); + } + + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1)) { + if (!fwrite($fp, (binary)"'97';'x';\n") || + !fwrite($fp, (binary)"'98';'y';\n") || + !fwrite($fp, (binary)"99;'z';\n")) { + if ($verbose) + printf("[%03d + 2] Cannot write CVS file '%s'\n", $offset, $file); + return NULL; + } + } else { + if (!fwrite($fp, "97;'x';\n") || + !fwrite($fp, "98;'y';\n") || + !fwrite($fp, "99;'z';\n")) { + if ($verbose) + printf("[%03d + 3] Cannot write CVS file '%s'\n", $offset, $file); + return NULL; + } + } + + fclose($fp); + + if (!chmod($file, 0644)) { + if ($verbose) + printf("[%03d + 4] Cannot change the file perms of '%s' from 0600 to 0644, MySQL might not be able to read it\n", + $offset, $file); + return NULL; + } + return $file; + } + + function try_handler($offset, $link, $file, $handler, $expected = null) { + + if ('default' == $handler) { + mysqli_set_local_infile_default($link); + } else if (!mysqli_set_local_infile_handler($link, $handler)) { + printf("[%03d] Cannot set infile handler to '%s'\n", $offset, $handler); + return false; + } + printf("Callback set to '%s'\n", $handler); + + if (!mysqli_query($link, sprintf("DELETE FROM test"))) { + printf("[%03d] Cannot remove records, [%d] %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!@mysqli_query($link, sprintf("LOAD DATA LOCAL INFILE '%s' + INTO TABLE test + FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '\'' + LINES TERMINATED BY '\n'", + mysqli_real_escape_string($link, $file)))) { + printf("[%03d] LOAD DATA failed, [%d] %s\n", + $offset + 2, + mysqli_errno($link), mysqli_error($link)); + } + + if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id")) { + printf("[%03d] [%d] %s\n", $offset + 3, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!is_array($expected)) + return true; + + foreach ($expected as $k => $values) { + if (!$tmp = mysqli_fetch_assoc($res)) { + printf("[%03d/%d] [%d] '%s'\n", $offset + 4, $k, mysqli_errno($link), mysqli_error($link)); + return false; + } + if ($values['id'] != $tmp['id']) { + printf("[%03d/%d] Expecting %s got %s\n", + $offset + 5, $k, + $values['id'], $tmp['id']); + return false; + } + if ($values['label'] != $tmp['label']) { + printf("[%03d/%d] Expecting %s got %s\n", + $offset + 6, $k, + $values['label'], $tmp['label']); + return false; + } + } + + if ($res && $tmp = mysqli_fetch_assoc($res)) { + printf("[%03d] More results than expected!\n", $offset + 7); + do { + var_dump($tmp); + } while ($tmp = mysqli_fetch_assoc($res)); + return false; + } + + if ($res) + mysqli_free_result($res); + + return true; + } +?>
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_affected_rows.phpt b/ext/mysqli/tests/mysqli_affected_rows.phpt new file mode 100644 index 0000000..958b83c --- /dev/null +++ b/ext/mysqli/tests/mysqli_affected_rows.phpt @@ -0,0 +1,135 @@ +--TEST-- +mysqli_affected_rows() +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifemb.inc'); + require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_affected_rows())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_affected_rows($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_affected_rows($link, $link))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[004] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (0 !== ($tmp = mysqli_affected_rows($link))) + printf("[005] Expecting int/0, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, 'CREATE TABLE test(id INT, label CHAR(1), PRIMARY KEY(id)) ENGINE = ' . $engine)) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "INSERT INTO test(id, label) VALUES (1, 'a')")) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (1 !== ($tmp = mysqli_affected_rows($link))) + printf("[010] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + + // ignore INSERT error, NOTE: command line returns 0, affected_rows returns -1 as documented + mysqli_query($link, "INSERT INTO test(id, label) VALUES (1, 'a')"); + if (-1 !== ($tmp = mysqli_affected_rows($link))) + printf("[011] Expecting int/-1, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, "INSERT INTO test(id, label) VALUES (1, 'a') ON DUPLICATE KEY UPDATE id = 4")) + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (2 !== ($tmp = mysqli_affected_rows($link))) + printf("[013] Expecting int/2, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, "INSERT INTO test(id, label) VALUES (2, 'b'), (3, 'c')")) + printf("[014] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (2 !== ($tmp = mysqli_affected_rows($link))) + printf("[015] Expecting int/2, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, "INSERT IGNORE INTO test(id, label) VALUES (1, 'a')")) { + printf("[016] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + if (1 !== ($tmp = mysqli_affected_rows($link))) + printf("[017] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, "INSERT INTO test(id, label) SELECT id + 10, label FROM test")) + printf("[018] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (4 !== ($tmp = mysqli_affected_rows($link))) + printf("[019] Expecting int/4, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, "REPLACE INTO test(id, label) values (4, 'd')")) + printf("[020] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (2 !== ($tmp = mysqli_affected_rows($link))) + printf("[021] Expecting int/2, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, "REPLACE INTO test(id, label) values (5, 'e')")) + printf("[022] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (1 !== ($tmp = mysqli_affected_rows($link))) + printf("[023] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, "UPDATE test SET label = 'a' WHERE id = 2")) + printf("[024] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (1 !== ($tmp = mysqli_affected_rows($link))) + printf("[025] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + + $charsets = array('utf8'); + foreach ($charsets as $k => $charset) { + if (!($res = mysqli_query($link, sprintf("SHOW CHARACTER SET LIKE '%s'", $charset)))) + continue; + mysqli_free_result($res); + if (true !== ($tmp = mysqli_set_charset($link, $charset))) + printf("[026] Expecting boolean/true got %s/%s\n", + gettype($tmp), $tmp); + if (0 !== ($tmp = mysqli_affected_rows($link))) + printf("[027] Expecting int/0 got %s/%s\n", gettype($tmp), $tmp); + } + + if (!mysqli_query($link, "UPDATE test SET label = 'a' WHERE id = 2")) { + printf("[028] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + if (0 !== ($tmp = mysqli_affected_rows($link))) + printf("[029] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, "UPDATE test SET label = 'a' WHERE id = 100")) { + printf("[030] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + if (0 !== ($tmp = mysqli_affected_rows($link))) + printf("[031] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) + printf("[032] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + + mysqli_close($link); + + if (NULL !== ($tmp = @mysqli_affected_rows($link))) + printf("[033] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_affected_rows_oo.phpt b/ext/mysqli/tests/mysqli_affected_rows_oo.phpt new file mode 100644 index 0000000..6da026b --- /dev/null +++ b/ext/mysqli/tests/mysqli_affected_rows_oo.phpt @@ -0,0 +1,114 @@ +--TEST-- +mysqli->affected_rows +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifemb.inc'); + require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $mysqli = new mysqli(); + if (NULL !== ($tmp = @$mysqli->affected_rows)) + printf("[000a] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) { + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } + + if (0 !== ($tmp = $mysqli->affected_rows)) + printf("[002] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli->query('DROP TABLE IF EXISTS test')) + printf("[003] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (!$mysqli->query('CREATE TABLE test(id INT, label CHAR(1), PRIMARY KEY(id)) ENGINE = ' . $engine)) + printf("[004] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (!$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'a')")) + printf("[005] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (1 !== ($tmp = $mysqli->affected_rows)) + printf("[006] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + + // ignore INSERT error, NOTE: command line returns 0, affected_rows returns -1 as documented + $mysqli->query("INSERT INTO test(id, label) VALUES (1, 'a')"); + if (-1 !== ($tmp = $mysqli->affected_rows)) + printf("[007] Expecting int/-1, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'a') ON DUPLICATE KEY UPDATE id = 4")) + printf("[008] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (2 !== ($tmp = $mysqli->affected_rows)) + printf("[009] Expecting int/2, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli->query("INSERT INTO test(id, label) VALUES (2, 'b'), (3, 'c')")) + printf("[010] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (2 !== ($tmp = $mysqli->affected_rows)) + printf("[011] Expecting int/2, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli->query("INSERT IGNORE INTO test(id, label) VALUES (1, 'a')")) { + printf("[012] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + if (1 !== ($tmp = $mysqli->affected_rows)) + printf("[013] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli->query("INSERT INTO test(id, label) SELECT id + 10, label FROM test")) + printf("[014] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (4 !== ($tmp = $mysqli->affected_rows)) + printf("[015] Expecting int/4, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli->query("REPLACE INTO test(id, label) values (4, 'd')")) + printf("[015] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (2 !== ($tmp = $mysqli->affected_rows)) + printf("[016] Expecting int/2, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli->query("REPLACE INTO test(id, label) values (5, 'e')")) + printf("[017] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (1 !== ($tmp = $mysqli->affected_rows)) + printf("[018] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli->query("UPDATE test SET label = 'a' WHERE id = 2")) + printf("[019] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (1 !== ($tmp = $mysqli->affected_rows)) + printf("[020] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli->query("UPDATE test SET label = 'a' WHERE id = 2")) { + printf("[021] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + if (0 !== ($tmp = $mysqli->affected_rows)) + printf("[022] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli->query("UPDATE test SET label = 'a' WHERE id = 100")) { + printf("[023] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + if (0 !== ($tmp = $mysqli->affected_rows)) + printf("[024] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli->query('DROP TABLE IF EXISTS test')) + printf("[025] [%d] %s\n", $mysqli->errno, $mysqli->error); + + $mysqli->close(); + + if (NULL !== ($tmp = @$mysqli->affected_rows)) + printf("[026] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_auth_pam.phpt b/ext/mysqli/tests/mysqli_auth_pam.phpt new file mode 100644 index 0000000..fe15529 --- /dev/null +++ b/ext/mysqli/tests/mysqli_auth_pam.phpt @@ -0,0 +1,98 @@ +--TEST-- +PAM auth plugin +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('connect.inc'); + +if (version_compare(PHP_VERSION, '5.3.99') >= 0) { + die("SKIP Available as of PHP 5.3.99"); +} + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf("SKIP Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket)); +} + +if ($link->server_version < 50500) + die(sprintf("SKIP Needs MySQL 5.5 or newer, found MySQL %s\n", $link->server_info)); + +if (!$res = $link->query("SHOW PLUGINS")) + die(sprintf("SKIP [%d] %s\n", $link->errno, $link->error)); + +$have_pam = false; +while ($row = $res->fetch_assoc()) { + if (isset($row['Name']) && ('mysql_clear_password' == $row['Name'])) { + $have_pam = true; + break; + } +} +$res->close(); + +if (!$have_pam) + die("SKIP Server PAM plugin not installed"); + + +mysqli_query($link, 'DROP USER pamtest'); +mysqli_query($link, 'DROP USER pamtest@localhost'); + +if (!mysqli_query($link, 'CREATE USER pamtest@"%" IDENTIFIED WITH mysql_clear_password') || + !mysqli_query($link, 'CREATE USER pamtest@"localhost" IDENTIFIED WITH mysql_clear_password')) { + printf("skip Cannot create second DB user [%d] %s", mysqli_errno($link), mysqli_error($link)); + mysqli_close($link); + die("skip CREATE USER failed"); +} + +if (!$link->query("CREATE TABLE test (id INT)") || !$link->query("INSERT INTO test(id) VALUES (1)")) + die(sprintf("SKIP [%d] %s\n", $link->errno, $link->error)); + + + +if (!mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pamtest@'%%'", $db)) || + !mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pamtest@'localhost'", $db))) { + printf("skip Cannot grant SELECT to user [%d] %s", mysqli_errno($link), mysqli_error($link)); + mysqli_close($link); + die("skip GRANT failed"); +} +?> +--INI-- +max_execution_time=240 +--FILE-- +<?php + require_once('connect.inc'); + require_once('table.inc'); + + if (!$link = my_mysqli_connect($host, 'pamtest', 'pamtest', $db, $port, $socket)) { + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } else { + + if (!$res = $link->query("SELECT id FROM test WHERE id = 1")) + printf("[002] [%d] %s\n", $link->errno, $link->error); + + if (!$row = mysqli_fetch_assoc($res)) { + printf("[003] [%d] %s\n", $link->errno, $link->error); + } + + if ($row['id'] != 1) { + printf("[004] Expecting 1 got %s/'%s'", gettype($row['id']), $row['id']); + } + + $res->close(); + $link->close(); + } + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); + mysqli_query($link, 'DROP USER pamtest'); + mysqli_query($link, 'DROP USER pamtest@localhost'); +?> +--EXPECTF-- + +Warning: mysqli_real_connect(): (28000/1045): Access denied for user %s +[001] Cannot connect to the server using host=%s +done! diff --git a/ext/mysqli/tests/mysqli_autocommit.phpt b/ext/mysqli/tests/mysqli_autocommit.phpt new file mode 100644 index 0000000..a93d89f --- /dev/null +++ b/ext/mysqli/tests/mysqli_autocommit.phpt @@ -0,0 +1,147 @@ +--TEST-- +mysqli_autocommit() +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifemb.inc'); + require_once('connect.inc'); + require_once('skipifconnectfailure.inc'); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf("skip Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket)); + } + + if (!have_innodb($link)) + die(sprintf("Needs InnoDB support, [%d] %s", $link->errno, $link->error)); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_autocommit())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_autocommit($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_autocommit($link, $link, $link))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[004] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } + + if (!is_bool($tmp = mysqli_autocommit($link, true))) + printf("[005] Expecting boolean/any, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, 'SET AUTOCOMMIT = 0')) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, 'SELECT @@autocommit as auto_commit')) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $tmp = mysqli_fetch_assoc($res); + mysqli_free_result($res); + if ($tmp['auto_commit']) + printf("[008] Cannot turn off autocommit\n"); + + if (true !== ($tmp = mysqli_autocommit($link, true))) + printf("[009] Expecting true, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = mysqli_query($link, 'SELECT @@autocommit as auto_commit')) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + mysqli_free_result($res); + if (!$tmp['auto_commit']) + printf("[011] Cannot turn on autocommit\n"); + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, 'CREATE TABLE test(id INT) ENGINE = InnoDB')) { + printf("[013] Cannot create test table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + if (!mysqli_query($link, 'INSERT INTO test(id) VALUES (1)')) + printf("[014] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, 'ROLLBACK')) + printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, 'SELECT COUNT(*) AS num FROM test')) + printf("[016] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ((!$tmp = mysqli_fetch_assoc($res)) || (1 != $tmp['num'])) + printf("[17] Expecting 1 row in table test, found %d rows. [%d] %s\n", + $tmp['num'], mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) + printf("[018] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, 'SET AUTOCOMMIT = 1')) + printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, 'SELECT @@autocommit as auto_commit')) + printf("[020] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + mysqli_free_result($res); + if (!$tmp['auto_commit']) + printf("[021] Cannot turn on autocommit\n"); + + if (true !== ($tmp = mysqli_autocommit($link, false))) + printf("[022] Expecting true, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, 'CREATE TABLE test(id INT) ENGINE = InnoDB')) { + printf("[023] Cannot create test table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + if (!mysqli_query($link, 'INSERT INTO test(id) VALUES (1)')) + printf("[024] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, 'ROLLBACK')) + printf("[025] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, 'SELECT COUNT(*) AS num FROM test')) + printf("[026] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + if (0 != $tmp['num']) + printf("[27] Expecting 0 rows in table test, found %d rows\n", $tmp['num']); + mysqli_free_result($res); + + if (!mysqli_query($link, 'INSERT INTO test(id) VALUES (1)')) + printf("[028] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, 'COMMIT')) + printf("[029] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, 'SELECT COUNT(*) AS num FROM test')) + printf("[030] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ((!$tmp = mysqli_fetch_assoc($res)) || (1 != $tmp['num'])) + printf("[31] Expecting 1 row in table test, found %d rows. [%d] %s\n", + $tmp['num'], mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) + printf("[032] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_close($link); + + if (NULL !== ($tmp = @mysqli_autocommit($link, false))) + printf("[033] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done! diff --git a/ext/mysqli/tests/mysqli_autocommit_oo.phpt b/ext/mysqli/tests/mysqli_autocommit_oo.phpt new file mode 100644 index 0000000..3a5a257 --- /dev/null +++ b/ext/mysqli/tests/mysqli_autocommit_oo.phpt @@ -0,0 +1,137 @@ +--TEST-- +mysqli->autocommit() +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifemb.inc'); + require_once('skipifconnectfailure.inc'); + require_once('connect.inc'); + + if (!$link = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) { + printf("skip Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + exit(1); + } + + if (!have_innodb($link)) + die(sprintf("Needs InnoDB support, [%d] %s", $link->errno, $link->error)); +?> +--FILE-- +<?php + require_once("connect.inc"); + + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) { + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } + + if (!is_bool($tmp = $mysqli->autocommit(true))) + printf("[002] Expecting boolean/any, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli->query('SET AUTOCOMMIT = 0')) + printf("[003] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (!$res = $mysqli->query('SELECT @@autocommit as auto_commit')) + printf("[004] [%d] %s\n", $mysqli->errno, $mysqli->error); + + $tmp = $res->fetch_assoc(); + $res->free_result(); + if ($tmp['auto_commit']) + printf("[005] Cannot turn off autocommit\n"); + + if (true !== ($tmp = $mysqli->autocommit( true))) + printf("[006] Expecting true, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = $mysqli->query('SELECT @@autocommit as auto_commit')) + printf("[007] [%d] %s\n", $mysqli->errno, $mysqli->error); + $tmp = $res->fetch_assoc(); + $res->free_result(); + if (!$tmp['auto_commit']) + printf("[008] Cannot turn on autocommit\n"); + + if (!$mysqli->query('DROP TABLE IF EXISTS test')) + printf("[009] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (!$mysqli->query('CREATE TABLE test(id INT) ENGINE = InnoDB')) { + printf("[010] Cannot create test table, [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + if (!$mysqli->query('INSERT INTO test(id) VALUES (1)')) + printf("[011] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (!$mysqli->query('ROLLBACK')) + printf("[012] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (!$res = $mysqli->query('SELECT COUNT(*) AS num FROM test')) + printf("[013] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if ((!$tmp = $res->fetch_assoc()) || (1 != $tmp['num'])) + printf("[014] Expecting 1 row in table test, found %d rows. [%d] %s\n", + $tmp['num'], $mysqli->errno, $mysqli->error); + + $res->free_result(); + + if (!$mysqli->query('DROP TABLE IF EXISTS test')) + printf("[015] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (!$mysqli->query('SET AUTOCOMMIT = 1')) + printf("[016] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (!$res = $mysqli->query('SELECT @@autocommit as auto_commit')) + printf("[017] [%d] %s\n", $mysqli->errno, $mysqli->error); + + $tmp = $res->fetch_assoc(); + $res->free_result(); + if (!$tmp['auto_commit']) + printf("[018] Cannot turn on autocommit\n"); + + if (true !== ($tmp = $mysqli->autocommit( false))) + printf("[019] Expecting true, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli->query('CREATE TABLE test(id INT) ENGINE = InnoDB')) { + printf("[020] Cannot create test table, [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + if (!$mysqli->query('INSERT INTO test(id) VALUES (1)')) + printf("[021] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (!$mysqli->query('ROLLBACK')) + printf("[022] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (!$res = $mysqli->query('SELECT COUNT(*) AS num FROM test')) + printf("[023] [%d] %s\n", $mysqli->errno, $mysqli->error); + $tmp = $res->fetch_assoc(); + if (0 != $tmp['num']) + printf("[24] Expecting 0 rows in table test, found %d rows\n", $tmp['num']); + $res->free_result(); + + if (!$mysqli->query('INSERT INTO test(id) VALUES (1)')) + printf("[025] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (!$mysqli->query('COMMIT')) + printf("[025] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (!$res = $mysqli->query('SELECT COUNT(*) AS num FROM test')) + printf("[027] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if ((!$tmp = $res->fetch_assoc()) || (1 != $tmp['num'])) + printf("[028] Expecting 1 row in table test, found %d rows. [%d] %s\n", + $tmp['num'], $mysqli->errno, $mysqli->error); + $res->free_result(); + + if (!$mysqli->query('DROP TABLE IF EXISTS test')) + printf("[029] [%d] %s\n", $mysqli->errno, $mysqli->error); + + $mysqli->close(); + + if (NULL !== ($tmp = @$mysqli->autocommit( false))) + printf("[030] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_change_user.phpt b/ext/mysqli/tests/mysqli_change_user.phpt new file mode 100644 index 0000000..bfea423 --- /dev/null +++ b/ext/mysqli/tests/mysqli_change_user.phpt @@ -0,0 +1,112 @@ +--TEST-- +mysqli_change_user() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_change_user())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_change_user($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_change_user($link, $link))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_change_user($link, $link, $link))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_change_user($link, $link, $link, $link, $link))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[006] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (false !== ($tmp = mysqli_change_user($link, $user . '_unknown_really', $passwd . 'non_empty', $db))) + printf("[007] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = mysqli_change_user($link, $user, $passwd . '_unknown_really', $db))) + printf("[008] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = mysqli_change_user($link, $user, $passwd, $db . '_unknown_really'))) + printf("[009] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, 'SET @mysqli_change_user_test_var=1')) + printf("[010] Failed to set test variable: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, 'SELECT @mysqli_change_user_test_var AS test_var')) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + mysqli_free_result($res); + if (1 != $tmp['test_var']) + printf("[012] Cannot set test variable\n"); + + if (true !== ($tmp = mysqli_change_user($link, $user, $passwd, $db))) + printf("[013] Expecting true, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = mysqli_query($link, 'SELECT database() AS dbname, user() AS user')) + printf("[014] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + mysqli_free_result($res); + + if (substr($tmp['user'], 0, strlen($user)) !== $user) + printf("[015] Expecting user %s, got user() %s\n", $user, $tmp['user']); + if ($tmp['dbname'] != $db) + printf("[016] Expecting database %s, got database() %s\n", $db, $tmp['dbname']); + + if (!$res = mysqli_query($link, 'SELECT @mysqli_change_user_test_var AS test_var')) + printf("[017] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + mysqli_free_result($res); + if (NULL !== $tmp['test_var']) + printf("[019] Test variable is still set!\n"); + + mysqli_close($link); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[020] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } + + if (false !== ($tmp = mysqli_change_user($link, str_repeat('user', 16384), str_repeat('pass', 16384), str_repeat('dbase', 16384)))) + printf("[021] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[022] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } + + /* silent protocol change if no db which requires workaround in mysqlnd/libmysql + (empty db = no db send with COM_CHANGE_USER) */ + if (true !== ($tmp = mysqli_change_user($link, $user, $passwd, ""))) + printf("[023] Expecting true, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = mysqli_query($link, 'SELECT database() AS dbname, user() AS user')) + printf("[024] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + mysqli_free_result($res); + + if ($tmp['dbname'] != "") + printf("[025] Expecting database '', got database() '%s'\n", $tmp['dbname']); + + mysqli_close($link); + + if (NULL !== ($tmp = @mysqli_change_user($link, $user, $passwd, $db))) + printf("[026] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_change_user_get_lock.phpt b/ext/mysqli/tests/mysqli_change_user_get_lock.phpt new file mode 100644 index 0000000..4cc071d --- /dev/null +++ b/ext/mysqli/tests/mysqli_change_user_get_lock.phpt @@ -0,0 +1,106 @@ +--TEST-- +mysqli_change_user() - GET_LOCK() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +die("skip - is the server still buggy?"); +?> +--INI-- +max_execution_time=240 +--FILE-- +<?php + require_once('connect.inc'); + require_once('table.inc'); + + // We need this little hack to be able to re-run the test + $lock = 'phptest_' . mt_rand(0, 100000); + $thread_id = mysqli_thread_id($link); + + printf("Testing GET_LOCK()...\n"); + + if (!$res = mysqli_query($link, sprintf('SELECT GET_LOCK("%s", 2) AS _ok', $lock))) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ($row['_ok'] != 1) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + else + printf("... lock '%s' acquired by thread %d\n", $lock, $thread_id); + + mysqli_free_result($res); + + + // GET_LOCK("phptest") should be released + /* From the mysql_change_user documentation: +This command resets the state as if one had done a new connect. (See Section 25.2.13, “Controlling Automatic Reconnect Behaviorâ€.) It always performs a ROLLBACK of any active transactions, closes and drops all temporary tables, and unlocks all locked tables. Session system variables are reset to the values of the corresponding global system variables. Prepared statements are released and HANDLER variables are closed. Locks acquired with GET_LOCK() are released. These effects occur even if the user didn't change. + */ + mysqli_change_user($link, $user, $passwd, $db); +sleep(5); + $new_thread_id = mysqli_thread_id($link); + + printf("... calling IS_USED_LOCK() on '%s' using thread '%d'\n", $lock, $new_thread_id); + if (!$res = mysqli_query($link, 'SELECT IS_USED_LOCK("phptest") AS _ok')) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ($row['_ok'] != NULL) + printf("[006] Lock '%s' should have been released, [%d] %s\n", + $lock, + mysqli_errno($link), mysqli_error($link)); + + printf("... calling IS_FREE_LOCK() on '%s' using thread '%d'\n", $lock, $new_thread_id); + if (!$res = mysqli_query($link, 'SELECT IS_FREE_LOCK("phptest") AS _ok')) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ($row['_ok'] != 1) + printf("[009] Lock '%s' should have been released, [%d] %s\n", + $lock, + mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + + /* Ok, let's try a NEW connection and a NEW lock! */ + mysqli_close($link); + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[010] Cannot open new connection, [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error()); + + do { + $newlock = 'phptest_' . mt_rand(0, 100000); + } while ($lock == $newlock); + + $new_thread_id = mysqli_thread_id($link); + printf("... calling IS_USED_LOCK() on '%s' using new connection with thread '%d'\n", $newlock, $new_thread_id); + if (!$res = mysqli_query($link, 'SELECT IS_USED_LOCK("phptest") AS _ok')) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ($row['_ok'] != NULL) + printf("[013] Lock '%s' should have been released, [%d] %s\n", + $lock, + mysqli_errno($link), mysqli_error($link)); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Testing GET_LOCK()... +... lock 'phptest_%d' acquired by thread %d +... calling IS_USED_LOCK() on 'phptest_%d' using thread '%d' +... calling IS_FREE_LOCK() on 'phptest_%d' using thread '%d' +... calling IS_USED_LOCK() on 'phptest_%d' using new connection with thread '%d' +done! diff --git a/ext/mysqli/tests/mysqli_change_user_insert_id.phpt b/ext/mysqli/tests/mysqli_change_user_insert_id.phpt new file mode 100644 index 0000000..7d1c398 --- /dev/null +++ b/ext/mysqli/tests/mysqli_change_user_insert_id.phpt @@ -0,0 +1,65 @@ +--TEST-- +mysqli_change_user() - LAST_INSERT_ID() - http://bugs.mysql.com/bug.php?id=45184? +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); + +if (!$IS_MYSQLND) { + die("skip Might hit known and open bugs http://bugs.mysql.com/bug.php?id=30472, http://bugs.mysql.com/bug.php?id=45184"); +} +?> +--FILE-- +<?php + require_once('connect.inc'); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, 'CREATE TABLE test(id INT AUTO_INCREMENT PRIMARY KEY, label CHAR(10))')) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "INSERT INTO test(id, label) VALUES (100, 'z')")) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (($insert_id = mysqli_insert_id($link)) !== 100) + printf("[005] Expecting 100, got %d, [%d] %s\n", + $insert_id, + mysqli_errno($link), mysqli_error($link)); + + // LAST_INSERT_ID should be reset + mysqli_change_user($link, $user, $passwd, $db); + + if (($insert_id = mysqli_insert_id($link)) !== 0) + printf("[006] Expecting 0, got %d, [%d] %s\n", + $insert_id, + mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, 'SELECT LAST_INSERT_ID() as _insert_id')) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + + if ($row['_insert_id'] != $insert_id) + printf("LAST_INSERT_ID() [%d] and mysqli_insert_id [%d] differ!\n", + $row['_insert_id'], $insert_id); + + if ($row['_insert_id'] != 0) + printf("Expecting 0 got %d\n", $row['_insert_id']); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt b/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt new file mode 100644 index 0000000..e40154c --- /dev/null +++ b/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt @@ -0,0 +1,107 @@ +--TEST-- +mysqli_change_user() - table locks, GET_LOCK(), temporary tables +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +die("skip - is the server still buggy?"); +?> +--FILE-- +<?php + require_once('connect.inc'); + require_once('table.inc'); + + if (!$link2 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot create second connection handle, [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error()); + + if (!mysqli_query($link, 'LOCK TABLE test WRITE')) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + /* + if ($res = mysqli_query($link2, 'SELECT COUNT(*) AS _num FROM test')) { + printf("[003] Reading from test should not be possible due to a lock, [%d] %s\n", + mysqli_errno($link2), mysqli_error($link2)); + mysqli_free_result($res); + } + */ + + // LOCKS should be removed + mysqli_change_user($link, $user, $passwd, $db); + + if (!$res = mysqli_query($link2, 'SELECT COUNT(*) AS _num FROM test')) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ($row['_num'] < 1) + printf("[005] There should be some rows in the table test\n"); + + mysqli_free_result($res); + mysqli_close($link2); + + if (!mysqli_query($link, 'DROP TABLE test')) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, 'CREATE TEMPORARY TABLE test(id INT)')) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, 'INSERT INTO test(id) VALUES (1), (2), (3)')) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, 'SELECT COUNT(*) AS _num FROM test')) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ($row['_num'] != 3) + printf("[011] There should be three rows in the table test\n"); + + mysqli_free_result($res); + + // Temporary tables should be dropped + mysqli_change_user($link, $user, $passwd, $db); + + if ($res = mysqli_query($link, 'SELECT COUNT(*) AS _num FROM test')) { + printf("[012] There should be no table test any more, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + } + + if (!$res = mysqli_query($link, 'SELECT GET_LOCK("phptest", 2) AS _ok')) + printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[014] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ($row['_ok'] != 1) + printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + + // GET_LOCK("phptest") should be released + mysqli_change_user($link, $user, $passwd, $db); + + if (!$res = mysqli_query($link, 'SELECT IS_FREE_LOCK("phptest") AS _ok')) + printf("[016] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[017] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ($row['_ok'] != 1) + printf("[018] Lock 'phptest' should have been released, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done! diff --git a/ext/mysqli/tests/mysqli_change_user_oo.phpt b/ext/mysqli/tests/mysqli_change_user_oo.phpt new file mode 100644 index 0000000..61444ae --- /dev/null +++ b/ext/mysqli/tests/mysqli_change_user_oo.phpt @@ -0,0 +1,84 @@ +--TEST-- +mysqli->change_user() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +require_once('table.inc'); +if (!$IS_MYSQLND && (mysqli_get_server_version($link) < 50118 && mysqli_get_server_version($link) > 50100)) { + die("skip Your MySQL Server version has a known bug that will cause a crash"); +} +?> +--FILE-- +<?php + include_once("connect.inc"); + + $link = NULL; + $tmp = NULL; + + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!is_null($tmp = @$mysqli->change_user())) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @$mysqli->change_user($link))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @$mysqli->change_user($link, $link))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @$mysqli->change_user($link, $link, $link, $link))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = $mysqli->change_user($user . '_unknown_really', $passwd . 'non_empty', $db))) + printf("[006] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = $mysqli->change_user($user, $passwd . '_unknown_really', $db))) + printf("[007] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = $mysqli->change_user($user, $passwd, $db . '_unknown_really'))) + printf("[008] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli->query('SET @mysqli_change_user_test_var=1')) + printf("[009] Failed to set test variable: [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (!$res = $mysqli->query('SELECT @mysqli_change_user_test_var AS test_var')) + printf("[010] [%d] %s\n", $mysqli->errno, $mysqli->error); + $tmp = $res->fetch_assoc(); + $res->free_result(); + if (1 != $tmp['test_var']) + printf("[011] Cannot set test variable\n"); + + if (true !== ($tmp = $mysqli->change_user($user, $passwd, $db))) + printf("[012] Expecting true, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = $mysqli->query('SELECT database() AS dbname, user() AS user')) + printf("[013] [%d] %s\n", $mysqli->errno, $mysqli->error); + $tmp = $res->fetch_assoc(); + $res->free_result(); + + if (substr($tmp['user'], 0, strlen($user)) !== $user) + printf("[014] Expecting user %s, got user() %s\n", $user, $tmp['user']); + if ($tmp['dbname'] != $db) + printf("[015] Expecting database %s, got database() %s\n", $db, $tmp['dbname']); + + if (!$res = $mysqli->query('SELECT @mysqli_change_user_test_var AS test_var')) + printf("[016] [%d] %s\n", $mysqli->errno, $mysqli->error); + $tmp = $res->fetch_assoc(); + $res->free_result(); + if (NULL !== $tmp['test_var']) + printf("[017] Test variable is still set!\n"); + + $mysqli->close(); + + if (NULL !== ($tmp = @$mysqli->change_user($user, $passwd, $db))) + printf("[018] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_change_user_prepared_statements.phpt b/ext/mysqli/tests/mysqli_change_user_prepared_statements.phpt new file mode 100644 index 0000000..6a37b6b --- /dev/null +++ b/ext/mysqli/tests/mysqli_change_user_prepared_statements.phpt @@ -0,0 +1,33 @@ +--TEST-- +mysqli_change_user() - Prepared Statement +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once('connect.inc'); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (!$stmt = mysqli_prepare($link, "SELECT 'prepared statements should be released'")) + printf("[002] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + mysqli_change_user($link, $user, $passwd, $db); + + $wrong = null; + if ($stmt->execute() && $stmt->bind_result($wrong) && $stmt->fetch()) { + printf("This is wrong, because after a mysqli_change_user() %s\n", $wrong); + } else { + if ($stmt->errno == 0) + printf("Error code 2013, 1243 or similar should have been set\n"); + } + + mysqli_close($link); + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_change_user_rollback.phpt b/ext/mysqli/tests/mysqli_change_user_rollback.phpt new file mode 100644 index 0000000..ed3330e --- /dev/null +++ b/ext/mysqli/tests/mysqli_change_user_rollback.phpt @@ -0,0 +1,70 @@ +--TEST-- +mysqli_change_user() - ROLLBACK +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die(sprintf("Cannot connect, [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); + +if (!have_innodb($link)) + die(sprintf("Needs InnoDB support, [%d] %s", $link->errno, $link->error)); +?> +--FILE-- +<?php + require_once('connect.inc'); + require_once('table.inc'); + + if (!mysqli_query($link, 'ALTER TABLE test ENGINE=InnoDB')) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_autocommit($link, false); + + if (!$res = mysqli_query($link, 'SELECT COUNT(*) AS _num FROM test')) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + + $num = $row['_num']; + assert($num > 0); + + if (!$res = mysqli_query($link, 'DELETE FROM test')) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, 'SELECT COUNT(*) AS _num FROM test')) + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + + if (0 != $row['_num']) + printf("[007] Rows should have been deleted in this transaction\n"); + + // DELETE should be rolled back + mysqli_change_user($link, $user, $passwd, $db); + + if (!$res = mysqli_query($link, 'SELECT COUNT(*) AS _num FROM test')) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ($row['_num'] != $num) + printf("[010] Expecting %d rows in the table test, found %d rows\n", + $num, $row['_num']); + + mysqli_free_result($res); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_change_user_set_names.phpt b/ext/mysqli/tests/mysqli_change_user_set_names.phpt new file mode 100644 index 0000000..3579e31 --- /dev/null +++ b/ext/mysqli/tests/mysqli_change_user_set_names.phpt @@ -0,0 +1,165 @@ +--TEST-- +mysqli_change_user() - SET NAMES +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die(sprintf("skip [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); + +if (!$res = mysqli_query($link, 'SELECT version() AS server_version')) + die(sprintf("skip [%d] %s\n", mysqli_errno($link), mysqli_error($link))); + +$tmp = mysqli_fetch_assoc($res); +mysqli_free_result($res); +$version = explode('.', $tmp['server_version']); +if (empty($version)) + die(sprintf("skip Cannot determine server version, we need MySQL Server 4.1+ for the test!")); + +if ($version[0] <= 4 && $version[1] < 1) + die(sprintf("skip We need MySQL Server 4.1+ for the test!")); +?> +--FILE-- +<?php + require_once('connect.inc'); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (!$res = mysqli_query($link, "SHOW CHARACTER SET LIKE 'latin%'")) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $charsets = array(); + while ($row = mysqli_fetch_assoc($res)) + $charsets[$row['Charset']] = $row['Default collation']; + + mysqli_free_result($res); + if (!mysqli_query($link, 'SET NAMES DEFAULT')) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, 'SELECT + @@character_set_client AS charset_client, + @@character_set_connection AS charset_connection, + @@character_set_results AS charset_results, + @@collation_connection AS collation_connection, + @@collation_database AS collation_database, + @@collation_server AS collation_server')) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$defaults = mysqli_fetch_assoc($res)) + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + + $not_changed = $defaults; + foreach ($charsets as $charset => $collation) { + + if (isset($not_changed['charset_client']) && + $charset != $not_changed['charset_client'] && + mysqli_query($link, sprintf("SET @@character_set_client = '%s'", $charset))) + unset($not_changed['charset_client']); + + if (isset($not_changed['charset_connection']) && + $charset != $not_changed['charset_connection'] && + mysqli_query($link, sprintf("SET @@character_connection = '%s'", $charset))) + unset($not_changed['charset_connection']); + + if (isset($not_changed['charset_results']) && + $charset != $not_changed['charset_results'] && + mysqli_query($link, sprintf("SET @@character_set_results = '%s'", $charset))) + unset($not_changed['charset_results']); + + if (isset($not_changed['collation_connection']) && + $collation != $not_changed['collation_connection'] && + mysqli_query($link, sprintf("SET @@collation_connection = '%s'", $collation))) + unset($not_changed['collation_connection']); + + if (isset($not_changed['collation_database']) && + $collation != $not_changed['collation_database'] && + mysqli_query($link, sprintf("SET @@collation_database = '%s'", $collation))) + unset($not_changed['collation_database']); + + if (isset($not_changed['collation_server']) && + $collation != $not_changed['collation_server'] && + mysqli_query($link, sprintf("SET @@collation_server = '%s'", $collation))) + unset($not_changed['collation_server']); + + if (empty($not_changed)) + break; + } + + if (!$res = mysqli_query($link, 'SELECT + @@character_set_client AS charset_client, + @@character_set_connection AS charset_connection, + @@character_set_results AS charset_results, + @@collation_connection AS collation_connection, + @@collation_database AS collation_database, + @@collation_server AS collation_server')) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$modified = mysqli_fetch_assoc($res)) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + + if ($modified == $defaults) + printf("[008] Not all settings have been changed\n"); + + // LAST_INSERT_ID should be reset + mysqli_change_user($link, $user, $passwd, $db); + + if (!$res = mysqli_query($link, 'SELECT + @@character_set_client AS charset_client, + @@character_set_connection AS charset_connection, + @@character_set_results AS charset_results, + @@collation_connection AS collation_connection, + @@collation_database AS collation_database, + @@collation_server AS collation_server')) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$new = mysqli_fetch_assoc($res)) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + + if ($new == $modified) { + printf("[011] Charsets/collations have not been reset.\n"); + printf("Got:\n"); + var_dump($new); + printf("Expected:\n"); + var_dump($defaults); + } + + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1)) { + // charsets cannot take any other value but utf8 in unicode mode + $defaults['charset_client'] = 'utf8'; + $defaults['charset_connection'] = 'utf8'; + $defaults['charset_results'] = 'utf8'; + $defaults['collation_connection'] = 'utf8_general_ci'; + } + + if ($new != $defaults) { + printf("[012] Charsets/collations have not been reset to their defaults.\n"); + printf("Got:\n"); + var_dump($new); + printf("Expected:\n"); + var_dump($defaults); + } + + if (!is_object($charset = mysqli_get_charset($link))) + printf("[013] Expecting object/std_class, got %s/%s\n", gettype($charset), $charset); + + if ($charset->charset != $defaults['charset_connection']) + printf("[014] Expecting connection charset to be %s got %s\n", + $defaults['charset_connection'], + $charset->charset); + + if ($charset->collation != $defaults['collation_connection']) + printf("[015] Expecting collation to be %s got %s\n", + $defaults['collation_connection'], + $charset->collation); + + mysqli_close($link); + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_character_set.phpt b/ext/mysqli/tests/mysqli_character_set.phpt new file mode 100644 index 0000000..1bfe9cb --- /dev/null +++ b/ext/mysqli/tests/mysqli_character_set.phpt @@ -0,0 +1,111 @@ +--TEST-- +Fetching results from tables of different charsets. +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +require_once('skipifunicode.inc'); +require_once('skipifemb.inc'); + +if (!function_exists('mysqli_set_charset')) { + die('skip mysqli_set_charset() not available'); +} +if (version_compare(PHP_VERSION, '5.9.9', '>') == 1) { + die('skip set character set not functional with PHP 6 (fomerly PHP 6 && unicode.semantics=On)'); +} +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!$res = mysqli_query($link, 'SELECT version() AS server_version')) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + mysqli_free_result($res); + $version = explode('.', $tmp['server_version']); + if (empty($version)) + printf("[003] Cannot determine server version, need MySQL Server 4.1+ for the test!\n"); + + if ($version[0] <= 4 && $version[1] < 1) + printf("[004] Need MySQL Server 4.1+ for the test!\n"); + + if (!$res = mysqli_query($link, "SHOW CHARACTER SET")) + printf("[005] Cannot get list of available character sets, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + $charsets = array(); + while ($row = mysqli_fetch_assoc($res)) + $charsets[] = $row; + mysqli_free_result($res); + + foreach ($charsets as $charset) { + $k = $charset['Charset']; + /* The server currently 17.07.2007 can't handle data sent in ucs2 */ + /* The server currently 16.08.2010 can't handle data sent in utf16 and utf32 */ + /* The server currently 02.09.2011 can't handle data sent in utf16le */ + if ($charset['Charset'] == 'ucs2' || $charset['Charset'] == 'utf16' || $charset['Charset'] == 'utf32' || 'utf16le' == $charset['Charset']) { + continue; + } + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[006 + %s] [%d] %s\n", $k, mysqli_errno($link), mysqli_error($link)); + + $sql = sprintf("CREATE TABLE test(id INT, label CHAR(1)) CHARACTER SET '%s' ", $charset['Charset']); + if (!mysqli_query($link, $sql)) { + printf("[007 + %s] %s [%d] %s\n", $k, $sql, mysqli_errno($link), mysqli_error($link)); + continue; + } + + if (!mysqli_set_charset($link, $charset['Charset'])) { + printf("[008 + %s] [%d] %s\n", $k, mysqli_errno($link), mysqli_error($link)); + continue; + } + + for ($i = 1; $i <= 3; $i++) { + if (!mysqli_query($link, sprintf("INSERT INTO test (id, label) VALUES (%d, '%s')", + $i, mysqli_real_escape_string($link, chr(ord("a") + $i))))) + { + var_dump($charset['Charset']); + printf("[009 + %s] [%d] %s\n", $k, mysqli_errno($link), mysqli_error($link)); + continue; + } + } + + if (!$res = mysqli_query($link, "SELECT id, label FROM test")) + printf("[010 + %s] [%d] %s\n", $k, mysqli_errno($link), mysqli_error($link)); + + for ($i = 1; $i <= 3; $i++) { + + if (!$tmp = mysqli_fetch_assoc($res)) + printf("[011 + %s] [%d] %s\n", $k, mysqli_errno($link), mysqli_error($link)); + + if ($tmp['id'] != $i) + printf("[012 + %s] Expecting %d, got %s, [%d] %s\n", $k, + $i, $tmp['id'], + mysqli_errno($link), mysqli_error($link)); + + if ($tmp['label'] != chr(ord("a") + $i)) + printf("[013 + %s] Expecting %d, got %s, [%d] %s\n", $k, + chr(ord("a") + $i), $tmp['label'], + mysqli_errno($link), mysqli_error($link)); + + } + mysqli_free_result($res); + } + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done! diff --git a/ext/mysqli/tests/mysqli_character_set_name.phpt b/ext/mysqli/tests/mysqli_character_set_name.phpt new file mode 100644 index 0000000..722faca --- /dev/null +++ b/ext/mysqli/tests/mysqli_character_set_name.phpt @@ -0,0 +1,75 @@ +--TEST-- +mysqli_chararcter_set_name(), mysql_client_encoding() [alias] +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + /* NOTE: http://bugs.mysql.com/bug.php?id=7923 makes this test fail very likely on all 4.1.x - 5.0.x! */ + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_character_set_name())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_character_set_name($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_character_set_name($link, $link, $link))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[005] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!$res = mysqli_query($link, 'SELECT version() AS server_version')) + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + mysqli_free_result($res); + $version = explode('.', $tmp['server_version']); + if (empty($version)) + printf("[006] Cannot determine server version, need MySQL Server 4.1+ for the test!\n"); + + if ($version[0] <= 4 && $version[1] < 1) + printf("[007] Need MySQL Server 4.1+ for the test!\n"); + + if (!$res = mysqli_query($link, 'SELECT @@character_set_connection AS charset, @@collation_connection AS collation')) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + mysqli_free_result($res); + if (!$tmp['charset']) + printf("[009] Cannot determine current character set and collation\n"); + + $charset = mysqli_character_set_name($link); + if ($tmp['charset'] !== $charset) { + if ($tmp['collation'] === $charset) { + printf("[010] Could be known server bug http://bugs.mysql.com/bug.php?id=7923, collation %s instead of character set returned, expected string/%s, got %s/%s\n", + $tmp['collation'], $tmp['charset'], gettype($charset), $charset); + } else { + printf("[011] Expecting character set %s/%s, got %s/%s\n", gettype($tmp['charset']), $tmp['charset'], gettype($charset), $charset); + } + } + + $charset2 = mysqli_character_set_name($link); + if ($charset2 !== $charset) { + printf("[012] Alias mysqli_character_set_name returned %s/%s, expected %s/%s\n", gettype($charset2), $charset2, gettype($charset), $charset); + } + + mysqli_close($link); + + if (NULL !== ($tmp = @mysqli_character_set_name($link))) + printf("[013] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + /* Make sure that the function alias exists */ + if (!is_null($tmp = @mysqli_character_set_name())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_character_set_name_oo.phpt b/ext/mysqli/tests/mysqli_character_set_name_oo.phpt new file mode 100644 index 0000000..7b71940 --- /dev/null +++ b/ext/mysqli/tests/mysqli_character_set_name_oo.phpt @@ -0,0 +1,70 @@ +--TEST-- +mysqli_chararcter_set_name(), mysql_client_encoding() [alias] +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifemb.inc'); + require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + /* NOTE: http://bugs.mysql.com/bug.php?id=7923 makes this test fail very likely on all 4.1.x - 5.0.x! */ + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!is_null($tmp = @$mysqli->character_set_name($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = $mysqli->query('SELECT version() AS server_version')) + printf("[003] [%d] %s\n", $mysqli->errno, $mysqli->error); + $tmp = $res->fetch_assoc(); + $res->free_result(); + $version = explode('.', $tmp['server_version']); + if (empty($version)) + printf("[006] Cannot determine server version, need MySQL Server 4.1+ for the test!\n"); + + if ($version[0] <= 4 && $version[1] < 1) + printf("[007] Need MySQL Server 4.1+ for the test!\n"); + + if (!$res = $mysqli->query('SELECT @@character_set_connection AS charset, @@collation_connection AS collation')) + printf("[008] [%d] %s\n", $mysqli->errno, $mysqli->error); + $tmp = $res->fetch_assoc(); + $res->free_result(); + if (!$tmp['charset']) + printf("[009] Cannot determine current character set and collation\n"); + + $charset = $mysqli->character_set_name(); + if ($tmp['charset'] !== $charset) { + if ($tmp['collation'] === $charset) { + printf("[010] Could be known server bug http://bugs.mysql.com/bug.php?id=7923, collation %s instead of character set returned, expected string/%s, got %s/%s\n", + $tmp['collation'], $tmp['charset'], gettype($charset), $charset); + } else { + printf("[011] Expecting character set %s/%s, got %s/%s\n", gettype($tmp['charset']), $tmp['charset'], gettype($charset), $charset); + } + } + + $charset2 = $mysqli->character_set_name(); + if ($charset2 !== $charset) { + printf("[012] Alias mysqli_character_set_name returned %s/%s, expected %s/%s\n", + gettype($charset2), $charset2, gettype($charset), $charset); + } + + $mysqli->close(); + + if (NULL !== ($tmp = @$mysqli->character_set_name())) + printf("[013] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + /* Make sure that the function alias exists */ + if (!is_null($tmp = @$mysqli->character_set_name())) + printf("[014] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_class_mysqli_driver_interface.phpt b/ext/mysqli/tests/mysqli_class_mysqli_driver_interface.phpt new file mode 100644 index 0000000..681590e --- /dev/null +++ b/ext/mysqli/tests/mysqli_class_mysqli_driver_interface.phpt @@ -0,0 +1,128 @@ +--TEST-- +Interface of the class mysqli_driver +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require('connect.inc'); + require('table.inc'); + + $driver = new mysqli_driver(); + + printf("Parent class:\n"); + var_dump(get_parent_class($driver)); + + printf("\nMethods:\n"); + $methods = get_class_methods($driver); + $expected_methods = array(); + + if (!$IS_MYSQLND && (isset($methods['embedded_server_start']))) { + /* libmysql only - needs extra compile flag, no way to check properly in the + PHP user land if its compiled in or not */ + $expected_methods = array_merge($expected_methods, array( + 'embedded_server_start' => true, + 'embedded_server_end' => true, + )); + } + + foreach ($methods as $k => $method) { + if (isset($expected_methods[$method])) { + unset($expected_methods[$method]); + unset($methods[$k]); + } + } + if (!empty($expected_methods)) { + printf("Dumping list of missing methods.\n"); + var_dump($expected_methods); + } + if (!empty($methods)) { + printf("Dumping list of unexpected methods.\n"); + var_dump($methods); + } + if (empty($expected_methods) && empty($methods)) + printf("ok\n"); + + printf("\nClass variables:\n"); + $variables = array_keys(get_class_vars(get_class($driver))); + sort($variables); + foreach ($variables as $k => $var) + printf("%s\n", $var); + + printf("\nObject variables:\n"); + $variables = array_keys(get_object_vars($driver)); + foreach ($variables as $k => $var) + printf("%s\n", $var); + + printf("\nMagic, magic properties:\n"); + + assert(mysqli_get_client_info() === $driver->client_info); + printf("driver->client_info = '%s'\n", $driver->client_info); + + assert(mysqli_get_client_version() === $driver->client_version); + printf("driver->client_version = '%s'\n", $driver->client_version); + + assert($driver->driver_version > 0); + printf("driver->driver_version = '%s'\n", $driver->driver_version); + + assert(in_array($driver->report_mode, + array( + MYSQLI_REPORT_ALL, + MYSQLI_REPORT_STRICT, + MYSQLI_REPORT_ERROR, + MYSQLI_REPORT_INDEX, + MYSQLI_REPORT_OFF + ) + )); + + printf("driver->report_mode = '%s'\n", $driver->report_mode); + $driver->report_mode = MYSQLI_REPORT_STRICT; + assert($driver->report_mode === MYSQLI_REPORT_STRICT); + + assert(is_bool($driver->embedded)); + printf("driver->embedded = '%s'\n", $driver->embedded); + + printf("driver->reconnect = '%s'\n", $driver->reconnect); + + printf("\nAccess to undefined properties:\n"); + printf("driver->unknown = '%s'\n", @$driver->unknown); + + print "done!"; +?> +--EXPECTF-- +Parent class: +bool(false) + +Methods: +ok + +Class variables: +client_info +client_version +driver_version +embedded +reconnect +report_mode + +Object variables: +client_info +client_version +driver_version +embedded +reconnect +report_mode + +Magic, magic properties: +driver->client_info = '%s' +driver->client_version = '%d' +driver->driver_version = '%d' +driver->report_mode = '%d' +driver->embedded = '' +driver->reconnect = '' + +Access to undefined properties: +driver->unknown = '' +done! diff --git a/ext/mysqli/tests/mysqli_class_mysqli_driver_reflection.phpt b/ext/mysqli/tests/mysqli_class_mysqli_driver_reflection.phpt new file mode 100644 index 0000000..2e6d9c2 --- /dev/null +++ b/ext/mysqli/tests/mysqli_class_mysqli_driver_reflection.phpt @@ -0,0 +1,92 @@ +--TEST-- +Interface of the class mysqli_driver - Reflection +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('connect.inc'); +if (($tmp = substr(PHP_VERSION, 0, strpos(PHP_VERSION, '.'))) && ($tmp < 5)) + die("skip Reflection not available before PHP 5 (found PHP $tmp)"); + +/* +Let's not deal with cross-version issues in the EXPECTF/UEXPECTF. +Most of the things which we test are covered by mysqli_class_*_interface.phpt. +Those tests go into the details and are aimed to be a development tool, no more. +*/ +if (!$IS_MYSQLND) + die("skip Test has been written for the latest version of mysqlnd only"); +?> +--FILE-- +<?php + require_once('reflection_tools.inc'); + $class = new ReflectionClass('mysqli_driver'); + inspectClass($class); + print "done!"; +?> +--EXPECTF-- +Inspecting class 'mysqli_driver' +isInternal: yes +isUserDefined: no +isInstantiable: yes +isInterface: no +isAbstract: no +isFinal: yes +isIteratable: no +Modifiers: '%d' +Parent Class: '' +Extension: 'mysqli' + +Inspecting property 'client_info' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'client_version' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'driver_version' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'embedded' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'reconnect' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'report_mode' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 +Default property 'client_info' +Default property 'client_version' +Default property 'driver_version' +Default property 'embedded' +Default property 'reconnect' +Default property 'report_mode' +done! diff --git a/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt b/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt new file mode 100644 index 0000000..df7d1c6 --- /dev/null +++ b/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt @@ -0,0 +1,319 @@ +--TEST-- +Interface of the class mysqli +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require('connect.inc'); + + $mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + + printf("Parent class:\n"); + var_dump(get_parent_class($mysqli)); + + printf("\nMethods:\n"); + $methods = get_class_methods($mysqli); + $expected_methods = array( + 'autocommit' => true, + 'change_user' => true, + 'character_set_name' => true, + 'close' => true, + 'commit' => true, + 'connect' => true, + 'dump_debug_info' => true, + 'escape_string' => true, + 'get_charset' => true, + 'get_client_info' => true, + 'get_server_info' => true, + 'get_warnings' => true, + 'init' => true, + 'kill' => true, + 'more_results' => true, + 'multi_query' => true, + 'mysqli' => true, + 'next_result' => true, + 'options' => true, + 'ping' => true, + 'prepare' => true, + 'query' => true, + 'real_connect' => true, + 'real_escape_string' => true, + 'real_query' => true, + 'refresh' => true, + 'rollback' => true, + 'select_db' => true, + 'set_charset' => true, + 'set_opt' => true, + 'ssl_set' => true, + 'stat' => true, + 'stmt_init' => true, + 'store_result' => true, + 'thread_safe' => true, + 'use_result' => true, + ); + + if (version_compare(PHP_VERSION, '5.3.99', '<=')) { + $expected_methods['client_encoding'] = true; + } + + if ($IS_MYSQLND) { + // mysqlnd only + /* $expected_methods['get_client_stats'] = true; */ + $expected_methods['get_connection_stats'] = true; + $expected_methods['reap_async_query'] = true; + $expected_methods['poll'] = true; + } else { + // libmysql only + if (function_exists('mysqli_ssl_set')) + $expected_methods['ssl_set'] = true; + $expected_methods['set_local_infile_default'] = true; + $expected_methods['set_local_infile_handler'] = true; + } + + /* we should add ruled when to expect them */ + if (function_exists('mysqli_debug')) + $expected_methods['debug'] = true; + if (function_exists('ssl_set')) + $expected_methods['ssl_set'] = true; + + foreach ($methods as $k => $method) { + if (isset($expected_methods[$method])) { + unset($methods[$k]); + unset($expected_methods[$method]); + } + } + if (!empty($methods)) { + printf("Dumping list of unexpected methods.\n"); + var_dump($methods); + } + if (!empty($expected_methods)) { + printf("Dumping list of missing methods.\n"); + var_dump($expected_methods); + } + if (empty($methods) && empty($expected_methods)) + printf("ok\n"); + + printf("\nClass variables:\n"); + + $expected_class_variables = $expected_object_variables = array( + "affected_rows" => true, + "client_info" => true, + "client_version" => true, + "connect_errno" => true, + "connect_error" => true, + "errno" => true, + "error" => true, + "field_count" => true, + "host_info" => true, + "info" => true, + "insert_id" => true, + "protocol_version" => true, + "server_info" => true, + "server_version" => true, + "sqlstate" => true, + "stat" => true, + "thread_id" => true, + "warning_count" => true, + ); + + if (version_compare(PHP_VERSION, '5.3.99', '>')) { + $expected_class_variables["error_list"] = true; + $expected_object_variables["error_list"] = true; + } + + $variables = get_class_vars(get_class($mysqli)); + foreach ($variables as $var => $v) { + if (isset($expected_class_variables[$var])) { + unset($expected_class_variables[$var]); + unset($variables[$var]); + } + } + + if (!empty($expected_class_variables)) { + printf("Dumping list of missing class variables\n"); + var_dump($expected_class_variables); + } + if (!empty($variables)) { + printf("Dumping list of unexpected class variables\n"); + var_dump($variables); + } + echo "ok\n"; + + printf("\nObject variables:\n"); + $variables = get_object_vars($mysqli); + foreach ($variables as $var => $v) { + if (isset($expected_object_variables[$var])) { + unset($expected_object_variables[$var]); + unset($variables[$var]); + } + } + + if (!empty($expected_object_variables)) { + printf("Dumping list of missing object variables\n"); + var_dump($expected_object_variables); + } + if (!empty($variables)) { + printf("Dumping list of unexpected object variables\n"); + var_dump($variables); + } + echo "ok\n"; + + + printf("\nMagic, magic properties:\n"); + + assert(mysqli_affected_rows($link) === $mysqli->affected_rows); + printf("mysqli->affected_rows = '%s'/%s ('%s'/%s)\n", + $mysqli->affected_rows, gettype($mysqli->affected_rows), + mysqli_affected_rows($link), gettype(mysqli_affected_rows($link))); + + assert(mysqli_get_client_info() === $mysqli->client_info); + printf("mysqli->client_info = '%s'/%s ('%s'/%s)\n", + $mysqli->client_info, gettype($mysqli->client_info), + mysqli_get_client_info(), gettype(mysqli_get_client_info())); + + assert(mysqli_get_client_version() === $mysqli->client_version); + printf("mysqli->client_version = '%s'/%s ('%s'/%s)\n", + $mysqli->client_version, gettype($mysqli->client_version), + mysqli_get_client_version(), gettype(mysqli_get_client_version())); + + assert(mysqli_errno($link) === $mysqli->errno); + printf("mysqli->errno = '%s'/%s ('%s'/%s)\n", + $mysqli->errno, gettype($mysqli->errno), + mysqli_errno($link), gettype(mysqli_errno($link))); + + assert(mysqli_error($link) === $mysqli->error); + printf("mysqli->error = '%s'/%s ('%s'/%s)\n", + $mysqli->error, gettype($mysqli->error), + mysqli_error($link), gettype(mysqli_error($link))); + + if (version_compare(PHP_VERSION, '5.3.99', '>')) { + assert(mysqli_error_list($link) === $mysqli->error_list); + assert(is_array($mysqli->error_list)); + } + + assert(mysqli_field_count($link) === $mysqli->field_count); + printf("mysqli->field_count = '%s'/%s ('%s'/%s)\n", + $mysqli->field_count, gettype($mysqli->field_count), + mysqli_field_count($link), gettype(mysqli_field_count($link))); + + assert(mysqli_insert_id($link) === $mysqli->insert_id); + printf("mysqli->insert_id = '%s'/%s ('%s'/%s)\n", + $mysqli->insert_id, gettype($mysqli->insert_id), + mysqli_insert_id($link), gettype(mysqli_insert_id($link))); + + assert(mysqli_sqlstate($link) === $mysqli->sqlstate); + printf("mysqli->sqlstate = '%s'/%s ('%s'/%s)\n", + $mysqli->sqlstate, gettype($mysqli->sqlstate), + mysqli_sqlstate($link), gettype(mysqli_sqlstate($link))); + + assert(soundex(mysqli_stat($link)) == soundex($mysqli->stat)); + printf("mysqli->stat = '%s'/%s ('%s'/%s)\n", + $mysqli->stat, gettype($mysqli->stat), + mysqli_stat($link), gettype(mysqli_stat($link))); + + assert(mysqli_get_host_info($link) === $mysqli->host_info); + printf("mysqli->host_info = '%s'/%s ('%s'/%s)\n", + $mysqli->host_info, gettype($mysqli->host_info), + mysqli_get_host_info($link), gettype(mysqli_get_host_info($link))); + + /* note that the data types are different */ + assert(mysqli_info($link) == $mysqli->info); + printf("mysqli->info = '%s'/%s ('%s'/%s)\n", + $mysqli->info, gettype($mysqli->info), + mysqli_info($link), gettype(mysqli_info($link))); + + assert(mysqli_thread_id($link) > $mysqli->thread_id); + assert(gettype($mysqli->thread_id) == gettype(mysqli_thread_id($link))); + printf("mysqli->thread_id = '%s'/%s ('%s'/%s)\n", + $mysqli->thread_id, gettype($mysqli->thread_id), + mysqli_thread_id($link), gettype(mysqli_thread_id($link))); + + assert(mysqli_get_proto_info($link) === $mysqli->protocol_version); + printf("mysqli->protocol_version = '%s'/%s ('%s'/%s)\n", + $mysqli->protocol_version, gettype($mysqli->protocol_version), + mysqli_get_proto_info($link), gettype(mysqli_get_proto_info($link))); + + assert(mysqli_get_server_info($link) === $mysqli->server_info); + printf("mysqli->server_info = '%s'/%s ('%s'/%s)\n", + $mysqli->server_info, gettype($mysqli->server_info), + mysqli_get_server_info($link), gettype(mysqli_get_server_info($link))); + + assert(mysqli_get_server_version($link) === $mysqli->server_version); + printf("mysqli->server_version = '%s'/%s ('%s'/%s)\n", + $mysqli->server_version, gettype($mysqli->server_version), + mysqli_get_server_version($link), gettype(mysqli_get_server_version($link))); + + assert(mysqli_warning_count($link) === $mysqli->warning_count); + printf("mysqli->warning_count = '%s'/%s ('%s'/%s)\n", + $mysqli->warning_count, gettype($mysqli->warning_count), + mysqli_warning_count($link), gettype(mysqli_warning_count($link))); + + printf("\nAccess to undefined properties:\n"); + printf("mysqli->unknown = '%s'\n", @$mysqli->unknown); + + @$mysqli->unknown = 13; + printf("setting mysqli->unknown, mysqli_unknown = '%s'\n", @$mysqli->unknown); + + $unknown = 'friday'; + @$mysqli->unknown = $unknown; + printf("setting mysqli->unknown, mysqli_unknown = '%s'\n", @$mysqli->unknown); + + $mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + printf("\nAccess hidden properties for MYSLQI_STATUS_INITIALIZED (TODO documentation):\n"); + assert(mysqli_connect_error() === $mysqli->connect_error); + printf("mysqli->connect_error = '%s'/%s ('%s'/%s)\n", + $mysqli->connect_error, gettype($mysqli->connect_error), + mysqli_connect_error(), gettype(mysqli_connect_error())); + + assert(mysqli_connect_errno() === $mysqli->connect_errno); + printf("mysqli->connect_errno = '%s'/%s ('%s'/%s)\n", + $mysqli->connect_errno, gettype($mysqli->connect_errno), + mysqli_connect_errno(), gettype(mysqli_connect_errno())); + + print "done!"; +?> +--EXPECTF-- +Parent class: +bool(false) + +Methods: +ok + +Class variables: +ok + +Object variables: +ok + +Magic, magic properties: +mysqli->affected_rows = '%s'/integer ('%s'/integer) +mysqli->client_info = '%s'/%unicode|string% ('%s'/%unicode|string%) +mysqli->client_version = '%d'/integer ('%d'/integer) +mysqli->errno = '0'/integer ('0'/integer) +mysqli->error = ''/%unicode|string% (''/%unicode|string%) +mysqli->field_count = '0'/integer ('0'/integer) +mysqli->insert_id = '0'/integer ('0'/integer) +mysqli->sqlstate = '00000'/%unicode|string% ('00000'/%unicode|string%) +mysqli->stat = 'Uptime: %d Threads: %d Questions: %d Slow queries: %d Opens: %d Flush tables: %d Open tables: %d Queries per second avg: %d.%d'/string ('Uptime: %d Threads: %d Questions: %d Slow queries: %d Opens: %d Flush tables: %d Open tables: %d Queries per second avg: %d.%d'/string) +mysqli->host_info = '%s'/%unicode|string% ('%s'/%unicode|string%) +mysqli->info = ''/NULL (''/%unicode|string%) +mysqli->thread_id = '%d'/integer ('%d'/integer) +mysqli->protocol_version = '%d'/integer ('%d'/integer) +mysqli->server_info = '%s'/%unicode|string% ('%s'/%unicode|string%) +mysqli->server_version = '%d'/integer ('%d'/integer) +mysqli->warning_count = '0'/integer ('0'/integer) + +Access to undefined properties: +mysqli->unknown = '' +setting mysqli->unknown, mysqli_unknown = '13' +setting mysqli->unknown, mysqli_unknown = 'friday' + +Access hidden properties for MYSLQI_STATUS_INITIALIZED (TODO documentation): +mysqli->connect_error = ''/NULL (''/NULL) +mysqli->connect_errno = '0'/integer ('0'/integer) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt b/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt new file mode 100644 index 0000000..e4d0b08 --- /dev/null +++ b/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt @@ -0,0 +1,290 @@ +--TEST-- +Interface of the class mysqli +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require('table.inc'); + + function dump_properties($mysqli) { + + printf("\nClass variables:\n"); + $variables = array_keys(get_class_vars(get_class($mysqli))); + sort($variables); + foreach ($variables as $k => $var) { + printf("%s = '%s'\n", $var, var_export(@$mysqli->$var, true)); + } + + printf("\nObject variables:\n"); + $variables = array_keys(get_object_vars($mysqli)); + foreach ($variables as $k => $var) { + printf("%s = '%s'\n", $var, var_export(@$mysqli->$var, true)); + } + + printf("\nMagic, magic properties:\n"); + + assert(@mysqli_affected_rows($mysqli) === @$mysqli->affected_rows); + printf("mysqli->affected_rows = '%s'/%s ('%s'/%s)\n", + @$mysqli->affected_rows, gettype(@$mysqli->affected_rows), + @mysqli_affected_rows($mysqli), gettype(@mysqli_affected_rows($mysqli))); + + assert(@mysqli_get_client_info() === @$mysqli->client_info); + printf("mysqli->client_info = '%s'/%s ('%s'/%s)\n", + @$mysqli->client_info, gettype(@$mysqli->client_info), + @mysqli_get_client_info(), gettype(@mysqli_get_client_info())); + + assert(@mysqli_get_client_version() === @$mysqli->client_version); + printf("mysqli->client_version = '%s'/%s ('%s'/%s)\n", + @$mysqli->client_version, gettype(@$mysqli->client_version), + @mysqli_get_client_version(), gettype(@mysqli_get_client_version())); + + assert(@mysqli_errno($mysqli) === @$mysqli->errno); + printf("mysqli->errno = '%s'/%s ('%s'/%s)\n", + @$mysqli->errno, gettype(@$mysqli->errno), + + @mysqli_errno($mysqli), gettype(@mysqli_errno($mysqli))); + + assert(@mysqli_error($mysqli) === @$mysqli->error); + printf("mysqli->error = '%s'/%s ('%s'/%s)\n", + @$mysqli->error, gettype(@$mysqli->error), + @mysqli_error($mysqli), gettype(@mysqli_error($mysqli))); + + assert(@mysqli_field_count($mysqli) === @$mysqli->field_count); + printf("mysqli->field_count = '%s'/%s ('%s'/%s)\n", + @$mysqli->field_count, gettype(@$mysqli->field_count), + @mysqli_field_count($mysqli), gettype(@mysqli_field_count($mysqli))); + + assert(@mysqli_insert_id($mysqli) === @$mysqli->insert_id); + printf("mysqli->insert_id = '%s'/%s ('%s'/%s)\n", + @$mysqli->insert_id, gettype(@$mysqli->insert_id), + @mysqli_insert_id($mysqli), gettype(@mysqli_insert_id($mysqli))); + + assert(@mysqli_sqlstate($mysqli) === @$mysqli->sqlstate); + printf("mysqli->sqlstate = '%s'/%s ('%s'/%s)\n", + @$mysqli->sqlstate, gettype(@$mysqli->sqlstate), + @mysqli_sqlstate($mysqli), gettype(@mysqli_sqlstate($mysqli))); + + assert(@mysqli_get_host_info($mysqli) === @$mysqli->host_info); + printf("mysqli->host_info = '%s'/%s ('%s'/%s)\n", + @$mysqli->host_info, gettype(@$mysqli->host_info), + @mysqli_get_host_info($mysqli), gettype(@mysqli_get_host_info($mysqli))); + + /* note that the data types are different */ + assert(@mysqli_info($mysqli) == @$mysqli->info); + printf("mysqli->info = '%s'/%s ('%s'/%s)\n", + @$mysqli->info, gettype(@$mysqli->info), + @mysqli_info($mysqli), gettype(@mysqli_info($mysqli))); + + assert(@mysqli_thread_id($mysqli) > @$mysqli->thread_id); + assert(gettype(@$mysqli->thread_id) == gettype(@mysqli_thread_id($mysqli))); + printf("mysqli->thread_id = '%s'/%s ('%s'/%s)\n", + @$mysqli->thread_id, gettype(@$mysqli->thread_id), + @mysqli_thread_id($mysqli), gettype(@mysqli_thread_id($mysqli))); + + assert(@mysqli_get_proto_info($mysqli) === @$mysqli->protocol_version); + printf("mysqli->protocol_version = '%s'/%s ('%s'/%s)\n", + @$mysqli->protocol_version, gettype(@$mysqli->protocol_version), + @mysqli_get_proto_info($mysqli), gettype(@mysqli_get_proto_info($mysqli))); + + assert(@mysqli_get_server_info($mysqli) === @$mysqli->server_info); + printf("mysqli->server_info = '%s'/%s ('%s'/%s)\n", + @$mysqli->server_info, gettype(@$mysqli->server_info), + @mysqli_get_server_info($mysqli), gettype(@mysqli_get_server_info($mysqli))); + + assert(@mysqli_get_server_version($mysqli) === @$mysqli->server_version); + printf("mysqli->server_version = '%s'/%s ('%s'/%s)\n", + @$mysqli->server_version, gettype(@$mysqli->server_version), + @mysqli_get_server_version($mysqli), gettype(@mysqli_get_server_version($mysqli))); + + assert(@mysqli_warning_count($mysqli) === @$mysqli->warning_count); + printf("mysqli->warning_count = '%s'/%s ('%s'/%s)\n", + @$mysqli->warning_count, gettype(@$mysqli->warning_count), + @mysqli_warning_count($mysqli), gettype(@mysqli_warning_count($mysqli))); + + printf("\nAccess to undefined properties:\n"); + printf("mysqli->unknown = '%s'\n", @$mysqli->unknown); + + @$mysqli->unknown = 13; + printf("setting mysqli->unknown, @mysqli_unknown = '%s'\n", @$mysqli->unknown); + + $unknown = 'friday'; + @$mysqli->unknown = $unknown; + printf("setting mysqli->unknown, @mysqli_unknown = '%s'\n", @$mysqli->unknown); + + printf("\nAccess hidden properties for MYSLQI_STATUS_INITIALIZED (TODO documentation):\n"); + assert(@mysqli_connect_error() === @$mysqli->connect_error); + printf("mysqli->connect_error = '%s'/%s ('%s'/%s)\n", + @$mysqli->connect_error, gettype(@$mysqli->connect_error), + @mysqli_connect_error(), gettype(@mysqli_connect_error())); + + assert(@mysqli_connect_errno() === @$mysqli->connect_errno); + printf("mysqli->connect_errno = '%s'/%s ('%s'/%s)\n", + @$mysqli->connect_errno, gettype(@$mysqli->connect_errno), + @mysqli_connect_errno(), gettype(@mysqli_connect_errno())); + } + + printf("Without RS\n"); + $mysqli = @new mysqli($host, $user, $passwd . "invalid", $db, $port, $socket); + dump_properties($mysqli); + + printf("With RS\n"); + $mysqli = @new mysqli($host, $user, $passwd . "invalid", $db, $port, $socket); + $res = @$mysqli->query("SELECT * FROM test"); + dump_properties($mysqli); + + print "done!"; +?> +--CLEAN-- +<?php require_once("clean_table.inc"); ?> +--EXPECTF-- +Without RS + +Class variables: +affected_rows = 'NULL' +client_info = 'NULL' +client_version = '%s' +connect_errno = '%s' +connect_error = ''%s' +errno = 'NULL' +error = 'NULL' +error_list = 'NULL' +field_count = 'NULL' +host_info = 'NULL' +info = 'NULL' +insert_id = 'NULL' +protocol_version = 'NULL' +server_info = 'NULL' +server_version = 'NULL' +sqlstate = 'NULL' +stat = 'NULL' +thread_id = 'NULL' +warning_count = 'NULL' + +Object variables: +affected_rows = 'NULL' +client_info = 'NULL' +client_version = '%s' +connect_errno = '%s' +connect_error = '%s' +errno = 'NULL' +error = 'NULL' +error_list = 'NULL' +field_count = 'NULL' +host_info = 'NULL' +info = 'NULL' +insert_id = 'NULL' +server_info = 'NULL' +server_version = 'NULL' +stat = 'NULL' +sqlstate = 'NULL' +protocol_version = 'NULL' +thread_id = 'NULL' +warning_count = 'NULL' + +Magic, magic properties: +mysqli->affected_rows = ''/NULL (''/NULL) + +Warning: assert(): Assertion failed in %s on line %d +mysqli->client_info = ''/NULL ('%s'/%s) +mysqli->client_version = '%s'/integer ('%s'/integer) +mysqli->errno = ''/NULL (''/NULL) +mysqli->error = ''/NULL (''/NULL) +mysqli->field_count = ''/NULL (''/NULL) +mysqli->insert_id = ''/NULL (''/NULL) +mysqli->sqlstate = ''/NULL (''/NULL) +mysqli->host_info = ''/NULL (''/NULL) +mysqli->info = ''/NULL (''/NULL) + +Warning: assert(): Assertion failed in %s on line %d +mysqli->thread_id = ''/NULL (''/NULL) +mysqli->protocol_version = ''/NULL (''/NULL) +mysqli->server_info = ''/NULL (''/NULL) +mysqli->server_version = ''/NULL (''/NULL) +mysqli->warning_count = ''/NULL (''/NULL) + +Access to undefined properties: +mysqli->unknown = '' +setting mysqli->unknown, @mysqli_unknown = '13' +setting mysqli->unknown, @mysqli_unknown = 'friday' + +Access hidden properties for MYSLQI_STATUS_INITIALIZED (TODO documentation): +mysqli->connect_error = '%s'/%s) +mysqli->connect_errno = '%s'/integer ('%s'/integer) +With RS + +Class variables: +affected_rows = 'NULL' +client_info = 'NULL' +client_version = '%s' +connect_errno = '%s' +connect_error = '%s' +errno = 'NULL' +error = 'NULL' +error_list = 'NULL' +field_count = 'NULL' +host_info = 'NULL' +info = 'NULL' +insert_id = 'NULL' +protocol_version = 'NULL' +server_info = 'NULL' +server_version = 'NULL' +sqlstate = 'NULL' +stat = 'NULL' +thread_id = 'NULL' +warning_count = 'NULL' + +Object variables: +affected_rows = 'NULL' +client_info = 'NULL' +client_version = '%s' +connect_errno = '%s' +connect_error = '%s' +errno = 'NULL' +error = 'NULL' +error_list = 'NULL' +field_count = 'NULL' +host_info = 'NULL' +info = 'NULL' +insert_id = 'NULL' +server_info = 'NULL' +server_version = 'NULL' +stat = 'NULL' +sqlstate = 'NULL' +protocol_version = 'NULL' +thread_id = 'NULL' +warning_count = 'NULL' + +Magic, magic properties: +mysqli->affected_rows = ''/NULL (''/NULL) + +Warning: assert(): Assertion failed in %s on line %d +mysqli->client_info = ''/NULL ('%s'/%s) +mysqli->client_version = '%s'/integer ('%s'/integer) +mysqli->errno = ''/NULL (''/NULL) +mysqli->error = ''/NULL (''/NULL) +mysqli->field_count = ''/NULL (''/NULL) +mysqli->insert_id = ''/NULL (''/NULL) +mysqli->sqlstate = ''/NULL (''/NULL) +mysqli->host_info = ''/NULL (''/NULL) +mysqli->info = ''/NULL (''/NULL) + +Warning: assert(): Assertion failed in %s on line %d +mysqli->thread_id = ''/NULL (''/NULL) +mysqli->protocol_version = ''/NULL (''/NULL) +mysqli->server_info = ''/NULL (''/NULL) +mysqli->server_version = ''/NULL (''/NULL) +mysqli->warning_count = ''/NULL (''/NULL) + +Access to undefined properties: +mysqli->unknown = '' +setting mysqli->unknown, @mysqli_unknown = '13' +setting mysqli->unknown, @mysqli_unknown = 'friday' + +Access hidden properties for MYSLQI_STATUS_INITIALIZED (TODO documentation): +mysqli->connect_error = '%s'/%s) +mysqli->connect_errno = '%s'/integer ('%s'/integer) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt b/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt new file mode 100644 index 0000000..5fd4b6f --- /dev/null +++ b/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt @@ -0,0 +1,1246 @@ +--TEST-- +Interface of the class mysqli - Reflection +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('connect.inc'); + +if (($tmp = substr(PHP_VERSION, 0, strpos(PHP_VERSION, '.'))) && ($tmp < 5)) + die("skip Reflection not available before PHP 5 (found PHP $tmp)"); +/* +Let's not deal with cross-version issues in the EXPECTF/UEXPECTF. +Most of the things which we test are covered by mysqli_class_*_interface.phpt. +Those tests go into the details and are aimed to be a development tool, no more. +*/ +if (!$IS_MYSQLND) + die("skip Test has been written for the latest version of mysqlnd only"); +if ($MYSQLND_VERSION < 50004) + die("skip Test requires mysqlnd Revision 5.0.4 or newer"); + +?> +--FILE-- +<?php + require_once('reflection_tools.inc'); + $class = new ReflectionClass('mysqli'); + inspectClass($class); + print "done!\n"; +?> +--EXPECTF-- +Inspecting class 'mysqli' +isInternal: yes +isUserDefined: no +isInstantiable: yes +isInterface: no +isAbstract: no +isFinal: no +isIteratable: no +Modifiers: '0' +Parent Class: '' +Extension: 'mysqli' + +Inspecting method 'mysqli' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: yes +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 8448 +Number of Parameters: 6 +Number of Required Parameters: 0 + +Inspecting parameter 'host' of method 'mysqli' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'user' of method 'mysqli' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'password' of method 'mysqli' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'database' of method 'mysqli' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'port' of method 'mysqli' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'socket' of method 'mysqli' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting method 'autocommit' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 1 +Number of Required Parameters: 1 + +Inspecting parameter 'mode' of method 'autocommit' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'change_user' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 3 +Number of Required Parameters: 3 + +Inspecting parameter 'user' of method 'change_user' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting parameter 'password' of method 'change_user' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting parameter 'database' of method 'change_user' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'character_set_name' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'close' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'commit' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'connect' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 6 +Number of Required Parameters: 0 + +Inspecting parameter 'host' of method 'connect' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'user' of method 'connect' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'password' of method 'connect' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'database' of method 'connect' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'port' of method 'connect' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'socket' of method 'connect' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting method 'debug' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 1 +Number of Required Parameters: 1 + +Inspecting parameter 'debug_options' of method 'debug' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'dump_debug_info' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'escape_string' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 1 +Number of Required Parameters: 1 + +Inspecting parameter 'string_to_escape' of method 'escape_string' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'get_charset' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'get_client_info' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'get_connection_stats' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'get_server_info' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'get_warnings' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'init' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'kill' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 1 +Number of Required Parameters: 1 + +Inspecting parameter 'connection_id' of method 'kill' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'more_results' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'multi_query' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 1 +Number of Required Parameters: 1 + +Inspecting parameter 'query' of method 'multi_query' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'mysqli' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: yes +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 8448 +Number of Parameters: 6 +Number of Required Parameters: 0 + +Inspecting parameter 'host' of method 'mysqli' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'user' of method 'mysqli' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'password' of method 'mysqli' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'database' of method 'mysqli' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'port' of method 'mysqli' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'socket' of method 'mysqli' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting method 'next_result' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'options' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 2 +Number of Required Parameters: 2 + +Inspecting parameter 'option' of method 'options' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting parameter 'value' of method 'options' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'ping' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'poll' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: yes +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 257 +Number of Parameters: 5 +Number of Required Parameters: 4 + +Inspecting parameter 'read' of method 'poll' +isArray: yes +allowsNull: yes +isPassedByReference: yes +isOptional: no +isDefaultValueAvailable: no + +Inspecting parameter 'write' of method 'poll' +isArray: yes +allowsNull: yes +isPassedByReference: yes +isOptional: no +isDefaultValueAvailable: no + +Inspecting parameter 'error' of method 'poll' +isArray: yes +allowsNull: yes +isPassedByReference: yes +isOptional: no +isDefaultValueAvailable: no + +Inspecting parameter 'sec' of method 'poll' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting parameter 'usec' of method 'poll' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting method 'prepare' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 1 +Number of Required Parameters: 1 + +Inspecting parameter 'query' of method 'prepare' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'query' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 1 +Number of Required Parameters: 1 + +Inspecting parameter 'query' of method 'query' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'real_connect' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 7 +Number of Required Parameters: 0 + +Inspecting parameter 'host' of method 'real_connect' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'user' of method 'real_connect' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'password' of method 'real_connect' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'database' of method 'real_connect' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'port' of method 'real_connect' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'socket' of method 'real_connect' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'flags' of method 'real_connect' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting method 'real_escape_string' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 1 +Number of Required Parameters: 1 + +Inspecting parameter 'string_to_escape' of method 'real_escape_string' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'real_query' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 1 +Number of Required Parameters: 1 + +Inspecting parameter 'query' of method 'real_query' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'reap_async_query' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'refresh' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 1 +Number of Required Parameters: 1 + +Inspecting parameter 'options' of method 'refresh' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'rollback' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'select_db' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 1 +Number of Required Parameters: 1 + +Inspecting parameter 'database' of method 'select_db' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'set_charset' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 1 +Number of Required Parameters: 1 + +Inspecting parameter 'charset' of method 'set_charset' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'set_opt' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 2 +Number of Required Parameters: 2 + +Inspecting parameter 'option' of method 'set_opt' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting parameter 'value' of method 'set_opt' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'ssl_set' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 5 +Number of Required Parameters: 5 + +Inspecting parameter 'key' of method 'ssl_set' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting parameter 'cert' of method 'ssl_set' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting parameter 'certificate_authority' of method 'ssl_set' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting parameter 'certificate_authority_path' of method 'ssl_set' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting parameter 'cipher' of method 'ssl_set' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'stat' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'stmt_init' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'store_result' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'thread_safe' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'use_result' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting property 'affected_rows' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'client_info' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'client_version' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'connect_errno' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'connect_error' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'errno' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'error' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'error_list' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'field_count' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'host_info' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'info' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'insert_id' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'protocol_version' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'server_info' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'server_version' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'sqlstate' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'stat' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'thread_id' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'warning_count' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 +Default property 'affected_rows' +Default property 'client_info' +Default property 'client_version' +Default property 'connect_errno' +Default property 'connect_error' +Default property 'errno' +Default property 'error' +Default property 'error_list' +Default property 'field_count' +Default property 'host_info' +Default property 'info' +Default property 'insert_id' +Default property 'protocol_version' +Default property 'server_info' +Default property 'server_version' +Default property 'sqlstate' +Default property 'stat' +Default property 'thread_id' +Default property 'warning_count' +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt b/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt new file mode 100644 index 0000000..b327fe6 --- /dev/null +++ b/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt @@ -0,0 +1,193 @@ +--TEST-- +Interface of the class mysqli_result +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require('connect.inc'); + require('table.inc'); + + $mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + $mysqli_result = $mysqli->query('SELECT * FROM test'); + $row = $mysqli_result->fetch_row(); + + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $res = mysqli_query($link, 'SELECT * FROM test'); + assert(mysqli_fetch_row($res) === $row); + + printf("Parent class:\n"); + var_dump(get_parent_class($mysqli_result)); + + printf("\nMethods:\n"); + $methods = get_class_methods($mysqli_result); + $expected_methods = array( + '__construct' => true, + 'close' => true, + 'data_seek' => true, + 'fetch_array' => true, + 'fetch_assoc' => true, + 'fetch_field' => true, + 'fetch_field_direct' => true, + 'fetch_fields' => true, + 'fetch_object' => true, + 'fetch_row' => true, + 'field_seek' => true, + 'free' => true, + 'free_result' => true, + ); + if ($IS_MYSQLND) + $expected_methods['fetch_all'] = true; + + foreach ($methods as $k => $method) { + if (isset($expected_methods[$method])) { + unset($expected_methods[$method]); + unset($methods[$k]); + } + if ($method == 'mysqli_result') { + // get_class_method reports different constructor names + unset($expected_methods['__construct']); + unset($methods[$k]); + } + } + + if (!empty($expected_methods)) { + printf("Dumping list of missing methods.\n"); + var_dump($expected_methods); + } + if (!empty($methods)) { + printf("Dumping list of unexpected methods.\n"); + var_dump($methods); + } + if (empty($expected_methods) && empty($methods)) + printf("ok\n"); + + + printf("\nClass variables:\n"); + $variables = array_keys(get_class_vars(get_class($mysqli_result))); + sort($variables); + foreach ($variables as $k => $var) + printf("%s\n", $var); + + printf("\nObject variables:\n"); + $variables = array_keys(get_object_vars($mysqli_result)); + foreach ($variables as $k => $var) + printf("%s\n", $var); + + printf("\nMagic, magic properties:\n"); + + assert(($tmp = mysqli_field_tell($res)) === $mysqli_result->current_field); + printf("mysqli_result->current_field = '%s'/%s ('%s'/%s)\n", + $mysqli_result->current_field, gettype($mysqli_result->current_field), + $tmp, gettype($tmp)); + + assert(($tmp = mysqli_field_count($link)) === $mysqli_result->field_count); + printf("mysqli_result->field_count = '%s'/%s ('%s'/%s)\n", + $mysqli_result->field_count, gettype($mysqli_result->field_count), + $tmp, gettype($tmp)); + + assert(($tmp = mysqli_fetch_lengths($res)) === $mysqli_result->lengths); + printf("mysqli_result->lengths -> '%s'/%s ('%s'/%s)\n", + ((is_array($mysqli_result->lengths)) ? implode(' ', $mysqli_result->lengths) : 'n/a'), + gettype($mysqli_result->lengths), + ((is_array($tmp)) ? implode(' ', $tmp) : 'n/a'), + gettype($tmp)); + + assert(($tmp = mysqli_num_rows($res)) === $mysqli_result->num_rows); + printf("mysqli_result->num_rows = '%s'/%s ('%s'/%s)\n", + $mysqli_result->num_rows, gettype($mysqli_result->num_rows), + $tmp, gettype($tmp)); + + assert(in_array($mysqli_result->type, array(MYSQLI_STORE_RESULT, MYSQLI_USE_RESULT))); + printf("mysqli_result->type = '%s'/%s\n", + ((MYSQLI_STORE_RESULT == $mysqli_result->type) ? 'store' : 'use'), + gettype($mysqli_result->type)); + + printf("\nAccess to undefined properties:\n"); + printf("mysqli_result->unknown = '%s'\n", @$mysqli_result->unknown); + + printf("\nConstructor:\n"); + if (!is_object($res = new mysqli_result($link))) + printf("[001] Expecting object/mysqli_result got %s/%s\n", gettye($res), $res); + + if (null !== ($tmp = @$res->num_rows)) + printf("[002] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, "SELECT id FROM test ORDER BY id")) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_object($res = new mysqli_result($link))) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_object($res = new mysqli_result($link, MYSQLI_STORE_RESULT))) + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_object($res = new mysqli_result($link, MYSQLI_USE_RESULT))) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_object($res = new mysqli_result($link, 'invalid'))) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $valid = array(MYSQLI_STORE_RESULT, MYSQLI_USE_RESULT); + do { + $mode = mt_rand(-1000, 1000); + } while (in_array($mode, $valid)); + + if ($TEST_EXPERIMENTAL) { + ob_start(); + if (!is_object($res = new mysqli_result($link, $mode))) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $content = ob_get_contents(); + ob_end_clean(); + if (!stristr($content, 'Invalid value for resultmode')) + printf("[009] Expecting warning because of invalid resultmode\n"); + } + + if (!is_object($res = new mysqli_result('foo'))) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_object($res = @new mysqli_result($link, MYSQLI_STORE_RESULT, 1))) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + print "done!"; +?> +--EXPECTF-- +Parent class: +bool(false) + +Methods: +ok + +Class variables: +current_field +field_count +lengths +num_rows +type + +Object variables: +current_field +field_count +lengths +num_rows +type + +Magic, magic properties: +mysqli_result->current_field = '0'/integer ('0'/integer) +mysqli_result->field_count = '2'/integer ('2'/integer) +mysqli_result->lengths -> '1 1'/array ('1 1'/array) +mysqli_result->num_rows = '6'/integer ('6'/integer) +mysqli_result->type = 'store'/integer + +Access to undefined properties: +mysqli_result->unknown = '' + +Constructor: + +Warning: mysqli_result::__construct() expects parameter 2 to be long, %unicode_string_optional% given in %s on line %d + +Warning: mysqli_result::__construct() expects parameter 1 to be mysqli, %unicode_string_optional% given in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_class_mysqli_result_reflection.phpt b/ext/mysqli/tests/mysqli_class_mysqli_result_reflection.phpt new file mode 100644 index 0000000..988b827 --- /dev/null +++ b/ext/mysqli/tests/mysqli_class_mysqli_result_reflection.phpt @@ -0,0 +1,369 @@ +--TEST-- +Interface of the class mysqli_result - Reflection +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); + +if (($tmp = substr(PHP_VERSION, 0, strpos(PHP_VERSION, '.'))) && ($tmp < 5)) + die("skip Reflection not available before PHP 5 (found PHP $tmp)"); + +/* +Let's not deal with cross-version issues in the EXPECTF/UEXPECTF. +Most of the things which we test are covered by mysqli_class_*_interface.phpt. +Those tests go into the details and are aimed to be a development tool, no more. +*/ +if (!$IS_MYSQLND) + die("skip Test has been written for the latest version of mysqlnd only"); +if ($MYSQLND_VERSION < 50004) + die("skip Test requires mysqlnd Revision 5.0.4 or newer"); +?> +--FILE-- +<?php + require_once('reflection_tools.inc'); + $class = new ReflectionClass('mysqli_result'); + inspectClass($class); + print "done!"; +?> +--EXPECTF-- +Inspecting class 'mysqli_result' +isInternal: yes +isUserDefined: no +isInstantiable: yes +isInterface: no +isAbstract: no +isFinal: no +isIteratable: yes +Modifiers: '0' +Parent Class: '' +Extension: 'mysqli' + +Inspecting method '__construct' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: yes +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 8448 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method '__construct' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: yes +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 8448 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'close' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'data_seek' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 1 +Number of Required Parameters: 1 + +Inspecting parameter 'offset' of method 'data_seek' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'fetch_all' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'fetch_array' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 1 +Number of Required Parameters: 0 + +Inspecting parameter 'result_type' of method 'fetch_array' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting method 'fetch_assoc' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'fetch_field' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'fetch_field_direct' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 1 +Number of Required Parameters: 1 + +Inspecting parameter 'field_nr' of method 'fetch_field_direct' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'fetch_fields' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'fetch_object' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 2 +Number of Required Parameters: 0 + +Inspecting parameter 'class_name' of method 'fetch_object' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting parameter 'params' of method 'fetch_object' +isArray: yes +allowsNull: no +isPassedByReference: no +isOptional: yes +isDefaultValueAvailable: no + +Inspecting method 'fetch_row' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'field_seek' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 1 +Number of Required Parameters: 1 + +Inspecting parameter 'field_nr' of method 'field_seek' +isArray: no +allowsNull: no +isPassedByReference: no +isOptional: no +isDefaultValueAvailable: no + +Inspecting method 'free' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'free_result' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting property 'current_field' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'field_count' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'lengths' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'num_rows' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'type' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 +Default property 'current_field' +Default property 'field_count' +Default property 'lengths' +Default property 'num_rows' +Default property 'type' +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt b/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt new file mode 100644 index 0000000..acf7379 --- /dev/null +++ b/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt @@ -0,0 +1,198 @@ +--TEST-- +Interface of the class mysqli_stmt +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifemb.inc'); + require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require('connect.inc'); + require('table.inc'); + + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $stmt = new mysqli_stmt($link); + + printf("Parent class:\n"); + var_dump(get_parent_class($stmt)); + + printf("\nMethods:\n"); + + $methods = get_class_methods($stmt); + $expected_methods = array( + '__construct' => true, + 'attr_get' => true, + 'attr_set' => true, + 'bind_param' => true, + 'bind_result' => true, + 'close' => true, + 'data_seek' => true, + 'execute' => true, + 'fetch' => true, + 'free_result' => true, + 'get_warnings' => true, + 'num_rows' => true, + 'prepare' => true, + 'reset' => true, + 'result_metadata' => true, + 'send_long_data' => true, + 'store_result' => true, + ); + + if ($IS_MYSQLND) { + $expected_methods['get_result'] = true; + $expected_methods['more_results'] = true; + $expected_methods['next_result'] = true; + } + + foreach ($methods as $k => $method) { + if (isset($expected_methods[$method])) { + unset($methods[$k]); + unset($expected_methods[$method]); + } + if ($method == 'mysqli_stmt') { + // get_class_method reports different constructor names + unset($expected_methods['__construct']); + unset($methods[$k]); + } + } + if (!empty($methods)) { + printf("More methods found than indicated. Dumping list of unexpected methods.\n"); + var_dump($methods); + } + if (!empty($expected_methods)) { + printf("Some methods are missing. Dumping list of missing methods.\n"); + var_dump($expected_methods); + } + if (empty($methods) && empty($expected_methods)) + printf("ok\n"); + + printf("\nClass variables:\n"); + $variables = array_keys(get_class_vars(get_class($stmt))); + sort($variables); + foreach ($variables as $k => $var) + printf("%s\n", $var); + + printf("\nObject variables:\n"); + $variables = array_keys(get_object_vars($stmt)); + foreach ($variables as $k => $var) + printf("%s\n", $var); + +printf("\nMagic, magic properties:\n"); + +assert(mysqli_stmt_affected_rows($stmt) === $stmt->affected_rows); +printf("stmt->affected_rows = '%s'\n", $stmt->affected_rows); + +if (!$stmt->prepare("INSERT INTO test(id, label) VALUES (100, 'z')") || +!$stmt->execute()) +printf("[001] [%d] %s\n", $stmt->errno, $stmt->error); + +assert(mysqli_stmt_affected_rows($stmt) === $stmt->affected_rows); +printf("stmt->affected_rows = '%s'\n", $stmt->affected_rows); + +assert(mysqli_stmt_errno($stmt) === $stmt->errno); +printf("stmt->errno = '%s'\n", $stmt->errno); + +assert(mysqli_stmt_error($stmt) === $stmt->error); +printf("stmt->error = '%s'\n", $stmt->error); + +assert(mysqli_stmt_error_list($stmt) === $stmt->error_list); +var_dump("stmt->error = ", $stmt->error_list); + +assert(mysqli_stmt_field_count($stmt) === $stmt->field_count); +printf("stmt->field_count = '%s'\n", $stmt->field_count); + +assert($stmt->id > 0); +printf("stmt->id = '%s'\n", $stmt->id); + +assert(mysqli_stmt_insert_id($stmt) === $stmt->insert_id); +printf("stmt->insert_id = '%s'\n", $stmt->insert_id); + +assert(mysqli_stmt_num_rows($stmt) === $stmt->num_rows); +printf("stmt->num_rows = '%s'\n", $stmt->num_rows); + +assert(mysqli_stmt_param_count($stmt) === $stmt->param_count); +printf("stmt->param_count = '%s'\n", $stmt->param_count); + +assert(mysqli_stmt_sqlstate($stmt) === $stmt->sqlstate); +printf("stmt->sqlstate = '%s'\n", $stmt->sqlstate); + +printf("\nAccess to undefined properties:\n"); +printf("stmt->unknown = '%s'\n", @$stmt->unknown); +@$stmt->unknown = 13; +printf("stmt->unknown = '%s'\n", @$stmt->unknown); + +printf("\nPrepare using the constructor:\n"); +$stmt = new mysqli_stmt($link, 'SELECT id FROM test ORDER BY id'); +if (!$stmt->execute()) +printf("[002] [%d] %s\n", $stmt->errno, $stmt->error); +$stmt->close(); + +$obj = new stdClass(); +if (!is_object($stmt = new mysqli_stmt($link, $obj))) +printf("[003] Expecting NULL got %s/%s\n", gettype($stmt), $stmt); + +print "done!"; +?> +--EXPECTF-- +Parent class: +bool(false) + +Methods: +ok + +Class variables: +affected_rows +errno +error +error_list +field_count +id +insert_id +num_rows +param_count +sqlstate + +Object variables: +affected_rows +insert_id +num_rows +param_count +field_count +errno +error +error_list +sqlstate +id + +Magic, magic properties: + +Warning: mysqli_stmt_affected_rows(): invalid object or resource mysqli_stmt + in %s on line %d + +Warning: main(): Property access is not allowed yet in %s on line %d + +Warning: main(): Property access is not allowed yet in %s on line %d +stmt->affected_rows = '' +stmt->affected_rows = '1' +stmt->errno = '0' +stmt->error = '' +string(14) "stmt->error = " +array(0) { +} +stmt->field_count = '0' +stmt->id = '%d' +stmt->insert_id = '0' +stmt->num_rows = '0' +stmt->param_count = '0' +stmt->sqlstate = '00000' + +Access to undefined properties: +stmt->unknown = '' +stmt->unknown = '13' + +Prepare using the constructor: + +Warning: mysqli_stmt::__construct() expects parameter 2 to be %binary_string_optional%, object given in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_class_mysqli_warning.phpt b/ext/mysqli/tests/mysqli_class_mysqli_warning.phpt new file mode 100644 index 0000000..62f01ca --- /dev/null +++ b/ext/mysqli/tests/mysqli_class_mysqli_warning.phpt @@ -0,0 +1,132 @@ +--TEST-- +Interface of the class mysqli_warning - TODO +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); + +if (!$TEST_EXPERIMENTAL) + die("skip - experimental (= unsupported) feature"); +?> +--FILE-- +<?php + require('connect.inc'); + + $warning = new mysqli_warning(); + $warning = new mysqli_warning(null); + $warning = new mysqli_warning(null, null); + + $mysqli = new mysqli(); + $warning = new mysqli_warning($mysqli); + + $mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + $stmt = new mysqli_stmt($mysqli); + $warning = new mysqli_warning($stmt); + + $stmt = $mysqli->stmt_init(); + $warning = new mysqli_warning($stmt); + + $obj = new stdClass(); + $warning = new mysqli_warning($obj); + + include("table.inc"); + $mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket); + $res = $mysqli->query('INSERT INTO test(id, label) VALUES (1, "zz")'); + $warning = mysqli_get_warnings($mysqli); + + printf("Parent class:\n"); + var_dump(get_parent_class($warning)); + + printf("\nMethods:\n"); + $methods = get_class_methods($warning); + $expected_methods = array( + 'next' => true, + ); + + foreach ($methods as $k => $method) { + if (isset($expected_methods[$method])) { + unset($methods[$k]); + unset($expected_methods[$method]); + } + } + if (!empty($methods)) { + printf("Dumping list of unexpected methods.\n"); + var_dump($methods); + } + if (!empty($expected_methods)) { + printf("Dumping list of missing methods.\n"); + var_dump($expected_methods); + } + if (empty($methods) && empty($expected_methods)) + printf("ok\n"); + + printf("\nClass variables:\n"); + $variables = get_class_vars(get_class($mysqli)); + sort($variables); + foreach ($variables as $k => $var) + printf("%s\n", $var); + + printf("\nObject variables:\n"); + $variables = get_object_vars($mysqli); + foreach ($variables as $k => $var) + printf("%s\n", $var); + + printf("\nMagic, magic properties:\n"); + + assert('' === $warning->message); + printf("warning->message = '%s'\n", $warning->message); + + assert('' === $warning->sqlstate); + printf("warning->sqlstate= '%s'\n", $warning->sqlstate); + + assert(0 === $warning->errno); + printf("warning->errno = '%s'\n", $warning->errno); + + printf("\nAccess to undefined properties:\n"); + printf("warning->unknown = '%s'\n", @$warning->unknown); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: Wrong parameter count for mysqli_warning::mysqli_warning() in %s on line %d + +Warning: mysqli_warning::mysqli_warning() expects parameter 1 to be object, null given in %s on line %d + +Warning: Wrong parameter count for mysqli_warning::mysqli_warning() in %s on line %d + +Warning: mysqli_warning::mysqli_warning(): Couldn't fetch mysqli in %s on line %d + +Warning: mysqli_warning::mysqli_warning(): invalid object or resource mysqli_stmt + in %s on line %d + +Warning: mysqli_warning::mysqli_warning(): invalid object or resource mysqli_stmt + in %s on line %d + +Warning: mysqli_warning::mysqli_warning(): invalid class argument in /home/nixnutz/php6_mysqlnd/ext/mysqli/tests/mysqli_class_mysqli_warning.php on line 19 + +Warning: mysqli_warning::mysqli_warning(): No warnings found in %s on line %d +Parent class: +bool(false) + +Methods: +ok + +Class variables: + +Object variables: + +Magic, magic properties: +warning->message = '' +warning->sqlstate= '' +warning->errno = '' + +Access to undefined properties: + +warning->unknown = '' +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_class_mysqli_warning_reflection.phpt b/ext/mysqli/tests/mysqli_class_mysqli_warning_reflection.phpt new file mode 100644 index 0000000..dc0c14e --- /dev/null +++ b/ext/mysqli/tests/mysqli_class_mysqli_warning_reflection.phpt @@ -0,0 +1,116 @@ +--TEST-- +Interface of the class mysqli_stmt - Reflection +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('connect.inc'); + +if (($tmp = substr(PHP_VERSION, 0, strpos(PHP_VERSION, '.'))) && ($tmp < 5)) + die("skip Reflection not available before PHP 5 (found PHP $tmp)"); + +/* +Let's not deal with cross-version issues in the EXPECTF/UEXPECTF. +Most of the things which we test are covered by mysqli_class_*_interface.phpt. +Those tests go into the details and are aimed to be a development tool, no more. +*/ +if (!$IS_MYSQLND) + die("skip Test has been written for the latest version of mysqlnd only"); +if ($MYSQLND_VERSION < 50004) + die("skip Test requires mysqlnd Revision 5.0.4 or newer"); +?> +--FILE-- +<?php + require_once('reflection_tools.inc'); + $class = new ReflectionClass('mysqli_warning'); + inspectClass($class); + print "done!\n"; +?> +--EXPECTF-- +Inspecting class 'mysqli_warning' +isInternal: yes +isUserDefined: no +isInstantiable: no +isInterface: no +isAbstract: no +isFinal: yes +isIteratable: no +Modifiers: '%d' +Parent Class: '' +Extension: 'mysqli' + +Inspecting method '__construct' +isFinal: no +isAbstract: no +isPublic: no +isPrivate: no +isProtected: yes +isStatic: no +isConstructor: yes +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: %d +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method '__construct' +isFinal: no +isAbstract: no +isPublic: no +isPrivate: no +isProtected: yes +isStatic: no +isConstructor: yes +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: %d +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'next' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: %d +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting property 'errno' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'message' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 + +Inspecting property 'sqlstate' +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isDefault: yes +Modifiers: 256 +Default property 'errno' +Default property 'message' +Default property 'sqlstate' +done! diff --git a/ext/mysqli/tests/mysqli_close.phpt b/ext/mysqli/tests/mysqli_close.phpt new file mode 100644 index 0000000..c6ac92d --- /dev/null +++ b/ext/mysqli/tests/mysqli_close.phpt @@ -0,0 +1,40 @@ +--TEST-- +mysqli_close() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_close())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_close($link, $link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + $tmp = @mysqli_close(NULL); + if (NULL !== $tmp) + printf("[004] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + $tmp = mysqli_close($link); + if (true !== $tmp) + printf("[005] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_query($link, "SELECT 1"))) + printf("[006] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_close_oo.phpt b/ext/mysqli/tests/mysqli_close_oo.phpt new file mode 100644 index 0000000..be67f77 --- /dev/null +++ b/ext/mysqli/tests/mysqli_close_oo.phpt @@ -0,0 +1,36 @@ +--TEST-- +mysqli_close() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!is_null($tmp = @$mysqli->close($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + $tmp = $mysqli->close(); + if (true !== $tmp) + printf("[003] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @$mysqli->close())) + printf("[004] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @$mysqli->query("SELECT 1"))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_commit.phpt b/ext/mysqli/tests/mysqli_commit.phpt new file mode 100644 index 0000000..d20ba5d --- /dev/null +++ b/ext/mysqli/tests/mysqli_commit.phpt @@ -0,0 +1,77 @@ +--TEST-- +mysqli_commit() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +require_once('connect.inc'); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die(sprintf("Cannot connect, [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); + +if (!have_innodb($link)) + die(sprintf("Needs InnoDB support, [%d] %s", $link->errno, $link->error)); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_commit())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_commit($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_commit($link, $link))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[004] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (true !== ($tmp = mysqli_autocommit($link, false))) + printf("[005] Cannot turn off autocommit, expecting true, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, 'CREATE TABLE test(id INT) ENGINE = InnoDB')) + printf("[007] Cannot create test table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, 'INSERT INTO test(id) VALUES (1)')) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $tmp = mysqli_commit($link); + if ($tmp !== true) + printf("[009] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, 'ROLLBACK')) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, 'SELECT COUNT(*) AS num FROM test')) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + if (1 != $tmp['num']) + printf("[12] Expecting 1 row in table test, found %d rows\n", $tmp['num']); + mysqli_free_result($res); + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) + printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_close($link); + + if (NULL !== ($tmp = @mysqli_commit($link))) + printf("[014] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_commit_oo.phpt b/ext/mysqli/tests/mysqli_commit_oo.phpt new file mode 100644 index 0000000..34ec4bf --- /dev/null +++ b/ext/mysqli/tests/mysqli_commit_oo.phpt @@ -0,0 +1,79 @@ +--TEST-- +mysqli_commit() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +require_once('connect.inc'); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die(sprintf("Cannot connect, [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); + +if (!have_innodb($link)) + die(sprintf("Needs InnoDB support, [%d] %s", $link->errno, $link->error)); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + $mysqli = new mysqli(); + if (!is_null($tmp = @$mysqli->commit())) + printf("[013] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!is_null($tmp = @$mysqli->commit($link))) + printf("[002] Expecting NULL/NULL, got %s/%s, [%d] %s\n", + gettype($tmp), $tmp, $mysqli->errno, $mysqli->error); + + if (true !== ($tmp = $mysqli->commit())) + printf("[014] Expecting boolean/true got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = $mysqli->autocommit(false))) + printf("[003] Cannot turn off autocommit, expecting true, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli->query('DROP TABLE IF EXISTS test')) + printf("[004] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (!$mysqli->query('CREATE TABLE test(id INT) ENGINE = InnoDB')) + printf("[005] Cannot create test table, [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (!$mysqli->query('INSERT INTO test(id) VALUES (1)')) + printf("[006] [%d] %s\n", $mysqli->errno, $mysqli->error); + + $tmp = $mysqli->commit(); + if ($tmp !== true) + printf("[007] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli->query('ROLLBACK')) + printf("[008] [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (!$res = $mysqli->query('SELECT COUNT(*) AS num FROM test')) + printf("[009] [%d] %s\n", $mysqli->errno, $mysqli->error); + $tmp = $res->fetch_assoc(); + if (1 != $tmp['num']) + printf("[010] Expecting 1 row in table test, found %d rows\n", $tmp['num']); + $res->free(); + + if (!$mysqli->query('DROP TABLE IF EXISTS test')) + printf("[011] [%d] %s\n", $mysqli->errno, $mysqli->error); + + $mysqli->close(); + + if (NULL !== ($tmp = @$mysqli->commit())) + printf("[012] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_connect.phpt b/ext/mysqli/tests/mysqli_connect.phpt new file mode 100644 index 0000000..e14d88f --- /dev/null +++ b/ext/mysqli/tests/mysqli_connect.phpt @@ -0,0 +1,175 @@ +--TEST-- +mysqli_connect() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + /* we need to check, if the server allows anonymous login (empty user) */ + $tmp = @mysqli_connect('localhost'); + $anon_allow = (gettype($tmp) == "object"); + + $exptype = ($anon_allow) ? "mysqli_object" : "false"; + + $obj = new stdClass(); + if (!is_null($tmp = @mysqli_connect($obj))) + printf("[001] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + $tmp = @mysqli_connect($link); + if (($anon_allow && gettype($tmp) != "object") || (!$anon_allow && $tmp != false)) { + printf("[002] Expecting %s, got %s/%s\n", $exptype, gettype($tmp), $tmp); + } + + $tmp = @mysqli_connect($link, $link); + if (($anon_allow && gettype($tmp) != "object") || (!$anon_allow && $tmp != false)) { + printf("[003] Expecting %s, got %s/%s\n", $exptype, gettype($tmp), $tmp); + } + + $tmp = @mysqli_connect($link, $link, $link); + if (($anon_allow && gettype($tmp) != "object") || (!$anon_allow && $tmp != false)) { + printf("[004] Expecting %s, got %s/%s\n", $exptype, gettype($tmp), $tmp); + } + + $tmp = @mysqli_connect($link, $link, $link, $link); + if (($anon_allow && gettype($tmp) != "object") || (!$anon_allow && $tmp != false)) { + printf("[005] Expecting %s, got %s/%s\n", $exptype, gettype($tmp), $tmp); + } + + $tmp = @mysqli_connect($link, $link, $link, $link, $link); + if (($anon_allow && gettype($tmp) != "object") || (!$anon_allow && $tmp != false)) { + printf("[006] Expecting %s, got %s/%s\n", $exptype, gettype($tmp), $tmp); + } + + $tmp = @mysqli_connect($link, $link, $link, $link, $link, $link); + if (($anon_allow && gettype($tmp) != "object") || (!$anon_allow && $tmp != false)) { + printf("[007] Expecting %s, got %s/%s\n", $exptype, gettype($tmp), $tmp); + } + + if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[008] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + mysqli_close($link); + + if ($link = mysqli_connect($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) + printf("[009] Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", + $host, $user . 'unknown_really', $db, $port, $socket); + + if (false !== $link) + printf("[010] Expecting boolean/false, got %s/%s\n", gettype($link), $link); + + // Run the following tests without an anoynmous MySQL user and use a password for the test user! + ini_set('mysqli.default_socket', $socket); + if (!is_object($link = mysqli_connect($host, $user, $passwd, $db, $port))) { + printf("[011] Usage of mysqli.default_socket failed\n") ; + } else { + if (!$res = mysqli_query($link, "SELECT 'mysqli.default_socket' AS 'testing'")) + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + mysqli_close($link); + } + + ini_set('mysqli.default_port', $port); + if (!is_object($link = mysqli_connect($host, $user, $passwd, $db))) { + printf("[013] Usage of mysqli.default_port failed\n") ; + } else { + if (!$res = mysqli_query($link, "SELECT 'mysqli.default_port' AS 'testing'")) + printf("[014] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + mysqli_close($link); + } + + ini_set('mysqli.default_pw', $passwd); + if (!is_object($link = mysqli_connect($host, $user))) { + printf("[015] Usage of mysqli.default_pw failed\n") ; + } else { + if (!$res = mysqli_query($link, "SELECT 'mysqli.default_pw' AS 'testing'")) + printf("[016] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + mysqli_close($link); + } + + ini_set('mysqli.default_user', $user); + if (!is_object($link = mysqli_connect($host))) { + printf("[017] Usage of mysqli.default_user failed\n") ; + } else { + if (!$res = mysqli_query($link, "SELECT 'mysqli.default_user' AS 'testing'")) + printf("[018] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump(mysqli_fetch_array($res, MYSQLI_BOTH)); + mysqli_free_result($res); + mysqli_close($link); + } + + ini_set('mysqli.default_host', $host); + if (!is_object($link = mysqli_connect())) { + printf("[019] Usage of mysqli.default_host failed\n") ; + } else { + if (!$res = mysqli_query($link, "SELECT 'mysqli.default_host' AS 'testing'")) + printf("[020] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump(mysqli_fetch_array($res, MYSQLI_NUM)); + mysqli_free_result($res); + mysqli_close($link); + } + + if ($IS_MYSQLND) { + ini_set('mysqli.default_host', 'p:' . $host); + if (!is_object($link = mysqli_connect())) { + printf("[021] Usage of mysqli.default_host (persistent) failed\n") ; + } else { + if (!$res = mysqli_query($link, "SELECT 'mysqli.default_host (persistent)' AS 'testing'")) + printf("[022] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + if ($tmp['testing'] !== 'mysqli.default_host (persistent)') { + printf("[023] Result looks strange - check manually, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + var_dump($tmp); + } + mysqli_free_result($res); + mysqli_close($link); + } + + ini_set('mysqli.default_host', 'p:'); + if (is_object($link = @mysqli_connect())) { + printf("[024] Usage of mysqli.default_host=p: did not fail\n") ; + mysqli_close($link); + } + } + + print "done!"; +?> +--EXPECTF-- +Warning: mysqli_connect(): (%s/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d +array(1) { + [%u|b%"testing"]=> + %unicode|string%(21) "mysqli.default_socket" +} +array(1) { + [%u|b%"testing"]=> + %unicode|string%(19) "mysqli.default_port" +} +array(1) { + [%u|b%"testing"]=> + %unicode|string%(17) "mysqli.default_pw" +} +array(2) { + [0]=> + %unicode|string%(19) "mysqli.default_user" + [%u|b%"testing"]=> + %unicode|string%(19) "mysqli.default_user" +} +array(1) { + [0]=> + %unicode|string%(19) "mysqli.default_host" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_connect_errno.phpt b/ext/mysqli/tests/mysqli_connect_errno.phpt new file mode 100644 index 0000000..a7f90f1 --- /dev/null +++ b/ext/mysqli/tests/mysqli_connect_errno.phpt @@ -0,0 +1,40 @@ +--TEST-- +mysqli_connect_errno() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + // too many parameter + if (0 !== ($tmp = @mysqli_connect_errno($link))) + printf("[001] Expecting integer/0, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (0 !== ($tmp = mysqli_connect_errno())) + printf("[003] Expecting integer/0, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + $link = @my_mysqli_connect($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket); + if (false !== $link) + printf("[004] Connect to the server should fail using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s, expecting boolean/false, got %s/%s\n", + $host, $user . 'unknown_really', $db, $port, $socket, gettype($link), var_export($link, true)); + + if (0 === ($tmp = mysqli_connect_errno())) + printf("[005] Expecting integer/any non-zero, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_connect_error.phpt b/ext/mysqli/tests/mysqli_connect_error.phpt new file mode 100644 index 0000000..79ac3f1 --- /dev/null +++ b/ext/mysqli/tests/mysqli_connect_error.phpt @@ -0,0 +1,39 @@ +--TEST-- +mysqli_connect_error() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + // too many parameter + if (!is_null($tmp = @mysqli_connect_error($link))) + printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (NULL !== ($tmp = mysqli_connect_error())) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + if ($link = @my_mysqli_connect($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) + printf("[003] Connect to the server should fail using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", + $host, $user . 'unknown_really', $db, $port, $socket); + + if ('' === ($tmp = mysqli_connect_error())) + printf("[004] Expecting string/'', got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_connect_oo.phpt b/ext/mysqli/tests/mysqli_connect_oo.phpt new file mode 100644 index 0000000..35cc116 --- /dev/null +++ b/ext/mysqli/tests/mysqli_connect_oo.phpt @@ -0,0 +1,153 @@ +--TEST-- +new mysqli() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + $obj = new stdClass(); + + if ($mysqli = new mysqli($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket) && !mysqli_connect_errno()) + printf("[003] Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", + $host, $user . 'unknown_really', $db, $port, $socket); + + if (false !== $mysqli) + printf("[004] Expecting boolean/false, got %s/%s\n", gettype($mysqli), $mysqli); + + // Run the following tests without an anoynmous MySQL user and use a password for the test user! + ini_set('mysqli.default_socket', $socket); + if (!is_object($mysqli = new mysqli($host, $user, $passwd, $db, $port)) || (0 !== mysqli_connect_errno())) { + printf("[005] Usage of mysqli.default_socket failed\n") ; + } else { + $mysqli->close(); + } + + ini_set('mysqli.default_port', $port); + if (!is_object($mysqli = new mysqli($host, $user, $passwd, $db)) || (0 !== mysqli_connect_errno())) { + printf("[006] Usage of mysqli.default_port failed\n") ; + } else { + $mysqli->close(); + } + + ini_set('mysqli.default_pw', $passwd); + if (!is_object($mysqli = new mysqli($host, $user)) || (0 !== mysqli_connect_errno())) { + printf("[007] Usage of mysqli.default_pw failed\n") ; + } else { + $mysqli->close(); + } + + ini_set('mysqli.default_user', $user); + if (!is_object($mysqli = new mysqli($host)) || (0 !== mysqli_connect_errno())) { + printf("[008] Usage of mysqli.default_user failed\n") ; + } else { + $mysqli->close(); + } + + ini_set('mysqli.default_host', $host); + if (!is_object($mysqli = new mysqli()) || (0 !== mysqli_connect_errno())) { + printf("[012] Failed to create mysqli object\n"); + } else { + // There shall be NO connection! Using new mysqli(void) shall not use defaults for a connection! + // We had long discussions on this and found that the ext/mysqli API as + // such is broken. As we can't fix it, we document how it has behaved from + // the first day on. And that's: no connection. + if (NULL !== ($tmp = @$mysqli->query('SELECT 1'))) { + printf("[013] There shall be no connection!\n"); + $mysqli->close(); + } + } + + if ($IS_MYSQLND) { + ini_set('mysqli.default_host', 'p:' . $host); + if (!is_object($mysqli = new mysqli())) { + // Due to an API flaw this shall not connect + printf("[010] Failed to create mysqli object\n"); + } else { + // There shall be NO connection! Using new mysqli(void) shall not use defaults for a connection! + // We had long discussions on this and found that the ext/mysqli API as + // such is broken. As we can't fix it, we document how it has behaved from + // the first day on. And that's: no connection. + if (NULL !== ($tmp = @$mysqli->query('SELECT 1'))) { + printf("[011] There shall be no connection!\n"); + $mysqli->close(); + } + } + } + + print "... and now Exceptions\n"; + mysqli_report(MYSQLI_REPORT_OFF); + mysqli_report(MYSQLI_REPORT_STRICT); + + try { + $mysqli = new mysqli($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket); + printf("[016] Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", + $host, $user . 'unknown_really', $db, $port, $socket); + $mysqli->close(); + } catch (mysqli_sql_exception $e) { + printf("%s\n", $e->getMessage()); + } + + ini_set('mysqli.default_socket', $socket); + try { + $mysqli = new mysqli($host, $user, $passwd, $db, $port); + $mysqli->close(); + } catch (mysqli_sql_exception $e) { + printf("%s\n", $e->getMessage()); + printf("[017] Usage of mysqli.default_socket failed\n") ; + } + + ini_set('mysqli.default_port', $port); + try { + $mysqli = new mysqli($host, $user, $passwd, $db); + $mysqli->close(); + } catch (mysqli_sql_exception $e) { + printf("%s\n", $e->getMessage()); + printf("[018] Usage of mysqli.default_port failed\n") ; + } + + ini_set('mysqli.default_pw', $passwd); + try { + $mysqli = new mysqli($host, $user); + $mysqli->close(); + } catch (mysqli_sql_exception $e) { + printf("%s\n", $e->getMessage()); + printf("[019] Usage of mysqli.default_pw failed\n"); + } + + ini_set('mysqli.default_user', $user); + try { + $mysqli = new mysqli($host); + $mysqli->close(); + } catch (mysqli_sql_exception $e) { + printf("%s\n", $e->getMessage()); + printf("[020] Usage of mysqli.default_user failed\n") ; + } + + ini_set('mysqli.default_host', $host); + try { + /* NOTE that at this point one must use a different syntax! */ + $mysqli = mysqli_init(); + $mysqli->real_connect(); + assert(0 === mysqli_connect_errno()); + $mysqli->close(); + assert(0 === mysqli_connect_errno()); + } catch (mysqli_sql_exception $e) { + printf("%s\n", $e->getMessage()); + printf("[021] Usage of mysqli.default_host failed\n"); + } + + print "done!"; +?> +--EXPECTF-- +Warning: mysqli::mysqli(): (%s/%d): Access denied for user '%sunknown%s'@'%s' (using password: %s) in %s on line %d +... and now Exceptions +Access denied for user '%s'@'%s' (using password: %s) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_connect_oo_defaults.phpt b/ext/mysqli/tests/mysqli_connect_oo_defaults.phpt new file mode 100644 index 0000000..1855a20 --- /dev/null +++ b/ext/mysqli/tests/mysqli_connect_oo_defaults.phpt @@ -0,0 +1,180 @@ +--TEST-- +new mysqli() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if ($socket != "") + /* mysqli.default_socket requires non-empty string */ + ini_set('mysqli.default_socket', 'socket'); + + ini_set('mysqli.default_port', 9999); + ini_set('mysqli.default_pw', 'password'); + ini_set('mysqli.default_user', 'user'); + ini_set('mysqli.default_host', 'host'); + + mysqli_report(MYSQLI_REPORT_OFF); + mysqli_report(MYSQLI_REPORT_STRICT); + + if ($socket != "") { + ini_set('mysqli.default_socket', $socket); + try { + $mysqli = mysqli_init(); + $mysqli->real_connect($host, $user, $passwd, $db, $port); + + if (!$res = $mysqli->query("SELECT 'mysqli.default_socket' AS testing")) + printf("[001] [%d] %s\n", $mysqli->errno, $mysqli->error); + $tmp = $res->fetch_assoc(); + $res->free_result(); + + if (!isset($tmp['testing']) || $tmp['testing'] != 'mysqli.default_socket') { + printf("[002] mysqli.default_socket not properly set?\n"); + var_dump($tmp); + } + + $mysqli->close(); + + } catch (mysqli_sql_exception $e) { + printf("%s\n", $e->getMessage()); + printf("[002] Usage of mysqli.default_socket failed\n"); + } + } + + ini_set('mysqli.default_port', $port); + try { + $mysqli = mysqli_init(); + $mysqli->real_connect($host, $user, $passwd, $db); + + if (!$res = $mysqli->query("SELECT 'mysqli.default_port' AS testing")) + printf("[003] [%d] %s\n", $mysqli->errno, $mysqli->error); + var_dump($res->fetch_assoc()); + $res->free_result(); + + $mysqli->close(); + + } catch (mysqli_sql_exception $e) { + printf("%s\n", $e->getMessage()); + printf("[004] Usage of mysqli.default_port failed\n"); + } + + ini_set('mysqli.default_pw', $passwd); + try { + $mysqli = mysqli_init(); + $mysqli->real_connect($host, $user); + $mysqli->select_db($db); + + if (!$res = $mysqli->query("SELECT 'mysqli.default_pw' AS testing")) + printf("[005] [%d] %s\n", $mysqli->errno, $mysqli->error); + var_dump($res->fetch_assoc()); + $res->free_result(); + + $mysqli->close(); + + } catch (mysqli_sql_exception $e) { + printf("%s\n", $e->getMessage()); + printf("[006] Usage of mysqli.default_pw failed\n"); + } + + ini_set('mysqli.default_user', $user); + try { + $mysqli = mysqli_init(); + $mysqli->real_connect($host); + $mysqli->select_db($db); + + if (!$res = $mysqli->query("SELECT 'mysqli.default_user' AS testing")) + printf("[007] [%d] %s\n", $mysqli->errno, $mysqli->error); + var_dump($res->fetch_assoc()); + $res->free_result(); + + $mysqli->close(); + + } catch (mysqli_sql_exception $e) { + printf("%s\n", $e->getMessage()); + printf("[008] Usage of mysqli.default_user failed\n"); + } + + ini_set('mysqli.default_host', $host); + try { + $mysqli = mysqli_init(); + $mysqli->real_connect(); + $mysqli->select_db($db); + + if (!$res = $mysqli->query("SELECT 1")) + printf("[009] [%d] %s\n", $mysqli->errno, $mysqli->error); + $res->free_result(); + + if (!$res = $mysqli->query("SELECT SUBSTRING_INDEX(USER(),'@',1) AS username")) + printf("[010] [%d] %s\n", $mysqli->errno, $mysqli->error); + + $tmp = $res->fetch_assoc(); + $res->free_result(); + if ($tmp['username'] !== $user) + printf("[011] Expecting string/%s, got %s/%s\n", $user, gettype($tmp['username']), $tmp['username']); + + $mysqli->close(); + + } catch (mysqli_sql_exception $e) { + printf("%s\n", $e->getMessage()); + printf("[012] Usage of mysqli.default_host failed\n"); + } + + try { + $link = mysqli_connect($host, $user, $passwd, null, ini_get('mysqli.default_port')); + mysqli_select_db($link, $db); + if (!$res = mysqli_query($link, "SELECT 'have been set' AS all_defaults")) + printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + mysqli_close($link); + } catch (mysqli_sql_exception $e) { + printf("%s\n", $e->getMessage()); + printf("[014] Usage of mysqli_connect() has failed\n"); + } + + try { + $link = mysqli_connect($host, $user, $passwd, null); + mysqli_select_db($link, $db); + if (!$res = mysqli_query($link, "SELECT 'have been set' AS all_defaults")) + printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + mysqli_close($link); + } catch (mysqli_sql_exception $e) { + printf("%s\n", $e->getMessage()); + printf("[016] Usage of mysqli_connect() has failed\n"); + } + + + print "done!"; +?> +--EXPECTF-- +array(1) { + [%u|b%"testing"]=> + %unicode|string%(19) "mysqli.default_port" +} +array(1) { + [%u|b%"testing"]=> + %unicode|string%(17) "mysqli.default_pw" +} +array(1) { + [%u|b%"testing"]=> + %unicode|string%(19) "mysqli.default_user" +} +array(1) { + [%u|b%"all_defaults"]=> + %unicode|string%(13) "have been set" +} +array(1) { + [%u|b%"all_defaults"]=> + %unicode|string%(13) "have been set" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_connect_oo_warnings.phpt b/ext/mysqli/tests/mysqli_connect_oo_warnings.phpt new file mode 100644 index 0000000..5ede445 --- /dev/null +++ b/ext/mysqli/tests/mysqli_connect_oo_warnings.phpt @@ -0,0 +1,57 @@ +--TEST-- +new mysqli() +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifemb.inc'); + require_once('skipifconnectfailure.inc'); + if (!get_current_user()) + die('skip: get_current_user() not supported'); + if (stristr(mysqli_get_client_info(), 'mysqlnd')) + die("skip: test for libmysql (different error output when using php streams"); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $myhost = 'invalidhost'; + $link = NULL; + + print "1) bail\n"; + if (!is_object($mysqli = new mysqli($myhost)) || ('mysqli' !== get_class($mysqli))) + printf("[001] Expecting NULL, got %s/%s\n", gettype($mysqli), (is_object($mysqli)) ? var_export($mysqli, true) : $mysqli); + + print "2) be quiet\n"; + if (!is_object($mysqli = @new mysqli($myhost)) || ('mysqli' !== get_class($mysqli))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($mysqli), (is_object($mysqli)) ? var_export($mysqli, true) : $mysqli); + var_dump(mysqli_connect_error()); + var_dump(mysqli_connect_errno()); + + print "3) bail\n"; + if (false !== ($link = mysqli_connect($myhost))) { + printf("[003] Expecting boolean/false, got %s/%s\n", gettype($link), $link); + } + + print "4) be quiet\n"; + if (false !== ($link = @mysqli_connect($myhost))) { + printf("[004] Expecting boolean/false, got %s/%s\n", gettype($link), $link); + } + var_dump(mysqli_connect_error()); + var_dump(mysqli_connect_errno()); + + print "done!"; +?> +--EXPECTF-- +1) bail + +Warning: mysqli::mysqli(): (HY000/200%d): %s +2) be quiet +%s(%d) "%s" +int(200%d) +3) bail + +Warning: mysqli_connect(): (HY000/200%d): %s +4) be quiet +%s(%d) "%s" +int(200%d) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_connect_twice.phpt b/ext/mysqli/tests/mysqli_connect_twice.phpt new file mode 100644 index 0000000..a9d5b7e --- /dev/null +++ b/ext/mysqli/tests/mysqli_connect_twice.phpt @@ -0,0 +1,84 @@ +--TEST-- +Calling connect() on an open connection to create a new connection +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!$thread_id = mysqli_thread_id($link)) + printf("[002] Cannot determine thread id, test will fail, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (true !== ($tmp = my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket))) + printf("[003] Expecting boolean/true got %s/%s\n", gettype($tmp), $tmp); + + if (!is_int($new_thread_id = mysqli_thread_id($link)) || ($new_thread_id < 0)) + printf("[004] Expecting int/any got %s/%s\n", gettype($tmp), $tmp); + + if ($thread_id == $new_thread_id) + printf("[005] Expecting new connection and new thread id. Old thread id %d, new thread id %d\n", $thread_id, $new_thread_id); + + if (!($res = mysqli_query($link, "SELECT 'ok' AS it_works")) || + !($row = mysqli_fetch_assoc($res))) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + var_dump($row); + mysqli_free_result($res); + + mysqli_close($link); + + if (!$link = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[007] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!$thread_id = $link->thread_id) + printf("[008] Cannot determine thread id, test will fail, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (true !== ($tmp = $link->real_connect($host, $user, $passwd, $db, $port, $socket))) + printf("[009] Expecting boolean/true got %s/%s\n", gettype($tmp), $tmp); + + if (!is_int($new_thread_id = $link->thread_id) || ($new_thread_id < 0)) + printf("[010] Expecting int/any got %s/%s\n", gettype($tmp), $tmp); + + if ($thread_id == $new_thread_id) + printf("[011] Expecting new connection and new thread id. Old thread id %d, new thread id %d\n", $thread_id, $new_thread_id); + + if (!($res = $link->query("SELECT 'works also with oo' AS syntax")) || + !($row = $res->fetch_assoc())) + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + var_dump($row); + mysqli_free_result($res); + + mysqli_close($link); + + if (NULL !== ($tmp = $link->connect($host, $user, $passwd, $db, $port, $socket))) + printf("[013] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[014] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (NULL !== ($tmp = $link->connect($host, $user, $passwd, $db, $port, $socket))) + printf("[015] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +array(1) { + [%u|b%"it_works"]=> + %unicode|string%(2) "ok" +} +array(1) { + [%u|b%"syntax"]=> + %unicode|string%(18) "works also with oo" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_constants.phpt b/ext/mysqli/tests/mysqli_constants.phpt new file mode 100644 index 0000000..8bdc849 --- /dev/null +++ b/ext/mysqli/tests/mysqli_constants.phpt @@ -0,0 +1,212 @@ +--TEST-- +Constants exported by ext/mysqli +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require("connect.inc"); + require("table.inc"); + + $php_version = (int)str_replace('.', '', PHP_VERSION); + $constants = get_defined_constants(true); + sort($constants); + + $expected_constants = array( + 'MYSQLI_READ_DEFAULT_GROUP' => true, + 'MYSQLI_READ_DEFAULT_FILE' => true, + 'MYSQLI_OPT_CONNECT_TIMEOUT' => true, + 'MYSQLI_OPT_LOCAL_INFILE' => true, + 'MYSQLI_INIT_COMMAND' => true, + 'MYSQLI_CLIENT_SSL' => true, + "MYSQLI_CLIENT_COMPRESS" => true, + "MYSQLI_CLIENT_INTERACTIVE" => true, + "MYSQLI_CLIENT_IGNORE_SPACE" => true, + "MYSQLI_CLIENT_NO_SCHEMA" => true, + "MYSQLI_CLIENT_FOUND_ROWS" => true, + "MYSQLI_STORE_RESULT" => true, + "MYSQLI_USE_RESULT" => true, + "MYSQLI_ASSOC" => true, + "MYSQLI_NUM" => true, + "MYSQLI_BOTH" => true, + "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH" => true, + "MYSQLI_NOT_NULL_FLAG" => true, + "MYSQLI_PRI_KEY_FLAG" => true, + "MYSQLI_UNIQUE_KEY_FLAG" => true, + "MYSQLI_MULTIPLE_KEY_FLAG" => true, + "MYSQLI_BLOB_FLAG" => true, + "MYSQLI_UNSIGNED_FLAG" => true, + "MYSQLI_ZEROFILL_FLAG" => true, + "MYSQLI_AUTO_INCREMENT_FLAG" => true, + "MYSQLI_TIMESTAMP_FLAG" => true, + "MYSQLI_SET_FLAG" => true, + "MYSQLI_NUM_FLAG" => true, + "MYSQLI_ENUM_FLAG" => true, + "MYSQLI_BINARY_FLAG" => true, + "MYSQLI_PART_KEY_FLAG" => true, + "MYSQLI_GROUP_FLAG" => true, + "MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED"=> true, + "MYSQLI_SERVER_QUERY_NO_INDEX_USED" => true, + + "MYSQLI_TYPE_DECIMAL" => true, + "MYSQLI_TYPE_TINY" => true, + "MYSQLI_TYPE_SHORT" => true, + "MYSQLI_TYPE_LONG" => true, + "MYSQLI_TYPE_FLOAT" => true, + "MYSQLI_TYPE_DOUBLE" => true, + "MYSQLI_TYPE_NULL" => true, + "MYSQLI_TYPE_TIMESTAMP" => true, + "MYSQLI_TYPE_LONGLONG" => true, + "MYSQLI_TYPE_INT24" => true, + "MYSQLI_TYPE_DATE" => true, + "MYSQLI_TYPE_TIME" => true, + "MYSQLI_TYPE_DATETIME" => true, + "MYSQLI_TYPE_YEAR" => true, + "MYSQLI_TYPE_NEWDATE" => true, + "MYSQLI_TYPE_ENUM" => true, + "MYSQLI_TYPE_SET" => true, + "MYSQLI_TYPE_TINY_BLOB" => true, + "MYSQLI_TYPE_MEDIUM_BLOB" => true, + "MYSQLI_TYPE_LONG_BLOB" => true, + "MYSQLI_TYPE_BLOB" => true, + "MYSQLI_TYPE_VAR_STRING" => true, + "MYSQLI_TYPE_STRING" => true, + "MYSQLI_TYPE_CHAR" => true, + "MYSQLI_TYPE_INTERVAL" => true, + "MYSQLI_TYPE_GEOMETRY" => true, + "MYSQLI_NO_DATA" => true, + "MYSQLI_REPORT_INDEX" => true, + "MYSQLI_REPORT_STRICT" => true, + "MYSQLI_REPORT_ALL" => true, + "MYSQLI_REPORT_ERROR" => true, + "MYSQLI_REPORT_OFF" => true, + "MYSQLI_SET_CHARSET_NAME" => true, + "MYSQLI_SET_CHARSET_DIR" => true, + "MYSQLI_REFRESH_GRANT" => true, + "MYSQLI_REFRESH_LOG" => true, + "MYSQLI_REFRESH_TABLES" => true, + "MYSQLI_REFRESH_HOSTS" => true, + "MYSQLI_REFRESH_STATUS" => true, + "MYSQLI_REFRESH_THREADS" => true, + "MYSQLI_REFRESH_SLAVE" => true, + "MYSQLI_REFRESH_MASTER" => true, + "MYSQLI_DEBUG_TRACE_ENABLED" => true, + ); + + /* depends on the build - experimental */ + if ($IS_MYSQLND && defined('MYSQLI_OPT_INT_AND_FLOAT_NATIVE')) { + $expected_constants['MYSQLI_OPT_INT_AND_FLOAT_NATIVE'] = true; + } + + if ($IS_MYSQLND || defined('MYSQLI_REFRESH_BACKUP_LOG')) { + $expected_constants['MYSQLI_REFRESH_BACKUP_LOG'] = true; + } + + if ($IS_MYSQLND) { + $version = 50007 + 1; + $expected_constants['MYSQLI_OPT_NET_CMD_BUFFER_SIZE'] = true; + $expected_constants['MYSQLI_OPT_NET_READ_BUFFER_SIZE'] = true; + $expected_constants['MYSQLI_ASYNC'] = true; + + $expected_constants['MYSQLI_SERVER_PS_OUT_PARAMS'] = true; + } else { + $version = mysqli_get_client_version(); + } + + if (($version > 51122 && $version < 60000) || ($version > 60003) || $IS_MYSQLND) { + $expected_constants['MYSQLI_ON_UPDATE_NOW_FLAG'] = true; + } + + /* First introduced in MySQL 6.0, backported to MySQL 5.5 */ + if ($version >= 50500 || $IS_MYSQLND) { + $expected_constants['MYSQLI_SERVER_QUERY_WAS_SLOW'] = true; + } + + if ($version > 50002) { + $expected_constants = array_merge($expected_constants, array( + "MYSQLI_TYPE_NEWDECIMAL" => true, + "MYSQLI_TYPE_BIT" => true, + )); + } + + if ($version > 50002 || $IS_MYSQLND) { + $expected_constants['MYSQLI_NO_DEFAULT_VALUE_FLAG'] = true; + } + + if ($version > 50003) { + $expected_constants = array_merge($expected_constants, array( + "MYSQLI_STMT_ATTR_CURSOR_TYPE" => true, + "MYSQLI_CURSOR_TYPE_NO_CURSOR" => true, + "MYSQLI_CURSOR_TYPE_READ_ONLY" => true, + "MYSQLI_CURSOR_TYPE_FOR_UPDATE" => true, + "MYSQLI_CURSOR_TYPE_SCROLLABLE" => true, + )); + } + + if ($version > 50007) { + $expected_constants = array_merge($expected_constants, array( + "MYSQLI_STMT_ATTR_PREFETCH_ROWS" => true, + )); + } + + if ($version > 50110 || $IS_MYSQLND) { + $expected_constants['MYSQLI_OPT_SSL_VERIFY_SERVER_CERT'] = true; + } + + /* pretty dump test, but that is the best way to mimic mysql.c */ + if (defined('MYSQLI_DATA_TRUNCATED')) + $expected_constants["MYSQLI_DATA_TRUNCATED"] = true; + + if (defined('MYSQLI_SERVER_PS_OUT_PARAMS')) + $expected_constants["MYSQLI_SERVER_PS_OUT_PARAMS"] = true; + + if (!$IS_MYSQLND) { + /* libmysql only */ + + /* are they available in all versions of ext/mysqli ? + ... no we must have removed them at some point - for BC, weakening the test + */ + if (defined("MYSQLI_RPL_MASTER")) { + $expected_constants["MYSQLI_RPL_MASTER"] = true; + $expected_constants["MYSQLI_RPL_SLAVE"] = true; + $expected_constants["MYSQLI_RPL_ADMIN"] = true; + } + } + + if (($IS_MYSQLND && version_compare(PHP_VERSION, ' 5.4.12-dev', '>=')) || (!$IS_MYSQLND && ($version > 50610))) { + /* could be that MySQL/libmysql 5.6.9 had the flag already but it was no stable release */ + $expected_constants["MYSQLI_OPT_CAN_HANDLE_EXPIRED_PASSWORDS"] = true; + } + + $unexpected_constants = array(); + + foreach ($constants as $group => $consts) { + foreach ($consts as $name => $value) { + if (stristr($name, 'mysqli')) { + $name = strtoupper($name); + if (isset($expected_constants[$name])) { + unset($expected_constants[$name]); + } else { + $unexpected_constants[$name] = $name; + } + } + } + } + + if (!empty($unexpected_constants)) { + printf("Dumping list of unexpected constants\n"); + var_dump($unexpected_constants); + } + + if (!empty($expected_constants)) { + printf("Dumping list of missing constants\n"); + var_dump($expected_constants); + } + + print "done!"; +?> +--EXPECTF-- +done! diff --git a/ext/mysqli/tests/mysqli_constants_categories.phpt b/ext/mysqli/tests/mysqli_constants_categories.phpt new file mode 100644 index 0000000..e51325a --- /dev/null +++ b/ext/mysqli/tests/mysqli_constants_categories.phpt @@ -0,0 +1,24 @@ +--TEST-- +Constants exported by ext/mysqli - checking category - PHP bug not mysqli bug (check from time to time) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +?> +--FILE-- +<?php + $constants = get_defined_constants(true); + + foreach ($constants as $group => $consts) { + foreach ($consts as $name => $value) { + if (stristr($name, 'mysqli')) { + if ('mysqli' != $group) + printf("found constant '%s' in group '%s'. expecting group 'mysqli'\n", $name, $group); + } + } + } + + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_data_seek.phpt b/ext/mysqli/tests/mysqli_data_seek.phpt new file mode 100644 index 0000000..9e2d650 --- /dev/null +++ b/ext/mysqli/tests/mysqli_data_seek.phpt @@ -0,0 +1,74 @@ +--TEST-- +mysqli_data_seek() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (NULL !== ($tmp = @mysqli_data_seek())) + printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @mysqli_data_seek($link))) + printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @mysqli_data_seek($link, $link))) + printf("[003] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + if (!$res = mysqli_query($link, 'SELECT * FROM test ORDER BY id LIMIT 4', MYSQLI_STORE_RESULT)) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (true !== ($tmp = mysqli_data_seek($res, 3))) + printf("[005] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + $row = mysqli_fetch_assoc($res); + if (4 != $row['id']) + printf("[006] Expecting record 4/d, got record %s/%s\n", $row['id'], $row['label']); + + if (true !== ($tmp = mysqli_data_seek($res, 0))) + printf("[007] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + $row = mysqli_fetch_assoc($res); + if (1 != $row['id']) + printf("[008] Expecting record 1/a, got record %s/%s\n", $row['id'], $row['label']); + + if (false !== ($tmp = mysqli_data_seek($res, 4))) + printf("[009] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = mysqli_data_seek($res, -1))) + printf("[010] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_free_result($res); + + if (!$res = mysqli_query($link, 'SELECT * FROM test ORDER BY id', MYSQLI_USE_RESULT)) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (false !== ($tmp = mysqli_data_seek($res, 3))) + printf("[012] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_free_result($res); + + if (NULL !== ($tmp = mysqli_data_seek($res, 1))) + printf("[013] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_data_seek(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d + +Warning: mysqli_data_seek(): Couldn't fetch mysqli_result in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_data_seek_oo.phpt b/ext/mysqli/tests/mysqli_data_seek_oo.phpt new file mode 100644 index 0000000..0858218 --- /dev/null +++ b/ext/mysqli/tests/mysqli_data_seek_oo.phpt @@ -0,0 +1,83 @@ +--TEST-- +mysqli_result->data_seek() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + require('table.inc'); + + if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + $res = new mysqli_result($mysqli); + if (NULL !== ($tmp = @$res->data_seek(0))) + printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = $mysqli->query('SELECT * FROM test ORDER BY id LIMIT 4', MYSQLI_STORE_RESULT)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (NULL !== ($tmp = @$res->data_seek())) + printf("[004] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @$res->data_seek($link))) + printf("[005] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @$res->data_seek($link, $link))) + printf("[006] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = $res->data_seek(3))) + printf("[007] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + $row = $res->fetch_assoc(); + if (4 != $row['id']) + printf("[008] Expecting record 4/d, got record %s/%s\n", $row['id'], $row['label']); + + if (true !== ($tmp = $res->data_seek(0))) + printf("[009] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + $row = $res->fetch_assoc(); + if (1 != $row['id']) + printf("[010] Expecting record 1/a, got record %s/%s\n", $row['id'], $row['label']); + + if (false !== ($tmp = $res->data_seek(4))) + printf("[011] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = $res->data_seek(-1))) + printf("[012] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + $res->free_result(); + + if (!$res = $mysqli->query('SELECT * FROM test ORDER BY id', MYSQLI_USE_RESULT)) + printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (false !== ($tmp = $res->data_seek(3))) + printf("[014] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + $res->free_result(); + + if (NULL !== ($tmp = $res->data_seek(1))) + printf("[015] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + $mysqli->close(); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_result::data_seek(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d + +Warning: mysqli_result::data_seek(): Couldn't fetch mysqli_result in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_debug.phpt b/ext/mysqli/tests/mysqli_debug.phpt new file mode 100644 index 0000000..2b754ea --- /dev/null +++ b/ext/mysqli/tests/mysqli_debug.phpt @@ -0,0 +1,69 @@ +--TEST-- +mysqli_debug() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_debug')) + die("skip: mysqli_debug() not available"); + +if (!defined('MYSQLI_DEBUG_TRACE_ENABLED')) + die("skip: can't say for sure if mysqli_debug works"); + +if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) + die("skip: debug functionality not enabled"); +?> +--FILE-- +<?php + require_once('connect.inc');; + + if (NULL !== ($tmp = @mysqli_debug())) + printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + // NOTE: documentation is not clear on this: function always return NULL or TRUE + if (true !== ($tmp = mysqli_debug(sprintf('d:t:O,%s/mysqli_debug_phpt.trace', sys_get_temp_dir())))) + printf("[002] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if ($IS_MYSQLND) { + // let's make this mysqlnd only - for libmysql we need debug installation + + // table.inc will create a database connection and run some SQL queries, therefore + // the debug file should have entries + require_once('table.inc'); + + clearstatcache(); + $trace_file = sprintf('%s/mysqli_debug_phpt.trace', sys_get_temp_dir()); + if (!file_exists($trace_file)) + printf("[003] Trace file '%s' has not been created\n", $trace_file); + if (filesize($trace_file) < 50) + printf("[004] Trace file '%s' is very small. filesize() reports only %d bytes. Please check.\n", + $trace_file, + filesize($trace_file)); + + // will mysqli_debug() mind if the trace file gets removed? + unlink($trace_file); + clearstatcache(); + + if (!$res = mysqli_query($link, 'SELECT * FROM test')) + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + else + mysqli_free_result($res); + + mysqli_close($link); + + clearstatcache(); + if (!file_exists($trace_file)) + printf("[006] Trace file '%s' does not exist\n", $trace_file); + unlink($trace_file); + } + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done%s diff --git a/ext/mysqli/tests/mysqli_debug_append.phpt b/ext/mysqli/tests/mysqli_debug_append.phpt new file mode 100644 index 0000000..f916995 --- /dev/null +++ b/ext/mysqli/tests/mysqli_debug_append.phpt @@ -0,0 +1,93 @@ +--TEST-- +mysqli_debug() - append to trace file +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_debug')) + die("skip: mysqli_debug() not available"); + +if (!defined('MYSQLI_DEBUG_TRACE_ENABLED')) + die("skip: can't say for sure if mysqli_debug works"); + +if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) + die("skip: debug functionality not enabled"); + +if (!$IS_MYSQLND) + die("SKIP Libmysql feature not sufficiently spec'd in MySQL C API documentation"); +?> +--FILE-- +<?php + require_once('connect.inc');; + + if (true !== ($tmp = mysqli_debug(sprintf('d:t:O,%s/mysqli_debug_phpt.trace', sys_get_temp_dir())))) + printf("[001] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + // table.inc will create a database connection and run some SQL queries, therefore + // the debug file should have entries + require_once('table.inc'); + + clearstatcache(); + $trace_file = sprintf('%s/mysqli_debug_phpt.trace', sys_get_temp_dir()); + if (!file_exists($trace_file)) + printf("[002] Trace file '%s' has not been created\n", $trace_file); + if (filesize($trace_file) < 50) + printf("[003] Trace file '%s' is very small. filesize() reports only %d bytes. Please check.\n", + $trace_file, + filesize($trace_file)); + + // will mysqli_debug() mind if the trace file gets removed? + unlink($trace_file); + clearstatcache(); + + if (!$fp = fopen($trace_file, 'w')) { + printf("[004] Cannot create trace file to test append mode\n"); + } else { + + if (!fwrite($fp, (binary) 'mysqli_debug.phpt test line')) + printf("[005] Cannot write to trace file.\n"); + fclose($fp); + + if (true !== ($tmp = mysqli_debug(sprintf('d:a,%s', $trace_file)))) + printf("[006] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = mysqli_query($link, 'SELECT * FROM test')) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + else + mysqli_free_result($res); + + $trace = file_get_contents($trace_file); + if (!strstr($trace, 'mysqli_debug.phpt test line')) + printf("[008] Cannot find original file content any more. Seems that the trace file got overwritten and not appended. Please check."); + + if (true !== ($tmp = mysqli_debug(sprintf('d:A,%s', $trace_file)))) + printf("[009] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = mysqli_query($link, 'SELECT * FROM test')) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + else + mysqli_free_result($res); + + if (!strstr(file_get_contents($trace_file), $trace)) + printf("[011] Cannot find original file content any more. Seems that the trace file got overwritten and not appended. Please check."); + } + + // what will happen if we create new trace entries...? + unlink($trace_file); + clearstatcache(); + if (file_exists($trace_file)) + printf("[012] Could not remove trace file '%s'.\n", $trace_file); + + mysqli_close($link); + print "done"; + if ($IS_MYSQLND) + print "libmysql/DBUG package prints some debug info here." +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done%s diff --git a/ext/mysqli/tests/mysqli_debug_control_string.phpt b/ext/mysqli/tests/mysqli_debug_control_string.phpt new file mode 100644 index 0000000..42a802d --- /dev/null +++ b/ext/mysqli/tests/mysqli_debug_control_string.phpt @@ -0,0 +1,77 @@ +--TEST-- +mysqli_debug() - invalid debug control strings +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_debug')) + die("skip: mysqli_debug() not available"); + +if (!defined('MYSQLI_DEBUG_TRACE_ENABLED')) + die("skip: can't say for sure if mysqli_debug works"); + +if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) + die("skip: debug functionality not enabled"); + +if (!$IS_MYSQLND) + die("SKIP Libmysql feature not sufficiently spec'd in MySQL C API documentation"); +?> +--FILE-- +<?php + require_once('connect.inc'); + require_once('table.inc'); + + function try_control_string($link, $control_string, $trace_file, $offset) { + + if (true !== ($tmp = mysqli_debug($control_string))) { + printf("[%03d][control string '%s'] Expecting boolean/true, got %s/%s.\n", + $offset + 1, + $control_string, + gettype($tmp), + $tmp); + return false; + } + + if (!$res = mysqli_query($link, 'SELECT * FROM test')) { + printf("[%03d][control string '%s'] [%d] %s.\n", + $offset + 2, + $control_string, + mysqli_errno($link), + mysqli_error($link)); + return false; + } + + clearstatcache(); + if (!file_exists($trace_file)) { + printf("[%03d][control string '%s'] Trace file has not been written.\n", + $offset + 3, + $control_string, + gettype($tmp), + $tmp); + return false; + } + + unlink($trace_file); + } + + $trace_file = sprintf('%s%s%s', sys_get_temp_dir(), DIRECTORY_SEPARATOR, 'mysqli_debug_phpt.trace'); + try_control_string($link, 't:,,:o,' . $trace_file, $trace_file, 10); + try_control_string($link, ':' . chr(0) . 'A,' . $trace_file, $trace_file, 20); + try_control_string($link, 't:o,' . $trace_file . ':abc', $trace_file, 30); + try_control_string($link, 't:o,' . $trace_file . ':ABC,123:b', $trace_file, 40); + try_control_string($link, 't:ABC,123:b;:o,' . $trace_file, $trace_file, 50); + try_control_string($link, 't:A;BC,123:b;:o,' . $trace_file, $trace_file, 60); + try_control_string($link, 't:p:o,' . $trace_file, $trace_file, 70); + try_control_string($link, 't:p,1,,2:o,' . $trace_file, $trace_file, 80); + try_control_string($link, 't:z,1,,2:o,' . $trace_file, $trace_file, 90);# + + mysqli_close($link); + print "done"; + if ($IS_MYSQLND) + print "libmysql/DBUG package prints some debug info here." +?> +--EXPECTF-- +[023][control string '%s'] Trace file has not been written. +done%s diff --git a/ext/mysqli/tests/mysqli_debug_ini.phpt b/ext/mysqli/tests/mysqli_debug_ini.phpt new file mode 100644 index 0000000..bcf0067 --- /dev/null +++ b/ext/mysqli/tests/mysqli_debug_ini.phpt @@ -0,0 +1,53 @@ +--TEST-- +mysqli_debug() - enabling trace with ini setting +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_debug')) + die("skip mysqli_debug() not available"); + +if (!defined('MYSQLI_DEBUG_TRACE_ENABLED')) + die("skip: can't say for sure if mysqli_debug works"); + +if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) + die("skip: debug functionality not enabled"); + +require_once('connect.inc'); +if (!$IS_MYSQLND || ($MYSQLND_VERSION < 50004)) + die("skip needs mysqlnd version/revision 5.0.4"); + +if (!$fp = @fopen('/tmp/mysqli_debug_phpt.trace', 'w')) + die("skip PHP cannot create a file in /tmp/mysqli_debug_phpt"); +else + fclose($fp); +@unlink("/tmp/mysqli_debug_phpt.trace"); +?> +--INI-- +mysqlnd.debug="t:O,/tmp/mysqli_debug_phpt.trace" +--FILE-- +<?php + require_once('connect.inc'); + require_once('table.inc'); + + var_dump(ini_get('mysqlnd.debug')); + + $trace_file = '/tmp/mysqli_debug_phpt.trace'; + clearstatcache(); + if (!file_exists($trace_file)) + printf("[003] Trace file '%s' has not been created\n", $trace_file); + if (filesize($trace_file) < 50) + printf("[004] Trace file '%s' is very small. filesize() reports only %d bytes. Please check.\n", + $trace_file, + filesize($trace_file)); + + mysqli_close($link); + unlink($trace_file); + + print "done!"; +?> +--EXPECTF-- +string(32) "t:O,/tmp/mysqli_debug_phpt.trace" +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt b/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt new file mode 100644 index 0000000..1de2eeb --- /dev/null +++ b/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt @@ -0,0 +1,230 @@ +--TEST-- +mysqli_debug() - all control string options supported by both mysqlnd and libmysql except oOaA +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_debug')) + die("skip: mysqli_debug() not available"); + +if (!defined('MYSQLI_DEBUG_TRACE_ENABLED')) + die("skip: can't say for sure if mysqli_debug works"); + +if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) + die("skip: debug functionality not enabled"); + +if (!$IS_MYSQLND) + die("SKIP Libmysql feature not sufficiently spec'd in MySQL C API documentation"); +?> +--FILE-- +<?php + require_once('connect.inc');; + require_once('table.inc'); + + function try_control_string($link, $control_string, $trace_file, $offset) { + + @unlink($trace_file); + if (true !== ($tmp = @mysqli_debug($control_string))) { + printf("[%03d][control string '%s'] Expecting boolean/true, got %s/%s.\n", + $offset + 1, + $control_string, + gettype($tmp), + $tmp); + return false; + } + + if (!$res = mysqli_query($link, 'SELECT * FROM test')) { + printf("[%03d][control string '%s'] [%d] %s.\n", + $offset + 2, + $control_string, + mysqli_errno($link), + mysqli_error($link)); + return false; + } + while ($row = mysqli_fetch_assoc($res)) + ; + mysqli_free_result($res); + + clearstatcache(); + if (!file_exists($trace_file)) { + printf("[%03d][control string '%s'] Trace file has not been written.\n", + $offset + 3, + $control_string, + gettype($tmp), + $tmp); + return false; + } + + return trim(substr(file_get_contents($trace_file), 0, 100024)); + } + + $trace_file = sprintf('%s%s%s', sys_get_temp_dir(), DIRECTORY_SEPARATOR, 'mysqli_debug_phpt.trace'); + + $trace = try_control_string($link, 't:O,' . $trace_file, $trace_file, 10); + if (!strstr($trace, 'SELECT * FROM test') && !strstr($trace, 'mysql_real_query')) + printf("[015] SELECT query cannot be found in trace. Trace contents seems wrong.\n"); + + // T - gettimeofday() system call, system dependent format + // 16:57:03.350734 >mysql_real_query + $trace = try_control_string($link, 't:O,' . $trace_file . ':T', $trace_file, 20); + if (!preg_match('@^[012]{0,1}[0-9]{1}:[0-5]{0,1}[0-9]{1}:[0-5]{0,1}[0-9]{1}@ismU', $trace)) + printf("[025] Timestamp not found. One reason could be that the test is borked and does not recognize the format of the gettimeofday() system call. Check manually (and fix the test, if needed :-)). First characters from trace are '%s'\n", substr($trace, 0, 80)); + + // i - add PID of the current process + // currently PHP is not multi-threaded, so it should be save to test for the PID of this PHP process + if (false === ($pid = getmypid())) + $pid = "[\d]+"; + + $trace = try_control_string($link, 't:O,' . $trace_file . ':i', $trace_file, 30); + if (!preg_match("@^" . $pid . "*@ismU", $trace)) + printf("[035] Process ID has not been found, first characters from trace are '%s'\n", substr($trace, 0, 80)); + + // L - line numbers + $trace = try_control_string($link, 't:O,' . $trace_file . ':L', $trace_file, 40); + if (!preg_match("@^[\d]+@ismU", $trace)) + printf("[045] Line numbers have not been found, first characters from trace are '%s'\n", substr($trace, 0, 80)); + + // F - file name + $trace = try_control_string($link, 't:O,' . $trace_file . ':F', $trace_file, 50); + // hopefully we'll never see a file name that's not covered by this regular expression... + if (!preg_match("@^\s*[/\w\\\\d\.\-]+\.[ch]@ismU", $trace)) + printf("[055] File names seem to be missing, first characters from trace are '%s'\n", substr($trace, 0, 80)); + + // -n - print function nesting depth + $trace = try_control_string($link, 't:O,' . $trace_file . ':n', $trace_file, 60); + if (!preg_match("@^\d+:@ismU", $trace)) + printf("[065] Nesting level seem to be missing, first characters from trace are '%s'\n", substr($trace, 0, 80)); + + // -t,[N] - maximum nesting level + $trace = try_control_string($link, 't,1:n:O,' . $trace_file, $trace_file, 70); + $lines = explode("\n", $trace); + foreach ($lines as $k => $line) { + $line = trim($line); + if (!preg_match("@^(\d+):+@ismU", $line, $matches)) { + printf("[075] Nesting level seem to be missing, first characters from trace are '%s'\n", substr($line, 0, 80)); + } else { + if (!isset($matches[1]) || ((int)$matches[1] > 1)) { + printf("[076] Nesting level seem to be %d, should not be higher than 1, first characters from trace are '%s'\n", + $matches[1], + substr($line, 0, 80)); + } + } + } + + // omitting t + $trace = try_control_string($link, 'n:O,' . $trace_file, $trace_file, 80); + $lines = explode("\n", $trace); + foreach ($lines as $k => $line) { + $line = trim($line); + if (preg_match("@^[|\s]*>[\w]+@ism", $line, $matches)) { + printf("[085] Looks like a function call, but there should be none in the trace file, first characters from trace are '%s'\n", + substr($line, 0, 80)); + } + } + + // -f[,functions] - Limit debugger list to specified functions. Empty list -> all functions + $lines_all_funcs = explode("\n", try_control_string($link, 't:O,' . $trace_file, $trace_file, 90)); + $functions_all_funcs = array(); + foreach ($lines_all_funcs as $k => $line) { + $line = trim($line); + if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) { + $functions_all_funcs[$matches[1]] = $matches[1]; + } + } + + $lines_trace = explode("\n", try_control_string($link, 't:f:O,' . $trace_file, $trace_file, 100)); + $functions_trace = array(); + foreach ($lines_trace as $k => $line) { + $line = trim($line); + if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) { + $functions_trace[$matches[1]] = $matches[1]; + } + } + + $tmp = array_diff($functions_all_funcs, $functions_trace); + if (!empty($tmp)) { + printf("[105] Looks like not all functions are listed in the trace. Check manually, dumping diff."); + var_dump($tmp); + } + + // get two or three function names to play with... + $test_functions = array('simple' => array(), 'doubledot' => array()); + + foreach ($functions_all_funcs as $func) { + if (count($test_functions['simple']) < 2 && !strstr($func, '::')) + $test_functions['simple'][$func] = $func; + else if (count($test_functions['doubledot']) < 2 && strstr($func, '::')) + $test_functions['doubledot'][$func] = $func; + } + + $control_string = ''; + if ($func = reset($test_functions['simple'])) + $control_string .= sprintf('%s,', $func); + if ($func = reset($test_functions['doubledot'])) + $control_string .= sprintf('%s,', $func); + if ($func = next($test_functions['simple'])) + $control_string .= sprintf('%s,', $func); + if ($func = next($test_functions['doubledot'])) + $control_string .= sprintf('%s,', $func); + $control_string = sprintf('t:f,%s:O,%s', $control_string, $trace_file); + + $lines_trace = explode("\n", try_control_string($link, $control_string, $trace_file, 110)); + $functions_trace = array(); + foreach ($lines_trace as $k => $line) { + $line = trim($line); + if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) { + $functions_trace[$matches[1]] = $matches[1]; + } + } + + foreach ($test_functions['simple'] as $func) + if (isset($functions_trace[$func])) { + unset($functions_trace[$func]); + unset($test_functions['simple'][$func]); + } + + foreach ($test_functions['doubledot'] as $func) + if (isset($functions_trace[$func])) { + unset($functions_trace[$func]); + unset($test_functions['doubledot'][$func]); + } + + if (!empty($functions_trace)) { + printf("[115] Dumping list of unexpected functions which should have not been shown when using control string '%s'.\n", + $control_string); + var_dump($functions_trace); + } + $tmp = array_merge($test_functions['doubledot'], $test_functions['simple']); + if (!empty($tmp)) { + printf("[116] Dumping list of functions which should have been shown when using control string '%s'.\n", + $control_string); + var_dump($tmp); + } + + if ($IS_MYSQLND) { + // mysqlnd only option + // m - trace memory allocations + $trace = try_control_string($link, 't:O,' . $trace_file . ':m', $trace_file, 120); + if (!preg_match("@^[|\s]*>\_mysqlnd_pefree@ismU", $trace, $matches) && + !preg_match("@^[|\s]*>\_mysqlnd_pemalloc@ismU", $trace, $matches)) { + printf("[125] Memory dump does neither contain _mysqlnd_pefree nor _mysqlnd_pemalloc calls - check manually.\n"); + var_dump($trace); + } + + } + + mysqli_close($link); + print "done"; + if ($IS_MYSQLND) + print "libmysql/DBUG package prints some debug info here."; + @unlink($trace_file); +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +[083][control string 'n:O,%smysqli_debug_phpt.trace'] Trace file has not been written. +done%s diff --git a/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt b/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt new file mode 100644 index 0000000..8ecf516 --- /dev/null +++ b/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt @@ -0,0 +1,128 @@ +--TEST-- +mysqli_debug() - mysqlnd only control strings +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); + +if (!function_exists('mysqli_debug')) + die("skip mysqli_debug() not available"); + +if (!defined('MYSQLI_DEBUG_TRACE_ENABLED')) + die("skip: can't say for sure if mysqli_debug works"); + +if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) + die("skip: debug functionality not enabled"); + +if (!$IS_MYSQLND) + die("skip mysqlnd only test"); +?> +--FILE-- +<?php + require_once('connect.inc');; + require_once('table.inc'); + + function try_control_string($link, $control_string, $trace_file, $offset) { + + @unlink($trace_file); + if (true !== ($tmp = @mysqli_debug($control_string))) { + printf("[%03d][control string '%s'] Expecting boolean/true, got %s/%s.\n", + $offset + 1, + $control_string, + gettype($tmp), + $tmp); + return false; + } + + if (!$res = mysqli_query($link, 'SELECT * FROM test')) { + printf("[%03d][control string '%s'] [%d] %s.\n", + $offset + 2, + $control_string, + mysqli_errno($link), + mysqli_error($link)); + return false; + } + while ($row = mysqli_fetch_assoc($res)) + ; + mysqli_free_result($res); + + clearstatcache(); + if (!file_exists($trace_file)) { + printf("[%03d][control string '%s'] Trace file has not been written.\n", + $offset + 3, + $control_string, + gettype($tmp), + $tmp); + return false; + } + + return trim(substr(file_get_contents($trace_file), 0, 100024)); + } + + $memory_funcs = array( + '_mysqlnd_ecalloc', + '_mysqlnd_emalloc', + '_mysqlnd_palloc_free_thd_cache_reference', + '_mysqlnd_pecalloc', + '_mysqlnd_pefree', + '_mysqlnd_pemalloc', + '_mysqlnd_perealloc', + ); + $trace_file = sprintf('%s%s%s', sys_get_temp_dir(), DIRECTORY_SEPARATOR, 'mysqli_debug_phpt.trace'); + + $trace = try_control_string($link, 't:m:O,' . $trace_file, $trace_file, 10); + if (!strstr($trace, 'SELECT * FROM test') && !strstr($trace, 'mysql_real_query')) + printf("[015] SELECT query cannot be found in trace. Trace contents seems wrong.\n"); + + $lines_trace = explode("\n", $trace); + $functions_trace = array(); + foreach ($lines_trace as $k => $line) { + $line = trim($line); + if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) { + $functions_trace[$matches[1]] = $matches[1]; + } + } + + $found = 0; + foreach ($memory_funcs as $k => $name) + if (isset($functions_trace[$name])) + $found++; + + if ($found < (count($memory_funcs) - 2)) + printf("[016] Only %d memory functions have been found, expecting at least %d.\n", + $found, count($memory_funcs) - 2); + + $trace = try_control_string($link, 't:O,' . $trace_file, $trace_file, 20); + if (!strstr($trace, 'SELECT * FROM test') && !strstr($trace, 'mysql_real_query')) + printf("[025] SELECT query cannot be found in trace. Trace contents seems wrong.\n"); + + $lines_trace = explode("\n", $trace); + $functions_trace = array(); + foreach ($lines_trace as $k => $line) { + $line = trim($line); + if (preg_match("@^[|\s]*>([\w:]+)@ism", $line, $matches)) { + $functions_trace[$matches[1]] = $matches[1]; + } + } + + $found = 0; + foreach ($memory_funcs as $k => $name) + if (isset($functions_trace[$name])) + $found++; + + if ($found > 2) + printf("[026] More than %d memory functions have been recorded, that's strange.\n", + $found); + + mysqli_close($link); + @unlink($trace_file); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_disable_reads_from_master.phpt b/ext/mysqli/tests/mysqli_disable_reads_from_master.phpt new file mode 100644 index 0000000..9814c6e --- /dev/null +++ b/ext/mysqli/tests/mysqli_disable_reads_from_master.phpt @@ -0,0 +1,47 @@ +--TEST-- +mysqli_disable_reads_from_master() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_disable_reads_from_master')) { + die("skip mysqli_disable_reads_from_master() not available"); +} +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (NULL !== ($tmp = @mysqli_disable_reads_from_master())) + printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @mysqli_disable_reads_from_master($link))) + printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } + + if (!is_bool($tmp = mysqli_disable_reads_from_master($link))) + printf("[004] Expecting boolean/[true|false] value, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + if (NULL !== ($tmp = mysqli_disable_reads_from_master($link))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_disable_reads_from_master(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_driver.phpt b/ext/mysqli/tests/mysqli_driver.phpt new file mode 100644 index 0000000..4e266a0 --- /dev/null +++ b/ext/mysqli/tests/mysqli_driver.phpt @@ -0,0 +1,114 @@ +--TEST-- +mysqli_driver class +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require("table.inc"); + + if (!is_object($driver = new mysqli_driver())) + printf("[001] Failed to create mysqli_driver object\n"); + + $client_info = mysqli_get_client_info(); + if (($tmp = $driver->client_info) !== $client_info) + printf("[002] Expecting %s/%s, got %s/%s\n", + gettype($client_info), $client_info, + gettype($tmp), $tmp); + + $client_version = mysqli_get_client_version(); + if (($tmp = $driver->client_version) !== $client_version) + printf("[003] Expecting %s/%s, got %s/%s\n", + gettype($client_version), $client_version, + gettype($tmp), $tmp); + + if (!is_int($tmp = $driver->driver_version) || (0 == $tmp)) + printf("[004] Expecting int/any, got %s/%s\n", + gettype($tmp), $tmp); + + + $all_modes = array(MYSQLI_REPORT_INDEX, MYSQLI_REPORT_ERROR, MYSQLI_REPORT_STRICT, + MYSQLI_REPORT_ALL, MYSQLI_REPORT_OFF); + $report_mode = $driver->report_mode; + if (!is_int($report_mode)) + printf("[005] Expecting int/any, got %s/%s\n", + gettype($report_mode), $report_mode); + + if (!in_array($report_mode, $all_modes)) + printf("[006] Illegal report mode returned? Got %s, expected %s\n", + $report_mode, implode(', ', $all_modes)); + + $driver->report_mode = MYSQLI_REPORT_STRICT; + $ok = false; + try { + + if ($link = my_mysqli_connect($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) + printf("[007] Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", + $host, $user . 'unknown_really', $db, $port, $socket); + mysqli_close($link); + + } catch (mysqli_sql_exception $e) { + $ok = true; + if ('' == $e->getMessage()) + printf("[008] getMessage() has returned an emptry string.\n"); + if ('' == $e->getCode()) + printf("[009] getCode() has returned an empty string.\n"); + if ('' == $e->getFile()) + printf("[010] getFile() has returned an empty string.\n"); + if ('' == $e->getLine()) + printf("[011] getLine() has returned an empty string.\n"); + $tmp = $e->getTrace(); + if (empty($tmp)) + printf("[012] getTrace() has returned an empty array.\n"); + if ('' == $e->getTraceAsString()) + printf("[013] getTraceAsString() has returned an empty string.\n"); + if ('' == $e->__toString()) + printf("[014] __toString() has returned an empty string.\n"); + + } + if (!$ok) + printf("[015] Error reporting mode has not been switched to exceptions and or no exception thrown\n"); + + + $driver->report_mode = MYSQLI_REPORT_OFF; + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[016] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + mysqli_query($link, "NO_SQL"); + mysqli_close($link); + + $driver->report_mode = MYSQLI_REPORT_ERROR; + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[017] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + mysqli_query($link, "NO_SQL"); + mysqli_close($link); + + if (MYSQLI_REPORT_ERROR !== $driver->report_mode) + printf("[018] Error mode should be different\n"); + + /* TODO - more report testing should go in here, but it's not really documented what behaviour is expected */ + + $driver->report_mode = $report_mode; + + $reconnect = $driver->reconnect; + if (!is_bool($reconnect)) + printf("[019] Expecting boolean/any, got %s/%s\n", + gettype($reconnect), $reconnect); + + /* pointless, but I need more documentation */ + $driver->reconnect = true; + $driver->reconnect = false; + $driver->reconnect = $reconnect; + + if (!is_bool($embedded = $driver->embedded)) + printf("[020] Expecting boolean/any, got %s/%s\n", + gettype($embedded), $embedded); + + print "done!"; +?> +--EXPECTF-- +Warning: mysqli_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NO_SQL' at line 1 in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_driver_unclonable.phpt b/ext/mysqli/tests/mysqli_driver_unclonable.phpt new file mode 100644 index 0000000..0e2438e --- /dev/null +++ b/ext/mysqli/tests/mysqli_driver_unclonable.phpt @@ -0,0 +1,13 @@ +--TEST-- +Trying to clone mysqli_driver object +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +<?php require_once('skipifemb.inc'); ?> +--FILE-- +<?php + $driver = new mysqli_driver; + $driver_clone = clone $driver; + print "done!"; +?> +--EXPECTF-- +Fatal error: Trying to clone an uncloneable object of class mysqli_driver in %s on line %d
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_dump_debug_info.phpt b/ext/mysqli/tests/mysqli_dump_debug_info.phpt new file mode 100644 index 0000000..bd87ddf --- /dev/null +++ b/ext/mysqli/tests/mysqli_dump_debug_info.phpt @@ -0,0 +1,44 @@ +--TEST-- +mysqli_dump_debug_info() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (NULL !== ($tmp = @mysqli_dump_debug_info())) + printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @mysqli_dump_debug_info($link))) + printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + exit(1); + } + + if (!is_bool($tmp = mysqli_dump_debug_info($link))) + printf("[004] Expecting boolean/[true|false] value, got %s/%s, [%d] %s\n", + gettype($tmp), $tmp, + mysqli_errno($link), mysqli_error($link)); + + mysqli_close($link); + + if (NULL !== ($tmp = mysqli_dump_debug_info($link))) + printf("[005] Expecting NULL, got %s/%s\n", + gettype($tmp), $tmp, + mysqli_errno($link), mysqli_error($link)); + + print "done!"; +?> +--EXPECTF-- +Warning: mysqli_dump_debug_info(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt b/ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt new file mode 100644 index 0000000..82edef5 --- /dev/null +++ b/ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt @@ -0,0 +1,38 @@ +--TEST-- +mysqli_dump_debug_info() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); + + if (NULL !== ($tmp = @$mysqli->dump_debug_info($link))) + printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_bool($tmp = $mysqli->dump_debug_info())) + printf("[003] Expecting boolean/[true|false] value, got %s/%s, [%d] %s\n", + gettype($tmp), $tmp, + $mysqli->errno, $mysqli->error); + + $mysqli->close(); + + if (NULL !== ($tmp = $mysqli->dump_debug_info())) + printf("[004] Expecting NULL, got %s/%s, [%d] %s\n", + gettype($tmp), $tmp, + $mysqli->errno, $mysqli->error); + + print "done!"; +?> +--EXPECTF-- +Warning: mysqli::dump_debug_info(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_embedded_connect.phpt b/ext/mysqli/tests/mysqli_embedded_connect.phpt new file mode 100644 index 0000000..37891f5 --- /dev/null +++ b/ext/mysqli/tests/mysqli_embedded_connect.phpt @@ -0,0 +1,32 @@ +--TEST-- +mysqli_embedded_connect() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifnotemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + $tmp = NULL; + $link = NULL; + + if (NULL !== ($tmp = @mysqli_embedded_connect())) + printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = mysqli_embedded_connect($db)) { + printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } + + if (!is_bool($tmp = mysqli_embedded_connect($db . '_unknown'))) + printf("[003] Expecting boolean/[true|false] value, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + print "done!"; +?> +--EXPECTF-- +Warning: mysqli_embedded_connect() expects parameter 1 to be mysqli, null given in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_enable_reads_from_master.phpt b/ext/mysqli/tests/mysqli_enable_reads_from_master.phpt new file mode 100644 index 0000000..e23ddd1 --- /dev/null +++ b/ext/mysqli/tests/mysqli_enable_reads_from_master.phpt @@ -0,0 +1,43 @@ +--TEST-- +mysqli_enable_reads_from_master() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_enable_reads_from_master')) { + die("skip function mysqli_enable_reads_from_master() not available\n"); +} +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (NULL !== ($tmp = @mysqli_enable_reads_from_master())) + printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @mysqli_enable_reads_from_master($link))) + printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } + + if (!is_bool($tmp = mysqli_enable_reads_from_master($link))) + printf("[004] Expecting boolean/[true|false] value, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + if (NULL !== ($tmp = mysqli_enable_reads_from_master($link))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +Warning: mysqli_enable_reads_from_master(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_errno.phpt b/ext/mysqli/tests/mysqli_errno.phpt new file mode 100644 index 0000000..0e9f049 --- /dev/null +++ b/ext/mysqli/tests/mysqli_errno.phpt @@ -0,0 +1,52 @@ +--TEST-- +mysqli_errno() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_errno())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_errno($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); +} + + var_dump(mysqli_errno($link)); + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { + printf("[004] Failed to drop old test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + mysqli_query($link, 'SELECT * FROM test'); + var_dump(mysqli_errno($link)); + + @mysqli_query($link, 'No SQL'); + if (($tmp = mysqli_errno($link)) == 0) + printf("[005] Expecting int/any non zero got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + var_dump(mysqli_errno($link)); + + print "done!"; +?> +--EXPECTF-- +int(0) +int(%d) + +Warning: mysqli_errno(): Couldn't fetch mysqli in %s on line %d +NULL +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_errno_oo.phpt b/ext/mysqli/tests/mysqli_errno_oo.phpt new file mode 100644 index 0000000..5d5ea25 --- /dev/null +++ b/ext/mysqli/tests/mysqli_errno_oo.phpt @@ -0,0 +1,49 @@ +--TEST-- +$mysqli->errno +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + $mysqli = new mysqli(); + if (0 !== ($tmp = @$mysqli->errno)) + printf("[001] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + var_dump($mysqli->errno); + + if (!$mysqli->query('DROP TABLE IF EXISTS test')) { + printf("[003] Failed to drop old test table: [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + $mysqli->query('SELECT * FROM test'); + var_dump($mysqli->errno); + + @$mysqli->query('No SQL'); + if (($tmp = $mysqli->errno) === 0) + printf("[004] Expecting int/any non zero got %s/%s\n", gettype($tmp), $tmp); + + $mysqli->close(); + + var_dump($mysqli->errno); + + print "done!"; +?> +--EXPECTF-- +int(0) +int(%d) + +Warning: main(): Couldn't fetch mysqli in %s on line %d +NULL +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_error.phpt b/ext/mysqli/tests/mysqli_error.phpt new file mode 100644 index 0000000..5e70d59 --- /dev/null +++ b/ext/mysqli/tests/mysqli_error.phpt @@ -0,0 +1,49 @@ +--TEST-- +mysqli_error() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_error())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_error($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } + + $tmp = mysqli_error($link); + if (!is_string($tmp) || ('' !== $tmp)) + printf("[004] Expecting string/empty, got %s/%s. [%d] %s\n", gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { + printf("[005] Failed to drop old test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + mysqli_query($link, 'SELECT * FROM test'); + $tmp = mysqli_error($link); + if (!is_string($tmp) || !preg_match("/Table '\w*\.test' doesn't exist/su", $tmp)) + printf("[006] Expecting string/[Table... doesn't exit], got %s/%s. [%d] %s\n", gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); + + mysqli_close($link); + + var_dump(mysqli_error($link)); + + print "done!"; +?> +--EXPECTF-- +Warning: mysqli_error(): Couldn't fetch mysqli in %s on line %d +NULL +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_error_oo.phpt b/ext/mysqli/tests/mysqli_error_oo.phpt new file mode 100644 index 0000000..1f05896 --- /dev/null +++ b/ext/mysqli/tests/mysqli_error_oo.phpt @@ -0,0 +1,46 @@ +--TEST-- +$mysqli->error +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + $mysqli = new mysqli(); + if ('' !== ($tmp = @$mysqli->error)) + printf("[001] Expecting empty string, got %s/'%s'\n", gettype($tmp), $tmp); + + if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + $tmp = $mysqli->error; + if (!is_string($tmp) || ('' !== $tmp)) + printf("[003] Expecting string/empty, got %s/%s. [%d] %s\n", gettype($tmp), $tmp, $mysqli->errno, $mysqli->error); + + if (!$mysqli->query('DROP TABLE IF EXISTS test')) { + printf("[004] Failed to drop old test table: [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + $mysqli->query('SELECT * FROM test'); + $tmp = $mysqli->error; + if (!is_string($tmp) || !preg_match("/Table '\w*\.test' doesn't exist/su", $tmp)) + printf("[006] Expecting string/[Table... doesn't exit], got %s/%s. [%d] %s\n", gettype($tmp), $tmp, $mysqli->errno, $mysqli->error); + + $mysqli->close(); + + var_dump($mysqli->error); + + print "done!"; +?> +--EXPECTF-- +Warning: main(): Couldn't fetch mysqli in %s on line %d +NULL +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_error_unicode.phpt b/ext/mysqli/tests/mysqli_error_unicode.phpt new file mode 100644 index 0000000..b59ed5f --- /dev/null +++ b/ext/mysqli/tests/mysqli_error_unicode.phpt @@ -0,0 +1,51 @@ +--TEST-- +mysqli_error() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_error())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_error($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } + + if (!(version_compare(PHP_VERSION, '5.9.9', '>') == 1)) { + mysqli_query($link, "set names utf8"); + } + + $tmp = mysqli_error($link); + if (!is_string($tmp) || ('' !== $tmp)) + printf("[004] Expecting string/empty, got %s/%s. [%d] %s\n", gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); + + + mysqli_query($link, 'SELECT * FROM нÑма_такава_таблица'); + $tmp = mysqli_error($link); + var_dump(str_replace($db.".", "", $tmp)); + + mysqli_close($link); + + var_dump(mysqli_error($link)); + + print "done!"; +?> +--EXPECTF-- +%unicode|string%(%d) "Table 'нÑма_такава_таблица' doesn't exist" + +Warning: mysqli_error(): Couldn't fetch mysqli in %s on line %d +NULL +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_expire_password.phpt b/ext/mysqli/tests/mysqli_expire_password.phpt new file mode 100644 index 0000000..ce89a21 --- /dev/null +++ b/ext/mysqli/tests/mysqli_expire_password.phpt @@ -0,0 +1,145 @@ +--TEST-- +MySQL 5.6 EXPIRE PASSWORD protocol change +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('connect.inc'); + +if ($IS_MYSQLND && !version_compare(PHP_VERSION, '5.4.12-dev', ">=")) { + die("SKIP Available in mysqlnd as of PHP 5.4.12-dev"); +} + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf("SKIP Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket)); +} + +if ($link->server_version < 50610) + die(sprintf("SKIP Needs MySQL 5.6.10 or newer, found MySQL %s\n", $link->server_info)); + +if (!$IS_MYSQLND && (mysqli_get_client_version() < 50610)) { + die(sprintf("SKIP Needs libmysql 5.6.10 or newer, found %s\n", mysqli_get_client_version())); +} + +mysqli_query($link, 'DROP USER expiretest'); +mysqli_query($link, 'DROP USER expiretest@localhost'); + +if (!mysqli_query($link, 'CREATE USER expiretest@"%"') || + !mysqli_query($link, 'CREATE USER expiretest@"localhost"')) { + printf("skip Cannot create second DB user [%d] %s", mysqli_errno($link), mysqli_error($link)); + mysqli_close($link); + die("skip CREATE USER failed"); +} + +if (!mysqli_query($link, 'ALTER USER expiretest@"%" PASSWORD EXPIRE') || + !mysqli_query($link, 'ALTER USER expiretest@"localhost" PASSWORD EXPIRE')) { + printf("skip Cannot modify second DB user [%d] %s", mysqli_errno($link), mysqli_error($link)); + mysqli_close($link); + die("skip ALTER USER failed"); +} + +if (!$link->query("DROP TABLE IF EXISTS test") || + !$link->query("CREATE TABLE test (id INT)") || !$link->query("INSERT INTO test(id) VALUES (1)")) + die(sprintf("SKIP [%d] %s\n", $link->errno, $link->error)); + + + +if (!mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO expiretest@'%%'", $db)) || + !mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO expiretest@'localhost'", $db))) { + printf("skip Cannot grant SELECT to user [%d] %s", mysqli_errno($link), mysqli_error($link)); + mysqli_close($link); + die("skip GRANT failed"); +} +?> +--FILE-- +<?php + require_once('connect.inc'); + require_once('table.inc'); + + /* default */ + if (!$link = my_mysqli_connect($host, 'expiretest', "", $db, $port, $socket)) { + printf("[001] Cannot connect [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error()); + } else { + $link->query("SELECT id FROM test WHERE id = 1"); + printf("[002] Connect should fail, [%d] %s\n", $link->errno, $link->error); + } + + /* explicitly requesting default */ + $link = mysqli_init(); + $link->options(MYSQLI_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, 0); + if (!my_mysqli_real_connect($link, $host, 'expiretest', "", $db, $port, $socket)) { + printf("[003] Cannot connect [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error()); + } else { + $link->query("SELECT id FROM test WHERE id = 1"); + printf("[004] Connect should fail, [%d] %s\n", $link->errno, $link->error); + } + + /* allow connect */ + $link = mysqli_init(); + $link->options(MYSQLI_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, 1); + if (!my_mysqli_real_connect($link, $host, 'expiretest', "", $db, $port, $socket)) { + printf("[005] Cannot connect [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error()); + } else { + $link->query("SELECT id FROM test WHERE id = 1"); + printf("[006] Connect allowed, query fail, [%d] %s\n", $link->errno, $link->error); + $link->close(); + } + + /* allow connect, fix pw */ + $link = mysqli_init(); + $link->options(MYSQLI_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, 1); + if (!my_mysqli_real_connect($link, $host, 'expiretest', "", $db, $port, $socket)) { + printf("[007] Cannot connect [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error()); + } else { + $link->query("SET PASSWORD=PASSWORD('expiretest')"); + printf("[008] Connect allowed, pw set, [%d] %s\n", $link->errno, $link->error); + if ($res = $link->query("SELECT id FROM test WHERE id = 1")) + var_dump($res->fetch_assoc()); + $link->close(); + } + + + /* check login */ + if (!$link = my_mysqli_connect($host, 'expiretest', "expiretest", $db, $port, $socket)) { + printf("[001] Cannot connect [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error()); + } else { + $link->query("SELECT id FROM test WHERE id = 1"); + if ($res = $link->query("SELECT id FROM test WHERE id = 1")) + var_dump($res->fetch_assoc()); + $link->close(); + } + + + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); + mysqli_query($link, 'DROP USER expiretest'); + mysqli_query($link, 'DROP USER expiretest@localhost'); +?> +--EXPECTF-- + +Warning: mysqli_real_connect(): (HY000/1820): %s in %s on line %d +[001] Cannot connect [1820] %s + +Warning: mysqli_real_connect(): (HY000/1820): %s in %s on line %d +[003] Cannot connect [1820] %s +[006] Connect allowed, query fail, [1820] %s +[008] Connect allowed, pw set, [0%A +array(1) { + ["id"]=> + string(1) "1" +} +array(1) { + ["id"]=> + string(1) "1" +} +done! diff --git a/ext/mysqli/tests/mysqli_explain_metadata.phpt b/ext/mysqli/tests/mysqli_explain_metadata.phpt new file mode 100644 index 0000000..fc1f9db --- /dev/null +++ b/ext/mysqli/tests/mysqli_explain_metadata.phpt @@ -0,0 +1,162 @@ +--TEST-- +EXPLAIN - metadata +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once("connect.inc"); +if (!$IS_MYSQLND) + die("skip Open libmysql/MySQL issue http://bugs.mysql.com/?id=62350"); +?> +--FILE-- +<?php + require_once('connect.inc'); + require_once('table.inc'); + + if (!$res = mysqli_query($link, 'EXPLAIN SELECT t1.*, t2.* FROM test AS t1, test AS t2')) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $num_rows = 0; + $num_fields = 0; + $field_names = array(); + if (!$row = mysqli_fetch_assoc($res)) { + printf("[002] Expecting result but got no data [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + } else { + $num_rows++; + $num_fields = count($row); + foreach ($row as $name => $value) + $field_names[$name] = gettype($value); + } + + while ($row = mysqli_fetch_assoc($res)) + $num_rows++; + + if (($tmp = mysqli_num_rows($res)) !== $num_rows) { + printf("[003] Expecting int/%d got %s/%s\n", + $num_rows, gettype($tmp), $tmp); + } + if (($tmp = mysqli_field_count($link)) !== $num_fields) { + printf("[004] Expecting int/%d got %s/%s\n", + $num_fields, gettype($tmp), $tmp); + } + $fields = mysqli_fetch_fields($res); + if (($tmp = count($fields)) !== $num_fields) { + printf("[005] Expecting int/%d got %s/%s\n", + $num_fields, gettype($tmp), $tmp); + } + + foreach ($fields as $k => $field) { + $field->max_length = 0;// change it or we will get diff error + if (isset($field_names[$field->name])) { + unset($field_names[$field->name]); + } else { + printf("[006] Unexpected field '%s', dumping info\n"); + var_dump($field); + } + } + if (!empty($field_names)) { + printf("[007] Field descriptions missing for the following columns\n"); + var_dump($field_names); + } + + mysqli_free_result($res); + + $stmt = mysqli_stmt_init($link); + /* Depending on your version, the MySQL server migit not support this */ + if ($stmt->prepare('EXPLAIN SELECT t1.*, t2.* FROM test AS t1, test AS t2') && $stmt->execute()) { + if (!mysqli_stmt_store_result($stmt)) + printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!$res_meta = mysqli_stmt_result_metadata($stmt)) + printf("[009] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (($tmp = mysqli_stmt_num_rows($stmt)) !== $num_rows) { + printf("[010] Expecting int/%d got %s/%s\n", + $num_rows, gettype($tmp), $tmp); + } + if (($tmp = mysqli_stmt_field_count($stmt)) !== $num_fields) { + printf("[011] Expecting int/%d got %s/%s\n", + $num_fields, gettype($tmp), $tmp); + } + if (($tmp = mysqli_field_count($link)) !== $num_fields) { + printf("[013] Expecting int/%d got %s/%s\n", + $num_fields, gettype($tmp), $tmp); + } + if (($tmp = $res_meta->field_count) !== $num_fields) { + printf("[014] Expecting int/%d got %s/%s\n", + $num_fields, gettype($tmp), $tmp); + } + $fields_res_meta = mysqli_fetch_fields($res_meta); + if (($tmp = count($fields_res_meta)) !== $num_fields) + printf("[015] Expecting int/%d got %s/%s\n", + $num_fields, gettype($tmp), $tmp); + + if ($fields_res_meta != $fields) { + printf("[016] Prepared Statement metadata differs from normal metadata, dumping\n"); + var_dump($fields_res_meta); + var_dump($fields); + } + + if (function_exists('mysqli_stmt_get_result') && + $stmt->prepare('EXPLAIN SELECT t1.*, t2.* FROM test AS t1, test AS t2') && + $stmt->execute()) { + if (!$res_stmt = mysqli_stmt_get_result($stmt)) { + printf("[017] Cannot fetch result from PS [%d] %s\n", + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + if (($tmp = mysqli_num_rows($res_stmt)) !== $num_rows) { + printf("[018] Expecting int/%d got %s/%s\n", + $num_rows, gettype($tmp), $tmp); + } + if ((mysqli_stmt_num_rows($stmt)) !== 0) { + printf("[019] Expecting int/0 got %s/%s\n", gettype($tmp), $tmp); + } + if (($tmp = mysqli_stmt_field_count($stmt)) !== $num_fields) { + printf("[020] Expecting int/%d got %s/%s\n", + $num_fields, gettype($tmp), $tmp); + + } + if (($tmp = $res_stmt->field_count) !== $num_fields) { + printf("[021] Expecting int/%d got %s/%s\n", + $num_fields, gettype($tmp), $tmp); + } + + $fields_stmt = mysqli_fetch_fields($res_stmt); + if (($tmp = count($fields_stmt)) !== $num_fields) { + printf("[022] Expecting int/%d got %s/%s\n", + $num_fields, gettype($tmp), $tmp); + } + reset($fields); + foreach ($fields_stmt as $fields_stmt_val) { + list(,$fields_val) = each($fields); + unset($fields_stmt_val->max_length); + unset($fields_val->max_length); + if ($fields_stmt_val != $fields_val) { + printf("[023] PS mysqli_stmt_get_result() metadata seems wrong, dumping\n"); + var_dump($fields_stmt_val); + var_dump($fields_val); + } + } +/* + if ($fields_stmt != $fields) { + printf("[023] PS mysqli_stmt_get_result() metadata seems wrong, dumping\n"); + var_dump($fields_stmt); + var_dump($fields); + } +*/ + mysqli_free_result($res_stmt); + } + } + mysqli_stmt_close($stmt); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done! diff --git a/ext/mysqli/tests/mysqli_fetch_all.phpt b/ext/mysqli/tests/mysqli_fetch_all.phpt new file mode 100644 index 0000000..63b6ad2 --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_all.phpt @@ -0,0 +1,440 @@ +--TEST-- +mysqli_fetch_all() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +if (!function_exists('mysqli_fetch_all')) + die("skip: function only available with mysqlnd"); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_fetch_all())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_fetch_all($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id LIMIT 2")) { + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + print "[005]\n"; + var_dump(mysqli_fetch_all($res)); + mysqli_free_result($res); + + if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id LIMIT 2")) { + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + print "[007]\n"; + var_dump(mysqli_fetch_all($res, MYSQLI_NUM)); + mysqli_free_result($res); + + if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id LIMIT 2")) { + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + print "[008]\n"; + var_dump(mysqli_fetch_all($res, MYSQLI_BOTH)); + mysqli_free_result($res); + + if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id LIMIT 2")) { + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + print "[010]\n"; + var_dump(mysqli_fetch_all($res, MYSQLI_ASSOC)); + + print "[011]\n"; + var_dump(mysqli_fetch_all($res)); + mysqli_free_result($res); + + if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id LIMIT 2")) { + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + print "[013]\n"; + var_dump(mysqli_fetch_all($res, MYSQLI_ASSOC)); + + print "[016]\n"; + var_dump(mysqli_fetch_all($res)); + + if (!$res = mysqli_query($link, "SELECT 1 AS a, 2 AS a, 3 AS c, 4 AS C, NULL AS d, true AS e")) { + printf("[010] Cannot run query, [%d] %s\n", mysqli_errno($link), $mysqli_error($link)); + } + print "[017]\n"; + var_dump(mysqli_fetch_all($res, MYSQLI_BOTH)); + + mysqli_free_result($res); + if (!$res = mysqli_query($link, "SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS C")) { + printf("[018] Cannot run query, [%d] %s\n", + mysqli_errno($link), $mysqli_error($link)); + exit(1); + } + + do { + $illegal_mode = mt_rand(-10000, 10000); + } while (in_array($illegal_mode, array(MYSQLI_ASSOC, MYSQLI_NUM, MYSQLI_BOTH))); + // NOTE: for BC reasons with ext/mysql, ext/mysqli accepts invalid result modes. + $tmp = mysqli_fetch_all($res, $illegal_mode); + if (false !== $tmp) + printf("[019] Expecting boolean/false although, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + + function func_mysqli_fetch_all($link, $engine, $sql_type, $sql_value, $php_value, $offset, $regexp_comparison = NULL) { + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) { + printf("[%04d] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!mysqli_query($link, $sql = sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { + // don't bail, engine might not support the datatype + return false; + } + + if (is_null($php_value)) { + if (!mysqli_query($link, $sql = sprintf("INSERT INTO test(id, label) VALUES (1, NULL)"))) { + printf("[%04d] [%d] %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link)); + return false; + } + } else { + if (is_string($sql_value)) { + if (!mysqli_query($link, $sql = "INSERT INTO test(id, label) VALUES (1, '" . $sql_value . "')")) { + printf("[%04ds] [%d] %s - %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link), $sql); + return false; + } + } else { + if (!mysqli_query($link, $sql = sprintf("INSERT INTO test(id, label) VALUES (1, '%d')", $sql_value))) { + printf("[%04di] [%d] %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link)); + return false; + } + } + } + + if (!$res = mysqli_query($link, "SELECT id, label FROM test")) { + printf("[%04d] [%d] %s\n", $offset + 2, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!$tmp = mysqli_fetch_all($res, MYSQLI_BOTH)) { + printf("[%04d] [%d] %s\n", $offset + 3, mysqli_errno($link), mysqli_error($link)); + return false; + } + $row = $tmp[0]; + + $fields = mysqli_fetch_fields($res); + + if (!(gettype($php_value)=="unicode" && ($fields[1]->flags & 128))) { + + if ($regexp_comparison) { + if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) { + printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, + gettype($php_value), $php_value, $regexp_comparison, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], mysqli_errno($link), mysqli_error($link)); + return false; + } + } else { + if (($row['label'] !== $php_value) || ($row[1] != $php_value)) { + printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, + gettype($php_value), $php_value, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], mysqli_errno($link), mysqli_error($link)); + return false; + } + } + } + + return true; + } + + function func_mysqli_fetch_array_make_string($len) { + + $ret = ''; + for ($i = 0; $i < $len; $i++) + $ret .= chr(mt_rand(65, 90)); + + return $ret; + } + + func_mysqli_fetch_all($link, $engine, "TINYINT", -11, "-11", 20); + func_mysqli_fetch_all($link, $engine, "TINYINT", NULL, NULL, 30); + func_mysqli_fetch_all($link, $engine, "TINYINT UNSIGNED", 1, "1", 40); + func_mysqli_fetch_all($link, $engine, "TINYINT UNSIGNED", NULL, NULL, 50); + + func_mysqli_fetch_all($link, $engine, "BOOL", 1, "1", 60); + func_mysqli_fetch_all($link, $engine, "BOOL", NULL, NULL, 70); + func_mysqli_fetch_all($link, $engine, "BOOLEAN", 0, "0", 80); + func_mysqli_fetch_all($link, $engine, "BOOLEAN", NULL, NULL, 90); + + func_mysqli_fetch_all($link, $engine, "SMALLINT", -32768, "-32768", 100); + func_mysqli_fetch_all($link, $engine, "SMALLINT", 32767, "32767", 110); + func_mysqli_fetch_all($link, $engine, "SMALLINT", NULL, NULL, 120); + func_mysqli_fetch_all($link, $engine, "SMALLINT UNSIGNED", 65535, "65535", 130); + func_mysqli_fetch_all($link, $engine, "SMALLINT UNSIGNED", NULL, NULL, 140); + + func_mysqli_fetch_all($link, $engine, "MEDIUMINT", -8388608, "-8388608", 150); + func_mysqli_fetch_all($link, $engine, "MEDIUMINT", 8388607, "8388607", 160); + func_mysqli_fetch_all($link, $engine, "MEDIUMINT", NULL, NULL, 170); + func_mysqli_fetch_all($link, $engine, "MEDIUMINT UNSIGNED", 16777215, "16777215", 180); + func_mysqli_fetch_all($link, $engine, "MEDIUMINT UNSIGNED", NULL, NULL, 190); + + func_mysqli_fetch_all($link, $engine, "INTEGER", -2147483648, "-2147483648", 200); + func_mysqli_fetch_all($link, $engine, "INTEGER", 2147483647, "2147483647", 210); + func_mysqli_fetch_all($link, $engine, "INTEGER", NULL, NULL, 220); + func_mysqli_fetch_all($link, $engine, "INTEGER UNSIGNED", "4294967295", "4294967295", 230); + func_mysqli_fetch_all($link, $engine, "INTEGER UNSIGNED", NULL, NULL, 240); + + func_mysqli_fetch_all($link, $engine, "BIGINT", "-9223372036854775808", "-9223372036854775808", 250); + + func_mysqli_fetch_all($link, $engine, "BIGINT", NULL, NULL, 260); + func_mysqli_fetch_all($link, $engine, "BIGINT UNSIGNED", "18446744073709551615", "18446744073709551615", 270); + func_mysqli_fetch_all($link, $engine, "BIGINT UNSIGNED", NULL, NULL, 280); + + func_mysqli_fetch_all($link, $engine, "FLOAT", (string)(-9223372036854775808 - 1.1), "-9.22337e+18", 290, "/-9\.22337e\+?[0]?18/iu"); + func_mysqli_fetch_all($link, $engine, "FLOAT", NULL, NULL, 300); + func_mysqli_fetch_all($link, $engine, "FLOAT UNSIGNED", (string)(18446744073709551615 + 1.1), "1.84467e+19", 310, "/1\.84467e\+?[0]?19/iu"); + func_mysqli_fetch_all($link, $engine, "FLOAT UNSIGNED ", NULL, NULL, 320); + + func_mysqli_fetch_all($link, $engine, "DOUBLE(10,2)", "-99999999.99", "-99999999.99", 330); + func_mysqli_fetch_all($link, $engine, "DOUBLE(10,2)", NULL, NULL, 340); + func_mysqli_fetch_all($link, $engine, "DOUBLE(10,2) UNSIGNED", "99999999.99", "99999999.99", 350); + func_mysqli_fetch_all($link, $engine, "DOUBLE(10,2) UNSIGNED", NULL, NULL, 360); + + func_mysqli_fetch_all($link, $engine, "DECIMAL(10,2)", "-99999999.99", "-99999999.99", 370); + func_mysqli_fetch_all($link, $engine, "DECIMAL(10,2)", NULL, NULL, 380); + func_mysqli_fetch_all($link, $engine, "DECIMAL(10,2)", "99999999.99", "99999999.99", 390); + func_mysqli_fetch_all($link, $engine, "DECIMAL(10,2)", NULL, NULL, 400); + + // don't care about date() strict TZ warnings... + func_mysqli_fetch_all($link, $engine, "DATE", @date('Y-m-d'), @date('Y-m-d'), 410); + func_mysqli_fetch_all($link, $engine, "DATE NOT NULL", @date('Y-m-d'), @date('Y-m-d'), 420); + func_mysqli_fetch_all($link, $engine, "DATE", NULL, NULL, 430); + + func_mysqli_fetch_all($link, $engine, "DATETIME", @date('Y-m-d H:i:s'), @date('Y-m-d H:i:s'), 440); + func_mysqli_fetch_all($link, $engine, "DATETIME NOT NULL", @date('Y-m-d H:i:s'), @date('Y-m-d H:i:s'), 450); + func_mysqli_fetch_all($link, $engine, "DATETIME", NULL, NULL, 460); + + func_mysqli_fetch_all($link, $engine, "TIMESTAMP", @date('Y-m-d H:i:s'), @date('Y-m-d H:i:s'), 470); + + func_mysqli_fetch_all($link, $engine, "TIME", @date('H:i:s'), @date('H:i:s'), 480); + func_mysqli_fetch_all($link, $engine, "TIME NOT NULL", @date('H:i:s'), @date('H:i:s'), 490); + func_mysqli_fetch_all($link, $engine, "TIME", NULL, NULL, 500); + + func_mysqli_fetch_all($link, $engine, "YEAR", @date('Y'), @date('Y'), 510); + func_mysqli_fetch_all($link, $engine, "YEAR NOT NULL", @date('Y'), @date('Y'), 520); + func_mysqli_fetch_all($link, $engine, "YEAR", NULL, NULL, 530); + + $string255 = func_mysqli_fetch_array_make_string(255); + func_mysqli_fetch_all($link, $engine, "CHAR(1)", "a", "a", 540); + func_mysqli_fetch_all($link, $engine, "CHAR(255)", $string255, $string255, 550); + func_mysqli_fetch_all($link, $engine, "CHAR(1) NOT NULL", "a", "a", 560); + func_mysqli_fetch_all($link, $engine, "CHAR(1)", NULL, NULL, 570); + + $string65k = func_mysqli_fetch_array_make_string(65400); + func_mysqli_fetch_all($link, $engine, "VARCHAR(1)", "a", "a", 580); + func_mysqli_fetch_all($link, $engine, "VARCHAR(255)", $string255, $string255, 590); + func_mysqli_fetch_all($link, $engine, "VARCHAR(65400)", $string65k, $string65k, 600); + func_mysqli_fetch_all($link, $engine, "VARCHAR(1) NOT NULL", "a", "a", 610); + func_mysqli_fetch_all($link, $engine, "VARCHAR(1)", NULL, NULL, 620); + + func_mysqli_fetch_all($link, $engine, "BINARY(1)", "a", "a", 630); + func_mysqli_fetch_all($link, $engine, "BINARY(2)", chr(0) . "a", chr(0) . "a", 640); + func_mysqli_fetch_all($link, $engine, "BINARY(1) NOT NULL", "b", "b", 650); + func_mysqli_fetch_all($link, $engine, "BINARY(1)", NULL, NULL, 660); + + func_mysqli_fetch_all($link, $engine, "VARBINARY(1)", "a", "a", 670); + func_mysqli_fetch_all($link, $engine, "VARBINARY(2)", chr(0) . "a", chr(0) . "a", 680); + func_mysqli_fetch_all($link, $engine, "VARBINARY(1) NOT NULL", "b", "b", 690); + func_mysqli_fetch_all($link, $engine, "VARBINARY(1)", NULL, NULL, 700); + + func_mysqli_fetch_all($link, $engine, "TINYBLOB", "a", "a", 710); + func_mysqli_fetch_all($link, $engine, "TINYBLOB", chr(0) . "a", chr(0) . "a", 720); + func_mysqli_fetch_all($link, $engine, "TINYBLOB NOT NULL", "b", "b", 730); + func_mysqli_fetch_all($link, $engine, "TINYBLOB", NULL, NULL, 740); + + func_mysqli_fetch_all($link, $engine, "TINYTEXT", "a", "a", 750); + func_mysqli_fetch_all($link, $engine, "TINYTEXT NOT NULL", "a", "a", 760); + func_mysqli_fetch_all($link, $engine, "TINYTEXT", NULL, NULL, 770); + + func_mysqli_fetch_all($link, $engine, "BLOB", "a", "a", 780); + func_mysqli_fetch_all($link, $engine, "BLOB", chr(0) . "a", chr(0) . "a", 780); + func_mysqli_fetch_all($link, $engine, "BLOB", NULL, NULL, 790); + + func_mysqli_fetch_all($link, $engine, "TEXT", "a", "a", 800); + func_mysqli_fetch_all($link, $engine, "TEXT", chr(0) . "a", chr(0) . "a", 810); + func_mysqli_fetch_all($link, $engine, "TEXT", NULL, NULL, 820); + + func_mysqli_fetch_all($link, $engine, "MEDIUMBLOB", "a", "a", 830); + func_mysqli_fetch_all($link, $engine, "MEDIUMBLOB", chr(0) . "a", chr(0) . "a", 840); + func_mysqli_fetch_all($link, $engine, "MEDIUMBLOB", NULL, NULL, 850); + + func_mysqli_fetch_all($link, $engine, "MEDIUMTEXT", "a", "a", 860); + func_mysqli_fetch_all($link, $engine, "MEDIUMTEXT", chr(0) . "a", chr(0) . "a", 870); + func_mysqli_fetch_all($link, $engine, "MEDIUMTEXT", NULL, NULL, 880); + + func_mysqli_fetch_all($link, $engine, "LONGBLOB", "a", "a", 890); + func_mysqli_fetch_all($link, $engine, "LONGTEXT", chr(0) . "a", chr(0) . "a", 900); + func_mysqli_fetch_all($link, $engine, "LONGBLOB", NULL, NULL, 910); + + func_mysqli_fetch_all($link, $engine, "ENUM('a', 'b')", "a", "a", 920); + func_mysqli_fetch_all($link, $engine, "ENUM('a', 'b')", NULL, NULL, 930); + + func_mysqli_fetch_all($link, $engine, "SET('a', 'b')", "a", "a", 940); + func_mysqli_fetch_all($link, $engine, "SET('a', 'b')", NULL, NULL, 950); + + mysqli_close($link); + + if (null !== ($tmp = mysqli_fetch_array($res, MYSQLI_ASSOC))) + printf("[015] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + // require_once("clean_table.inc"); +?> +--EXPECTF-- +[005] +array(2) { + [0]=> + array(2) { + [0]=> + %unicode|string%(1) "1" + [1]=> + %unicode|string%(1) "a" + } + [1]=> + array(2) { + [0]=> + %unicode|string%(1) "2" + [1]=> + %unicode|string%(1) "b" + } +} +[007] +array(2) { + [0]=> + array(2) { + [0]=> + %unicode|string%(1) "1" + [1]=> + %unicode|string%(1) "a" + } + [1]=> + array(2) { + [0]=> + %unicode|string%(1) "2" + [1]=> + %unicode|string%(1) "b" + } +} +[008] +array(2) { + [0]=> + array(4) { + [0]=> + %unicode|string%(1) "1" + [%u|b%"id"]=> + %unicode|string%(1) "1" + [1]=> + %unicode|string%(1) "a" + [%u|b%"label"]=> + %unicode|string%(1) "a" + } + [1]=> + array(4) { + [0]=> + %unicode|string%(1) "2" + [%u|b%"id"]=> + %unicode|string%(1) "2" + [1]=> + %unicode|string%(1) "b" + [%u|b%"label"]=> + %unicode|string%(1) "b" + } +} +[010] +array(2) { + [0]=> + array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" + } + [1]=> + array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "2" + [%u|b%"label"]=> + %unicode|string%(1) "b" + } +} +[011] +array(0) { +} +[013] +array(2) { + [0]=> + array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" + } + [1]=> + array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "2" + [%u|b%"label"]=> + %unicode|string%(1) "b" + } +} +[016] +array(0) { +} +[017] +array(1) { + [0]=> + array(11) { + [0]=> + %unicode|string%(1) "1" + [%u|b%"a"]=> + %unicode|string%(1) "2" + [1]=> + %unicode|string%(1) "2" + [2]=> + %unicode|string%(1) "3" + [%u|b%"c"]=> + %unicode|string%(1) "3" + [3]=> + %unicode|string%(1) "4" + [%u|b%"C"]=> + %unicode|string%(1) "4" + [4]=> + NULL + [%u|b%"d"]=> + NULL + [5]=> + %unicode|string%(1) "1" + [%u|b%"e"]=> + %unicode|string%(1) "1" + } +} + +Warning: mysqli_fetch_all(): Mode can be only MYSQLI_FETCH_NUM, MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH in %s on line %d + +Warning: mysqli_fetch_array(): Couldn't fetch mysqli_result in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_all_oo.phpt b/ext/mysqli/tests/mysqli_fetch_all_oo.phpt new file mode 100644 index 0000000..575f953 --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_all_oo.phpt @@ -0,0 +1,440 @@ +--TEST-- +$mysqli->fetch_all() (introduced with mysqlnd) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_fetch_all')) + die("skip: function only available with mysqlnd"); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + $mysqli = new mysqli(); + + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + require('table.inc'); + if (!$res = $mysqli->query("SELECT * FROM test ORDER BY id LIMIT 2")) { + printf("[004] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + print "[005]\n"; + var_dump($res->fetch_all()); + $res->free_result(); + + if (!$res = $mysqli->query("SELECT * FROM test ORDER BY id LIMIT 2")) { + printf("[006] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + print "[007]\n"; + var_dump($res->fetch_all(MYSQLI_NUM)); + $res->free_result(); + + if (!$res = $mysqli->query("SELECT * FROM test ORDER BY id LIMIT 2")) { + printf("[008] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + print "[008]\n"; + var_dump($res->fetch_all(MYSQLI_BOTH)); + $res->free_result(); + + if (!$res = $mysqli->query("SELECT * FROM test ORDER BY id LIMIT 2")) { + printf("[009] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + print "[010]\n"; + var_dump($res->fetch_all(MYSQLI_ASSOC)); + + print "[011]\n"; + var_dump($res->fetch_array()); + $res->free_result(); + + if (!$res = $mysqli->query("SELECT * FROM test ORDER BY id LIMIT 2")) { + printf("[012] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + print "[013]\n"; + var_dump($res->fetch_all(MYSQLI_ASSOC)); + + print "[016]\n"; + var_dump($res->fetch_array()); + + if (!$res = $mysqli->query("SELECT 1 AS a, 2 AS a, 3 AS c, 4 AS C, NULL AS d, true AS e")) { + printf("[010] Cannot run query, [%d] %s\n", $mysqli->errno, $$mysqli->error); + } + print "[017]\n"; + var_dump($res->fetch_all(MYSQLI_BOTH)); + + $res->free_result(); + if (!$res = $mysqli->query("SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS C")) { + printf("[018] Cannot run query, [%d] %s\n", + $mysqli->errno, $$mysqli->error); + exit(1); + } + + do { + $illegal_mode = mt_rand(-10000, 10000); + } while (in_array($illegal_mode, array(MYSQLI_ASSOC, MYSQLI_NUM, MYSQLI_BOTH))); + // NOTE: for BC reasons with ext/mysql, ext/mysqli accepts invalid result modes. + $tmp = $res->fetch_all($illegal_mode); + if (false !== $tmp) + printf("[019] Expecting boolean/false although, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, $mysqli->errno, $mysqli->error); + + $res->free_result(); + + function func_mysqli_fetch_all_oo($link, $engine, $sql_type, $sql_value, $php_value, $offset, $regexp_comparison = NULL) { + + if (!$link->query("DROP TABLE IF EXISTS test")) { + printf("[%04d] [%d] %s\n", $offset, $link->errno, $link->error); + return false; + } + + if (!$link->query($sql = sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { + // don't bail, engine might not support the datatype + return false; + } + + if (is_null($php_value)) { + if (!$link->query($sql = sprintf("INSERT INTO test(id, label) VALUES (1, NULL)"))) { + printf("[%04d] [%d] %s\n", $offset + 1, $link->errno, $link->error); + return false; + } + } else { + if (is_string($sql_value)) { + if (!$link->query($sql = "INSERT INTO test(id, label) VALUES (1, '" . $sql_value . "')")) { + printf("[%04ds] [%d] %s - %s\n", $offset + 1, $link->errno, $link->error, $sql); + return false; + } + } else { + if (!$link->query($sql = sprintf("INSERT INTO test(id, label) VALUES (1, '%d')", $sql_value))) { + printf("[%04di] [%d] %s\n", $offset + 1, $link->errno, $link->error); + return false; + } + } + } + + if (!$res = $link->query("SELECT id, label FROM test")) { + printf("[%04d] [%d] %s\n", $offset + 2, $link->errno, $link->error); + return false; + } + + if (!$tmp = $res->fetch_all(MYSQLI_BOTH)) { + printf("[%04d] [%d] %s\n", $offset + 3, $link->errno, $link->error); + return false; + } + $row = $tmp[0]; + + $fields = mysqli_fetch_fields($res); + + if (!(gettype($php_value)=="unicode" && ($fields[1]->flags & 128))) { + if ($regexp_comparison) { + if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) { + printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, + gettype($php_value), $php_value, $regexp_comparison, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], $link->errno, $link->error); + return false; + } + } else { + if (($row['label'] !== $php_value) || ($row[1] != $php_value)) { + printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, + gettype($php_value), $php_value, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], $link->errno, $link->error); + return false; + } + } + } + + return true; + } + + function func_mysqli_fetch_array_oo_make_string($len) { + + $ret = ''; + for ($i = 0; $i < $len; $i++) + $ret .= chr(mt_rand(65, 90)); + + return $ret; + } + + func_mysqli_fetch_all_oo($link, $engine, "TINYINT", -11, "-11", 20); + func_mysqli_fetch_all_oo($link, $engine, "TINYINT", NULL, NULL, 30); + func_mysqli_fetch_all_oo($link, $engine, "TINYINT UNSIGNED", 1, "1", 40); + func_mysqli_fetch_all_oo($link, $engine, "TINYINT UNSIGNED", NULL, NULL, 50); + + func_mysqli_fetch_all_oo($link, $engine, "BOOL", 1, "1", 60); + func_mysqli_fetch_all_oo($link, $engine, "BOOL", NULL, NULL, 70); + func_mysqli_fetch_all_oo($link, $engine, "BOOLEAN", 0, "0", 80); + func_mysqli_fetch_all_oo($link, $engine, "BOOLEAN", NULL, NULL, 90); + + func_mysqli_fetch_all_oo($link, $engine, "SMALLINT", -32768, "-32768", 100); + func_mysqli_fetch_all_oo($link, $engine, "SMALLINT", 32767, "32767", 110); + func_mysqli_fetch_all_oo($link, $engine, "SMALLINT", NULL, NULL, 120); + func_mysqli_fetch_all_oo($link, $engine, "SMALLINT UNSIGNED", 65400, "65400", 130); + func_mysqli_fetch_all_oo($link, $engine, "SMALLINT UNSIGNED", NULL, NULL, 140); + + func_mysqli_fetch_all_oo($link, $engine, "MEDIUMINT", -8388608, "-8388608", 150); + func_mysqli_fetch_all_oo($link, $engine, "MEDIUMINT", 8388607, "8388607", 160); + func_mysqli_fetch_all_oo($link, $engine, "MEDIUMINT", NULL, NULL, 170); + func_mysqli_fetch_all_oo($link, $engine, "MEDIUMINT UNSIGNED", 16777215, "16777215", 180); + func_mysqli_fetch_all_oo($link, $engine, "MEDIUMINT UNSIGNED", NULL, NULL, 190); + + func_mysqli_fetch_all_oo($link, $engine, "INTEGER", -2147483648, "-2147483648", 200); + func_mysqli_fetch_all_oo($link, $engine, "INTEGER", 2147483647, "2147483647", 210); + func_mysqli_fetch_all_oo($link, $engine, "INTEGER", NULL, NULL, 220); + func_mysqli_fetch_all_oo($link, $engine, "INTEGER UNSIGNED", "4294967295", "4294967295", 230); + func_mysqli_fetch_all_oo($link, $engine, "INTEGER UNSIGNED", NULL, NULL, 240); + + func_mysqli_fetch_all_oo($link, $engine, "BIGINT", "-9223372036854775808", "-9223372036854775808", 250); + func_mysqli_fetch_all_oo($link, $engine, "BIGINT", NULL, NULL, 260); + func_mysqli_fetch_all_oo($link, $engine, "BIGINT UNSIGNED", "18446744073709551615", "18446744073709551615", 270); + func_mysqli_fetch_all_oo($link, $engine, "BIGINT UNSIGNED", NULL, NULL, 280); + + func_mysqli_fetch_all_oo($link, $engine, "FLOAT", (string)(-9223372036854775808 - 1.1), "-9.22337e+18", 290, "/-9\.22337e\+?[0]?18/iu"); + func_mysqli_fetch_all_oo($link, $engine, "FLOAT", NULL, NULL, 300); + func_mysqli_fetch_all_oo($link, $engine, "FLOAT UNSIGNED", (string)(18446744073709551615 + 1.1), "1.84467e+?19", 310, "/1\.84467e\+?[0]?19/iu"); + func_mysqli_fetch_all_oo($link, $engine, "FLOAT UNSIGNED ", NULL, NULL, 320); + + func_mysqli_fetch_all_oo($link, $engine, "DOUBLE(10,2)", "-99999999.99", "-99999999.99", 330); + func_mysqli_fetch_all_oo($link, $engine, "DOUBLE(10,2)", NULL, NULL, 340); + func_mysqli_fetch_all_oo($link, $engine, "DOUBLE(10,2) UNSIGNED", "99999999.99", "99999999.99", 350); + func_mysqli_fetch_all_oo($link, $engine, "DOUBLE(10,2) UNSIGNED", NULL, NULL, 360); + + func_mysqli_fetch_all_oo($link, $engine, "DECIMAL(10,2)", "-99999999.99", "-99999999.99", 370); + func_mysqli_fetch_all_oo($link, $engine, "DECIMAL(10,2)", NULL, NULL, 380); + func_mysqli_fetch_all_oo($link, $engine, "DECIMAL(10,2)", "99999999.99", "99999999.99", 390); + func_mysqli_fetch_all_oo($link, $engine, "DECIMAL(10,2)", NULL, NULL, 400); + + // don't care about date() strict TZ warnings... + $date = @date('Y-m-d'); + func_mysqli_fetch_all_oo($link, $engine, "DATE", $date, $date, 410); + func_mysqli_fetch_all_oo($link, $engine, "DATE NOT NULL", $date, $date, 420); + func_mysqli_fetch_all_oo($link, $engine, "DATE", NULL, NULL, 430); + + $datetime = @date('Y-m-d H:i:s'); + func_mysqli_fetch_all_oo($link, $engine, "DATETIME", $datetime, $datetime, 440); + func_mysqli_fetch_all_oo($link, $engine, "DATETIME NOT NULL", $datetime, $datetime, 450); + func_mysqli_fetch_all_oo($link, $engine, "DATETIME", NULL, NULL, 460); + + func_mysqli_fetch_all_oo($link, $engine, "TIMESTAMP", $datetime, $datetime, 470); + + $time = @date('H:i:s'); + func_mysqli_fetch_all_oo($link, $engine, "TIME", $time, $time, 480); + func_mysqli_fetch_all_oo($link, $engine, "TIME NOT NULL", $time, $time, 490); + func_mysqli_fetch_all_oo($link, $engine, "TIME", NULL, NULL, 500); + + func_mysqli_fetch_all_oo($link, $engine, "YEAR", @date('Y'), @date('Y'), 510); + func_mysqli_fetch_all_oo($link, $engine, "YEAR NOT NULL", @date('Y'), @date('Y'), 520); + func_mysqli_fetch_all_oo($link, $engine, "YEAR", NULL, NULL, 530); + + $string255 = func_mysqli_fetch_array_oo_make_string(255); + func_mysqli_fetch_all_oo($link, $engine, "CHAR(1)", "a", "a", 540); + func_mysqli_fetch_all_oo($link, $engine, "CHAR(255)", $string255, $string255, 550); + func_mysqli_fetch_all_oo($link, $engine, "CHAR(1) NOT NULL", "a", "a", 560); + func_mysqli_fetch_all_oo($link, $engine, "CHAR(1)", NULL, NULL, 570); + + $string65k = func_mysqli_fetch_array_oo_make_string(65400); + func_mysqli_fetch_all_oo($link, $engine, "VARCHAR(1)", "a", "a", 580); + func_mysqli_fetch_all_oo($link, $engine, "VARCHAR(255)", $string255, $string255, 590); + func_mysqli_fetch_all_oo($link, $engine, "VARCHAR(65400)", $string65k, $string65k, 600); + func_mysqli_fetch_all_oo($link, $engine, "VARCHAR(1) NOT NULL", "a", "a", 610); + func_mysqli_fetch_all_oo($link, $engine, "VARCHAR(1)", NULL, NULL, 620); + + func_mysqli_fetch_all_oo($link, $engine, "BINARY(1)", "a", "a", 630); + func_mysqli_fetch_all_oo($link, $engine, "BINARY(2)", chr(0) . "a", chr(0) . "a", 640); + func_mysqli_fetch_all_oo($link, $engine, "BINARY(1) NOT NULL", "b", "b", 650); + func_mysqli_fetch_all_oo($link, $engine, "BINARY(1)", NULL, NULL, 660); + + func_mysqli_fetch_all_oo($link, $engine, "VARBINARY(1)", "a", "a", 670); + func_mysqli_fetch_all_oo($link, $engine, "VARBINARY(2)", chr(0) . "a", chr(0) . "a", 680); + func_mysqli_fetch_all_oo($link, $engine, "VARBINARY(1) NOT NULL", "b", "b", 690); + func_mysqli_fetch_all_oo($link, $engine, "VARBINARY(1)", NULL, NULL, 700); + + func_mysqli_fetch_all_oo($link, $engine, "TINYBLOB", "a", "a", 710); + func_mysqli_fetch_all_oo($link, $engine, "TINYBLOB", chr(0) . "a", chr(0) . "a", 720); + func_mysqli_fetch_all_oo($link, $engine, "TINYBLOB NOT NULL", "b", "b", 730); + func_mysqli_fetch_all_oo($link, $engine, "TINYBLOB", NULL, NULL, 740); + + func_mysqli_fetch_all_oo($link, $engine, "TINYTEXT", "a", "a", 750); + func_mysqli_fetch_all_oo($link, $engine, "TINYTEXT NOT NULL", "a", "a", 760); + func_mysqli_fetch_all_oo($link, $engine, "TINYTEXT", NULL, NULL, 770); + + func_mysqli_fetch_all_oo($link, $engine, "BLOB", "a", "a", 780); + func_mysqli_fetch_all_oo($link, $engine, "BLOB", chr(0) . "a", chr(0) . "a", 780); + func_mysqli_fetch_all_oo($link, $engine, "BLOB", NULL, NULL, 790); + + func_mysqli_fetch_all_oo($link, $engine, "TEXT", "a", "a", 800); + func_mysqli_fetch_all_oo($link, $engine, "TEXT", chr(0) . "a", chr(0) . "a", 810); + func_mysqli_fetch_all_oo($link, $engine, "TEXT", NULL, NULL, 820); + + func_mysqli_fetch_all_oo($link, $engine, "MEDIUMBLOB", "a", "a", 830); + func_mysqli_fetch_all_oo($link, $engine, "MEDIUMBLOB", chr(0) . "a", chr(0) . "a", 840); + func_mysqli_fetch_all_oo($link, $engine, "MEDIUMBLOB", NULL, NULL, 850); + + func_mysqli_fetch_all_oo($link, $engine, "MEDIUMTEXT", "a", "a", 860); + func_mysqli_fetch_all_oo($link, $engine, "MEDIUMTEXT", chr(0) . "a", chr(0) . "a", 870); + func_mysqli_fetch_all_oo($link, $engine, "MEDIUMTEXT", NULL, NULL, 880); + + func_mysqli_fetch_all_oo($link, $engine, "LONGBLOB", "a", "a", 890); + func_mysqli_fetch_all_oo($link, $engine, "LONGTEXT", chr(0) . "a", chr(0) . "a", 900); + func_mysqli_fetch_all_oo($link, $engine, "LONGBLOB", NULL, NULL, 910); + + func_mysqli_fetch_all_oo($link, $engine, "ENUM('a', 'b')", "a", "a", 920); + func_mysqli_fetch_all_oo($link, $engine, "ENUM('a', 'b')", NULL, NULL, 930); + + func_mysqli_fetch_all_oo($link, $engine, "SET('a', 'b')", "a", "a", 940); + func_mysqli_fetch_all_oo($link, $engine, "SET('a', 'b')", NULL, NULL, 950); + + mysqli_close($link); + + if (null !== ($tmp = $res->fetch_array(MYSQLI_ASSOC))) + printf("[015] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +[005] +array(2) { + [0]=> + array(2) { + [0]=> + %unicode|string%(1) "1" + [1]=> + %unicode|string%(1) "a" + } + [1]=> + array(2) { + [0]=> + %unicode|string%(1) "2" + [1]=> + %unicode|string%(1) "b" + } +} +[007] +array(2) { + [0]=> + array(2) { + [0]=> + %unicode|string%(1) "1" + [1]=> + %unicode|string%(1) "a" + } + [1]=> + array(2) { + [0]=> + %unicode|string%(1) "2" + [1]=> + %unicode|string%(1) "b" + } +} +[008] +array(2) { + [0]=> + array(4) { + [0]=> + %unicode|string%(1) "1" + [%u|b%"id"]=> + %unicode|string%(1) "1" + [1]=> + %unicode|string%(1) "a" + [%u|b%"label"]=> + %unicode|string%(1) "a" + } + [1]=> + array(4) { + [0]=> + %unicode|string%(1) "2" + [%u|b%"id"]=> + %unicode|string%(1) "2" + [1]=> + %unicode|string%(1) "b" + [%u|b%"label"]=> + %unicode|string%(1) "b" + } +} +[010] +array(2) { + [0]=> + array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" + } + [1]=> + array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "2" + [%u|b%"label"]=> + %unicode|string%(1) "b" + } +} +[011] +NULL +[013] +array(2) { + [0]=> + array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" + } + [1]=> + array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "2" + [%u|b%"label"]=> + %unicode|string%(1) "b" + } +} +[016] +NULL +[017] +array(1) { + [0]=> + array(11) { + [0]=> + %unicode|string%(1) "1" + [%u|b%"a"]=> + %unicode|string%(1) "2" + [1]=> + %unicode|string%(1) "2" + [2]=> + %unicode|string%(1) "3" + [%u|b%"c"]=> + %unicode|string%(1) "3" + [3]=> + %unicode|string%(1) "4" + [%u|b%"C"]=> + %unicode|string%(1) "4" + [4]=> + NULL + [%u|b%"d"]=> + NULL + [5]=> + %unicode|string%(1) "1" + [%u|b%"e"]=> + %unicode|string%(1) "1" + } +} + +Warning: mysqli_result::fetch_all(): Mode can be only MYSQLI_FETCH_NUM, MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH in %s on line %d + +Warning: mysqli_result::fetch_array(): Couldn't fetch mysqli_result in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_array.phpt b/ext/mysqli/tests/mysqli_fetch_array.phpt new file mode 100644 index 0000000..aa19ff6 --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_array.phpt @@ -0,0 +1,374 @@ +--TEST-- +mysqli_fetch_array() - all datatypes but BIT +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_fetch_array())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_fetch_array($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id LIMIT 5")) { + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + print "[005]\n"; + var_dump(mysqli_fetch_array($res)); + + print "[006]\n"; + var_dump(mysqli_fetch_array($res, MYSQLI_NUM)); + + print "[007]\n"; + var_dump(mysqli_fetch_array($res, MYSQLI_BOTH)); + + print "[008]\n"; + var_dump(mysqli_fetch_array($res, MYSQLI_ASSOC)); + + print "[009]\n"; + var_dump(mysqli_fetch_array($res)); + + mysqli_free_result($res); + + if (!$res = mysqli_query($link, "SELECT 1 AS a, 2 AS a, 3 AS c, 4 AS C, NULL AS d, true AS e")) { + printf("[010] Cannot run query, [%d] %s\n", mysqli_errno($link), $mysqli_error($link)); + } + print "[011]\n"; + var_dump(mysqli_fetch_array($res, MYSQLI_BOTH)); + + mysqli_free_result($res); + if (!$res = mysqli_query($link, "SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS C")) { + printf("[012] Cannot run query, [%d] %s\n", + mysqli_errno($link), $mysqli_error($link)); + exit(1); + } + + do { + $illegal_mode = mt_rand(-10000, 10000); + } while (in_array($illegal_mode, array(MYSQLI_ASSOC, MYSQLI_NUM, MYSQLI_BOTH))); + // NOTE: for BC reasons with ext/mysql, ext/mysqli accepts invalid result modes. + $tmp = mysqli_fetch_array($res, $illegal_mode); + if (false !== $tmp) + printf("[013] Expecting boolean/false although, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); + + $tmp = mysqli_fetch_array($res, $illegal_mode); + if (false !== $tmp) + printf("[014] Expecting boolean/false, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + + function func_mysqli_fetch_array($link, $engine, $sql_type, $sql_value, $php_value, $offset, $regexp_comparison = NULL, $binary_type = false) { + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) { + printf("[%04d] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!mysqli_query($link, $sql = sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { + // don't bail, engine might not support the datatype + return false; + } + + if (is_null($php_value)) { + if (!mysqli_query($link, $sql = sprintf("INSERT INTO test(id, label) VALUES (1, NULL)"))) { + printf("[%04d] [%d] %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link)); + return false; + } + } else { + if (is_string($sql_value)) { + if (!mysqli_query($link, $sql = "INSERT INTO test(id, label) VALUES (1, '" . $sql_value . "')")) { + printf("[%04ds] [%d] %s - %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link), $sql); + return false; + } + } else { + if (!mysqli_query($link, $sql = sprintf("INSERT INTO test(id, label) VALUES (1, '%d')", $sql_value))) { + printf("[%04di] [%d] %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link)); + return false; + } + } + } + if (!$res = mysqli_query($link, "SELECT id, label FROM test")) { + printf("[%04d] [%d] %s\n", $offset + 2, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!$row = mysqli_fetch_array($res, MYSQLI_BOTH)) { + printf("[%04d] [%d] %s\n", $offset + 3, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if ($regexp_comparison) { + if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) { + printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, + gettype($php_value), $php_value, $regexp_comparison, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], mysqli_errno($link), mysqli_error($link)); + return false; + } + } else if ((gettype($php_value) == 'unicode') && $binary_type) { + // Unicode is on and we are told that the MySQL column type is a binary type. + // Don't expect a unicode value from the database, you'll get binary string + if (($row['label'] != $php_value) || ($row[1] != $php_value)) { + printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 5, + gettype($php_value), $php_value, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], mysqli_errno($link), mysqli_error($link)); + return false; + } + if (gettype($row['label']) == 'unicode') { + var_dump(mysqli_fetch_field_direct($res, 1), $row['label']); + printf("[%04d] SQL Type: '%s', binary columns are supposed to return binary string and not unicode\n", + $offset + 6, $sql_type); + return false; + } + } else { + if (($row['label'] !== $php_value) || ($row[1] != $php_value)) { + printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 7, + gettype($php_value), $php_value, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], mysqli_errno($link), mysqli_error($link)); + return false; + } + } + return true; + } + + function func_mysqli_fetch_array_make_string($len) { + + $ret = ''; + for ($i = 0; $i < $len; $i++) + $ret .= chr(mt_rand(65, 90)); + + return $ret; + } + + func_mysqli_fetch_array($link, $engine, "TINYINT", -11, "-11", 20); + func_mysqli_fetch_array($link, $engine, "TINYINT", NULL, NULL, 30); + func_mysqli_fetch_array($link, $engine, "TINYINT UNSIGNED", 1, "1", 40); + func_mysqli_fetch_array($link, $engine, "TINYINT UNSIGNED", NULL, NULL, 50); + + func_mysqli_fetch_array($link, $engine, "BOOL", 1, "1", 60); + func_mysqli_fetch_array($link, $engine, "BOOL", NULL, NULL, 70); + func_mysqli_fetch_array($link, $engine, "BOOLEAN", 0, "0", 80); + func_mysqli_fetch_array($link, $engine, "BOOLEAN", NULL, NULL, 90); + + func_mysqli_fetch_array($link, $engine, "SMALLINT", -32768, "-32768", 100); + func_mysqli_fetch_array($link, $engine, "SMALLINT", 32767, "32767", 110); + func_mysqli_fetch_array($link, $engine, "SMALLINT", NULL, NULL, 120); + func_mysqli_fetch_array($link, $engine, "SMALLINT UNSIGNED", 65535, "65535", 130); + func_mysqli_fetch_array($link, $engine, "SMALLINT UNSIGNED", NULL, NULL, 140); + + func_mysqli_fetch_array($link, $engine, "MEDIUMINT", -8388608, "-8388608", 150); + func_mysqli_fetch_array($link, $engine, "MEDIUMINT", 8388607, "8388607", 160); + func_mysqli_fetch_array($link, $engine, "MEDIUMINT", NULL, NULL, 170); + func_mysqli_fetch_array($link, $engine, "MEDIUMINT UNSIGNED", 16777215, "16777215", 180); + func_mysqli_fetch_array($link, $engine, "MEDIUMINT UNSIGNED", NULL, NULL, 190); + + func_mysqli_fetch_array($link, $engine, "INTEGER", -2147483648, "-2147483648", 200); + func_mysqli_fetch_array($link, $engine, "INTEGER", 2147483647, "2147483647", 210); + func_mysqli_fetch_array($link, $engine, "INTEGER", NULL, NULL, 220); + func_mysqli_fetch_array($link, $engine, "INTEGER UNSIGNED", "4294967295", "4294967295", 230); + func_mysqli_fetch_array($link, $engine, "INTEGER UNSIGNED", NULL, NULL, 240); + + if ($IS_MYSQLND || + ((mysqli_get_server_version($link) >= 51000) && + (mysqli_get_client_version($link) >= 51000))) { + func_mysqli_fetch_array($link, $engine, "BIGINT", "-9223372036854775808", "-9223372036854775808", 250); + func_mysqli_fetch_array($link, $engine, "BIGINT", NULL, NULL, 260); + func_mysqli_fetch_array($link, $engine, "BIGINT UNSIGNED", "18446744073709551615", "18446744073709551615", 260); + func_mysqli_fetch_array($link, $engine, "BIGINT UNSIGNED", NULL, NULL, 280); + } + + func_mysqli_fetch_array($link, $engine, "FLOAT", (string)(-9223372036854775808 - 1.1), "-9.22337e+18", 290, "/-9\.22337e\+?[0]?18/iu"); + func_mysqli_fetch_array($link, $engine, "FLOAT", NULL, NULL, 300); + func_mysqli_fetch_array($link, $engine, "FLOAT UNSIGNED", (string)(18446744073709551615 + 1.1), "1.84467e+?19", 310, "/1\.84467e\+?[0]?19/iu"); + func_mysqli_fetch_array($link, $engine, "FLOAT UNSIGNED ", NULL, NULL, 320); + + func_mysqli_fetch_array($link, $engine, "DOUBLE(10,2)", "-99999999.99", "-99999999.99", 330); + func_mysqli_fetch_array($link, $engine, "DOUBLE(10,2)", NULL, NULL, 340); + func_mysqli_fetch_array($link, $engine, "DOUBLE(10,2) UNSIGNED", "99999999.99", "99999999.99", 350); + func_mysqli_fetch_array($link, $engine, "DOUBLE(10,2) UNSIGNED", NULL, NULL, 360); + + func_mysqli_fetch_array($link, $engine, "DECIMAL(10,2)", "-99999999.99", "-99999999.99", 370); + func_mysqli_fetch_array($link, $engine, "DECIMAL(10,2)", NULL, NULL, 380); + func_mysqli_fetch_array($link, $engine, "DECIMAL(10,2)", "99999999.99", "99999999.99", 390); + func_mysqli_fetch_array($link, $engine, "DECIMAL(10,2)", NULL, NULL, 400); + + // don't care about date() strict TZ warnings... + $date = @date('Y-m-d'); + func_mysqli_fetch_array($link, $engine, "DATE",$date, $date, 410); + func_mysqli_fetch_array($link, $engine, "DATE NOT NULL",$date, $date, 420); + func_mysqli_fetch_array($link, $engine, "DATE", NULL, NULL, 430); + + $date = @date('Y-m-d H:i:s'); + func_mysqli_fetch_array($link, $engine, "DATETIME", $date, $date, 440); + func_mysqli_fetch_array($link, $engine, "DATETIME NOT NULL", $date, $date, 450); + func_mysqli_fetch_array($link, $engine, "DATETIME", NULL, NULL, 460); + func_mysqli_fetch_array($link, $engine, "TIMESTAMP", $date, $date, 470); + + $date = @date('H:i:s'); + func_mysqli_fetch_array($link, $engine, "TIME", $date, $date, 480); + func_mysqli_fetch_array($link, $engine, "TIME NOT NULL", $date, $date, 490); + func_mysqli_fetch_array($link, $engine, "TIME", NULL, NULL, 500); + + func_mysqli_fetch_array($link, $engine, "YEAR", @date('Y'), @date('Y'), 510); + func_mysqli_fetch_array($link, $engine, "YEAR NOT NULL", @date('Y'), @date('Y'), 520); + func_mysqli_fetch_array($link, $engine, "YEAR", NULL, NULL, 530); + + $string255 = func_mysqli_fetch_array_make_string(255); + func_mysqli_fetch_array($link, $engine, "CHAR(1)", "a", "a", 540); + func_mysqli_fetch_array($link, $engine, "CHAR(255)", $string255, $string255, 550); + func_mysqli_fetch_array($link, $engine, "CHAR(1) NOT NULL", "a", "a", 560); + func_mysqli_fetch_array($link, $engine, "CHAR(1)", NULL, NULL, 570); + + $string65k = func_mysqli_fetch_array_make_string(65400); + func_mysqli_fetch_array($link, $engine, "VARCHAR(1)", "a", "a", 580); + func_mysqli_fetch_array($link, $engine, "VARCHAR(255)", $string255, $string255, 590); + func_mysqli_fetch_array($link, $engine, "VARCHAR(65400)", $string65k, $string65k, 600); + func_mysqli_fetch_array($link, $engine, "VARCHAR(1) NOT NULL", "a", "a", 610); + func_mysqli_fetch_array($link, $engine, "VARCHAR(1)", NULL, NULL, 620); + + func_mysqli_fetch_array($link, $engine, "BINARY(1)", "a", "a", 630, null, true); + func_mysqli_fetch_array($link, $engine, "BINARY(2)", chr(0) . "a", chr(0) . "a", 640, null, true); + func_mysqli_fetch_array($link, $engine, "BINARY(1) NOT NULL", "b", "b", 650, null, true); + func_mysqli_fetch_array($link, $engine, "BINARY(1)", NULL, NULL, 660, null, true); + + func_mysqli_fetch_array($link, $engine, "VARBINARY(1)", "a", "a", 670, null, true); + func_mysqli_fetch_array($link, $engine, "VARBINARY(2)", chr(0) . "a", chr(0) . "a", 680, null, true); + func_mysqli_fetch_array($link, $engine, "VARBINARY(1) NOT NULL", "b", "b", 690, null, true); + func_mysqli_fetch_array($link, $engine, "VARBINARY(1)", NULL, NULL, 700, null, true); + + func_mysqli_fetch_array($link, $engine, "TINYBLOB", "a", "a", 710, null, true); + func_mysqli_fetch_array($link, $engine, "TINYBLOB", chr(0) . "a", chr(0) . "a", 720, null, true); + func_mysqli_fetch_array($link, $engine, "TINYBLOB NOT NULL", "b", "b", 730, null, true); + func_mysqli_fetch_array($link, $engine, "TINYBLOB", NULL, NULL, 740, null, true); + + func_mysqli_fetch_array($link, $engine, "TINYTEXT", "a", "a", 750); + func_mysqli_fetch_array($link, $engine, "TINYTEXT NOT NULL", "a", "a", 760); + func_mysqli_fetch_array($link, $engine, "TINYTEXT", NULL, NULL, 770); + + func_mysqli_fetch_array($link, $engine, "BLOB", "a", "a", 780, null, true); + func_mysqli_fetch_array($link, $engine, "BLOB", chr(0) . "a", chr(0) . "a", 780, null, true); + func_mysqli_fetch_array($link, $engine, "BLOB", NULL, NULL, 790, null, true); + + func_mysqli_fetch_array($link, $engine, "TEXT", "a", "a", 800); + func_mysqli_fetch_array($link, $engine, "TEXT", chr(0) . "a", chr(0) . "a", 810); + func_mysqli_fetch_array($link, $engine, "TEXT", NULL, NULL, 820); + + func_mysqli_fetch_array($link, $engine, "MEDIUMBLOB", "a", "a", 830, null, true); + func_mysqli_fetch_array($link, $engine, "MEDIUMBLOB", chr(0) . "a", chr(0) . "a", 840, null, true); + func_mysqli_fetch_array($link, $engine, "MEDIUMBLOB", NULL, NULL, 850, null, true); + + func_mysqli_fetch_array($link, $engine, "MEDIUMTEXT", "a", "a", 860); + func_mysqli_fetch_array($link, $engine, "MEDIUMTEXT", chr(0) . "a", chr(0) . "a", 870); + func_mysqli_fetch_array($link, $engine, "MEDIUMTEXT", NULL, NULL, 880); + + func_mysqli_fetch_array($link, $engine, "LONGBLOB", "a", "a", 890, null, true); + func_mysqli_fetch_array($link, $engine, "LONGTEXT", chr(0) . "a", chr(0) . "a", 900); + func_mysqli_fetch_array($link, $engine, "LONGBLOB", NULL, NULL, 910, null, true); + + func_mysqli_fetch_array($link, $engine, "ENUM('a', 'b')", "a", "a", 920); + func_mysqli_fetch_array($link, $engine, "ENUM('a', 'b')", NULL, NULL, 930); + + func_mysqli_fetch_array($link, $engine, "SET('a', 'b')", "a", "a", 940); + func_mysqli_fetch_array($link, $engine, "SET('a', 'b')", NULL, NULL, 950); + + mysqli_close($link); + + if (null !== ($tmp = mysqli_fetch_array($res, MYSQLI_ASSOC))) + printf("[015] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +[005] +array(4) { + [0]=> + %unicode|string%(1) "1" + [%u|b%"id"]=> + %unicode|string%(1) "1" + [1]=> + %unicode|string%(1) "a" + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +[006] +array(2) { + [0]=> + %unicode|string%(1) "2" + [1]=> + %unicode|string%(1) "b" +} +[007] +array(4) { + [0]=> + %unicode|string%(1) "3" + [%u|b%"id"]=> + %unicode|string%(1) "3" + [1]=> + %unicode|string%(1) "c" + [%u|b%"label"]=> + %unicode|string%(1) "c" +} +[008] +array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "4" + [%u|b%"label"]=> + %unicode|string%(1) "d" +} +[009] +array(4) { + [0]=> + %unicode|string%(1) "5" + [%u|b%"id"]=> + %unicode|string%(1) "5" + [1]=> + %unicode|string%(1) "e" + [%u|b%"label"]=> + %unicode|string%(1) "e" +} +[011] +array(11) { + [0]=> + %unicode|string%(1) "1" + [%u|b%"a"]=> + %unicode|string%(1) "2" + [1]=> + %unicode|string%(1) "2" + [2]=> + %unicode|string%(1) "3" + [%u|b%"c"]=> + %unicode|string%(1) "3" + [3]=> + %unicode|string%(1) "4" + [%u|b%"C"]=> + %unicode|string%(1) "4" + [4]=> + NULL + [%u|b%"d"]=> + NULL + [5]=> + %unicode|string%(1) "1" + [%u|b%"e"]=> + %unicode|string%(1) "1" +} + +Warning: mysqli_fetch_array(): The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH in %s on line %d + +Warning: mysqli_fetch_array(): The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH in %s on line %d + +Warning: mysqli_fetch_array(): Couldn't fetch mysqli_result in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_array_assoc.phpt b/ext/mysqli/tests/mysqli_fetch_array_assoc.phpt new file mode 100644 index 0000000..957ca12 --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_array_assoc.phpt @@ -0,0 +1,49 @@ +--TEST-- +mysqli_fetch_array() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require('table.inc'); + + if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id LIMIT 5")) { + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + print "[002]\n"; + var_dump(mysqli_fetch_array($res, MYSQLI_ASSOC)); + mysqli_free_result($res); + + if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 5")) { + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + print "[004]\n"; + var_dump(mysqli_fetch_array($res, MYSQLI_ASSOC)); + mysqli_free_result($res); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +[002] +array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +[004] +array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_array_large.phpt b/ext/mysqli/tests/mysqli_fetch_array_large.phpt new file mode 100644 index 0000000..3c6a0f0 --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_array_large.phpt @@ -0,0 +1,169 @@ +--TEST-- +mysqli_fetch_array() - large packages (to test compression) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +memory_limit=-1 +--FILE-- +<?php + require_once("connect.inc"); + + function mysqli_fetch_array_large($offset, $link, $package_size) { + + /* we are aiming for maximum compression to test MYSQLI_CLIENT_COMPRESS */ + $random_char = str_repeat('a', 255); + $sql = "INSERT INTO test(label) VALUES "; + + while (strlen($sql) < ($package_size - 259)) + $sql .= sprintf("('%s'), ", $random_char); + + $sql = substr($sql, 0, -2); + $len = strlen($sql); + assert($len < $package_size); + + if (!@mysqli_query($link, $sql)) { + if (1153 == mysqli_errno($link) || 2006 == mysqli_errno($link) || stristr(mysqli_error($link), 'max_allowed_packet')) + /* + myslqnd - [1153] Got a packet bigger than 'max_allowed_packet' bytes + libmysql -[2006] MySQL server has gone away + */ + return false; + + printf("[%03d + 1] len = %d, [%d] %s\n", $offset, $len, mysqli_errno($link), mysqli_error($link)); + return false; + } + + /* buffered result set - let's hope we do not run into PHP memory limit... */ + if (!$res = mysqli_query($link, "SELECT id, label FROM test")) { + printf("[%03d + 2] len = %d, [%d] %s\n", $offset, $len, mysqli_errno($link), mysqli_error($link)); + return false; + } + + while ($row = mysqli_fetch_assoc($res)) { + if ($row['label'] != $random_char) { + printf("[%03d + 3] Wrong results - expecting '%s' got '%s', len = %d, [%d] %s\n", + $offset, $random_char, $row['label'], $len, mysqli_errno($link), mysqli_error($link)); + return false; + } + } + mysqli_free_result($res); + + if (!$stmt = mysqli_prepare($link, "SELECT id, label FROM test")) { + printf("[%03d + 4] len = %d, [%d] %s\n", $offset, $len, mysqli_errno($link), mysqli_error($link)); + return false; + } + + /* unbuffered result set */ + if (!mysqli_stmt_execute($stmt)) { + printf("[%03d + 5] len = %d, [%d] %s, [%d] %s\n", $offset, $len, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), mysqli_errno($link), mysqli_error($link)); + return false; + } + + $id = $label = NULL; + if (!mysqli_stmt_bind_result($stmt, $id, $label)) { + printf("[%03d + 6] len = %d, [%d] %s, [%d] %s\n", $offset, $len, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), mysqli_errno($link), mysqli_error($link)); + return false; + } + + while (mysqli_stmt_fetch($stmt)) { + if ($label != $random_char) { + printf("[%03d + 7] Wrong results - expecting '%s' got '%s', len = %d, [%d] %s\n", + $offset, $random_char, $label, $len, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + } + + mysqli_stmt_free_result($stmt); + mysqli_stmt_close($stmt); + + return true; + } + + function parse_memory_limit($limit) { + + $val = trim($limit); + $last = strtolower($val[strlen($val)-1]); + + switch($last) { + // The 'G' modifier is available since PHP 5.1.0 + case 'g': + $val *= 1024; + case 'm': + $val *= 1024; + case 'k': + $val *= 1024; + default: + break; + } + return $val; + } + + + function test_fetch($host, $user, $passwd, $db, $port, $socket, $engine, $flags = null) { + + $link = mysqli_init(); + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket, $flags)) { + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + return false; + } + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test") || + !mysqli_query($link, sprintf("CREATE TABLE test(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, label VARCHAR(255)) ENGINE = %s", $engine))) { + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + return false; + } + + $package_size = 524288; + $offset = 3; + $limit = (ini_get('memory_limit') > 0) ? parse_memory_limit(ini_get('memory_limit')) : pow(2, 32); + + /* try to respect php.ini but make run time a soft limit */ + $max_runtime = (ini_get('max_execution_time') > 0) ? ini_get('max_execution_time') : 30; + set_time_limit(0); + + do { + if ($package_size > $limit) { + printf("stop: memory limit - %s vs. %s\n", $package_size, $limit); + break; + } + + $start = microtime(true); + if (!mysqli_fetch_array_large($offset++, $link, $package_size)) { + printf("stop: packet size - %d\n", $package_size); + break; + } + + $duration = microtime(true) - $start; + $max_runtime -= $duration; + if ($max_runtime < ($duration * 3)) { + /* likely the next iteration will not be within max_execution_time */ + printf("stop: time limit - %2.2fs\n", $max_runtime); + break; + } + + $package_size += $package_size; + + } while (true); + + + mysqli_close($link); + return true; + } + + + test_fetch($host, $user, $passwd, $db, $port, $socket, $engine, null); + test_fetch($host, $user, $passwd, $db, $port, $socket, $engine, MYSQLI_CLIENT_COMPRESS); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +stop: %s +stop: %s +done! diff --git a/ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt b/ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt new file mode 100644 index 0000000..82e4d7b --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt @@ -0,0 +1,115 @@ +--TEST-- +mysqli_fetch_array() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require("table.inc"); + + // do as much as we can do in 5 seconds + $start = microtime(true); + for ($id = 100, $start = microtime(true); (microtime(true) - $start) < 5; $id++) { + if (!mysqli_query($link, $sql = sprintf("INSERT INTO test(id, label) VALUES (%d, '%s')", + $id, mysqli_real_escape_string($link, chr(65 + ($id % 26)))))) { + printf("[001] %s failed: [%d] %s\n", $sql, mysqli_errno($link), mysqli_error($link)); + break; + } + } + + if (!$res = mysqli_query($link, 'SELECT id, label FROM test')) { + printf("[002] SELECT failed: [%d] %s\n", mysqli_errno($link), mysqli_errno($link)); + } + + while ($row = mysqli_fetch_array($res)) { + // overwrite results and check if the cache magic works + $row['label'] = NULL; + } + mysqli_free_result($res); + + if (!$res = mysqli_query($link, 'SELECT id, label FROM test')) { + printf("[003] SELECT failed: [%d] %s\n", mysqli_errno($link), mysqli_errno($link)); + } + + $i = 0; + $results = array(); + while ($row = mysqli_fetch_array($res, MYSQLI_BOTH)) { + + // create copies and destroy later + $results[$i++] = &$row; + if ($i % 999) { + $results = array(); + } + + if ($row[0] < 0 || $row[0] > $id) { + printf("[004] Unexpected result row[0] = '%s' (range 0...%d), [%d] %s\n", + $row[0], $id, mysqli_errno($link), mysqli_error($link)); + break; + } + if ($row[0] !== $row['id']) { + printf("[005] Unexpected result row[0] = '%s', row[id] = '%s', [%d] %s\n", + $row[0], $row[id], mysqli_errno($link), mysqli_error($link)); + break; + } + + $len = strlen($row[1]); + if (!is_string($row[1]) || $len == 0 || $len > 1) { + printf("[006] Unexpected result row[1] = '%s', [%d] %s\n", + $row[1], mysqli_errno($link), mysqli_error($link)); + break; + } + if ($row[1] !== $row['label']) { + printf("[007] Unexpected result row[1] = '%s', row[label] = '%s', [%d] %s\n", + $row[1], $row['label'], mysqli_errno($link), mysqli_error($link)); + break; + } + + } + mysqli_free_result($res); + + if (!$res = mysqli_query($link, 'SELECT id, label FROM test')) { + printf("[008] SELECT failed: [%d] %s\n", mysqli_errno($link), mysqli_errno($link)); + } + + while ($row = mysqli_fetch_array($res, MYSQLI_ASSOC)) { + // overwrite results and check if the cache magic works + $row['label'] = NULL; + } + mysqli_free_result($res); + + if (!$res = mysqli_query($link, 'SELECT count(*) AS num FROM test')) { + printf("[009] SELECT failed: [%d] %s\n", mysqli_errno($link), mysqli_errno($link)); + } + $row = mysqli_fetch_assoc($res); + $num = $row['num']; + mysqli_free_result($res); + + if (!$res = mysqli_query($link, 'SELECT id, label FROM test')) { + printf("[010] SELECT failed: [%d] %s\n", mysqli_errno($link), mysqli_errno($link)); + } + + $i = 0; + while ($row = mysqli_fetch_array($res, MYSQLI_NUM)) { + // overwrite results and check if the cache magic works + $row[0] = NULL; + $i++; + } + mysqli_free_result($res); + + if ($i != $num) + printf("[011] Expecting %d results, got %d results, [%d] %s\n", + $num, $i, mysqli_errno($link), mysqli_error($link)); + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_array_oo.phpt b/ext/mysqli/tests/mysqli_fetch_array_oo.phpt new file mode 100644 index 0000000..21d78ae --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_array_oo.phpt @@ -0,0 +1,362 @@ +--TEST-- +mysqli->fetch_array() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + require('table.inc'); + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!$res = $mysqli->query("SELECT * FROM test ORDER BY id LIMIT 5")) { + printf("[004] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + print "[005]\n"; + var_dump($res->fetch_array()); + + print "[006]\n"; + var_dump($res->fetch_array(MYSQLI_NUM)); + + print "[007]\n"; + var_dump($res->fetch_array(MYSQLI_BOTH)); + + print "[008]\n"; + var_dump($res->fetch_array(MYSQLI_ASSOC)); + + print "[009]\n"; + var_dump($res->fetch_array()); + + $res->free_result(); + + if (!$res = $mysqli->query("SELECT 1 AS a, 2 AS a, 3 AS c, 4 AS C, NULL AS d, true AS e")) { + printf("[010] Cannot run query, [%d] %s\n", $mysqli->errno, $$mysqli->error); + } + print "[011]\n"; + var_dump($res->fetch_array(MYSQLI_BOTH)); + + $res->free_result(); + if (!$res = $mysqli->query("SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS C")) { + printf("[012] Cannot run query, [%d] %s\n", + $mysqli->errno, $$mysqli->error); + exit(1); + } + + do { + $illegal_mode = mt_rand(-10000, 10000); + } while (in_array($illegal_mode, array(MYSQLI_ASSOC, MYSQLI_NUM, MYSQLI_BOTH))); + // NOTE: for BC reasons with ext/mysql, ext/mysqli accepts invalid result modes. + $tmp = $res->fetch_array($illegal_mode); + if (false !== $tmp) + printf("[013] Expecting boolean/false although, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, $mysqli->errno, $mysqli->error); + + $tmp = $res->fetch_array($illegal_mode); + if (false !== $tmp) + printf("[014] Expecting boolean/false, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, $mysqli->errno, $mysqli->error); + + $res->free_result(); + + function func_mysqli_fetch_array($mysqli, $engine, $sql_type, $sql_value, $php_value, $offset, $regexp_comparison = NULL) { + + if (!$mysqli->query("DROP TABLE IF EXISTS test")) { + printf("[%04d] [%d] %s\n", $offset, $mysqli->errno, $mysqli->error); + return false; + } + + if (!$mysqli->query($sql = sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { + // don't bail, engine might not support the datatype + return false; + } + + if (is_null($php_value)) { + if (!$mysqli->query($sql = sprintf("INSERT INTO test(id, label) VALUES (1, NULL)"))) { + printf("[%04d] [%d] %s\n", $offset + 1, $mysqli->errno, $mysqli->error); + return false; + } + } else { + if (is_string($sql_value)) { + if (!$mysqli->query($sql = "INSERT INTO test(id, label) VALUES (1, '" . $sql_value . "')")) { + printf("[%04ds] [%d] %s - %s\n", $offset + 1, $mysqli->errno, $mysqli->error, $sql); + return false; + } + } else { + if (!$mysqli->query($sql = sprintf("INSERT INTO test(id, label) VALUES (1, '%d')", $sql_value))) { + printf("[%04di] [%d] %s\n", $offset + 1, $mysqli->errno, $mysqli->error); + return false; + } + } + } + + if (!$res = $mysqli->query("SELECT id, label FROM test")) { + printf("[%04d] [%d] %s\n", $offset + 2, $mysqli->errno, $mysqli->error); + return false; + } + + if (!$row = $res->fetch_array(MYSQLI_BOTH)) { + printf("[%04d] [%d] %s\n", $offset + 3, $mysqli->errno, $mysqli->error); + return false; + } + $fields = mysqli_fetch_fields($res); + + if (!(gettype($php_value)=="unicode" && ($fields[1]->flags & 128))) { + if ($regexp_comparison) { + if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) { + printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, + gettype($php_value), $php_value, $regexp_comparison, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], $mysqli->errno, $mysqli->error); + return false; + } + } else { + if (($row['label'] !== $php_value) || ($row[1] != $php_value)) { + printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, + gettype($php_value), $php_value, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], $mysqli->errno, $mysqli->error); + return false; + } + } + } + return true; + } + + function func_mysqli_fetch_array_make_string($len) { + + $ret = ''; + for ($i = 0; $i < $len; $i++) + $ret .= chr(mt_rand(65, 90)); + + return $ret; + } + + func_mysqli_fetch_array($mysqli, $engine, "TINYINT", -11, "-11", 20); + func_mysqli_fetch_array($mysqli, $engine, "TINYINT", NULL, NULL, 30); + func_mysqli_fetch_array($mysqli, $engine, "TINYINT UNSIGNED", 1, "1", 40); + func_mysqli_fetch_array($mysqli, $engine, "TINYINT UNSIGNED", NULL, NULL, 50); + + func_mysqli_fetch_array($mysqli, $engine, "BOOL", 1, "1", 60); + func_mysqli_fetch_array($mysqli, $engine, "BOOL", NULL, NULL, 70); + func_mysqli_fetch_array($mysqli, $engine, "BOOLEAN", 0, "0", 80); + func_mysqli_fetch_array($mysqli, $engine, "BOOLEAN", NULL, NULL, 90); + + func_mysqli_fetch_array($mysqli, $engine, "SMALLINT", -32768, "-32768", 100); + func_mysqli_fetch_array($mysqli, $engine, "SMALLINT", 32767, "32767", 110); + func_mysqli_fetch_array($mysqli, $engine, "SMALLINT", NULL, NULL, 120); + func_mysqli_fetch_array($mysqli, $engine, "SMALLINT UNSIGNED", 65535, "65535", 130); + func_mysqli_fetch_array($mysqli, $engine, "SMALLINT UNSIGNED", NULL, NULL, 140); + + func_mysqli_fetch_array($mysqli, $engine, "MEDIUMINT", -8388608, "-8388608", 150); + func_mysqli_fetch_array($mysqli, $engine, "MEDIUMINT", 8388607, "8388607", 160); + func_mysqli_fetch_array($mysqli, $engine, "MEDIUMINT", NULL, NULL, 170); + func_mysqli_fetch_array($mysqli, $engine, "MEDIUMINT UNSIGNED", 16777215, "16777215", 180); + func_mysqli_fetch_array($mysqli, $engine, "MEDIUMINT UNSIGNED", NULL, NULL, 190); + + func_mysqli_fetch_array($mysqli, $engine, "INTEGER", -2147483648, "-2147483648", 200); + func_mysqli_fetch_array($mysqli, $engine, "INTEGER", 2147483647, "2147483647", 210); + func_mysqli_fetch_array($mysqli, $engine, "INTEGER", NULL, NULL, 220); + func_mysqli_fetch_array($mysqli, $engine, "INTEGER UNSIGNED", "4294967295", "4294967295", 230); + func_mysqli_fetch_array($mysqli, $engine, "INTEGER UNSIGNED", NULL, NULL, 240); + + if ($IS_MYSQLND || + ((mysqli_get_server_version($link) >= 51000) && + (mysqli_get_client_version($link) >= 51000))) { + func_mysqli_fetch_array($mysqli, $engine, "BIGINT", "-9223372036854775808", "-9223372036854775808", 250); + func_mysqli_fetch_array($mysqli, $engine, "BIGINT", NULL, NULL, 260); + func_mysqli_fetch_array($mysqli, $engine, "BIGINT UNSIGNED", "18446744073709551615", "18446744073709551615", 270); + func_mysqli_fetch_array($mysqli, $engine, "BIGINT UNSIGNED", NULL, NULL, 280); + } + + func_mysqli_fetch_array($mysqli, $engine, "FLOAT", (string)(-9223372036854775808 - 1.1), "-9.22337e+18", 290, "/-9\.22337e\+?[0]?18/iu"); + func_mysqli_fetch_array($mysqli, $engine, "FLOAT", NULL, NULL, 300); + func_mysqli_fetch_array($mysqli, $engine, "FLOAT UNSIGNED", (string)(18446744073709551615 + 1.1), "1.84467e+?19", 310, "/1\.84467e\+?[0]?19/iu"); + func_mysqli_fetch_array($mysqli, $engine, "FLOAT UNSIGNED ", NULL, NULL, 320); + + func_mysqli_fetch_array($mysqli, $engine, "DOUBLE(10,2)", "-99999999.99", "-99999999.99", 330); + func_mysqli_fetch_array($mysqli, $engine, "DOUBLE(10,2)", NULL, NULL, 340); + func_mysqli_fetch_array($mysqli, $engine, "DOUBLE(10,2) UNSIGNED", "99999999.99", "99999999.99", 350); + func_mysqli_fetch_array($mysqli, $engine, "DOUBLE(10,2) UNSIGNED", NULL, NULL, 360); + func_mysqli_fetch_array($mysqli, $engine, "DECIMAL(10,2)", "-99999999.99", "-99999999.99", 370); + func_mysqli_fetch_array($mysqli, $engine, "DECIMAL(10,2)", NULL, NULL, 380); + func_mysqli_fetch_array($mysqli, $engine, "DECIMAL(10,2)", "99999999.99", "99999999.99", 390); + func_mysqli_fetch_array($mysqli, $engine, "DECIMAL(10,2)", NULL, NULL, 400); + + // don't care about date() strict TZ warnings... + $date = @date('Y-m-d'); + func_mysqli_fetch_array($mysqli, $engine, "DATE",$date, $date, 410); + func_mysqli_fetch_array($mysqli, $engine, "DATE NOT NULL",$date, $date, 420); + func_mysqli_fetch_array($mysqli, $engine, "DATE", NULL, NULL, 430); + + $date = @date('Y-m-d H:i:s'); + func_mysqli_fetch_array($mysqli, $engine, "DATETIME", $date, $date, 440); + func_mysqli_fetch_array($mysqli, $engine, "DATETIME NOT NULL", $date, $date, 450); + func_mysqli_fetch_array($mysqli, $engine, "DATETIME", NULL, NULL, 460); + func_mysqli_fetch_array($mysqli, $engine, "TIMESTAMP", $date, $date, 470); + $date = @date('H:i:s'); + func_mysqli_fetch_array($mysqli, $engine, "TIME", $date, $date, 480); + func_mysqli_fetch_array($mysqli, $engine, "TIME NOT NULL", $date, $date, 490); + func_mysqli_fetch_array($mysqli, $engine, "TIME", NULL, NULL, 500); + func_mysqli_fetch_array($mysqli, $engine, "YEAR", @date('Y'), @date('Y'), 510); + func_mysqli_fetch_array($mysqli, $engine, "YEAR NOT NULL", @date('Y'), @date('Y'), 520); + func_mysqli_fetch_array($mysqli, $engine, "YEAR", NULL, NULL, 530); + + $string255 = func_mysqli_fetch_array_make_string(255); + func_mysqli_fetch_array($mysqli, $engine, "CHAR(1)", "a", "a", 540); + func_mysqli_fetch_array($mysqli, $engine, "CHAR(255)", $string255, $string255, 550); + func_mysqli_fetch_array($mysqli, $engine, "CHAR(1) NOT NULL", "a", "a", 560); + func_mysqli_fetch_array($mysqli, $engine, "CHAR(1)", NULL, NULL, 570); + + $string65k = func_mysqli_fetch_array_make_string(65400); + func_mysqli_fetch_array($mysqli, $engine, "VARCHAR(1)", "a", "a", 580); + func_mysqli_fetch_array($mysqli, $engine, "VARCHAR(255)", $string255, $string255, 590); + func_mysqli_fetch_array($mysqli, $engine, "VARCHAR(65400)", $string65k, $string65k, 600); + func_mysqli_fetch_array($mysqli, $engine, "VARCHAR(1) NOT NULL", "a", "a", 610); + func_mysqli_fetch_array($mysqli, $engine, "VARCHAR(1)", NULL, NULL, 620); + + func_mysqli_fetch_array($mysqli, $engine, "BINARY(1)", "a", "a", 630); + func_mysqli_fetch_array($mysqli, $engine, "BINARY(2)", chr(0) . "a", chr(0) . "a", 640); + func_mysqli_fetch_array($mysqli, $engine, "BINARY(1) NOT NULL", "b", "b", 650); + func_mysqli_fetch_array($mysqli, $engine, "BINARY(1)", NULL, NULL, 660); + + func_mysqli_fetch_array($mysqli, $engine, "VARBINARY(1)", "a", "a", 670); + func_mysqli_fetch_array($mysqli, $engine, "VARBINARY(2)", chr(0) . "a", chr(0) . "a", 680); + func_mysqli_fetch_array($mysqli, $engine, "VARBINARY(1) NOT NULL", "b", "b", 690); + func_mysqli_fetch_array($mysqli, $engine, "VARBINARY(1)", NULL, NULL, 700); + + func_mysqli_fetch_array($mysqli, $engine, "TINYBLOB", "a", "a", 710); + func_mysqli_fetch_array($mysqli, $engine, "TINYBLOB", chr(0) . "a", chr(0) . "a", 720); + func_mysqli_fetch_array($mysqli, $engine, "TINYBLOB NOT NULL", "b", "b", 730); + func_mysqli_fetch_array($mysqli, $engine, "TINYBLOB", NULL, NULL, 740); + + func_mysqli_fetch_array($mysqli, $engine, "TINYTEXT", "a", "a", 750); + func_mysqli_fetch_array($mysqli, $engine, "TINYTEXT NOT NULL", "a", "a", 760); + func_mysqli_fetch_array($mysqli, $engine, "TINYTEXT", NULL, NULL, 770); + + func_mysqli_fetch_array($mysqli, $engine, "BLOB", "a", "a", 780); + func_mysqli_fetch_array($mysqli, $engine, "BLOB", chr(0) . "a", chr(0) . "a", 780); + func_mysqli_fetch_array($mysqli, $engine, "BLOB", NULL, NULL, 790); + + func_mysqli_fetch_array($mysqli, $engine, "TEXT", "a", "a", 800); + func_mysqli_fetch_array($mysqli, $engine, "TEXT", chr(0) . "a", chr(0) . "a", 810); + func_mysqli_fetch_array($mysqli, $engine, "TEXT", NULL, NULL, 820); + + func_mysqli_fetch_array($mysqli, $engine, "MEDIUMBLOB", "a", "a", 830); + func_mysqli_fetch_array($mysqli, $engine, "MEDIUMBLOB", chr(0) . "a", chr(0) . "a", 840); + func_mysqli_fetch_array($mysqli, $engine, "MEDIUMBLOB", NULL, NULL, 850); + + func_mysqli_fetch_array($mysqli, $engine, "MEDIUMTEXT", "a", "a", 860); + func_mysqli_fetch_array($mysqli, $engine, "MEDIUMTEXT", chr(0) . "a", chr(0) . "a", 870); + func_mysqli_fetch_array($mysqli, $engine, "MEDIUMTEXT", NULL, NULL, 880); + + func_mysqli_fetch_array($mysqli, $engine, "LONGBLOB", "a", "a", 890); + func_mysqli_fetch_array($mysqli, $engine, "LONGTEXT", chr(0) . "a", chr(0) . "a", 900); + func_mysqli_fetch_array($mysqli, $engine, "LONGBLOB", NULL, NULL, 910); + + func_mysqli_fetch_array($mysqli, $engine, "ENUM('a', 'b')", "a", "a", 920); + func_mysqli_fetch_array($mysqli, $engine, "ENUM('a', 'b')", NULL, NULL, 930); + + func_mysqli_fetch_array($mysqli, $engine, "SET('a', 'b')", "a", "a", 940); + func_mysqli_fetch_array($mysqli, $engine, "SET('a', 'b')", NULL, NULL, 950); + + $mysqli->close(); + + if (null !== ($tmp = $res->fetch_array(MYSQLI_ASSOC))) + printf("[015] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +[005] +array(4) { + [0]=> + %unicode|string%(1) "1" + [%u|b%"id"]=> + %unicode|string%(1) "1" + [1]=> + %unicode|string%(1) "a" + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +[006] +array(2) { + [0]=> + %unicode|string%(1) "2" + [1]=> + %unicode|string%(1) "b" +} +[007] +array(4) { + [0]=> + %unicode|string%(1) "3" + [%u|b%"id"]=> + %unicode|string%(1) "3" + [1]=> + %unicode|string%(1) "c" + [%u|b%"label"]=> + %unicode|string%(1) "c" +} +[008] +array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "4" + [%u|b%"label"]=> + %unicode|string%(1) "d" +} +[009] +array(4) { + [0]=> + %unicode|string%(1) "5" + [%u|b%"id"]=> + %unicode|string%(1) "5" + [1]=> + %unicode|string%(1) "e" + [%u|b%"label"]=> + %unicode|string%(1) "e" +} +[011] +array(11) { + [0]=> + %unicode|string%(1) "1" + [%u|b%"a"]=> + %unicode|string%(1) "2" + [1]=> + %unicode|string%(1) "2" + [2]=> + %unicode|string%(1) "3" + [%u|b%"c"]=> + %unicode|string%(1) "3" + [3]=> + %unicode|string%(1) "4" + [%u|b%"C"]=> + %unicode|string%(1) "4" + [4]=> + NULL + [%u|b%"d"]=> + NULL + [5]=> + %unicode|string%(1) "1" + [%u|b%"e"]=> + %unicode|string%(1) "1" +} + +Warning: mysqli_result::fetch_array(): The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH in %s on line %d + +Warning: mysqli_result::fetch_array(): The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH in %s on line %d + +Warning: mysqli_result::fetch_array(): Couldn't fetch mysqli_result in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_assoc.phpt b/ext/mysqli/tests/mysqli_fetch_assoc.phpt new file mode 100644 index 0000000..edf143b --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_assoc.phpt @@ -0,0 +1,119 @@ +--TEST-- +mysqli_fetch_assoc() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + // Note: no SQL type tests, internally the same function gets used as for mysqli_fetch_array() which does a lot of SQL type test + + if (!is_null($tmp = @mysqli_fetch_assoc())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_fetch_assoc($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 1")) { + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + print "[005]\n"; + var_dump(mysqli_fetch_assoc($res)); + + print "[006]\n"; + var_dump(mysqli_fetch_assoc($res)); + + mysqli_free_result($res); + + if (!$res = mysqli_query($link, "SELECT + 1 AS a, + 2 AS a, + 3 AS c, + 4 AS C, + NULL AS d, + true AS e, + 5 AS '-1', + 6 AS '-10', + 7 AS '-100', + 8 AS '-1000', + 9 AS '10000', + 'a' AS '100000', + 'b' AS '1000000', + 'c' AS '9', + 'd' AS '9', + 'e' AS '01', + 'f' AS '-02' + ")) { + printf("[007] Cannot run query, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + print "[008]\n"; + var_dump(mysqli_fetch_assoc($res)); + + mysqli_free_result($res); + + if (NULL !== ($tmp = mysqli_fetch_assoc($res))) + printf("[008] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +[005] +array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +[006] +NULL +[008] +array(15) { + [%u|b%"a"]=> + %unicode|string%(1) "2" + [%u|b%"c"]=> + %unicode|string%(1) "3" + [%u|b%"C"]=> + %unicode|string%(1) "4" + [%u|b%"d"]=> + NULL + [%u|b%"e"]=> + %unicode|string%(1) "1" + [-1]=> + %unicode|string%(1) "5" + [-10]=> + %unicode|string%(1) "6" + [-100]=> + %unicode|string%(1) "7" + [-1000]=> + %unicode|string%(1) "8" + [10000]=> + %unicode|string%(1) "9" + [100000]=> + %unicode|string%(1) "a" + [1000000]=> + %unicode|string%(1) "b" + [9]=> + %unicode|string%(1) "d" + [%u|b%"01"]=> + %unicode|string%(1) "e" + [%u|b%"-02"]=> + %unicode|string%(1) "f" +} + +Warning: mysqli_fetch_assoc(): Couldn't fetch mysqli_result in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt new file mode 100644 index 0000000..d9bdcfa --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt @@ -0,0 +1,117 @@ +--TEST-- +mysqli_fetch_assoc() - BIT +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifemb.inc'); + require_once('skipifconnectfailure.inc'); + + require_once('connect.inc'); + require_once('table.inc'); + if (mysqli_get_server_version($link) < 50003) + // b'001' syntax not supported before 5.0.3 + die("skip Syntax used for test not supported with MySQL Server before 5.0.3"); + if (!$IS_MYSQLND && (mysqli_get_client_version() < 50003)) + // better don't trust libmysql before 5.0.3 + die("skip Syntax used for test not supported with MySQL Server before 5.0.3"); +?> +--FILE-- +<?php + require('connect.inc'); + + function dec32bin($dec, $bits) { + + $maxval = pow(2, $bits); + $bin = ''; + for ($bitval = $maxval; $bitval >= 1; $bitval = $bitval / 2) { + if (($dec / $bitval) >= 1) { + $bin .= '1'; + $dec -= $bitval; + } else { + $bin .= '0'; + } + } + return $bin; + } + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + for ($bits = 1; $bits <= 46; $bits++) { + if (1 == $bits) + $max_value = 1; + else + $max_value = pow(2, $bits) - 1; + $tests = 0; + if (!mysqli_query($link, "DROP TABLE IF EXISTS test") || + !mysqli_query($link, $sql = sprintf('CREATE TABLE test(id BIGINT, bit_value BIT(%d) NOT NULL, bit_null BIT(%d) DEFAULT NULL) ENGINE="%s"', $bits, $bits, $engine))) + printf("[002 - %d] [%d] %s\n",$bits, mysqli_errno($link), mysqli_error($link)); + + $tests = 0; + $rand_max = mt_getrandmax(); + while ($tests < 10) { + + $tests++; + if (1 == $tests) + $value = 0; + else if (2 == $tests) + $value = $max_value; + else { + if ($max_value > $rand_max) { + $max_loops = floor($max_value/$rand_max); + $num_loops = mt_rand(1, $max_loops); + $value = 0; + for ($i = 0; $i < $num_loops; $i++) + $value += mt_rand(0, $rand_max); + } else { + $value = mt_rand(0, $max_value); + } + } + + $bin = ($bits < 32) ? decbin($value) : dec32bin($value, $bits); + $sql = sprintf("INSERT INTO test(id, bit_value) VALUES (%s, b'%s')", $value, $bin); + for ($i = 0; ($i < strlen($bin)) && ($bin[$i] == '0'); $i++) + ; + $bin2 = substr($bin, $i, strlen($bin)); + + if (!mysqli_query($link, $sql)) + printf("[003 - %d] [%d] %s\n", $bits, mysqli_errno($link), mysqli_error($link)); + + $sql = sprintf("SELECT id, BIN(bit_value) AS _bin, bit_value + 0 AS _bit_value0, bit_value, bit_null FROM test WHERE id = %s", $value); + if (!$res = mysqli_query($link, $sql)) + printf("[004 - %d] [%d] %s\n", $bits, mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[005 - %d] [%d] %s\n", $bits, mysqli_errno($link), mysqli_error($link)); + + if (($value != $row['id']) || (($bin != $row['_bin']) && ($bin2 != $row['_bin']))) { + debug_zval_dump($row); + printf("[006 - %d] Insert of %s in BIT(%d) column might have failed. id = %s, bin = %s (%s/%s)\n", + $bits, $value, $bits, $row['id'], $row['_bin'], $bin, $bin2); + break; + } + if ($value != $row['bit_value']) { + debug_zval_dump($row); + printf("%10s %64s\n%10s %64s\n", '_bin', $row['_bin'], 'insert', $bin); + printf("[007 - %d] Expecting %s got %s\n", $bits, $value, $row['bit_value']); + break; + } + + if (null !== $row['bit_null']) { + debug_zval_dump($row); + printf("[008 - %d] Expecting null got %s/%s\n", $bits, gettype($row['bit_value']), $row['bit_value']); + break; + } + } + } + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done! diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_no_alias.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_no_alias.phpt new file mode 100644 index 0000000..a273b73 --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_assoc_no_alias.phpt @@ -0,0 +1,142 @@ +--TEST-- +mysqli_fetch_assoc() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require('table.inc'); + + if (!$res = mysqli_query($link, "SELECT 1, 2")) { + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + print "[002]\n"; + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + + if (!$res = mysqli_query($link, "SELECT 1 AS a, 2")) { + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + print "[004]\n"; + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + + if (!$res = mysqli_query($link, "SELECT 1 AS a, 2, 2 as '2'")) { + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + print "[006]\n"; + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + + if (!$res = mysqli_query($link, "SELECT 1 AS a, 2 as '2', 2")) { + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + print "[008]\n"; + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + + /* Now do it with unbuffered queries */ + if (!$res = mysqli_real_query($link, "SELECT 1, 2")) { + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + if (!$res = mysqli_use_result($link)) { + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + print "[011]\n"; + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + + if (!$res = mysqli_real_query($link, "SELECT 1 AS a, 2")) { + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + if (!$res = mysqli_use_result($link)) { + printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + print "[014]\n"; + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + + if (!$res = mysqli_real_query($link, "SELECT 1 AS a, 2, 2 as '2'")) { + printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + if (!$res = mysqli_use_result($link)) { + printf("[016] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + print "[017]\n"; + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + + if (!$res = mysqli_real_query($link, "SELECT 1 AS a, 2 as '2', 2")) { + printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + if (!$res = mysqli_use_result($link)) { + printf("[016] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + print "[017]\n"; + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + mysqli_close($link); + + print "done!"; +?> +--EXPECTF-- +[002] +array(2) { + [1]=> + %unicode|string%(1) "1" + [2]=> + %unicode|string%(1) "2" +} +[004] +array(2) { + [%u|b%"a"]=> + %unicode|string%(1) "1" + [2]=> + %unicode|string%(1) "2" +} +[006] +array(2) { + [%u|b%"a"]=> + %unicode|string%(1) "1" + [2]=> + %unicode|string%(1) "2" +} +[008] +array(2) { + [%u|b%"a"]=> + %unicode|string%(1) "1" + [2]=> + %unicode|string%(1) "2" +} +[011] +array(2) { + [1]=> + %unicode|string%(1) "1" + [2]=> + %unicode|string%(1) "2" +} +[014] +array(2) { + [%u|b%"a"]=> + %s(1) "1" + [2]=> + %s(1) "2" +} +[017] +array(2) { + [%u|b%"a"]=> + %unicode|string%(1) "1" + [2]=> + %unicode|string%(1) "2" +} +[017] +array(2) { + [%u|b%"a"]=> + %unicode|string%(1) "1" + [2]=> + %unicode|string%(1) "2" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt new file mode 100644 index 0000000..fa00ecd --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_assoc_no_alias_utf8.phpt @@ -0,0 +1,164 @@ +--TEST-- +mysqli_fetch_assoc() - utf8 +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifemb.inc'); + require_once('skipifconnectfailure.inc'); + require_once("connect.inc"); + + if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die("skip Cannot connect to server to check charsets"); + + if (!$res = mysqli_query($link, "SHOW CHARACTER SET LIKE 'UTF8'")) + die("skip Cannot run SHOW CHARACTER SET to check charsets"); + + if (!$tmp = mysqli_fetch_assoc($res)) + die("skip Looks like UTF8 is not available on the server"); + + if (strtolower($tmp['Charset']) !== 'utf8') + die("skip Not sure if UTF8 is available, cancelling the test"); + + mysqli_free_result($res); + + if (!$res = mysqli_query($link, "SHOW CHARACTER SET LIKE 'UCS2'")) + die("skip Cannot run SHOW CHARACTER SET to check charsets"); + + if (!$tmp = mysqli_fetch_assoc($res)) + die("skip Looks like UCS2 is not available on the server"); + + if (strtolower($tmp['Charset']) !== 'ucs2') + die("skip Not sure if UCS2 is available, cancelling the test"); + + mysqli_free_result($res); + mysqli_close($link); +?> +--FILE-- +<?php + require('table.inc'); + + /* some cyrillic (utf8) comes here */ + if (!$res = mysqli_query($link, "SET NAMES UTF8")) { + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + if (!$res = mysqli_query($link, "SELECT 1 AS 'Ðндрей ХриÑтов', 2 AS 'Улф Вендел', 3 AS 'Георг Рихтер'")) { + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + print "[003]\n"; + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + + if (!$res = mysqli_query($link, "CREATE TABLE автори_на_mysqlnd (id integer not null auto_increment primary key, име varchar(20) character set ucs2, Ñ„Ð°Ð¼Ð¸Ð»Ð¸Ñ varchar(20) character set utf8)")) { + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + if (!$res = mysqli_query($link, "INSERT INTO автори_на_mysqlnd (име, фамилиÑ) VALUES ('Ðндрей', 'ХриÑтов'), ('Георг', 'Рихтер'), ('Улф','Вендел')")) { + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + if (!$res = mysqli_query($link, "INSERT INTO автори_на_mysqlnd (име, фамилиÑ) VALUES ('Andrey', 'Hristov'), ('Georg', 'Richter'), ('Ulf','Wendel')")) { + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + if (!$res = mysqli_query($link, "INSERT INTO автори_на_mysqlnd (име, фамилиÑ) VALUES ('安德烈', 'Hristov'), ('æ ¼å¥¥å°”', 'Richter'), ('乌尔夫','Wendel')")) { + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + if (!$res = mysqli_query($link, "SELECT id, име, Ñ„Ð°Ð¼Ð¸Ð»Ð¸Ñ FROM автори_на_mysqlnd ORDER BY фамилиÑ, име")) { + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + print "[009]\n"; + while ($row = mysqli_fetch_assoc($res)) { + var_dump($row); + } + mysqli_free_result($res); + + if (!$res = mysqli_query($link, "DROP TABLE автори_на_mysqlnd")) { + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + mysqli_close($link); + print "done!"; +?> +--EXPECTF-- +[003] +array(3) { + [%u|b%"Ðндрей ХриÑтов"]=> + %unicode|string%(%r[1|3]%r) "1" + [%u|b%"Улф Вендел"]=> + %unicode|string%(1) "2" + [%u|b%"Георг Рихтер"]=> + %unicode|string%(1) "3" +} +[009] +array(3) { + [%u|b%"id"]=> + %unicode|string%(1) "4" + [%u|b%"име"]=> + %unicode|string%(6) "Andrey" + [%u|b%"фамилиÑ"]=> + %unicode|string%(7) "Hristov" +} +array(3) { + [%u|b%"id"]=> + %unicode|string%(1) "7" + [%u|b%"име"]=> + %unicode|string%(9) "安德烈" + [%u|b%"фамилиÑ"]=> + %unicode|string%(7) "Hristov" +} +array(3) { + [%u|b%"id"]=> + %unicode|string%(1) "5" + [%u|b%"име"]=> + %unicode|string%(5) "Georg" + [%u|b%"фамилиÑ"]=> + %unicode|string%(7) "Richter" +} +array(3) { + [%u|b%"id"]=> + %unicode|string%(1) "8" + [%u|b%"име"]=> + %unicode|string%(9) "æ ¼å¥¥å°”" + [%u|b%"фамилиÑ"]=> + %unicode|string%(7) "Richter" +} +array(3) { + [%u|b%"id"]=> + %unicode|string%(1) "6" + [%u|b%"име"]=> + %unicode|string%(3) "Ulf" + [%u|b%"фамилиÑ"]=> + %unicode|string%(6) "Wendel" +} +array(3) { + [%u|b%"id"]=> + %unicode|string%(1) "9" + [%u|b%"име"]=> + %unicode|string%(9) "乌尔夫" + [%u|b%"фамилиÑ"]=> + %unicode|string%(6) "Wendel" +} +array(3) { + [%u|b%"id"]=> + %unicode|string%(1) "3" + [%u|b%"име"]=> + %unicode|string%(6) "Улф" + [%u|b%"фамилиÑ"]=> + %unicode|string%(12) "Вендел" +} +array(3) { + [%u|b%"id"]=> + %unicode|string%(1) "2" + [%u|b%"име"]=> + %unicode|string%(10) "Георг" + [%u|b%"фамилиÑ"]=> + %unicode|string%(12) "Рихтер" +} +array(3) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"име"]=> + %unicode|string%(12) "Ðндрей" + [%u|b%"фамилиÑ"]=> + %unicode|string%(14) "ХриÑтов" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_oo.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_oo.phpt new file mode 100644 index 0000000..8a71fa7 --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_assoc_oo.phpt @@ -0,0 +1,86 @@ +--TEST-- +mysqli_fetch_assoc() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + // Note: no SQL type tests, internally the same function gets used as for mysqli_fetch_array() which does a lot of SQL type test + $mysqli = new mysqli(); + $res = @new mysqli_result($mysqli); + if (!is_null($tmp = @$res->fetch_assoc())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!is_null($tmp = @$res->fetch_assoc($link))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = $mysqli->query("SELECT id, label FROM test ORDER BY id LIMIT 1")) { + printf("[004] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + print "[005]\n"; + var_dump($res->fetch_assoc()); + + print "[006]\n"; + var_dump($res->fetch_assoc()); + + $res->free_result(); + + if (!$res = $mysqli->query("SELECT 1 AS a, 2 AS a, 3 AS c, 4 AS C, NULL AS d, true AS e")) { + printf("[007] Cannot run query, [%d] %s\n", $mysqli->errno, $mysqli->error); + } + print "[008]\n"; + var_dump($res->fetch_assoc()); + + $res->free_result(); + + if (NULL !== ($tmp = $res->fetch_assoc())) + printf("[008] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +[005] +array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +[006] +NULL +[008] +array(5) { + [%u|b%"a"]=> + %unicode|string%(1) "2" + [%u|b%"c"]=> + %unicode|string%(1) "3" + [%u|b%"C"]=> + %unicode|string%(1) "4" + [%u|b%"d"]=> + NULL + [%u|b%"e"]=> + %unicode|string%(1) "1" +} + +Warning: mysqli_result::fetch_assoc(): Couldn't fetch mysqli_result in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_zerofill.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_zerofill.phpt new file mode 100644 index 0000000..ce7e82d --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_assoc_zerofill.phpt @@ -0,0 +1,78 @@ +--TEST-- +mysqli_fetch_assoc() - ZEROFILL +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once('connect.inc'); + require_once('table.inc'); + + function zerofill($offset, $link, $datatype, $insert = 1) { + + mysqli_query($link, 'ALTER TABLE test DROP zero'); + $sql = sprintf('ALTER TABLE test ADD zero %s UNSIGNED ZEROFILL', $datatype); + if (!mysqli_query($link, $sql)) { + // no worries - server might not support it + return true; + } + + if (!mysqli_query($link, sprintf('UPDATE test SET zero = %s', $insert))) { + printf("[%03d] UPDATE failed, [%d] %s\n", + $offset, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!($res = mysqli_query($link, 'SELECT zero FROM test LIMIT 1'))) { + printf("[%03d] SELECT failed, [%d] %s\n", + $offset, mysqli_errno($link), mysqli_error($link)); + return false; + } + + $row = mysqli_fetch_assoc($res); + $meta = mysqli_fetch_fields($res); + mysqli_free_result($res); + $meta = $meta[0]; + $length = $meta->length; + if ($length > strlen($insert)) { + + $expected = str_repeat('0', $length - strlen($insert)); + $expected .= $insert; + if ($expected !== $row['zero']) { + printf("[%03d] Expecting '%s' got '%s'\n", $offset, $expected, $row['zero']); + return false; + } + + } else if ($length <= 1) { + printf("[%03d] Length reported is too small to run test\n", $offset); + return false; + } + + return true; + } + + zerofill(2, $link, 'TINYINT'); + zerofill(3, $link, 'SMALLINT'); + zerofill(4, $link, 'MEDIUMINT'); + zerofill(5, $link, 'INT'); + zerofill(6, $link, 'INTEGER'); + zerofill(7, $link, 'BIGINT'); + zerofill(8, $link, 'FLOAT'); + zerofill(9, $link, 'DOUBLE'); + zerofill(10, $link, 'DOUBLE PRECISION'); + zerofill(11, $link, 'DECIMAL'); + zerofill(12, $link, 'DEC'); + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_field.phpt b/ext/mysqli/tests/mysqli_fetch_field.phpt new file mode 100644 index 0000000..d1d358b --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_field.phpt @@ -0,0 +1,177 @@ +--TEST-- +mysqli_fetch_field() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + // Note: no SQL type tests, internally the same function gets used as for mysqli_fetch_array() which does a lot of SQL type test + if (!is_null($tmp = @mysqli_fetch_field())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_fetch_field($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + $charsets = my_get_charsets($link); + if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1")) { + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + /* ID column, binary charset */ + $tmp = mysqli_fetch_field($res); + var_dump($tmp); + + /* label column, result set charset */ + $tmp = mysqli_fetch_field($res); + var_dump($tmp); + if ($tmp->charsetnr != $charsets['results']['nr']) { + printf("[004] Expecting charset %s/%d got %d\n", + $charsets['results']['charset'], + $charsets['results']['nr'], $tmp->charsetnr); + } + if ($tmp->length != (1 * $charsets['results']['maxlen'])) { + printf("[005] Expecting length %d got %d\n", + $charsets['results']['maxlen'], + $tmp->max_length); + } + if ($tmp->db != $db) { + printf("011] Expecting database '%s' got '%s'\n", + $db, $tmp->db); + } + + var_dump(mysqli_fetch_field($res)); + + mysqli_free_result($res); + + // Read http://bugs.php.net/bug.php?id=42344 on defaults! + if (NULL !== ($tmp = mysqli_fetch_field($res))) + printf("[006] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "CREATE TABLE test(id INT NOT NULL DEFAULT 1)")) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "INSERT INTO test(id) VALUES (2)")) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, "SELECT id as _default_test FROM test")) { + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + var_dump(mysqli_fetch_assoc($res)); + /* binary */ + var_dump(mysqli_fetch_field($res)); + mysqli_free_result($res); + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(2) "ID" + [%u|b%"orgname"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "TEST" + [%u|b%"orgtable"]=> + %unicode|string%(%d) "%s" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(1) + [%u|b%"length"]=> + int(11) + [%u|b%"charsetnr"]=> + int(63) + [%u|b%"flags"]=> + int(49155) + [%u|b%"type"]=> + int(3) + [%u|b%"decimals"]=> + int(0) +} +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(5) "label" + [%u|b%"orgname"]=> + %unicode|string%(5) "label" + [%u|b%"table"]=> + %unicode|string%(4) "TEST" + [%u|b%"orgtable"]=> + %unicode|string%(%d) "%s" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(%d) + [%u|b%"length"]=> + int(%d) + [%u|b%"charsetnr"]=> + int(%d) + [%u|b%"flags"]=> + int(0) + [%u|b%"type"]=> + int(254) + [%u|b%"decimals"]=> + int(0) +} +bool(false) + +Warning: mysqli_fetch_field(): Couldn't fetch mysqli_result in %s on line %d +array(1) { + [%u|b%"_default_test"]=> + %unicode|string%(1) "2" +} +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(13) "_default_test" + [%u|b%"orgname"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(%d) "%s" + [%u|b%"orgtable"]=> + %unicode|string%(%d) "%s" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(1) + [%u|b%"length"]=> + int(11) + [%u|b%"charsetnr"]=> + int(63) + [%u|b%"flags"]=> + int(32769) + [%u|b%"type"]=> + int(3) + [%u|b%"decimals"]=> + int(0) +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_field_direct.phpt b/ext/mysqli/tests/mysqli_fetch_field_direct.phpt new file mode 100644 index 0000000..fb34e44 --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_field_direct.phpt @@ -0,0 +1,83 @@ +--TEST-- +mysqli_fetch_field_direct() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_fetch_field_direct())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_fetch_field_direct($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_fetch_field_direct($link, $link))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1")) { + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + var_dump(mysqli_fetch_field_direct($res, -1)); + var_dump(mysqli_fetch_field_direct($res, 0)); + var_dump(mysqli_fetch_field_direct($res, 2)); + + mysqli_free_result($res); + + if (NULL !== ($tmp = mysqli_fetch_field_direct($res, 0))) + printf("Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_fetch_field_direct(): Field offset is invalid for resultset in %s on line %d +bool(false) +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(2) "ID" + [%u|b%"orgname"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "TEST" + [%u|b%"orgtable"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(%d) + [%u|b%"length"]=> + int(%d) + [%u|b%"charsetnr"]=> + int(%d) + [%u|b%"flags"]=> + int(%d) + [%u|b%"type"]=> + int(%d) + [%u|b%"decimals"]=> + int(%d) +} + +Warning: mysqli_fetch_field_direct(): Field offset is invalid for resultset in %s on line %d +bool(false) + +Warning: mysqli_fetch_field_direct(): Couldn't fetch mysqli_result in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt b/ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt new file mode 100644 index 0000000..9d511aa --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt @@ -0,0 +1,92 @@ +--TEST-- +$res->fetch_field_direct(s) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + $mysqli = new mysqli(); + $res = @new mysqli_result($mysqli); + if (!is_null($tmp = @$res->fetch_field_direct())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!$res = $mysqli->query("SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1")) { + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + if (!is_null($tmp = @$res->fetch_field_direct())) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @$res->fetch_field_direct($link))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @$res->fetch_field_direct($link, $link))) + printf("[006] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + var_dump($res->fetch_field_direct(-1)); + var_dump($res->fetch_field_direct(0)); + var_dump($res->fetch_field_direct(2)); + + $res->free_result(); + + if (NULL !== ($tmp = $res->fetch_field_direct(0))) + printf("[007] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + $mysqli->close(); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_result::fetch_field_direct(): Field offset is invalid for resultset in %s on line %d +bool(false) +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(2) "ID" + [%u|b%"orgname"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "TEST" + [%u|b%"orgtable"]=> + %unicode|string%(%d) "%s" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(%d) + [%u|b%"length"]=> + int(11) + [%u|b%"charsetnr"]=> + int(%d) + [%u|b%"flags"]=> + int(%d) + [%u|b%"type"]=> + int(%d) + [%u|b%"decimals"]=> + int(%d) +} + +Warning: mysqli_result::fetch_field_direct(): Field offset is invalid for resultset in %s on line %d +bool(false) + +Warning: mysqli_result::fetch_field_direct(): Couldn't fetch mysqli_result in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_field_flags.phpt b/ext/mysqli/tests/mysqli_fetch_field_flags.phpt new file mode 100644 index 0000000..8259d2f --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_field_flags.phpt @@ -0,0 +1,243 @@ +--TEST-- +mysqli_fetch_field() - flags/field->flags +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +require_once('connect.inc'); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die(printf("skip: [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error())); + +if (mysqli_get_server_version($link) < 50041) + die("skip: Due to many MySQL Server differences, the test requires 5.0.41+"); + +mysqli_close($link); +?> +--FILE-- +<?php + require_once("connect.inc"); + +/* TODO: mysqli.c needs to export a few more constants - see all the defined() calls! */ + + $flags = array( + MYSQLI_NOT_NULL_FLAG => 'NOT_NULL', + MYSQLI_PRI_KEY_FLAG => 'PRI_KEY', + MYSQLI_UNIQUE_KEY_FLAG => 'UNIQUE_KEY', + MYSQLI_MULTIPLE_KEY_FLAG => 'MULTIPLE_KEY', + MYSQLI_BLOB_FLAG => 'BLOB', + MYSQLI_UNSIGNED_FLAG => 'UNSIGNED', + MYSQLI_ZEROFILL_FLAG => 'ZEROFILL', + MYSQLI_AUTO_INCREMENT_FLAG => 'AUTO_INCREMENT', + MYSQLI_TIMESTAMP_FLAG => 'TIMESTAMP', + MYSQLI_SET_FLAG => 'SET', + MYSQLI_NUM_FLAG => 'NUM', + MYSQLI_PART_KEY_FLAG => 'PART_KEY', + // MYSQLI_GROUP_FLAG => 'MYSQLI_GROUP_FLAG' - internal usage only + (defined('MYSQLI_NO_DEFAULT_VALUE_FLAG') ? MYSQLI_NO_DEFAULT_VALUE_FLAG : 4096) => 'NO_DEFAULT_VALUE', + (defined('MYSQLI_BINARY_FLAG') ? MYSQLI_BINARY_FLAG : 128) => 'BINARY', + (defined('MYSQLI_ENUM_FLAG') ? MYSQLI_ENUM_FLAG : 256) => 'ENUM', + // MYSQLI_BINCMP_FLAG + ); + + // 5.1.24 / 6.0.4+ + if (defined('MYSQLI_ON_UPDATE_NOW')) + $flags[MYSQLI_ON_UPDATE_NOW] = 'ON_UPDATE_NOW'; + else + $flags[8192] = 'ON_UPDATE_NOW'; + + krsort($flags); + + $columns = array( + 'INT DEFAULT NULL' => 'NUM', + 'INT NOT NULL' => 'NOT_NULL NO_DEFAULT_VALUE NUM', + 'INT NOT NULL DEFAULT 1' => 'NOT_NULL NUM', + 'INT UNSIGNED DEFAULT NULL' => 'UNSIGNED NUM', + 'INT UNSIGNED NOT NULL' => 'NOT_NULL UNSIGNED NO_DEFAULT_VALUE NUM', + 'INT UNSIGNED NOT NULL DEFAULT 1' => 'NOT_NULL UNSIGNED NUM', + 'INT UNSIGNED ZEROFILL DEFAULT NULL' => 'UNSIGNED ZEROFILL NUM', + 'INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY' => 'NOT_NULL PRI_KEY UNSIGNED AUTO_INCREMENT NUM PART_KEY', + 'CHAR(1) DEFAULT NULL' => '', + 'CHAR(1) NOT NULL' => 'NOT_NULL NO_DEFAULT_VALUE', + 'TIMESTAMP NOT NULL' => 'NOT_NULL UNSIGNED ZEROFILL BINARY TIMESTAMP', + 'VARBINARY(127) DEFAULT NULL' => 'BINARY', + 'BLOB' => 'BLOB BINARY', + 'TINYBLOB' => 'BLOB BINARY', + 'MEDIUMBLOB' => 'BLOB BINARY', + 'LONGBLOB' => 'BLOB BINARY', + 'TEXT' => 'BLOB', + 'TINYTEXT' => 'BLOB', + 'MEDIUMTEXT' => 'BLOB', + 'LONGTEXT' => 'BLOB', + 'SET("one", "two")' => 'SET', + 'SET("one", "two") NOT NULL' => 'NOT_NULL SET NO_DEFAULT_VALUE', + 'SET("one", "two") NOT NULL DEFAULT "one"' => 'NOT_NULL SET', + 'ENUM("one", "two")' => 'ENUM', + 'ENUM("one", "two") NOT NULL' => 'NOT_NULL ENUM NO_DEFAULT_VALUE', + 'ENUM("one", "two") NOT NULL DEFAULT "one"' => 'NOT_NULL ENUM', + 'TINYINT UNIQUE' => 'UNIQUE_KEY NUM PART_KEY', + 'SMALLINT UNIQUE' => 'UNIQUE_KEY NUM PART_KEY', + 'MEDIUMINT UNIQUE DEFAULT 1' => 'UNIQUE_KEY NUM PART_KEY', + 'BIGINT UNSIGNED UNIQUE DEFAULT 100' => 'UNIQUE_KEY UNSIGNED NUM PART_KEY', + 'BIT' => 'UNSIGNED', + 'VARCHAR(2) NOT NULL PRIMARY KEY' => 'NOT_NULL PRI_KEY NO_DEFAULT_VALUE PART_KEY' + ); + + + + function checkFlags($reported_flags, $expected_flags, $flags) { + $found_flags = $unexpected_flags = ''; + foreach ($flags as $code => $name) { + if ($reported_flags >= $code) { + $reported_flags -= $code; + $found_flags .= $name . ' '; + if (stristr($expected_flags, $name)) { + $expected_flags = trim(str_ireplace($name, '', $expected_flags)); + } else { + $unexpected_flags .= $name . ' '; + } + } + } + + return array($expected_flags, $unexpected_flags, $found_flags); + } + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (mysqli_get_server_version($link) > 50600) { + $columns['TIMESTAMP NOT NULL'] = 'ON_UPDATE_NOW TIMESTAMP BINARY NOT_NULL'; + } + + foreach ($columns as $column_def => $expected_flags) { + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { + printf("[002] %s [%d] %s\n", $column_def, + mysqli_errno($link), mysqli_error($link)); + continue; + } + + $create = sprintf('CREATE TABLE test(id INT, col1 %s)', $column_def); + if (!mysqli_query($link, $create)) { + // Server might not support it - skip + continue; + } + + if (!$res = mysqli_query($link, 'SELECT * FROM test')) { + printf("[003] Can't select from table, %s [%d] %s\n", $column_def, + mysqli_errno($link), mysqli_error($link)); + continue; + } + + $field = mysqli_fetch_field_direct($res, 1); + if (!is_object($field)) { + printf("[004] Fetching the meta data failed, %s [%d] %s\n", $column_def, + mysqli_errno($link), mysqli_error($link)); + continue; + } + if ($field->name != 'col1') { + printf("[005] Field information seems wrong, %s [%d] %s\n", $column_def, + mysqli_errno($link), mysqli_error($link)); + continue; + } + + /* + TODO + Unfortunately different server versions give you slightly different + results.The test does not yet fully reflect all server changes/bugs etc. + */ + switch ($column_def) { + case 'TIMESTAMP NOT NULL': + // http://bugs.mysql.com/bug.php?id=30081 - new flag introduced in 5.1.24/6.0.4 + $version = mysqli_get_server_version($link); + if ((($version > 50122) && ($version < 60000) && ($version != 50200)) || + ($version >= 60004)) { + // new flag ON_UPDATE_NOW_FLAG (8192) + $expected_flags .= ' ON_UPDATE_NOW'; + } + break; + + case 'INT UNSIGNED NOT NULL': + case 'INT NOT NULL': + case 'CHAR(1) NOT NULL': + case 'SET("one", "two") NOT NULL': + case 'ENUM("one", "two") NOT NULL': + $version = mysqli_get_server_version($link); + if ($version < 50000) { + // TODO - check exact version! + $expected_flags = trim(str_replace('NO_DEFAULT_VALUE', '', $expected_flags)); + } + break; + + case 'BIT': + $version = mysqli_get_server_version($link); + if (($version <= 50114 && $version > 50100) || ($version == 50200)) { + // TODO - check exact version! + $expected_flags = trim(str_replace('UNSIGNED', '', $expected_flags)); + } + + default: + break; + } + + list($missing_flags, $unexpected_flags, $flags_found) = checkFlags($field->flags, $expected_flags, $flags); + if ($unexpected_flags) { + printf("[006] Found unexpected flags '%s' for %s, found '%s' with MySQL %s'\n", + $unexpected_flags, $column_def, $flags_found, mysqli_get_server_version($link)); + } + if ($missing_flags) { + printf("[007] The flags '%s' have not been reported for %s, found '%s'\n", + $missing_flags, $column_def, $flags_found); + var_dump($create); + var_dump(mysqli_get_server_version($link)); + die($missing_flags); + } + + mysqli_free_result($res); + } + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { + printf("[008] %s [%d] %s\n", $column_def, + mysqli_errno($link), mysqli_error($link)); + continue; + } + + $column_def = array('col1 CHAR(1)', 'col2 CHAR(2)','INDEX idx_col1_col2(col1, col2)'); + $expected_flags = array('col1' => 'MULTIPLE_KEY PART_KEY', 'col2' => 'PART_KEY'); + $create = 'CREATE TABLE test(id INT, '; + foreach ($column_def as $k => $v) { + $create .= sprintf('%s, ', $v); + } + $create = sprintf('%s)', substr($create, 0, -2)); + + if (mysqli_query($link, $create)) { + if (!$res = mysqli_query($link, 'SELECT * FROM test')) { + printf("[009] Cannot run SELECT, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + } + // id column - skip it + $field = mysqli_fetch_field($res); + while ($field = mysqli_fetch_field($res)) { + if (!isset($expected_flags[$field->name])) { + printf("[010] Found unexpected field '%s'\n", $field->name); + continue; + } + list($missing_flags, $unexpected_flags, $flags_found) = checkFlags($field->flags, $expected_flags[$field->name], $flags); + if ($unexpected_flags) + printf("[011] Found unexpected flags '%s' for %s, found '%s'\n", + $unexpected_flags, $field->name, $flags_found); + if ($missing_flags) + printf("[012] The flags '%s' have not been reported for %s, found '%s'\n", + $missing_flags, $field->name, $flags_found); + } + } + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_field_oo.phpt b/ext/mysqli/tests/mysqli_fetch_field_oo.phpt new file mode 100644 index 0000000..2d5ad26 --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_field_oo.phpt @@ -0,0 +1,129 @@ +--TEST-- +mysqli_fetch_field() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + // Note: no SQL type tests, internally the same function gets used as for mysqli_fetch_array() which does a lot of SQL type test + $mysqli = new mysqli(); + $res = @new mysqli_result($mysqli); + if (!is_null($tmp = @$res->fetch_field())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!is_null($tmp = @$res->fetch_field($link))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + $charsets = my_get_charsets($link); + + if (!$res = $mysqli->query("SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1")) { + printf("[004] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + var_dump($res->fetch_field()); + + $tmp = $res->fetch_field(); + var_dump($tmp); + if ($tmp->charsetnr != $charsets['results']['nr']) { + printf("[005] Expecting charset %s/%d got %d\n", + $charsets['results']['charset'], + $charsets['results']['nr'], $tmp->charsetnr); + } + if ($tmp->length != (1 * $charsets['results']['maxlen'])) { + printf("[006] Expecting length %d got %d\n", + $charsets['results']['maxlen'], + $tmp->max_length); + } + if ($tmp->db != $db) { + printf("008] Expecting database '%s' got '%s'\n", + $db, $tmp->db); + } + + var_dump($res->fetch_field()); + + $res->free_result(); + + if (NULL !== ($tmp = $res->fetch_field())) + printf("[007] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + $mysqli->close(); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(2) "ID" + [%u|b%"orgname"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "TEST" + [%u|b%"orgtable"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(1) + [%u|b%"length"]=> + int(11) + [%u|b%"charsetnr"]=> + int(63) + [%u|b%"flags"]=> + int(49155) + [%u|b%"type"]=> + int(3) + [%u|b%"decimals"]=> + int(0) +} +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(5) "label" + [%u|b%"orgname"]=> + %unicode|string%(5) "label" + [%u|b%"table"]=> + %unicode|string%(4) "TEST" + [%u|b%"orgtable"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(%d) + [%u|b%"length"]=> + int(%d) + [%u|b%"charsetnr"]=> + int(%d) + [%u|b%"flags"]=> + int(0) + [%u|b%"type"]=> + int(254) + [%u|b%"decimals"]=> + int(0) +} +bool(false) + +Warning: mysqli_result::fetch_field(): Couldn't fetch mysqli_result in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_field_types.phpt b/ext/mysqli/tests/mysqli_fetch_field_types.phpt new file mode 100644 index 0000000..d02c02c --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_field_types.phpt @@ -0,0 +1,126 @@ +--TEST-- +mysqli_fetch_field() - data types/field->type +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require('table.inc'); + + function mysqli_field_datatypes($link, $sql_type, $php_value, $php_type, $datatypes, $default_charset="latin1") { + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) { + printf("[001] %s, [%d] %s\n", $sql_type, + mysqli_errno($link), mysqli_error($link)); + return false; + } + + $create = sprintf("CREATE TABLE test(id %s) DEFAULT CHARSET %s", $sql_type, $default_charset); + if (!mysqli_query($link, $create)) { + printf("[002] '%s' - '%s', [%d] %s\n", $sql_type, $create, + mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (is_string($php_value)) + $sql = sprintf("INSERT INTO test(id) VALUES ('%s')", $php_value); + else + $sql = sprintf("INSERT INTO test(id) VALUES (%s)", $php_value); + + if (!mysqli_query($link, $sql)) { + printf("[003] '%s' - '%s' - '%s', [%d] %s\n", $sql_type, $create, $sql, + mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!$res = mysqli_query($link, 'SELECT id FROM test')) { + printf("[004] %s, [%d] %s\n", $sql_type, + mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!is_object($field = mysqli_fetch_field($res))) { + printf("[004] %s, expecting object got %s, [%d] %s\n", $sql_type, + gettype($field), + mysqli_errno($link), mysqli_error($link)); + return false; + } + + if ($field->type != $php_type) { + $code_name = 'unknown'; + foreach ($datatypes as $k => $v) { + if ($k == $field->type) { + $code_name = (is_array($v)) ? $v[0] : $v; + break; + } + } + printf("[006] Expecting %d for %s got code %d for %s\n", + $php_type, $sql_type, $field->type, $code_name); + return false; + } + + return true; + } + + $datatypes = array( + MYSQLI_TYPE_TINY => array('TINYINT', 5), + MYSQLI_TYPE_SHORT => array('SMALLINT', 10), + MYSQLI_TYPE_LONG => 'MYSQLI_TYPE_LONG - TODO add testing', + MYSQLI_TYPE_FLOAT => array('FLOAT', '1.3'), + MYSQLI_TYPE_DOUBLE => array('DOUBLE', '1.4'), + MYSQLI_TYPE_TIMESTAMP => array('TIMESTAMP', '2007-08-20 18:34:00'), + MYSQLI_TYPE_LONGLONG => array('BIGINT', 100), + MYSQLI_TYPE_INT24 => array('MEDIUMINT', 10), + MYSQLI_TYPE_DATE => array('DATE', '2007-08-20'), + MYSQLI_TYPE_TIME => array('TIME', '18:41:38'), + MYSQLI_TYPE_DATETIME => array('DATETIME', '2007-08-20 18:42:01'), + MYSQLI_TYPE_YEAR => array('YEAR', '2007'), + MYSQLI_TYPE_ENUM => array('ENUM("everything", "is", "just", "wonderful")', 'is'), + // MYSQLI_TYPE_SET => array('SET("I", "smash", "the")', 'I,smash,the'), - string + // MYSQLI_TYPE_TINY_BLOB => array("TINYBLOB", "I got a tiny blog"), - blob + // MYSQLI_TYPE_MEDIUM_BLOB => array("MEDIUMBLOB", "No blob for masses"), - blob + // MYSQLI_TYPE_LONG_BLOB => array("LONGBLOB", "Small is beautiful?"), - blob + MYSQLI_TYPE_BLOB => array("LONGBLOB", 'MySQL does not report proper type. Use Length to distinct BLOB types'), + MYSQLI_TYPE_BLOB => array("MEDIUMBLOB", 'MySQL does not report proper type. Use Length to distinct BLOB types'), + MYSQLI_TYPE_BLOB => array("TINYBLOB", 'MySQL does not report proper type. Use Length to distinct BLOB types'), + MYSQLI_TYPE_BLOB => array("BLOB", 'silly'), + MYSQLI_TYPE_VAR_STRING => array("VARCHAR(32768)", 'varchar'), + MYSQLI_TYPE_STRING => 'MYSQLI_TYPE_STRING - TODO add testing', + MYSQLI_TYPE_STRING => array('CHAR(1)', 'a'), + MYSQLI_TYPE_STRING => array("SET('I', 'smash', 'the')", 'smash'), + MYSQLI_TYPE_NULL => 'MYSQLI_TYPE_NULL - TODO add testing', + MYSQLI_TYPE_NEWDATE => 'MYSQLI_TYPE_NEWDATE - TODO add testing', + MYSQLI_TYPE_INTERVAL => 'MYSQLI_TYPE_INTERVAL - TODO add testing', + MYSQLI_TYPE_GEOMETRY => 'MYSQLI_TYPE_GEOMETRY - TODO add testing', + ); + + if ($IS_MYSQLND) { + $version = 50007 + 1; + } else { + $version = mysqli_get_client_version(); + } + + if ($version > 50002) { + $datatypes[MYSQLI_TYPE_NEWDECIMAL] = array('DECIMAL', '1.1'); + $datatypes[MYSQLI_TYPE_BIT] = array('BIT', 0); + } else { + $datatypes[MYSQLI_TYPE_DECIMAL] = array('DECIMAL', '1.1'); + } + + foreach ($datatypes as $php_type => $datatype) { + if (is_array($datatype)) + mysqli_field_datatypes($link, $datatype[0], $datatype[1], $php_type, $datatypes); + } + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_fields.phpt b/ext/mysqli/tests/mysqli_fetch_fields.phpt new file mode 100644 index 0000000..479c71c --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_fields.phpt @@ -0,0 +1,121 @@ +--TEST-- +mysqli_fetch_fields() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + // Note: no SQL type tests, internally the same function gets used as for mysqli_fetch_array() which does a lot of SQL type test + if (!is_null($tmp = @mysqli_fetch_fields())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_fetch_fields($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + $charsets = my_get_charsets($link); + + if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1")) { + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + $fields = mysqli_fetch_fields($res); + foreach ($fields as $k => $field) { + var_dump($field); + switch ($k) { + case 1: + /* label column, result set charset */ + if ($field->charsetnr != $charsets['results']['nr']) { + printf("[004] Expecting charset %s/%d got %d\n", + $charsets['results']['charset'], + $charsets['results']['nr'], $field->charsetnr); + } + if ($field->length != (1 * $charsets['results']['maxlen'])) { + printf("[005] Expecting length %d got %d\n", + $charsets['results']['maxlen'], + $field->max_length); + } + break; + } + } + + mysqli_free_result($res); + + if (NULL !== ($tmp = mysqli_fetch_fields($res))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(2) "ID" + [%u|b%"orgname"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "TEST" + [%u|b%"orgtable"]=> + %unicode|string%(%d) "%s" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(1) + [%u|b%"length"]=> + int(11) + [%u|b%"charsetnr"]=> + int(63) + [%u|b%"flags"]=> + int(49155) + [%u|b%"type"]=> + int(3) + [%u|b%"decimals"]=> + int(0) +} +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(5) "label" + [%u|b%"orgname"]=> + %unicode|string%(5) "label" + [%u|b%"table"]=> + %unicode|string%(4) "TEST" + [%u|b%"orgtable"]=> + %unicode|string%(%d) "%s" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(1) + [%u|b%"length"]=> + int(%d) + [%u|b%"charsetnr"]=> + int(%d) + [%u|b%"flags"]=> + int(0) + [%u|b%"type"]=> + int(254) + [%u|b%"decimals"]=> + int(0) +} + +Warning: mysqli_fetch_fields(): Couldn't fetch mysqli_result in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_lengths.phpt b/ext/mysqli/tests/mysqli_fetch_lengths.phpt new file mode 100644 index 0000000..1abc611 --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_lengths.phpt @@ -0,0 +1,55 @@ +--TEST-- +mysqli_fetch_lengths() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect\n"); + + if (!is_null($tmp = @mysqli_fetch_lengths())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_fetch_lengths($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 1")) { + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + var_dump(mysqli_fetch_lengths($res)); + while ($row = mysqli_fetch_assoc($res)) + var_dump(mysqli_fetch_lengths($res)); + var_dump(mysqli_fetch_lengths($res)); + + mysqli_free_result($res); + + var_dump(mysqli_fetch_lengths($res)); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +bool(false) +array(2) { + [0]=> + int(1) + [1]=> + int(1) +} +bool(false) + +Warning: mysqli_fetch_lengths(): Couldn't fetch mysqli_result in %s on line %d +NULL +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_lengths_oo.phpt b/ext/mysqli/tests/mysqli_fetch_lengths_oo.phpt new file mode 100644 index 0000000..7523621 --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_lengths_oo.phpt @@ -0,0 +1,50 @@ +--TEST-- +mysqli_result->lengths +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect\n"); + + require('table.inc'); + if (!$res = $mysqli->query("SELECT id, label FROM test ORDER BY id LIMIT 1")) { + printf("[002] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + var_dump($res->lengths); + while ($row = $res->fetch_assoc()) + var_dump($res->lengths); + var_dump($res->lengths); + + $res->free_result(); + var_dump($res->lengths); + $mysqli->close(); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +NULL +array(2) { + [0]=> + int(1) + [1]=> + int(1) +} +NULL + +Warning: main(): Property access is not allowed yet in %s on line %d +NULL +done! diff --git a/ext/mysqli/tests/mysqli_fetch_object.phpt b/ext/mysqli/tests/mysqli_fetch_object.phpt new file mode 100644 index 0000000..c70871e --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_object.phpt @@ -0,0 +1,156 @@ +--TEST-- +mysqli_fetch_object() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + include_once("connect.inc"); + + set_error_handler('handle_catchable_fatal'); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_fetch_object())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_fetch_object($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 5")) { + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + $obj = mysqli_fetch_object($res); + if (($obj->ID !== "1") || ($obj->label !== "a") || (get_class($obj) != 'stdClass')) { + printf("[004] Object seems wrong. [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump($obj); + } + + class mysqli_fetch_object_test { + + public $a = null; + public $b = null; + + public function toString() { + var_dump($this); + } + } + + $obj = mysqli_fetch_object($res, 'mysqli_fetch_object_test'); + if (($obj->ID !== "2") || ($obj->label !== "b") || ($obj->a !== NULL) || ($obj->b !== NULL) || (get_class($obj) != 'mysqli_fetch_object_test')) { + printf("[005] Object seems wrong. [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump($obj); + } + + + + class mysqli_fetch_object_construct extends mysqli_fetch_object_test { + + public function __construct($a, $b) { + $this->a = $a; + $this->b = $b; + } + + } + + $obj = mysqli_fetch_object($res, 'mysqli_fetch_object_construct', array()); + + if (($obj->ID !== "3") || ($obj->label !== "c") || ($obj->a !== NULL) || ($obj->b !== NULL) || (get_class($obj) != 'mysqli_fetch_object_construct')) { + printf("[006] Object seems wrong. [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump($obj); + } + + $obj = mysqli_fetch_object($res, 'mysqli_fetch_object_construct', array('a')); + if (($obj->ID !== "4") || ($obj->label !== "d") || ($obj->a !== 'a') || ($obj->b !== NULL) || (get_class($obj) != 'mysqli_fetch_object_construct')) { + printf("[007] Object seems wrong. [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump($obj); + } + + $obj = mysqli_fetch_object($res, 'mysqli_fetch_object_construct', array('a', 'b')); + if (($obj->ID !== "5") || ($obj->label !== "e") || ($obj->a !== 'a') || ($obj->b !== 'b') || (get_class($obj) != 'mysqli_fetch_object_construct')) { + printf("[008] Object seems wrong. [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump($obj); + } + + var_dump(mysqli_fetch_object($res, 'mysqli_fetch_object_construct', array('a', 'b', 'c'))); + var_dump(mysqli_fetch_object($res)); + + mysqli_free_result($res); + + if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST")) { + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + mysqli_free_result($res); + var_dump(mysqli_fetch_object($res)); + + if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 5")) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + /* + TODO + I'm using the procedural interface, this should not throw an exception. + Also, I did not ask to get exceptions using the mysqli_options() + */ + try { + if (false !== ($obj = @mysqli_fetch_object($res, 'mysqli_fetch_object_construct', 'a'))) + printf("[011] Should have failed\n"); + } catch (Exception $e) { + printf("%s\n", $e->getMessage()); + } + + mysqli_free_result($res); + + if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 5")) + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + class mysqli_fetch_object_private_constructor extends mysqli_fetch_object_test { + + private function __construct($a, $b) { + $this->a = $a; + $this->b = $b; + } + } + /* + TODO + I think we should bail out here. The following line will give a Fatal error: Call to private ... from invalid context + var_dump($obj = new mysqli_fetch_object_private_constructor(1, 2)); + This does not fail. + */ + $obj = mysqli_fetch_object($res, 'mysqli_fetch_object_private_constructor', array('a', 'b')); + mysqli_free_result($res); + + // Fatal error, script execution will end + var_dump(mysqli_fetch_object($res, 'this_class_does_not_exist')); + + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +[E_WARNING] mysqli_fetch_object() expects at least 1 parameter, 0 given in %s on line %d +[E_WARNING] mysqli_fetch_object() expects parameter 1 to be mysqli_result, null given in %s on line %d +[E_WARNING] Missing argument 1 for mysqli_fetch_object_construct::__construct() in %s on line %d +[E_WARNING] Missing argument 2 for mysqli_fetch_object_construct::__construct() in %s on line %d +[E_NOTICE] Undefined variable: a in %s on line %d +[E_NOTICE] Undefined variable: b in %s on line %d +[E_WARNING] Missing argument 2 for mysqli_fetch_object_construct::__construct() in %s on line %d +[E_NOTICE] Undefined variable: b in %s on line %d +NULL +NULL +[E_WARNING] mysqli_fetch_object(): Couldn't fetch mysqli_result in %s on line %d +NULL +[E_RECOVERABLE_ERROR] Argument 3 passed to mysqli_fetch_object() must be of the type array, string given in %s on line %d +Parameter ctor_params must be an array + +Fatal error: Class 'this_class_does_not_exist' not found in %s on line %d
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_object_no_constructor.phpt b/ext/mysqli/tests/mysqli_fetch_object_no_constructor.phpt new file mode 100644 index 0000000..2fa80cf --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_object_no_constructor.phpt @@ -0,0 +1,65 @@ +--TEST-- +mysqli_fetch_object() - calling constructor on class wo constructor +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + require('table.inc'); + if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 5")) { + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + class mysqli_fetch_object_test { + + public $a = null; + public $b = null; + + public function toString() { + var_dump($this); + } + } + + printf("No exception with PHP:\n"); + var_dump($obj = new mysqli_fetch_object_test(1, 2)); + + printf("\nException with mysqli. Note that at all other places we throws errors but no exceptions unless the error mode has been changed:\n"); + try { + var_dump($obj = mysqli_fetch_object($res, 'mysqli_fetch_object_test', array(1, 2))); + } catch (Exception $e) { + printf("Exception: %s\n", $e->getMessage()); + } + + printf("\nFatal error with PHP (but no exception!):\n"); + var_dump($obj->mysqli_fetch_object_test(1, 2)); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +No exception with PHP: +object(mysqli_fetch_object_test)#%d (%d) { + [%u|b%"a"]=> + NULL + [%u|b%"b"]=> + NULL +} + +Exception with mysqli. Note that at all other places we throws errors but no exceptions unless the error mode has been changed: +Exception: Class mysqli_fetch_object_test does not have a constructor hence you cannot use ctor_params + +Fatal error with PHP (but no exception!): + +Fatal error: Call to undefined method mysqli_fetch_object_test::mysqli_fetch_object_test() in %s on line %d diff --git a/ext/mysqli/tests/mysqli_fetch_object_no_object.phpt b/ext/mysqli/tests/mysqli_fetch_object_no_object.phpt new file mode 100644 index 0000000..c8e2b85 --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_object_no_object.phpt @@ -0,0 +1,27 @@ +--TEST-- +mysqli_fetch_object() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require('table.inc'); + if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 5")) { + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + $obj = mysqli_fetch_object($res); + var_dump(gettype($obj)); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +%s(6) "object" +done! diff --git a/ext/mysqli/tests/mysqli_fetch_object_oo.phpt b/ext/mysqli/tests/mysqli_fetch_object_oo.phpt new file mode 100644 index 0000000..1d62c6d --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_object_oo.phpt @@ -0,0 +1,134 @@ +--TEST-- +mysqli_fetch_object() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + set_error_handler('handle_catchable_fatal'); + + $tmp = NULL; + $link = NULL; + + $mysqli = new mysqli(); + $res = @new mysqli_result($mysqli); + if (!is_null($tmp = @$res->fetch_object())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!$res = $mysqli->query("SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 5")) { + printf("[003] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + if (!is_null($tmp = @$res->fetch_object($link))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @$res->fetch_object($link, $link))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @$res->fetch_object($link, $link, $link))) + printf("[006] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + $obj = mysqli_fetch_object($res); + if (($obj->ID !== "1") || ($obj->label !== "a") || (get_class($obj) != 'stdClass')) { + printf("[007] Object seems wrong. [%d] %s\n", $mysqli->errno, $mysqli->error); + var_dump($obj); + } + + class mysqli_fetch_object_test { + + public $a = null; + public $b = null; + + public function toString() { + var_dump($this); + } + } + + $obj = $res->fetch_object('mysqli_fetch_object_test'); + if (($obj->ID !== "2") || ($obj->label !== "b") || ($obj->a !== NULL) || ($obj->b !== NULL) || (get_class($obj) != 'mysqli_fetch_object_test')) { + printf("[008] Object seems wrong. [%d] %s\n", $mysqli->errno, $mysqli->error); + var_dump($obj); + } + + class mysqli_fetch_object_construct extends mysqli_fetch_object_test { + + public function __construct($a, $b) { + $this->a = $a; + $this->b = $b; + } + + } + + $obj = $res->fetch_object('mysqli_fetch_object_construct', null); + + if (($obj->ID !== "3") || ($obj->label !== "c") || ($obj->a !== NULL) || ($obj->b !== NULL) || (get_class($obj) != 'mysqli_fetch_object_construct')) { + printf("[009] Object seems wrong. [%d] %s\n", $mysqli->errno, $mysqli->error); + var_dump($obj); + } + + $obj = $res->fetch_object('mysqli_fetch_object_construct', array('a')); + if (($obj->ID !== "4") || ($obj->label !== "d") || ($obj->a !== 'a') || ($obj->b !== NULL) || (get_class($obj) != 'mysqli_fetch_object_construct')) { + printf("[010] Object seems wrong. [%d] %s\n", $mysqli->errno, $mysqli->error); + var_dump($obj); + } + + $obj = $res->fetch_object('mysqli_fetch_object_construct', array('a', 'b')); + if (($obj->ID !== "5") || ($obj->label !== "e") || ($obj->a !== 'a') || ($obj->b !== 'b') || (get_class($obj) != 'mysqli_fetch_object_construct')) { + printf("[011] Object seems wrong. [%d] %s\n", $mysqli->errno, $mysqli->error); + var_dump($obj); + } + + var_dump($res->fetch_object('mysqli_fetch_object_construct', array('a', 'b', 'c'))); + var_dump(mysqli_fetch_object($res)); + + mysqli_free_result($res); + + if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST")) { + printf("[012] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + mysqli_free_result($res); + + var_dump(mysqli_fetch_object($res)); + + // Fatal error, script execution will end + var_dump($res->fetch_object('this_class_does_not_exist')); + + $mysqli->close(); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +[E_WARNING] mysqli_result::__construct(): invalid object or resource mysql%s +%s on line %d +[E_WARNING] mysqli_result::fetch_object(): Couldn't fetch mysqli_result in %s on line %d +[E_WARNING] mysqli_result::fetch_object() expects parameter 1 to be string, object given in %s on line %d +[E_RECOVERABLE_ERROR] Argument 2 passed to mysqli_result::fetch_object() must be of the type array, object given in %s on line %d +[E_WARNING] mysqli_result::fetch_object() expects parameter 1 to be string, object given in %s on line %d +[E_RECOVERABLE_ERROR] Argument 2 passed to mysqli_result::fetch_object() must be of the type array, object given in %s on line %d +[E_WARNING] mysqli_result::fetch_object() expects at most 2 parameters, 3 given in %s on line %d +[E_RECOVERABLE_ERROR] Argument 2 passed to mysqli_result::fetch_object() must be of the type array, null given in %s on line %d +[E_WARNING] Missing argument 1 for mysqli_fetch_object_construct::__construct() in %s on line %d +[E_WARNING] Missing argument 2 for mysqli_fetch_object_construct::__construct() in %s on line %d +[E_NOTICE] Undefined variable: a in %s on line %d +[E_NOTICE] Undefined variable: b in %s on line %d +[E_WARNING] Missing argument 2 for mysqli_fetch_object_construct::__construct() in %s on line %d +[E_NOTICE] Undefined variable: b in %s on line %d +NULL +NULL +[E_WARNING] mysqli_fetch_object(): Couldn't fetch mysqli_result in %s on line %d +NULL + +Fatal error: Class 'this_class_does_not_exist' not found in %s on line %d
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_row.phpt b/ext/mysqli/tests/mysqli_fetch_row.phpt new file mode 100644 index 0000000..e0359e0 --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_row.phpt @@ -0,0 +1,59 @@ +--TEST-- +mysqli_fetch_row() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_fetch_row())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_fetch_row($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + if (!$res = mysqli_query($link, "SELECT id, label, id AS _id FROM test ORDER BY id LIMIT 1")) { + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + print "[004]\n"; + var_dump(mysqli_fetch_row($res)); + + print "[005]\n"; + var_dump(mysqli_fetch_row($res)); + + mysqli_free_result($res); + + var_dump(mysqli_fetch_row($res)); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +[004] +array(3) { + [0]=> + %unicode|string%(1) "1" + [1]=> + %unicode|string%(1) "a" + [2]=> + %unicode|string%(1) "1" +} +[005] +NULL + +Warning: mysqli_fetch_row(): Couldn't fetch mysqli_result in %s on line %d +NULL +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_field_count.phpt b/ext/mysqli/tests/mysqli_field_count.phpt new file mode 100644 index 0000000..9a778c9 --- /dev/null +++ b/ext/mysqli/tests/mysqli_field_count.phpt @@ -0,0 +1,63 @@ +--TEST-- +mysqli_field_count() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_field_count())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_field_count($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + var_dump(mysqli_field_count($link)); + + if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id LIMIT 1")) { + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + var_dump(mysqli_field_count($link)); + + mysqli_free_result($res); + + if (!mysqli_query($link, "INSERT INTO test(id, label) VALUES (100, 'x')")) + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump($link->field_count); + var_dump(mysqli_field_count($link)); + + if (!$res = mysqli_query($link, "SELECT NULL as _null, '' AS '', 'three' AS 'drei'")) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump(mysqli_field_count($link)); + mysqli_free_result($res); + + mysqli_close($link); + + var_dump(mysqli_field_count($link)); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +int(0) +int(2) +int(0) +int(0) +int(3) + +Warning: mysqli_field_count(): Couldn't fetch mysqli in %s on line %d +NULL +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_field_seek.phpt b/ext/mysqli/tests/mysqli_field_seek.phpt new file mode 100644 index 0000000..a747bdf --- /dev/null +++ b/ext/mysqli/tests/mysqli_field_seek.phpt @@ -0,0 +1,251 @@ +--TEST-- +mysqli_field_seek() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + function mysqli_field_seek_flags($flags) { + + $ret = ''; + + if ($flags & MYSQLI_NOT_NULL_FLAG) + $ret .= 'MYSQLI_NOT_NULL_FLAG '; + + if ($flags & MYSQLI_PRI_KEY_FLAG) + $ret .= 'MYSQLI_PRI_KEY_FLAG '; + + if ($flags & MYSQLI_UNIQUE_KEY_FLAG) + $ret .= 'MYSQLI_UNIQUE_KEY_FLAG '; + + if ($flags & MYSQLI_MULTIPLE_KEY_FLAG) + $ret .= 'MYSQLI_MULTIPLE_KEY_FLAG '; + + if ($flags & MYSQLI_BLOB_FLAG) + $ret .= 'MYSQLI_BLOB_FLAG '; + + if ($flags & MYSQLI_UNSIGNED_FLAG) + $ret .= 'MYSQLI_UNSIGNED_FLAG '; + + if ($flags & MYSQLI_ZEROFILL_FLAG) + $ret .= 'MYSQLI_ZEROFILL_FLAG '; + + if ($flags & MYSQLI_AUTO_INCREMENT_FLAG) + $ret .= 'MYSQLI_AUTO_INCREMENT_FLAG '; + + if ($flags & MYSQLI_TIMESTAMP_FLAG) + $ret .= 'MYSQLI_TIMESTAMP_FLAG '; + + if ($flags & MYSQLI_SET_FLAG) + $ret .= 'MYSQLI_SET_FLAG '; + + if ($flags & MYSQLI_NUM_FLAG) + $ret .= 'MYSQLI_NUM_FLAG '; + + if ($flags & MYSQLI_PART_KEY_FLAG) + $ret .= 'MYSQLI_PART_KEY_FLAG '; + + if ($flags & MYSQLI_GROUP_FLAG) + $ret .= 'MYSQLI_GROUP_FLAG '; + + return $ret; + } + + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_field_seek())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_field_seek($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + $charsets = my_get_charsets($link); + + if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 1", MYSQLI_USE_RESULT)) { + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + var_dump(mysqli_field_seek($res, -1)); + var_dump(mysqli_fetch_field($res)); + var_dump(mysqli_field_seek($res, 0)); + var_dump(mysqli_fetch_field($res)); + var_dump(mysqli_field_seek($res, 1)); + + $field = mysqli_fetch_field($res); + var_dump($field); + /* label column, result set charset */ + if ($field->charsetnr != $charsets['results']['nr']) { + printf("[004] Expecting charset %s/%d got %d\n", + $charsets['results']['charset'], + $charsets['results']['nr'], $field->charsetnr); + } + if ($field->length != (1 * $charsets['results']['maxlen'])) { + printf("[005] Expecting length %d got %d\n", + $charsets['results']['maxlen'], + $field->max_length); + } + + var_dump(mysqli_field_tell($res)); + var_dump(mysqli_field_seek($res, 2)); + var_dump(mysqli_fetch_field($res)); + var_dump(mysqli_field_seek($res, PHP_INT_MAX + 1)); + + if (!is_null($tmp = @mysqli_field_seek($res, 0, "too many"))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_free_result($res); + + if (!$res = mysqli_query($link, "SELECT NULL as _null", MYSQLI_STORE_RESULT)) { + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + var_dump(mysqli_field_seek($res, 0)); + var_dump(mysqli_fetch_field($res)); + + mysqli_free_result($res); + + var_dump(mysqli_field_seek($res, 0)); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_field_seek(): Invalid field offset in %s on line %d +bool(false) +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(2) "id" + [%u|b%"orgname"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"orgtable"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(0) + [%u|b%"length"]=> + int(11) + [%u|b%"charsetnr"]=> + int(63) + [%u|b%"flags"]=> + int(49155) + [%u|b%"type"]=> + int(3) + [%u|b%"decimals"]=> + int(0) +} +bool(true) +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(2) "id" + [%u|b%"orgname"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"orgtable"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(0) + [%u|b%"length"]=> + int(11) + [%u|b%"charsetnr"]=> + int(63) + [%u|b%"flags"]=> + int(49155) + [%u|b%"type"]=> + int(3) + [%u|b%"decimals"]=> + int(0) +} +bool(true) +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(5) "label" + [%u|b%"orgname"]=> + %unicode|string%(5) "label" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"orgtable"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(%d) + [%u|b%"length"]=> + int(%d) + [%u|b%"charsetnr"]=> + int(%d) + [%u|b%"flags"]=> + int(0) + [%u|b%"type"]=> + int(254) + [%u|b%"decimals"]=> + int(0) +} +int(2) + +Warning: mysqli_field_seek(): Invalid field offset in %s on line %d +bool(false) +bool(false) + +Warning: mysqli_field_seek(): Invalid field offset in %s on line %d +bool(false) +bool(true) +object(stdClass)#3 (13) { + [%u|b%"name"]=> + %unicode|string%(5) "_null" + [%u|b%"orgname"]=> + %unicode|string%(0) "" + [%u|b%"table"]=> + %unicode|string%(0) "" + [%u|b%"orgtable"]=> + %unicode|string%(0) "" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(0) "" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(0) + [%u|b%"length"]=> + int(0) + [%u|b%"charsetnr"]=> + int(63) + [%u|b%"flags"]=> + int(32896) + [%u|b%"type"]=> + int(6) + [%u|b%"decimals"]=> + int(0) +} + +Warning: mysqli_field_seek(): Couldn't fetch mysqli_result in %s on line %d +NULL +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_field_tell.phpt b/ext/mysqli/tests/mysqli_field_tell.phpt new file mode 100644 index 0000000..cac2001 --- /dev/null +++ b/ext/mysqli/tests/mysqli_field_tell.phpt @@ -0,0 +1,110 @@ +--TEST-- +mysqli_field_tell() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_field_tell())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_field_tell($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + if (!$res = mysqli_query($link, "SELECT id FROM test ORDER BY id LIMIT 1", MYSQLI_USE_RESULT)) { + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + var_dump(mysqli_field_tell($res)); + var_dump(mysqli_field_seek(1)); + var_dump(mysqli_field_tell($res)); + var_dump(mysqli_fetch_field($res)); + var_dump(mysqli_fetch_field($res)); + var_dump(mysqli_field_tell($res)); + + if (!is_null($tmp = @mysqli_field_tell($res, 'too many arguments'))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + + var_dump(mysqli_field_seek($res, 2)); + var_dump(mysqli_field_tell($res)); + + var_dump(mysqli_field_seek($res, -1)); + var_dump(mysqli_field_tell($res)); + + var_dump(mysqli_field_seek($res, 0)); + var_dump(mysqli_field_tell($res)); + + + + mysqli_free_result($res); + + var_dump(mysqli_field_tell($res)); + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +int(0) + +Warning: mysqli_field_seek() expects exactly 2 parameters, 1 given in %s on line %d +NULL +int(0) +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(2) "id" + [%u|b%"orgname"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"orgtable"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(0) + [%u|b%"length"]=> + int(11) + [%u|b%"charsetnr"]=> + int(63) + [%u|b%"flags"]=> + int(49155) + [%u|b%"type"]=> + int(3) + [%u|b%"decimals"]=> + int(0) +} +bool(false) +int(1) + +Warning: mysqli_field_seek(): Invalid field offset in %s on line %d +bool(false) +int(1) + +Warning: mysqli_field_seek(): Invalid field offset in %s on line %d +bool(false) +int(1) +bool(true) +int(0) + +Warning: mysqli_field_tell(): Couldn't fetch mysqli_result in %s on line %d +NULL +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fork.phpt b/ext/mysqli/tests/mysqli_fork.phpt new file mode 100644 index 0000000..f5a0b7b --- /dev/null +++ b/ext/mysqli/tests/mysqli_fork.phpt @@ -0,0 +1,252 @@ +--TEST-- +Forking a child and using the same connection. +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('pcntl_fork')) + die("skip Process Control Functions not available"); + +if (!function_exists('posix_getpid')) + die("skip POSIX functions not available"); + +require_once('connect.inc'); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die(sprintf("Cannot connect, [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); + +if (!have_innodb($link)) + die(sprintf("Needs InnoDB support, [%d] %s", $link->errno, $link->error)); +?> +--FILE-- +<?php + require_once("table.inc"); + + $res = mysqli_query($link, "SELECT 'dumped by the parent' AS message"); + $pid = pcntl_fork(); + switch ($pid) { + case -1: + printf("[001] Cannot fork child"); + break; + + case 0: + /* child */ + exit(0); + break; + + default: + /* parent */ + $status = null; + $wait_id = pcntl_waitpid($pid, $status); + if (pcntl_wifexited($status) && (0 != ($tmp = pcntl_wexitstatus($status)))) { + printf("Exit code: %s\n", (pcntl_wifexited($status)) ? pcntl_wexitstatus($status) : 'n/a'); + printf("Signal: %s\n", (pcntl_wifsignaled($status)) ? pcntl_wtermsig($status) : 'n/a'); + printf("Stopped: %d\n", (pcntl_wifstopped($status)) ? pcntl_wstopsig($status) : 'n/a'); + } + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + break; + } + + if (@mysqli_query($link, "SELECT id FROM test WHERE id = 1")) + printf("[003] Expecting error and closed connection, child exit should have closed connection\n"); + else if ((($errno = mysqli_errno($link)) == 0) || ('' == ($error = mysqli_error($link)))) + printf("[004] Expecting error string and error code from MySQL, got errno = %s/%s, error = %s/%s\n", + gettype($errno), $errno, gettype($error), $error); + + mysqli_close($link); + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[005] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + /* non trivial tests require a message list for parent-child communication */ + if (!mysqli_query($link, "DROP TABLE IF EXISTS messages")) + printf("[006] [%d] %s\n", mysqli_error($link), mysqli_errno($link)); + + if (!mysqli_query($link, "CREATE TABLE messages( + msg_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + msg_time TIMESTAMP, + pid INT NOT NULL, + sender ENUM('child', 'parent') NOT NULL, + msg TEXT) ENGINE = InnoDB")) + printf("[007] [%d] %s\n", mysqli_error($link), mysqli_errno($link)); + + mysqli_autocommit($link, false); + if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id ASC LIMIT 3", MYSQLI_USE_RESULT)) + printf("[008] [%d] %s\n", mysqli_error($link), mysqli_errno($link)); + + $pid = pcntl_fork(); + + switch ($pid) { + case -1: + printf("[009] Cannot fork child"); + break; + + case 0: + /* child */ + if (!($plink = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) || !mysqli_autocommit($plink, true)) + exit(mysqli_errno($plink)); + + $sql = sprintf("INSERT INTO messages(pid, sender, msg) VALUES (%d, 'child', '%%s')", posix_getpid()); + if (!mysqli_query($plink, sprintf($sql, 'start'))) + exit(mysqli_errno($plink)); + + $parent_sql = sprintf("SELECT msg_id, msg_time, msg FROM messages WHERE pid = %d AND sender = 'parent' ORDER BY msg_id DESC LIMIT 1", posix_getppid()); + $msg_id = 0; + while ($row = mysqli_fetch_assoc($res)) { + /* send row to parent */ + ob_start(); + var_dump($row); + $tmp = ob_get_contents(); + ob_end_clean(); + if (!mysqli_query($plink, sprintf($sql, $tmp))) + exit(mysqli_errno($plink)); + + /* let the parent reply... */ + $start = time(); + do { + usleep(100); + if (!$pres = mysqli_query($plink, $parent_sql)) + continue; + $tmp = mysqli_fetch_assoc($pres); + mysqli_free_result($pres); + if ($tmp['msg_id'] == $msg_id) + /* no new message */ + continue; + if ($tmp['msg'] == 'stop') + break 2; + $msg_id = $tmp['msg_id']; + break; + } while ((time() - $start) < 5); + + } + + if (!mysqli_query($plink, sprintf($sql, 'stop')) || !mysqli_commit($link)) + exit(mysqli_errno($plink)); + exit(0); + break; + + default: + /* parent */ + if (!$plink = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[010] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + $status = null; + $start = time(); + $sql = sprintf("SELECT msg_id, msg_time, msg FROM messages WHERE pid = %d AND sender = 'child' ORDER BY msg_id DESC LIMIT 1", $pid); + $parent_sql = sprintf("INSERT INTO messages (pid, sender, msg) VALUES (%d, 'parent', '%%s')", posix_getpid()); + $last_msg_id = 0; + $num_rows = 0; + do { + $wait_id = pcntl_waitpid($pid, $status, WNOHANG); + if ($pres = mysqli_query($plink, $sql)) { + $row = mysqli_fetch_assoc($pres); + if ($row['msg_id'] != $last_msg_id) { + $last_msg_id = $row['msg_id']; + switch ($row['msg']) { + case 'start': + break; + case 'stop': + break 2; + default: + /* client has started fetching rows */ + $client_row = $row['msg']; + + $num_rows++; + if ($num_rows > 3) { + printf("[011] Child has fetched more than three rows!\n"); + var_dump($client_row); + if (!mysqli_query($plink, sprintf($parent_sql, 'stop'))) { + printf("[012] Parent cannot inform child\n", mysqli_errno($plink), mysqli_error($plink)); + } + break 2; + } + + if (!$parent_row = mysqli_fetch_assoc($res)) { + printf("[013] Parent cannot fetch row %d\n", $num_rows, mysqli_errno($link), mysqli_error($link)); + if (!mysqli_query($plink, sprintf($parent_sql, 'stop'))) { + printf("[014] Parent cannot inform child\n", mysqli_errno($plink), mysqli_error($plink)); + } + break 2; + } + + ob_start(); + var_dump($parent_row); + $parent_row = ob_get_contents(); + ob_end_clean(); + + if ($parent_row != $client_row) { + printf("[015] Child indicates different results than parent.\n"); + var_dump($child_row); + var_dump($parent_row); + if (!mysqli_query($plink, sprintf($parent_sql, 'stop'))) { + printf("[016] Parent cannot inform child\n", mysqli_errno($plink), mysqli_error($plink)); + } + break 2; + } + + if (!mysqli_query($plink, sprintf($parent_sql, 'continue'))) { + printf("[017] Parent cannot inform child to continue.\n", mysqli_errno($plink), mysqli_error($plink)); + } + break; + } + } + mysqli_free_result($pres); + } + usleep(100); + } while (((time() - $start) < 5) && ($num_rows < 3)); + mysqli_close($plink); + $wait_id = pcntl_waitpid($pid, $status); + if (pcntl_wifexited($status) && (0 != ($tmp = pcntl_wexitstatus($status)))) { + printf("Exit code: %s\n", (pcntl_wifexited($status)) ? pcntl_wexitstatus($status) : 'n/a'); + printf("Signal: %s\n", (pcntl_wifsignaled($status)) ? pcntl_wtermsig($status) : 'n/a'); + printf("Stopped: %d\n", (pcntl_wifstopped($status)) ? pcntl_wstopsig($status) : 'n/a'); + } + break; + } + mysqli_free_result($res); + mysqli_close($link); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[018] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!$res = mysqli_query($link, "SELECT sender, msg FROM messages ORDER BY msg_id ASC")) + printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + while ($row = mysqli_fetch_assoc($res)) + printf("%10s %s\n", $row['sender'], substr($row['msg'], 0, 5)); + mysqli_free_result($res); + + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS messages")) + printf("[c003] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +array(1) { + ["message"]=> + string(20) "dumped by the parent" +} + child start + child array + parent conti + child array + parent conti + child array + parent conti + child stop +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_free_result.phpt b/ext/mysqli/tests/mysqli_free_result.phpt new file mode 100644 index 0000000..28f338a --- /dev/null +++ b/ext/mysqli/tests/mysqli_free_result.phpt @@ -0,0 +1,78 @@ +--TEST-- +mysqli_free_result() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_free_result())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_free_result($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + if (!$res = mysqli_query($link, "SELECT id FROM test ORDER BY id LIMIT 1")) { + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + print "a\n"; + var_dump(mysqli_free_result($res)); + print "b\n"; + var_dump(mysqli_free_result($res)); + + if (!$res = mysqli_query($link, "SELECT id FROM test ORDER BY id LIMIT 1")) { + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + print "c\n"; + var_dump($res = mysqli_store_result($link)); + var_dump(mysqli_error($link)); + print "[005]\n"; + var_dump(mysqli_free_result($res)); + + if (!$res = mysqli_query($link, "SELECT id FROM test ORDER BY id LIMIT 1")) { + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + print "d\n"; + var_dump($res = mysqli_use_result($link)); + var_dump(mysqli_error($link)); + print "[007]\n"; + var_dump(mysqli_free_result($res)); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +a +NULL +b + +Warning: mysqli_free_result(): Couldn't fetch mysqli_result in %s on line %d +NULL +c +bool(false) +%s(0) "" +[005] + +Warning: mysqli_free_result() expects parameter 1 to be mysqli_result, boolean given in %s on line %d +NULL +d +bool(false) +%s(0) "" +[007] + +Warning: mysqli_free_result() expects parameter 1 to be mysqli_result, boolean given in %s on line %d +NULL +done! diff --git a/ext/mysqli/tests/mysqli_get_charset.phpt b/ext/mysqli/tests/mysqli_get_charset.phpt new file mode 100644 index 0000000..8f81b33 --- /dev/null +++ b/ext/mysqli/tests/mysqli_get_charset.phpt @@ -0,0 +1,115 @@ +--TEST-- +mysqli_get_charset() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +if (!function_exists('mysqli_get_charset')) + die("skip: function not available"); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_get_charset())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_get_charset($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_set_charset($link, $link))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$res = mysqli_query($link, 'SELECT version() AS server_version')) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + mysqli_free_result($res); + $version = explode('.', $tmp['server_version']); + if (empty($version)) + printf("[005] Cannot determine server version, need MySQL Server 4.1+ for the test!\n"); + + if ($version[0] <= 4 && $version[1] < 1) + printf("[006] Need MySQL Server 4.1+ for the test!\n"); + + if (!$res = mysqli_query($link, 'SELECT @@character_set_connection AS charset, @@collation_connection AS collation')) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + mysqli_free_result($res); + if (!($character_set_connection = $tmp['charset']) || !($collation_connection = $tmp['collation'])) + printf("[008] Cannot determine current character set and collation\n"); + + if (!$res = mysqli_query($link, $sql = sprintf("SHOW CHARACTER SET LIKE '%s'", $character_set_connection))) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + if (empty($tmp)) + printf("[010] Cannot fetch Maxlen and/or Comment, test will fail: $sql\n"); + + $maxlen = (isset($tmp['Maxlen'])) ? $tmp['Maxlen'] : ''; + $comment = (isset($tmp['Description'])) ? $tmp['Description'] : ''; + + if (!$res = mysqli_query($link, sprintf("SHOW COLLATION LIKE '%s'", $collation_connection))) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + mysqli_free_result($res); + if (!($id = $tmp['Id'])) + printf("[012] Cannot fetch Id/Number, test will fail\n"); + + if (!$res = mysqli_query($link, sprintf("SHOW VARIABLES LIKE 'character_sets_dir'"))) + printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + mysqli_free_result($res); + if (!($character_sets_dir = $tmp['Value'])) + printf("[014] Cannot fetch character_sets_dir, test will fail\n"); + + if (!is_object($charset = mysqli_get_charset($link))) + printf("[015] Expecting object/std_class, got %s/%s\n", gettype($charset), $charset); + + if (!isset($charset->charset) || + !in_array(gettype($charset->charset), array("string", "unicode")) || + ($character_set_connection !== $charset->charset)) + printf("[016] Expecting string/%s, got %s/%s\n", $character_set_connection, gettype($charset->charset), $charset->charset); + if (!isset($charset->collation) || + !in_array(gettype($charset->collation), array("string", "unicode")) || + ($collation_connection !== $charset->collation)) + printf("[017] Expecting string/%s, got %s/%s\n", $collation_connection, gettype($charset->collation), $charset->collation); + + if (!isset($charset->dir) || + !is_string($charset->dir)) + printf("[019] Expecting string - ideally %s*, got %s/%s\n", $character_sets_dir, gettype($charset->dir), $charset->dir); + + if (!isset($charset->min_length) || + !(is_int($charset->min_length)) || + ($charset->min_length < 0) || + ($charset->min_length > $charset->max_length)) + printf("[020] Expecting int between 0 ... %d, got %s/%s\n", $charset->max_length, + gettype($charset->min_length), $charset->min_length); + + if (!isset($charset->number) || + !is_int($charset->number) || + ($charset->number !== (int)$id)) + printf("[021] Expecting int/%d, got %s/%s\n", $id, gettype($charset->number), $charset->number); + + if (!isset($charset->state) || + !is_int($charset->state)) + printf("[022] Expecting int/any, got %s/%s\n", gettype($charset->state), $charset->state); + + mysqli_close($link); + + if (NULL !== ($tmp = mysqli_get_charset($link))) + printf("[023] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_get_charset(): Couldn't fetch mysqli in %s on line %d +done! diff --git a/ext/mysqli/tests/mysqli_get_client_info.phpt b/ext/mysqli/tests/mysqli_get_client_info.phpt new file mode 100644 index 0000000..bb3f5cc --- /dev/null +++ b/ext/mysqli/tests/mysqli_get_client_info.phpt @@ -0,0 +1,18 @@ +--TEST-- +mysqli_get_client_info() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + if (!is_string($info = mysqli_get_client_info()) || ('' === $info)) + printf("[001] Expecting string/any_non_empty, got %s/%s\n", gettype($info), $info); + + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_get_client_stats.phpt b/ext/mysqli/tests/mysqli_get_client_stats.phpt new file mode 100644 index 0000000..ef5ef6e --- /dev/null +++ b/ext/mysqli/tests/mysqli_get_client_stats.phpt @@ -0,0 +1,1294 @@ +--TEST-- +mysqli_get_client_stats() +--SKIPIF-- +<?PHP +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +if (!function_exists('mysqli_get_client_stats')) { + die("skip only available with mysqlnd"); +} +?> +--INI-- +mysqlnd.collect_statistics=1 +mysqlnd.collect_memory_statistics=1 +--FILE-- +<?php + /* + TODO + no_index_used - difficult to simulate because server/engine dependent + bad_index_used - difficult to simulate because server/engine dependent + flushed_normal_sets + flushed_ps_sets + explicit_close + implicit_close + disconnect_close + in_middle_of_command_close + explicit_free_result + implicit_free_result + explicit_stmt_close + implicit_stmt_close + */ + + function mysqli_get_client_stats_assert_eq($field, $current, $expected, &$test_counter, $desc = "") { + + $test_counter++; + if (is_array($current) && is_array($expected)) { + if ($current[$field] !== $expected[$field]) { + printf("[%03d] %s Expecting %s = %s/%s, got %s/%s\n", + $test_counter, $desc, + $field, $expected[$field], gettype($expected[$field]), + $current[$field], gettype($current[$field])); + } + } else if (is_array($current)) { + if ($current[$field] !== $expected) { + printf("[%03d] %s Expecting %s = %s/%s, got %s/%s\n", + $test_counter, $desc, + $field, $expected, gettype($expected), + $current[$field], gettype($current[$field])); + } + } else { + if ($current !== $expected) { + printf("[%03d] %s Expecting %s = %s/%s, got %s/%s\n", + $test_counter, $desc, + $field, $expected, gettype($expected), + $current, gettype($current)); + } + } + + } + + function mysqli_get_client_stats_assert_gt($field, $current, $expected, &$test_counter, $desc = "") { + + $test_counter++; + if (is_array($current) && is_array($expected)) { + if ($current[$field] <= $expected[$field]) { + printf("[%03d] %s Expecting %s > %s/%s, got %s/%s\n", + $test_counter, $desc, + $field, $expected[$field], gettype($expected[$field]), + $current[$field], gettype($current[$field])); + } + } else { + if ($current <= $expected) { + printf("[%03d] %s Expecting %s > %s/%s, got %s/%s\n", + $test_counter, $desc, $field, + $expected, gettype($expected), + $current, gettype($current)); + } + } + + } + + + $tmp = $link = null; + if (!is_null($tmp = @mysqli_get_client_stats($link))) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require_once("connect.inc"); + + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[002] Expecting array/any_non_empty, got %s/%s\n", gettype($info), $info); + + var_dump($info); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + exit(1); + } + + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[004] Expecting array/any_non_empty, got %s/%s\n", gettype($new_info), $new_info); + + if (count($info) != count($new_info)) { + printf("[005] Expecting the same number of entries in the arrays\n"); + var_dump($info); + var_dump($new_info); + } + + $test_counter = 6; + + mysqli_get_client_stats_assert_gt('bytes_sent', $new_info, $info, $test_counter); + mysqli_get_client_stats_assert_gt('bytes_received', $new_info, $info, $test_counter); + mysqli_get_client_stats_assert_gt('packets_sent', $new_info, $info, $test_counter); + mysqli_get_client_stats_assert_gt('packets_received', $new_info, $info, $test_counter); + mysqli_get_client_stats_assert_gt('protocol_overhead_in', $new_info, $info, $test_counter); + mysqli_get_client_stats_assert_gt('protocol_overhead_out', $new_info, $info, $test_counter); + + // we assume the above as tested and in the following we check only those + mysqli_get_client_stats_assert_eq('result_set_queries', $new_info, $info, $test_counter); + + /* we need to skip this test in unicode - we send set names utf8 during mysql_connect */ + if (!(version_compare(PHP_VERSION, '5.9.9', '>') == 1)) + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, $info, $test_counter); + mysqli_get_client_stats_assert_eq('buffered_sets', $new_info, $info, $test_counter); + mysqli_get_client_stats_assert_eq('unbuffered_sets', $new_info, $info, $test_counter); + mysqli_get_client_stats_assert_eq('ps_buffered_sets', $new_info, $info, $test_counter); + mysqli_get_client_stats_assert_eq('ps_unbuffered_sets', $new_info, $info, $test_counter); + + mysqli_get_client_stats_assert_eq('rows_skipped_ps', $new_info, $info, $test_counter); + mysqli_get_client_stats_assert_eq('copy_on_write_saved', $new_info, $info, $test_counter); + mysqli_get_client_stats_assert_eq('copy_on_write_performed', $new_info, $info, $test_counter); + mysqli_get_client_stats_assert_eq('command_buffer_too_small', $new_info, $info, $test_counter); + // This is not a mistake that I use %unicode|string%(1) "1" here! Andrey did not go for int to avoid any + // issues for very large numbers and 32 vs. 64bit systems + mysqli_get_client_stats_assert_eq('connect_success', $new_info, "1", $test_counter); + mysqli_get_client_stats_assert_eq('connect_failure', $new_info, $info, $test_counter); + mysqli_get_client_stats_assert_eq('connection_reused', $new_info, $info, $test_counter); + + // No data fetched so far + mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $new_info, "0", $test_counter); + mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $new_info, "0", $test_counter); + + require('table.inc'); + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($info), $info); + + // fetch stats + $expected = $info; + + // buffered normal + print "Testing buffered normal...\n"; + if (!$res = mysqli_query($link, 'SELECT COUNT(*) AS _num FROM test', MYSQLI_STORE_RESULT)) + printf("[%03d] SELECT COUNT() FROM test failed, [%d] %s\n", + ++$test_counter, mysqli_errno($link), mysqli_error($link)); + + $expected['rows_fetched_from_server_normal'] = (string)($expected['rows_fetched_from_server_normal'] + 1); + $expected['buffered_sets'] = (string)($expected['buffered_sets'] + 1); + $expected['result_set_queries'] = (string)($expected['result_set_queries'] + 1); + $expected['rows_buffered_from_client_normal'] = (string)($expected['rows_buffered_from_client_normal'] + 1); + + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($info), $info); + + mysqli_get_client_stats_assert_gt('bytes_sent', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_gt('bytes_received', $info, $expected, $test_counter); + + // real_data_* get incremeneted after mysqli_*fetch*() + mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, "0", $test_counter); + mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $info, "0", $test_counter); + + mysqli_get_client_stats_assert_eq('rows_fetched_from_server_normal', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_fetched_from_client_normal_buffered', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('buffered_sets', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('result_set_queries', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_buffered_from_client_normal', $info, $expected, $test_counter); + + /* no change to rows_fetched_from_client_normal_buffered! */ + if (!$row = mysqli_fetch_assoc($res)) + printf("[%03d] fetch_assoc - SELECT COUNT() FROM test failed, [%d] %s\n", + ++$test_counter, mysqli_errno($link), mysqli_error($link)); + + $expected['rows_fetched_from_client_normal_buffered'] = (string)($expected['rows_fetched_from_client_normal_buffered'] + 1); + + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($info), $info); + + // fetch will increment + mysqli_get_client_stats_assert_gt('bytes_received_real_data_normal', $info, $expected, $test_counter); + $expected['bytes_received_real_data_normal'] = $info['bytes_received_real_data_normal']; + mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $info, "0", $test_counter); + + mysqli_get_client_stats_assert_eq('rows_fetched_from_server_normal', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_fetched_from_client_normal_buffered', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_buffered_from_client_normal', $info, $expected, $test_counter); + + $num_rows = $row['_num']; + mysqli_free_result($res); + + print "Testing buffered normal... - SELECT id, label FROM test\n"; + if (!$res = mysqli_query($link, 'SELECT id, label FROM test', MYSQLI_STORE_RESULT)) + printf("[%03d] SELECT id, label FROM test failed, [%d] %s\n", + ++$test_counter, mysqli_errno($link), mysqli_error($link)); + + + assert(mysqli_num_rows($res) == $num_rows); + + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($info), $info); + + + $expected['rows_fetched_from_server_normal'] = (string)($expected['rows_fetched_from_server_normal'] + $num_rows); + $expected['rows_buffered_from_client_normal'] = (string)($expected['rows_buffered_from_client_normal'] + $num_rows); + $expected['buffered_sets'] = (string)($expected['buffered_sets'] + 1); + $expected['result_set_queries'] = (string)($expected['result_set_queries'] + 1); + + mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, $expected, $test_counter); + + mysqli_get_client_stats_assert_eq('rows_fetched_from_server_normal', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_fetched_from_client_normal_buffered', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('buffered_sets', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('result_set_queries', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_buffered_from_client_normal', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_buffered_from_client_normal', $info, $expected, $test_counter); + + /* fetching none, but stats should not be affected - current implementation */ + mysqli_free_result($res); + + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($info), $info); + + + mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_fetched_from_server_normal', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_fetched_from_client_normal_buffered', $info, $expected, $test_counter); + + print "Testing unbuffered normal...\n"; + if (!$res = mysqli_query($link, 'SELECT id, label FROM test', MYSQLI_USE_RESULT)) + printf("[%03d] SELECT id, label FROM test failed, [%d] %s\n", + ++$test_counter, mysqli_errno($link), mysqli_error($link)); + + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($info), $info); + + mysqli_get_client_stats_assert_eq('rows_fetched_from_server_normal', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_fetched_from_client_normal_unbuffered', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, $expected, $test_counter); + + while ($row = mysqli_fetch_assoc($res)) + ; + mysqli_free_result($res); + + $expected['rows_fetched_from_server_normal'] = (string)($expected['rows_fetched_from_server_normal'] + $num_rows); + $expected['rows_fetched_from_client_normal_unbuffered'] = (string)($expected['rows_fetched_from_client_normal_unbuffered'] + $num_rows); + $expected['unbuffered_sets'] = (string)($expected['unbuffered_sets'] + 1); + $expected['result_set_queries'] = (string)($expected['result_set_queries'] + 1); + + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($info), $info); + + mysqli_get_client_stats_assert_gt('bytes_received_real_data_normal', $info, $expected, $test_counter); + $expected['bytes_received_real_data_normal'] = $info['bytes_received_real_data_normal']; + + mysqli_get_client_stats_assert_eq('rows_fetched_from_server_normal', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_fetched_from_client_normal_unbuffered', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('unbuffered_sets', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('result_set_queries', $info, $expected, $test_counter); + + print "Testing unbuffered normal... - SELECT id, label FROM test, not all fetched\n"; + if (!$res = mysqli_query($link, 'SELECT id, label FROM test', MYSQLI_USE_RESULT)) + printf("[%03d] SELECT id, label FROM test failed, [%d] %s\n", + ++$test_counter, mysqli_errno($link), mysqli_error($link)); + + for ($i = 0; $i < $num_rows - 1; $i++) + $row = mysqli_fetch_assoc($res); + + $expected['rows_fetched_from_server_normal'] = (string)($expected['rows_fetched_from_server_normal'] + $num_rows - 1); + $expected['rows_fetched_from_client_normal_unbuffered'] = (string)($expected['rows_fetched_from_client_normal_unbuffered'] + $num_rows - 1); + $expected['unbuffered_sets'] = (string)($expected['unbuffered_sets'] + 1); + $expected['result_set_queries'] = (string)($expected['result_set_queries'] + 1); + + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($info), $info); + + mysqli_get_client_stats_assert_gt('bytes_received_real_data_normal', $info, $expected, $test_counter); + $expected['bytes_received_real_data_normal'] = $info['bytes_received_real_data_normal']; + + mysqli_get_client_stats_assert_eq('rows_fetched_from_server_normal', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_fetched_from_client_normal_unbuffered', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('unbuffered_sets', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('result_set_queries', $info, $expected, $test_counter); + + print "Testing if implicit fetching and cleaning happens...\n"; + mysqli_free_result($res); + + /* last row has been implicitly cleaned from the wire by freeing the result set */ + $expected['rows_fetched_from_server_normal'] = (string)($expected['rows_fetched_from_server_normal'] + 1); + $expected['rows_fetched_from_client_normal_unbuffered'] = (string)($expected['rows_fetched_from_client_normal_unbuffered'] + 1); + $expected['rows_skipped_normal'] = (string)($info['rows_skipped_normal'] + 1); + $expected['flushed_normal_sets'] = (string)($expected['flushed_normal_sets'] + 1); + + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($info), $info); + + mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, $expected, $test_counter); + + mysqli_get_client_stats_assert_eq('rows_fetched_from_server_normal', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_fetched_from_client_normal_unbuffered', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_skipped_normal', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('flushed_normal_sets', $info, $expected, $test_counter); + + print "Testing buffered Prepared Statements...\n"; + if (!$stmt = mysqli_stmt_init($link)) + printf("[%03d] stmt_init() failed, [%d] %s\n", + ++$test_counter, mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test') || + !mysqli_stmt_execute($stmt)) + printf("[%03d] prepare/execute failed, [%d] %s\n", + ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + /* by default PS is unbuffered - no change */ + mysqli_get_client_stats_assert_eq('rows_fetched_from_server_ps', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_fetched_from_client_ps_buffered', $info, $expected, $test_counter); + + if (!mysqli_stmt_store_result($stmt)) + printf("[%03d] store_result failed, [%d] %s\n", + ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + mysqli_stmt_free_result($stmt); + + mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $info, "0", $test_counter); + mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, $expected, $test_counter); + + $expected['rows_fetched_from_server_ps'] = (string)($expected['rows_fetched_from_server_ps'] + $num_rows); + $expected['result_set_queries'] = (string)($expected['result_set_queries'] + 1); + $expected['ps_buffered_sets'] = (string)($expected['ps_buffered_sets'] + 1); + $expected['rows_buffered_from_client_ps'] = (string)($expected['rows_buffered_from_client_ps'] + $num_rows); + + + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($info), $info); + + mysqli_get_client_stats_assert_eq('rows_fetched_from_server_ps', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_fetched_from_client_ps_buffered', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('result_set_queries', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('ps_buffered_sets', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_buffered_from_client_ps', $info, $expected, $test_counter); + + mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $info, "0", $test_counter); + + print "Testing buffered Prepared Statements... - fetching all\n"; + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test') || + !mysqli_stmt_execute($stmt)) + printf("[%03d] prepare/execute failed, [%d] %s\n", + ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $label = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label)) + printf("[%03d] bind_result failed, [%d] %s\n", + ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_store_result($stmt)) + printf("[%03d] store_result failed, [%d] %s\n", + ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + while (mysqli_stmt_fetch($stmt)) + ; + + $expected['rows_fetched_from_server_ps'] = (string)($expected['rows_fetched_from_server_ps'] + $num_rows); + $expected['rows_fetched_from_client_ps_buffered'] = (string)($expected['rows_fetched_from_client_ps_buffered'] + $num_rows); + $expected['result_set_queries'] = (string)($expected['result_set_queries'] + 1); + $expected['ps_buffered_sets'] = (string)($expected['ps_buffered_sets'] + 1); + $expected['rows_buffered_from_client_ps'] = (string)($expected['rows_buffered_from_client_ps'] + $num_rows); + + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($info), $info); + + + mysqli_get_client_stats_assert_gt('bytes_received_real_data_ps', $info, $expected, $test_counter); + $expected['bytes_received_real_data_ps'] = $info['bytes_received_real_data_ps']; + + mysqli_get_client_stats_assert_eq('rows_fetched_from_server_ps', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_fetched_from_client_ps_buffered', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('result_set_queries', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('ps_buffered_sets', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_buffered_from_client_ps', $info, $expected, $test_counter); + + mysqli_stmt_free_result($stmt); + + print "Testing buffered Prepared Statements... - fetching all but one\n"; + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test') || + !mysqli_stmt_execute($stmt)) + printf("[%03d] prepare/execute failed, [%d] %s\n", + ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $label = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label)) + printf("[%03d] bind_result failed, [%d] %s\n", + ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_store_result($stmt)) + printf("[%03d] store_result failed, [%d] %s\n", + ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + for ($i = 0; $i < $num_rows - 1; $i++) + mysqli_stmt_fetch($stmt); + + $expected['rows_fetched_from_server_ps'] = (string)($expected['rows_fetched_from_server_ps'] + $num_rows); + $expected['rows_fetched_from_client_ps_buffered'] = (string)($expected['rows_fetched_from_client_ps_buffered'] + $num_rows - 1); + $expected['result_set_queries'] = (string)($expected['result_set_queries'] + 1); + $expected['ps_buffered_sets'] = (string)($expected['ps_buffered_sets'] + 1); + $expected['rows_buffered_from_client_ps'] = (string)($expected['rows_buffered_from_client_ps'] + $num_rows); + + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($info), $info); + + mysqli_get_client_stats_assert_gt('bytes_received_real_data_ps', $info, $expected, $test_counter); + $expected['bytes_received_real_data_ps'] = $info['bytes_received_real_data_ps']; + + mysqli_get_client_stats_assert_eq('rows_fetched_from_server_ps', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_fetched_from_client_ps_buffered', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('result_set_queries', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('ps_buffered_sets', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_buffered_from_client_ps', $info, $expected, $test_counter); + + $expected['rows_skipped_ps'] = $info['rows_skipped_ps']; + mysqli_stmt_free_result($stmt); + + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($info), $info); + + /* buffered result set - no skipping possible! */ + mysqli_get_client_stats_assert_eq('rows_skipped_ps', $info, $expected, $test_counter); + + print "Testing unbuffered Prepared Statements... - fetching all\n"; + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test') || + !mysqli_stmt_execute($stmt)) + printf("[%03d] prepare/execute failed, [%d] %s\n", + ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $label = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label)) + printf("[%03d] bind_result failed, [%d] %s\n", + ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $i = 0; + while (mysqli_stmt_fetch($stmt)) + $i++; + assert($num_rows = $i); + + $expected['rows_fetched_from_server_ps'] = (string)($expected['rows_fetched_from_server_ps'] + $num_rows); + $expected['rows_fetched_from_client_ps_unbuffered'] = (string)($expected['rows_fetched_from_client_ps_unbuffered'] + $num_rows); + $expected['result_set_queries'] = (string)($expected['result_set_queries'] + 1); + $expected['ps_unbuffered_sets'] = (string)($expected['ps_unbuffered_sets'] + 1); + + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($info), $info); + + mysqli_get_client_stats_assert_gt('bytes_received_real_data_ps', $info, $expected, $test_counter); + $expected['bytes_received_real_data_ps'] = $info['bytes_received_real_data_ps']; + + mysqli_get_client_stats_assert_eq('rows_fetched_from_server_ps', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_fetched_from_client_ps_unbuffered', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('result_set_queries', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('ps_unbuffered_sets', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_buffered_from_client_ps', $info, $expected, $test_counter); + + mysqli_stmt_free_result($stmt); + + print "Testing unbuffered Prepared Statements... - fetching all but one\n"; + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test') || + !mysqli_stmt_execute($stmt)) + printf("[%03d] prepare/execute failed, [%d] %s\n", + ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $label = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label)) + printf("[%03d] bind_result failed, [%d] %s\n", + ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + for ($i = 0; $i < $num_rows - 1; $i++) + mysqli_stmt_fetch($stmt); + + $expected['rows_fetched_from_server_ps'] = (string)($expected['rows_fetched_from_server_ps'] + $num_rows - 1); + $expected['rows_fetched_from_client_ps_unbuffered'] = (string)($expected['rows_fetched_from_client_ps_unbuffered'] + $num_rows - 1); + $expected['result_set_queries'] = (string)($expected['result_set_queries'] + 1); + $expected['ps_unbuffered_sets'] = (string)($expected['ps_unbuffered_sets'] + 1); + + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($info), $info); + + mysqli_get_client_stats_assert_gt('bytes_received_real_data_ps', $info, $expected, $test_counter); + $expected['bytes_received_real_data_ps'] = $info['bytes_received_real_data_ps']; + + mysqli_get_client_stats_assert_eq('rows_fetched_from_server_ps', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_fetched_from_client_ps_unbuffered', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('result_set_queries', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('ps_unbuffered_sets', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_buffered_from_client_ps', $info, $expected, $test_counter); + + mysqli_stmt_free_result($stmt); + $expected['rows_skipped_ps'] = (string)($expected['rows_skipped_ps'] + 1); + $expected['flushed_ps_sets'] = (string)($expected['flushed_ps_sets'] + 1); + $expected['rows_fetched_from_server_ps'] = (string)($expected['rows_fetched_from_server_ps'] + 1); + + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($info), $info); + + mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $info, $expected, $test_counter); + + mysqli_get_client_stats_assert_eq('rows_skipped_ps', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('flushed_ps_sets', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('rows_fetched_from_server_ps', $info, $expected, $test_counter); + + /* + print "Checking for normal buffered side effects...\n"; + foreach ($info as $k => $v) + if ($info[$k] != $expected[$k]) + printf("$k - $v != %s\n", $expected[$k]); + */ + print "... done with fetch statistics\n"; + + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($info), $info); + + mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $info, $expected, $test_counter); + + // + // result_set_queries statistics + // + + if (!is_array($info = mysqli_get_client_stats()) || empty($info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($info), $info); + + if (!$res = mysqli_query($link, "SELECT id, label FROM test")) + printf("[%03d] SELECT failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + $rows = 0; + while ($row = mysqli_fetch_assoc($res)) + $rows++; + + if (0 == $rows) + printf("[%03d] Expecting at least one result, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + + mysqli_get_client_stats_assert_eq('result_set_queries', $new_info, (string)($info['result_set_queries'] + 1), $test_counter); + $info = $new_info; + + mysqli_get_client_stats_assert_gt('bytes_received_real_data_normal', $info, $expected, $test_counter); + $expected['bytes_received_real_data_normal'] = $info['bytes_received_real_data_normal']; + + // + // non_result_set_queries - DDL + // + + // CREATE TABLE, DROP TABLE + if (!mysqli_query($link, "DROP TABLE IF EXISTS non_result_set_queries_test")) + printf("[%03d] DROP TABLE failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "CREATE TABLE non_result_set_queries_test(id INT) ENGINE = " . $engine)) { + printf("[%03d] CREATE TABLE failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + } else { + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 2), $test_counter, 'CREATE/DROP TABLE'); + } + $info = $new_info; + + // ALERT TABLE + if (!mysqli_query($link, "ALTER TABLE non_result_set_queries_test ADD label CHAR(1)")) { + printf("[%03d] ALTER TABLE failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + } else { + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'ALTER TABLE'); + } + $info = $new_info; + + // CREATE INDEX, DROP INDEX + if (!mysqli_query($link, "CREATE INDEX idx_1 ON non_result_set_queries_test(id)")) { + printf("[%03d] CREATE INDEX failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + } else { + + if (!mysqli_query($link, "DROP INDEX idx_1 ON non_result_set_queries_test")) + printf("[%03d] DROP INDEX failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 2), $test_counter, 'DROP INDEX'); + } + $info = $new_info; + + // RENAME TABLE + if (!mysqli_query($link, "DROP TABLE IF EXISTS client_stats_test")) + printf("[%03d] Cleanup, DROP TABLE client_stats_test failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + $info = $new_info; + + if (!mysqli_query($link, "RENAME TABLE non_result_set_queries_test TO client_stats_test")) { + printf("[%03d] RENAME TABLE failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + } else { + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'RENAME TABLE'); + + } + $info = $new_info; + + if (!mysqli_query($link, "DROP TABLE IF EXISTS non_result_set_queries_test")) + printf("[%03d] Cleanup, DROP TABLE failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS client_stats_test")) + printf("[%03d] Cleanup, DROP TABLE failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + // Let's see if we have privileges for CREATE DATABASE + mysqli_query($link, "DROP DATABASE IF EXISTS mysqli_get_client_stats"); + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + $info = $new_info; + + + // CREATE, ALTER, RENAME, DROP DATABASE + if (mysqli_query($link, "CREATE DATABASE mysqli_get_client_stats")) { + + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'CREATE DATABASE'); + $info = $new_info; + + if (!mysqli_query($link, "ALTER DATABASE DEFAULT CHARACTER SET latin1")) + printf("[%03d] ALTER DATABASE failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'CREATE DATABASE'); + $info = $new_info; + + if (mysqli_get_server_version($link) > 51700) { + if (!mysqli_query($link, "RENAME DATABASE mysqli_get_client_stats TO mysqli_get_client_stats_")) + printf("[%03d] RENAME DATABASE failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'CREATE DATABASE'); + $info = $new_info; + } else { + if (!mysqli_query($link, "CREATE DATABASE mysqli_get_client_stats_")) + printf("[%03d] CREATE DATABASE failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + $info = $new_info; + } + + if (!mysqli_query($link, "DROP DATABASE mysqli_get_client_stats_")) + printf("[%03d] DROP DATABASE failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'DROP DATABASE'); + $info = $new_info; + } + + // CREATE SERVER, ALTER SERVER, DROP SERVER + // We don't really try to use federated, we just want to see if the syntax works + mysqli_query($link, "DROP SERVER IF EXISTS myself"); + + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + $info = $new_info; + + $sql = sprintf("CREATE SERVER myself FOREIGN DATA WRAPPER mysql OPTIONS (user '%s', password '%s', database '%s')", + $user, $passwd, $db); + if (mysqli_query($link, $sql)) { + // server knows about it + + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'CREATE SERVER'); + $info = $new_info; + + if (!mysqli_query($link, sprintf("ALTER SERVER myself OPTIONS(user '%s_')", $user))) + printf("[%03d] ALTER SERVER failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'ALTER SERVER'); + $info = $new_info; + + if (!mysqli_query($link, "DROP SERVER myself")) + printf("[%03d] DROP SERVER failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'DROP SERVER'); + $info = $new_info; + } + + mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $info, $expected, $test_counter); + + /* + We don't test the NDB ones. + 13.1. Data Definition Statements + 13.1.3. ALTER LOGFILE GROUP Syntax + 13.1.4. ALTER TABLESPACE Syntax + 13.1.9. CREATE LOGFILE GROUP Syntax + 13.1.10. CREATE TABLESPACE Syntax + 13.1.15. DROP LOGFILE GROUP Syntax + 13.1.16. DROP TABLESPACE Syntax + */ + + // + // DML + // + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + $info = $new_info; + + if (!mysqli_query($link, "INSERT INTO test(id) VALUES (100)")) + printf("[%03d] INSERT failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'INSERT'); + $info = $new_info; + + if (!mysqli_query($link, "UPDATE test SET label ='z' WHERE id = 100")) + printf("[%03d] UPDATE failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'UPDATE'); + $info = $new_info; + + if (!mysqli_query($link, "REPLACE INTO test(id, label) VALUES (100, 'b')")) + printf("[%03d] INSERT failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'REPLACE'); + $info = $new_info; + + // NOTE: this will NOT update dbl_ddls counter + if (!$res = mysqli_query($link, "SELECT id, label FROM test WHERE id = 100")) + printf("[%03d] SELECT@dml failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, $info, $test_counter, 'SELECT@dml'); + $info = $new_info; + + if (!mysqli_query($link, "DELETE FROM test WHERE id = 100")) + printf("[%03d] DELETE failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'DELETE'); + $info = $new_info; + + if (!$res = mysqli_query($link, "TRUNCATE TABLE test")) + printf("[%03d] TRUNCATE failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'TRUNCATE'); + $info = $new_info; + + + $file = tempnam(sys_get_temp_dir(), 'mysqli_test'); + if ($fp = fopen($file, 'w')) { + @fwrite($fp, '1;"a"'); + fclose($fp); + chmod($file, 0644); + $sql = sprintf('LOAD DATA LOCAL INFILE "%s" INTO TABLE test', mysqli_real_escape_string($link, $file)); + if (mysqli_query($link, $sql)) { + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'LOAD DATA LOCAL'); + $info = $new_info; + } + unlink($file); + } + + mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, $expected, $test_counter); + mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $info, $expected, $test_counter); + + /* + We skip those: + 13.2. Data Manipulation Statements + 13.2.2. DO Syntax + 13.2.3. HANDLER Syntax + 13.2.5. LOAD DATA INFILE Syntax + */ + mysqli_query($link, "DELETE FROM test"); + if (!mysqli_query($link, "INSERT INTO test(id, label) VALUES (1, 'a'), (2, 'b')")) + printf("[%03d] Cannot insert new records, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id")) + printf("[%03d] Cannot SELECT with mysqli_real_query(), [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + if (!is_object($res = mysqli_use_result($link))) + printf("[%03d] mysqli_use_result() failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + while ($row = mysqli_fetch_assoc($res)) + ; + mysqli_free_result($res); + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('unbuffered_sets', $new_info, (string)($info['unbuffered_sets'] + 1), $test_counter, 'mysqli_use_result()'); + $info = $new_info; + + if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id")) + printf("[%03d] Cannot SELECT with mysqli_real_query() II, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + if (!is_object($res = mysqli_store_result($link))) + printf("[%03d] mysqli_use_result() failed, [%d] %s\n", ++$test_counter, + mysqli_errno($link), mysqli_error($link)); + + while ($row = mysqli_fetch_assoc($res)) + ; + mysqli_free_result($res); + if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info)) + printf("[%03d] Expecting array/any_non_empty, got %s/%s\n", + ++$test_counter, gettype($new_info), $new_info); + mysqli_get_client_stats_assert_eq('buffered_sets', $new_info, (string)($info['buffered_sets'] + 1), $test_counter, 'mysqli_use_result()'); + $info = $new_info; + + mysqli_close($link); + + mysqli_get_client_stats_assert_gt('bytes_received_real_data_normal', $info, $expected, $test_counter); + $expected['bytes_received_real_data_normal'] = $info['bytes_received_real_data_normal']; + mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $info, $expected, $test_counter); + + /* + no_index_used + bad_index_used + flushed_normal_sets + flushed_ps_sets + explicit_close + implicit_close + disconnect_close + in_middle_of_command_close + explicit_free_result + implicit_free_result + explicit_stmt_close + implicit_stmt_close + */ + + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS non_result_set_queries_test")) + printf("[c003] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS client_stats_test")) + printf("[c004] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +if (!mysqli_query($link, "DROP DATABASE IF EXISTS mysqli_get_client_stats_")) + printf("[c005] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +if (!mysqli_query($link, "DROP DATABASE IF EXISTS mysqli_get_client_stats")) + printf("[c006] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +if (!mysqli_query($link, "DROP SERVER IF EXISTS myself")) + printf("[c007] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +array(160) { + [%u|b%"bytes_sent"]=> + %unicode|string%(1) "0" + [%u|b%"bytes_received"]=> + %unicode|string%(1) "0" + [%u|b%"packets_sent"]=> + %unicode|string%(1) "0" + [%u|b%"packets_received"]=> + %unicode|string%(1) "0" + [%u|b%"protocol_overhead_in"]=> + %unicode|string%(1) "0" + [%u|b%"protocol_overhead_out"]=> + %unicode|string%(1) "0" + [%u|b%"bytes_received_ok_packet"]=> + %unicode|string%(1) "0" + [%u|b%"bytes_received_eof_packet"]=> + %unicode|string%(1) "0" + [%u|b%"bytes_received_rset_header_packet"]=> + %unicode|string%(1) "0" + [%u|b%"bytes_received_rset_field_meta_packet"]=> + %unicode|string%(1) "0" + [%u|b%"bytes_received_rset_row_packet"]=> + %unicode|string%(1) "0" + [%u|b%"bytes_received_prepare_response_packet"]=> + %unicode|string%(1) "0" + [%u|b%"bytes_received_change_user_packet"]=> + %unicode|string%(1) "0" + [%u|b%"packets_sent_command"]=> + %unicode|string%(1) "0" + [%u|b%"packets_received_ok"]=> + %unicode|string%(1) "0" + [%u|b%"packets_received_eof"]=> + %unicode|string%(1) "0" + [%u|b%"packets_received_rset_header"]=> + %unicode|string%(1) "0" + [%u|b%"packets_received_rset_field_meta"]=> + %unicode|string%(1) "0" + [%u|b%"packets_received_rset_row"]=> + %unicode|string%(1) "0" + [%u|b%"packets_received_prepare_response"]=> + %unicode|string%(1) "0" + [%u|b%"packets_received_change_user"]=> + %unicode|string%(1) "0" + [%u|b%"result_set_queries"]=> + %unicode|string%(1) "0" + [%u|b%"non_result_set_queries"]=> + %unicode|string%(1) "0" + [%u|b%"no_index_used"]=> + %unicode|string%(1) "0" + [%u|b%"bad_index_used"]=> + %unicode|string%(1) "0" + [%u|b%"slow_queries"]=> + %unicode|string%(1) "0" + [%u|b%"buffered_sets"]=> + %unicode|string%(1) "0" + [%u|b%"unbuffered_sets"]=> + %unicode|string%(1) "0" + [%u|b%"ps_buffered_sets"]=> + %unicode|string%(1) "0" + [%u|b%"ps_unbuffered_sets"]=> + %unicode|string%(1) "0" + [%u|b%"flushed_normal_sets"]=> + %unicode|string%(1) "0" + [%u|b%"flushed_ps_sets"]=> + %unicode|string%(1) "0" + [%u|b%"ps_prepared_never_executed"]=> + %unicode|string%(1) "0" + [%u|b%"ps_prepared_once_executed"]=> + %unicode|string%(1) "0" + [%u|b%"rows_fetched_from_server_normal"]=> + %unicode|string%(1) "0" + [%u|b%"rows_fetched_from_server_ps"]=> + %unicode|string%(1) "0" + [%u|b%"rows_buffered_from_client_normal"]=> + %unicode|string%(1) "0" + [%u|b%"rows_buffered_from_client_ps"]=> + %unicode|string%(1) "0" + [%u|b%"rows_fetched_from_client_normal_buffered"]=> + %unicode|string%(1) "0" + [%u|b%"rows_fetched_from_client_normal_unbuffered"]=> + %unicode|string%(1) "0" + [%u|b%"rows_fetched_from_client_ps_buffered"]=> + %unicode|string%(1) "0" + [%u|b%"rows_fetched_from_client_ps_unbuffered"]=> + %unicode|string%(1) "0" + [%u|b%"rows_fetched_from_client_ps_cursor"]=> + %unicode|string%(1) "0" + [%u|b%"rows_affected_normal"]=> + %unicode|string%(1) "0" + [%u|b%"rows_affected_ps"]=> + %unicode|string%(1) "0" + [%u|b%"rows_skipped_normal"]=> + %unicode|string%(1) "0" + [%u|b%"rows_skipped_ps"]=> + %unicode|string%(1) "0" + [%u|b%"copy_on_write_saved"]=> + %unicode|string%(1) "0" + [%u|b%"copy_on_write_performed"]=> + %unicode|string%(1) "0" + [%u|b%"command_buffer_too_small"]=> + %unicode|string%(1) "0" + [%u|b%"connect_success"]=> + %unicode|string%(1) "0" + [%u|b%"connect_failure"]=> + %unicode|string%(1) "0" + [%u|b%"connection_reused"]=> + %unicode|string%(1) "0" + [%u|b%"reconnect"]=> + %unicode|string%(1) "0" + [%u|b%"pconnect_success"]=> + %unicode|string%(1) "0" + [%u|b%"active_connections"]=> + %unicode|string%(1) "0" + [%u|b%"active_persistent_connections"]=> + %unicode|string%(1) "0" + [%u|b%"explicit_close"]=> + %unicode|string%(1) "0" + [%u|b%"implicit_close"]=> + %unicode|string%(1) "0" + [%u|b%"disconnect_close"]=> + %unicode|string%(1) "0" + [%u|b%"in_middle_of_command_close"]=> + %unicode|string%(1) "0" + [%u|b%"explicit_free_result"]=> + %unicode|string%(1) "0" + [%u|b%"implicit_free_result"]=> + %unicode|string%(1) "0" + [%u|b%"explicit_stmt_close"]=> + %unicode|string%(1) "0" + [%u|b%"implicit_stmt_close"]=> + %unicode|string%(1) "0" + [%u|b%"mem_emalloc_count"]=> + %unicode|string%(1) "0" + [%u|b%"mem_emalloc_amount"]=> + %unicode|string%(1) "0" + [%u|b%"mem_ecalloc_count"]=> + %unicode|string%(1) "0" + [%u|b%"mem_ecalloc_amount"]=> + %unicode|string%(1) "0" + [%u|b%"mem_erealloc_count"]=> + %unicode|string%(1) "0" + [%u|b%"mem_erealloc_amount"]=> + %unicode|string%(1) "0" + [%u|b%"mem_efree_count"]=> + %unicode|string%(1) "0" + [%u|b%"mem_efree_amount"]=> + %unicode|string%(1) "0" + [%u|b%"mem_malloc_count"]=> + %unicode|string%(1) "0" + [%u|b%"mem_malloc_amount"]=> + %unicode|string%(1) "0" + [%u|b%"mem_calloc_count"]=> + %unicode|string%(%d) "%d" + [%u|b%"mem_calloc_amount"]=> + %unicode|string%(%d) "%d" + [%u|b%"mem_realloc_count"]=> + %unicode|string%(1) "0" + [%u|b%"mem_realloc_amount"]=> + %unicode|string%(1) "0" + [%u|b%"mem_free_count"]=> + %unicode|string%(1) "0" + [%u|b%"mem_free_amount"]=> + %unicode|string%(1) "0" + [%u|b%"mem_estrndup_count"]=> + %unicode|string%(1) "0" + [%u|b%"mem_strndup_count"]=> + %unicode|string%(1) "0" + [%u|b%"mem_estndup_count"]=> + %unicode|string%(1) "0" + [%u|b%"mem_strdup_count"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_null"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_bit"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_tinyint"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_short"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_int24"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_int"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_bigint"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_decimal"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_float"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_double"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_date"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_year"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_time"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_datetime"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_timestamp"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_string"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_blob"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_enum"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_set"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_geometry"]=> + %unicode|string%(1) "0" + [%u|b%"proto_text_fetched_other"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_null"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_bit"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_tinyint"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_short"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_int24"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_int"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_bigint"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_decimal"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_float"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_double"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_date"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_year"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_time"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_datetime"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_timestamp"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_string"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_blob"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_enum"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_set"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_geometry"]=> + %unicode|string%(1) "0" + [%u|b%"proto_binary_fetched_other"]=> + %unicode|string%(1) "0" + [%u|b%"init_command_executed_count"]=> + %unicode|string%(1) "0" + [%u|b%"init_command_failed_count"]=> + %unicode|string%(1) "0" + [%u|b%"com_quit"]=> + %unicode|string%(1) "0" + [%u|b%"com_init_db"]=> + %unicode|string%(1) "0" + [%u|b%"com_query"]=> + %unicode|string%(1) "0" + [%u|b%"com_field_list"]=> + %unicode|string%(1) "0" + [%u|b%"com_create_db"]=> + %unicode|string%(1) "0" + [%u|b%"com_drop_db"]=> + %unicode|string%(1) "0" + [%u|b%"com_refresh"]=> + %unicode|string%(1) "0" + [%u|b%"com_shutdown"]=> + %unicode|string%(1) "0" + [%u|b%"com_statistics"]=> + %unicode|string%(1) "0" + [%u|b%"com_process_info"]=> + %unicode|string%(1) "0" + [%u|b%"com_connect"]=> + %unicode|string%(1) "0" + [%u|b%"com_process_kill"]=> + %unicode|string%(1) "0" + [%u|b%"com_debug"]=> + %unicode|string%(1) "0" + [%u|b%"com_ping"]=> + %unicode|string%(1) "0" + [%u|b%"com_time"]=> + %unicode|string%(1) "0" + [%u|b%"com_delayed_insert"]=> + %unicode|string%(1) "0" + [%u|b%"com_change_user"]=> + %unicode|string%(1) "0" + [%u|b%"com_binlog_dump"]=> + %unicode|string%(1) "0" + [%u|b%"com_table_dump"]=> + %unicode|string%(1) "0" + [%u|b%"com_connect_out"]=> + %unicode|string%(1) "0" + [%u|b%"com_register_slave"]=> + %unicode|string%(1) "0" + [%u|b%"com_stmt_prepare"]=> + %unicode|string%(1) "0" + [%u|b%"com_stmt_execute"]=> + %unicode|string%(1) "0" + [%u|b%"com_stmt_send_long_data"]=> + %unicode|string%(1) "0" + [%u|b%"com_stmt_close"]=> + %unicode|string%(1) "0" + [%u|b%"com_stmt_reset"]=> + %unicode|string%(1) "0" + [%u|b%"com_stmt_set_option"]=> + %unicode|string%(1) "0" + [%u|b%"com_stmt_fetch"]=> + %unicode|string%(1) "0" + [%u|b%"com_deamon"]=> + %unicode|string%(1) "0" + [%u|b%"bytes_received_real_data_normal"]=> + %unicode|string%(1) "0" + [%u|b%"bytes_received_real_data_ps"]=> + %unicode|string%(1) "0" +} +Testing buffered normal... +Testing buffered normal... - SELECT id, label FROM test +Testing unbuffered normal... +Testing unbuffered normal... - SELECT id, label FROM test, not all fetched +Testing if implicit fetching and cleaning happens... +Testing buffered Prepared Statements... +Testing buffered Prepared Statements... - fetching all +Testing buffered Prepared Statements... - fetching all but one +Testing unbuffered Prepared Statements... - fetching all +Testing unbuffered Prepared Statements... - fetching all but one +... done with fetch statistics +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_get_client_stats_implicit_free.phpt b/ext/mysqli/tests/mysqli_get_client_stats_implicit_free.phpt new file mode 100644 index 0000000..880ee32 --- /dev/null +++ b/ext/mysqli/tests/mysqli_get_client_stats_implicit_free.phpt @@ -0,0 +1,46 @@ +--TEST-- +mysqli_get_client_stats() - implicit_free_result +--SKIPIF-- +<?PHP +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +if (!function_exists('mysqli_get_client_stats')) { + die("skip only available with mysqlnd"); +} +?> +--INI-- +mysqlnd.collect_statistics=1 +mysqlnd.collect_memory_statistics=1 +--FILE-- +<?php + require_once('connect.inc'); + require_once('table.inc'); + + $stats = mysqli_get_client_stats(); + printf("BEGINNING: implicit_free_result = %d\n", $stats['implicit_free_result']); + + if (!$res = mysqli_query($link, 'SELECT id FROM test')) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + mysqli_close($link); + + $after = mysqli_get_client_stats(); + if ($after['implicit_free_result'] != $stats['implicit_free_result']) + printf("[002] Where is the missing mysqli_free_result() call? implicit_free_result has changed by %d.\n", + $after['implicit_free_result'] - $stats['implicit_free_result']); + + $stats = $after; + printf("END: implicit_free_result = %d\n", $stats['implicit_free_result']); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +BEGINNING: implicit_free_result = %d +END: implicit_free_result = %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_get_client_stats_off.phpt b/ext/mysqli/tests/mysqli_get_client_stats_off.phpt new file mode 100644 index 0000000..e2dff9b --- /dev/null +++ b/ext/mysqli/tests/mysqli_get_client_stats_off.phpt @@ -0,0 +1,48 @@ +--TEST-- +mysqli_get_client_stats() - php_ini setting +--SKIPIF-- +<?PHP +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +if (!function_exists('mysqli_get_client_stats')) { + die("skip only available with mysqlnd"); +} +?> +--INI-- +mysqlnd.collect_statistics=0 +mysqlnd.collect_memory_statistics=0 +--FILE-- +<?php + $before = mysqli_get_client_stats(); + if (!is_array($before) || empty($before)) { + printf("[001] Expecting non-empty array, got %s.\n", gettype($before)); + var_dump($before); + } + + // connect and table inc connect to mysql and create tables + require_once('connect.inc'); + require_once('table.inc'); + $after = mysqli_get_client_stats(); + + if ($before !== $after) { + printf("[002] Statistics have changed\n"); + var_dump($before); + var_dump($after); + } + + foreach ($after as $k => $v) + if ($v != 0) { + printf("[003] Field %s should not have any other value but 0, got %s.\n", + $k, $v); + } + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_get_client_stats_ps.phpt b/ext/mysqli/tests/mysqli_get_client_stats_ps.phpt new file mode 100644 index 0000000..d12957b --- /dev/null +++ b/ext/mysqli/tests/mysqli_get_client_stats_ps.phpt @@ -0,0 +1,106 @@ +--TEST-- +mysqli_get_client_stats() - PS +--SKIPIF-- +<?PHP +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +if (!function_exists('mysqli_get_client_stats')) { + die("skip only available with mysqlnd"); +} +?> +--INI-- +mysqlnd.collect_statistics=1 +mysqlnd.collect_memory_statistics=1 +--FILE-- +<?php + require_once('connect.inc'); + require_once('table.inc'); + + $stats = mysqli_get_client_stats(); + printf("BEGINNING: rows_fetched_from_client_ps_unbuffered = %d\n", $stats['rows_fetched_from_client_ps_unbuffered']); + printf("BEGINNING: rows_fetched_from_client_ps_buffered = %d\n", $stats['rows_fetched_from_client_ps_buffered']); + printf("BEGINNING: rows_fetched_from_client_ps_cursor = %d\n", $stats['rows_fetched_from_client_ps_cursor']); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $id = null; + if (!mysqli_stmt_prepare($stmt, 'SELECT id FROM test') || + !mysqli_stmt_execute($stmt) || + !mysqli_stmt_store_result($stmt) || + !mysqli_stmt_bind_result($stmt, $id)) + printf("[002] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $num_rows = 0; + while (mysqli_stmt_fetch($stmt)) + $num_rows++; + + mysqli_stmt_free_result($stmt); + + $after = mysqli_get_client_stats(); + + if ($after['rows_fetched_from_client_ps_unbuffered'] != $stats['rows_fetched_from_client_ps_unbuffered']) + printf("[003] Unbuffered rows got increased after buffered PS, expecting %d got %d.\n", + $stats['rows_fetched_from_client_ps_unbuffered'], + $after['rows_fetched_from_client_ps_unbuffered']); + + $stats['rows_fetched_from_client_ps_buffered'] += $num_rows; + if ($after['rows_fetched_from_client_ps_buffered'] != $stats['rows_fetched_from_client_ps_buffered'] ) + printf("[005] Buffered rows should be %d got %d.\n", + $stats['rows_fetched_from_client_ps_buffered'], + $after['rows_fetched_from_client_ps_buffered']); + + $stats = $after; + printf("BUFFERED: rows_fetched_from_client_ps_unbuffered = %d\n", $stats['rows_fetched_from_client_ps_unbuffered']); + printf("BUFFERED: rows_fetched_from_client_ps_buffered = %d\n", $stats['rows_fetched_from_client_ps_buffered']); + printf("BUFFERED: rows_fetched_from_client_ps_cursor = %d\n", $stats['rows_fetched_from_client_ps_cursor']); + + $id = null; + if (!mysqli_stmt_prepare($stmt, 'SELECT id FROM test') || + !mysqli_stmt_execute($stmt) || + !mysqli_stmt_bind_result($stmt, $id)) + printf("[006] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $num_rows = 0; + while (mysqli_stmt_fetch($stmt)) + $num_rows++; + + $after = mysqli_get_client_stats(); + $stats['rows_fetched_from_client_ps_unbuffered'] += $num_rows; + if ($after['rows_fetched_from_client_ps_unbuffered'] != $stats['rows_fetched_from_client_ps_unbuffered']) + printf("[007] Unbuffered rows should be %d got %d.\n", + $stats['rows_fetched_from_client_ps_unbuffered'], + $after['rows_fetched_from_client_ps_unbuffered']); + + if ($after['rows_fetched_from_client_ps_buffered'] != $stats['rows_fetched_from_client_ps_buffered'] ) + printf("[005] Buffered rows should be unchanged, expecting %d got %d.\n", + $stats['rows_fetched_from_client_ps_buffered'], + $after['rows_fetched_from_client_ps_buffered']); + + mysqli_stmt_free_result($stmt); + mysqli_stmt_close($stmt); + + $stats = $after; + printf("UNBUFFERED: rows_fetched_from_client_ps_unbuffered = %d\n", $stats['rows_fetched_from_client_ps_unbuffered']); + printf("UNBUFFERED: rows_fetched_from_client_ps_buffered = %d\n", $stats['rows_fetched_from_client_ps_buffered']); + printf("UNBUFFERED: rows_fetched_from_client_ps_cursor = %d\n", $stats['rows_fetched_from_client_ps_cursor']); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +BEGINNING: rows_fetched_from_client_ps_unbuffered = %d +BEGINNING: rows_fetched_from_client_ps_buffered = %d +BEGINNING: rows_fetched_from_client_ps_cursor = 0 +BUFFERED: rows_fetched_from_client_ps_unbuffered = %d +BUFFERED: rows_fetched_from_client_ps_buffered = %d +BUFFERED: rows_fetched_from_client_ps_cursor = 0 +UNBUFFERED: rows_fetched_from_client_ps_unbuffered = %d +UNBUFFERED: rows_fetched_from_client_ps_buffered = %d +UNBUFFERED: rows_fetched_from_client_ps_cursor = 0 +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_get_client_stats_skipped.phpt b/ext/mysqli/tests/mysqli_get_client_stats_skipped.phpt new file mode 100644 index 0000000..0358656 --- /dev/null +++ b/ext/mysqli/tests/mysqli_get_client_stats_skipped.phpt @@ -0,0 +1,52 @@ +--TEST-- +mysqli_get_client_stats() - skipped rows +--INI-- +mysqlnd.collect_statistics="1" +mysqlnd.collect_memory_statistics="1" +--SKIPIF-- +<?PHP +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +if (!function_exists('mysqli_get_client_stats')) { + die("skip only available with mysqlnd"); +} +?> +--FILE-- +<?php + require_once('connect.inc'); + require_once('table.inc'); + + if (!$res = mysqli_query($link, 'SELECT id FROM test', MYSQLI_STORE_RESULT)) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $num_rows = mysqli_num_rows($res); + assert($num_rows > 2); + mysqli_free_result($res); + + $before = mysqli_get_client_stats(); + printf("BEFORE: rows_skipped_normal = %d\n", $before['rows_skipped_normal']); + + if (!$res = mysqli_query($link, 'SELECT id FROM test', MYSQLI_USE_RESULT)) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + /* fetch all rows but the last one */ + for ($i = 0; $i < $num_rows - 1; $i++) + $row = mysqli_fetch_assoc($res); + + /* enforce implicit cleaning of the wire and skipping the last row */ + mysqli_free_result($res); + $after = mysqli_get_client_stats(); + printf("AFTER: rows_skipped_normal = %d\n", $after['rows_skipped_normal']); + + if ($after['rows_skipped_normal'] != $before['rows_skipped_normal'] + 1) + printf("Statistics should show an increase of 1 for rows_skipped_normal, ". + "but before=%d after=%d\n", $before['rows_skipped_normal'], $after['rows_skipped_normal']); + + mysqli_close($link); + print "done!"; +?> +--EXPECTF-- +BEFORE: rows_skipped_normal = %d +AFTER: rows_skipped_normal = %d +done! diff --git a/ext/mysqli/tests/mysqli_get_client_version.phpt b/ext/mysqli/tests/mysqli_get_client_version.phpt new file mode 100644 index 0000000..5862c0a --- /dev/null +++ b/ext/mysqli/tests/mysqli_get_client_version.phpt @@ -0,0 +1,14 @@ +--TEST-- +mysqli_get_client_version() +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +<?php require_once('skipifemb.inc'); ?> +--FILE-- +<?php + if (!is_int($info = mysqli_get_client_version()) || ($info < 100)) + printf("[001] Expecting int/any_non_empty, got %s/%s\n", gettype($info), $info); + + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_get_connection_stats.phpt b/ext/mysqli/tests/mysqli_get_connection_stats.phpt new file mode 100644 index 0000000..64eba16 --- /dev/null +++ b/ext/mysqli/tests/mysqli_get_connection_stats.phpt @@ -0,0 +1,87 @@ +--TEST-- +mysqli_get_connection_stats() +--INI-- +mysqlnd.collect_statistics="1" +mysqlnd.collect_memory_statistics="1" +--SKIPIF-- +<?PHP +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +if (!function_exists('mysqli_get_connection_stats')) { + die("skip only available with mysqlnd"); +} +?> +--FILE-- +<?php + $tmp = $link = null; + if (!is_null($tmp = @mysqli_get_connection_stats())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_get_connection_stats($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require("table.inc"); + + if (!is_array($info = mysqli_get_connection_stats($link)) || empty($info)) + printf("[003] Expecting array/any_non_empty, got %s/%s\n", gettype($info), $info); + + if (!is_array($info2 = mysqli_get_client_stats()) || empty($info2)) + printf("[004] Expecting array/any_non_empty, got %s/%s\n", gettype($info2), $info2); + + foreach ($info as $k => &$v) { + if (strpos($k, "mem_") === 0) { + $v = 0; + } + } + foreach ($info2 as $k => &$v) { + if (strpos($k, "mem_") === 0) { + $v = 0; + } + } + + if ($info !== $info2) { + printf("[005] The hashes should be identical except of the memory related fields\n"); + var_dump($info); + var_dump($info2); + } + + if (!is_array($info = $link->get_connection_stats()) || empty($info)) + printf("[006] Expecting array/any_non_empty, got %s/%s\n", gettype($info), $info); + + foreach ($info as $k => &$v) { + if (strpos($k, "mem_") === 0) { + $v = 0; + } + } + + if ($info !== $info2) { + printf("[007] The hashes should be identical except of the memory related fields\n"); + var_dump($info); + var_dump($info2); + } + + mysqli_close($link); + require("table.inc"); + + if (!is_array($info = mysqli_get_connection_stats($link)) || empty($info)) + printf("[008] Expecting array/any_non_empty, got %s/%s\n", gettype($info), $info); + + if (!is_array($info2 = mysqli_get_client_stats()) || empty($info2)) + printf("[009] Expecting array/any_non_empty, got %s/%s\n", gettype($info2), $info2); + + // assuming the test is run in a plain-vanilla CLI environment + if ($info === $info2) { + printf("[010] The hashes should not be identical\n"); + var_dump($info); + var_dump($info2); + } + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done! diff --git a/ext/mysqli/tests/mysqli_get_connection_stats_off.phpt b/ext/mysqli/tests/mysqli_get_connection_stats_off.phpt new file mode 100644 index 0000000..4897063 --- /dev/null +++ b/ext/mysqli/tests/mysqli_get_connection_stats_off.phpt @@ -0,0 +1,53 @@ +--TEST-- +mysqli_get_connection_stats() - disable via php.ini +--INI-- +mysqlnd.collect_statistics="0" +mysqlnd.collect_memory_statistics="0" +--SKIPIF-- +<?PHP +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +if (!function_exists('mysqli_get_connection_stats')) { + die("skip only available with mysqlnd"); +} +?> +--FILE-- +<?php + // connect and table inc connect to mysql and create tables + require_once('connect.inc'); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } + $before = mysqli_get_connection_stats($link); + if (!is_array($before) || empty($before)) { + printf("[002] Expecting non-empty array, got %s.\n", gettype($before)); + var_dump($before); + } + + mysqli_close($link); + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } + $after = mysqli_get_connection_stats($link); + + if ($before !== $after) { + printf("[004] Statistics differ!"); + var_dump($before); + var_dump($after); + } + + foreach ($after as $k => $v) + if ($v != 0) { + printf("[004] Field %s should not have any other value but 0, got %s.\n", + $k, $v); + } + + mysqli_close($link); + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_get_host_info.phpt b/ext/mysqli/tests/mysqli_get_host_info.phpt new file mode 100644 index 0000000..2c3c0f8 --- /dev/null +++ b/ext/mysqli/tests/mysqli_get_host_info.phpt @@ -0,0 +1,35 @@ +--TEST-- +mysqli_get_host_info() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + if (!is_null($tmp = @mysqli_get_host_info())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_get_host_info(NULL))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require "table.inc"; + if (!is_string($info = mysqli_get_host_info($link)) || ('' === $info)) + printf("[003] Expecting string/any_non_empty, got %s/%s\n", gettype($info), $info); + + if ($IS_MYSQLND && $host != 'localhost' && $host != '127.0.0.1' && $port != '' && $host != "" && strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') { + /* this should be a TCP/IP connection and not a Unix Socket (or SHM or Named Pipe) */ + if (!stristr($info, "TCP/IP")) + printf("[004] Should be a TCP/IP connection but mysqlnd says '%s'\n", $info); + } + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_get_proto_info.phpt b/ext/mysqli/tests/mysqli_get_proto_info.phpt new file mode 100644 index 0000000..7fbefeb --- /dev/null +++ b/ext/mysqli/tests/mysqli_get_proto_info.phpt @@ -0,0 +1,29 @@ +--TEST-- +mysqli_get_proto_info() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + if (!is_null($tmp = @mysqli_get_proto_info())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_get_proto_info(NULL))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require "table.inc"; + if (!is_int($info = mysqli_get_proto_info($link)) || ($info < 1)) + printf("[003] Expecting int/any_non_empty, got %s/%s\n", gettype($info), $info); + + if (!is_null($tmp = @mysqli_get_proto_info('too many', 'arguments'))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_get_server_info.phpt b/ext/mysqli/tests/mysqli_get_server_info.phpt new file mode 100644 index 0000000..a7f7853 --- /dev/null +++ b/ext/mysqli/tests/mysqli_get_server_info.phpt @@ -0,0 +1,33 @@ +--TEST-- +mysqli_get_server_info() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + if (!is_null($tmp = @mysqli_get_server_info())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_get_server_info(NULL))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require "table.inc"; + if (!is_string($info = mysqli_get_server_info($link)) || ('' === $info)) + printf("[003] Expecting string/any_non_empty, got %s/%s\n", gettype($info), $info); + + if (!is_null($tmp = @mysqli_get_server_info('too', 'many arguments'))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_get_server_version.phpt b/ext/mysqli/tests/mysqli_get_server_version.phpt new file mode 100644 index 0000000..b30c4a3 --- /dev/null +++ b/ext/mysqli/tests/mysqli_get_server_version.phpt @@ -0,0 +1,28 @@ +--TEST-- +mysqli_get_server_version() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + if (!is_null($tmp = @mysqli_get_server_version())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_get_server_version(NULL))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require "table.inc"; + /* 5.1.5 -> 50105 -- major_version*10000 + minor_version *100 + sub_version */ + /* < 30000 = pre 3.2.3, very unlikely! */ + if (!is_int($info = mysqli_get_server_version($link)) || ($info < (3 * 10000))) + printf("[003] Expecting int/any >= 30000, got %s/%s\n", gettype($info), $info); + + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_get_warnings.phpt b/ext/mysqli/tests/mysqli_get_warnings.phpt new file mode 100644 index 0000000..00548de --- /dev/null +++ b/ext/mysqli/tests/mysqli_get_warnings.phpt @@ -0,0 +1,160 @@ +--TEST-- +mysqli_get_warnings() - TODO +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); +if (!$TEST_EXPERIMENTAL) + die("skip - experimental (= unsupported) feature"); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_get_warnings())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_get_warnings($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_get_warnings(''))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[003] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + } + + if (false !== ($tmp = mysqli_get_warnings($link))) { + printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), (is_object($tmp) ? var_dump($tmp, true) : $tmp)); + } + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "CREATE TABLE test (id SMALLINT)")) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "INSERT INTO test (id) VALUES (1000000)")) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_object($warning = mysqli_get_warnings($link)) || 'mysqli_warning' != get_class($warning)) { + printf("[008] Expecting object/mysqli_warning, got %s/%s\n", gettype($tmp), (is_object($tmp) ? var_dump($tmp, true) : $tmp)); + } + + if (!method_exists($warning, 'next')) + printf("[009] Borked object, method next is missing\n"); + + $properties = array_merge(get_object_vars($warning), get_class_vars(get_class($warning))); + if (!empty($properties)) + printf("[010] Properties have always been magic, hidden things - why are they visible now, a BC break...\n"); + + if ((!is_string($warning->message)) || ('' == $warning->message)) /* NULL or not there at all */ + printf("[011] Expecting string/not empty, got %s/%s\n", gettype($warning->message), $warning->message); + + if ((!is_string($warning->sqlstate)) || ('' == $warning->sqlstate)) /* NULL or not there at all */ + printf("[012] Expecting string/not empty, got %s/%s\n", gettype($warning->sqlstate), $warning->sqlstate); + + if ((!is_int($warning->errno)) || (0 == $warning->errno)) /* NULL or not there at all */ + printf("[013] Expecting int/not 0, got %s/%s\n", gettype($warning->errno), $warning->errno); + + if (false !== ($tmp = $warning->next())) + printf("[014] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, "INSERT INTO test (id) VALUES (1000000), (1000001)")) + printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (($tmp = mysqli_warning_count($link)) !== 2) + printf("[016] Expecting 2 warnings, got %d warnings", $tmp); + + if (!is_object($warning = mysqli_get_warnings($link)) || 'mysqli_warning' != get_class($warning)) { + printf("[017] Expecting object/mysqli_warning, got %s/%s\n", gettype($tmp), (is_object($tmp) ? var_dump($tmp, true) : $tmp)); + } + + if (true !== ($tmp = $warning->next())) + printf("[018] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = $warning->next())) + printf("[020] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[021] Cannot create mysqli object: [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (!$mysqli->query("DROP TABLE IF EXISTS t1")) + printf("[022] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$mysqli->query("CREATE TABLE t1 (a smallint)")) + printf("[023] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_object($warning = new mysqli_warning($mysqli))) + printf("[024] Expecting object/mysqli_warning, got %s/%s", gettype($warning), $warning); + + if (!is_string($warning->message) || ('' == $warning->message)) + printf("[025] Expecting string, got %s/%s", gettype($warning->message), $warning->message); + + if (!$mysqli->query("DROP TABLE t1")) + printf("[026] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + /* Yes, I really want to check if the object property is empty */ + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[027] Cannot create mysqli object: [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + $warning = new mysqli_warning($mysqli); + if (false !== ($tmp = $warning->next())) + printf("[028] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if ('' != ($tmp = $warning->message)) + printf("[029] Expecting string/empty, got %s/%s\n", gettype($tmp), $tmp); + + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[030] Cannot create mysqli object: [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (!$mysqli->query("DROP TABLE IF EXISTS t1")) + printf("[031] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$mysqli->query("CREATE TABLE t1 (a smallint)")) + printf("[032] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + /* out of range, three warnings */ + if (!$mysqli->query("INSERT IGNORE INTO t1(a) VALUES (65536), (65536), (65536)")) + printf("[033] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $warning = new mysqli_warning($mysqli); + $i = 1; + while ($warning->next() && ('' != ($tmp = $warning->message))) { + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($tmp)) + printf("[033a] Warning should have been a unicode string, got %s/%s", gettype($tmp), $tmp); + $i++; + } + if (3 != $i) + printf("[034] Expecting three warnings, got %d warnings\n", $i); + + $stmt = mysqli_stmt_init(); + $warning = new mysqli_warning($stmt); + if (false !== ($tmp = $warning->next())) + printf("[035] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS t1")) + printf("[c003] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_info.phpt b/ext/mysqli/tests/mysqli_info.phpt new file mode 100644 index 0000000..2d5004f --- /dev/null +++ b/ext/mysqli/tests/mysqli_info.phpt @@ -0,0 +1,101 @@ +--TEST-- +mysqli_info() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + if (!is_null($tmp = @mysqli_info())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_info(NULL))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require "table.inc"; + if (!$res = mysqli_query($link, "INSERT INTO test(id, label) VALUES (100, 'a')")) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + // NOTE: empty string, no multiple insert syntax + if (!is_string($tmp = mysqli_info($link)) || ('' != $tmp)) + printf("[004] Expecting string/empty, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = mysqli_query($link, "INSERT INTO test(id, label) VALUES (101, 'a'), (102, 'b')")) + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_string($tmp = mysqli_info($link)) || ('' == $tmp)) + printf("[006] Expecting string/any_non_empty, got %s/%s\n", gettype($tmp), $tmp); + + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($tmp)) + printf("[007] Expecting unicode, because unicode mode it on. Got binary string\n"); + + if (!$res = mysqli_query($link, 'INSERT INTO test(id, label) SELECT id + 200, label FROM test')) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_string($tmp = mysqli_info($link)) || ('' == $tmp)) + printf("[008] Expecting string/any_non_empty, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = mysqli_query($link, 'ALTER TABLE test MODIFY label CHAR(2)')) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_string($tmp = mysqli_info($link)) || ('' == $tmp)) + printf("[010] Expecting string/any_non_empty, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = mysqli_query($link, "UPDATE test SET label = 'b' WHERE id >= 100")) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_string($tmp = mysqli_info($link)) || ('' == $tmp)) + printf("[012] Expecting string/any_non_empty, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = mysqli_query($link, "SELECT 1")) + printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_string($tmp = mysqli_info($link)) || ('' != $tmp)) + printf("[014] Expecting string/empty, got %s/%s\n", gettype($tmp), $tmp); + mysqli_free_result($res); + + // NOTE: no LOAD DATA INFILE test + if ($dir = sys_get_temp_dir()) { + do { + $file = $dir . '/' . 'mysqli_info_phpt.cvs'; + if (!$fp = fopen($file, 'w')) + /* ignore this error */ + break; + + if (!fwrite($fp, b"100;'a';\n") || + !fwrite($fp, b"101;'b';\n") || + !fwrite($fp, b"102;'c';\n")) { + @unlink($file); + break; + } + fclose($fp); + if (!mysqli_query($link, "DELETE FROM test")) { + printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + break; + } + + if (!@mysqli_query($link, sprintf("LOAD DATA LOCAL INFILE '%s' INTO TABLE test FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '\'' LINES TERMINATED BY '\n'", $file))) { + /* ok, because we might not be allowed to do this */ + @unlink($file); + break; + } + + if (!is_string($tmp = mysqli_info($link)) || ('' == $tmp)) + printf("[016] Expecting string/any_non_empty, got %s/%s\n", gettype($tmp), $tmp); + + unlink($file); + } while (false); + } + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_init.phpt b/ext/mysqli/tests/mysqli_init.phpt new file mode 100644 index 0000000..1abb7ca --- /dev/null +++ b/ext/mysqli/tests/mysqli_init.phpt @@ -0,0 +1,25 @@ +--TEST-- +mysqli_init() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + $link = mysqli_init(); + + if (!is_object($link) && false !== $link) + printf("[001] Expecting object/mysqli_link or boolean/false, got %s/%s\n", gettype($link), $link); + + if (is_object($link) && 'mysqli' != get_class($link)) + printf("[002] Expecting object of type mysqli got object of type %s\n", get_class($link)); + + if ($link) + mysqli_close($link); + + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_insert_id.phpt b/ext/mysqli/tests/mysqli_insert_id.phpt new file mode 100644 index 0000000..549d71d --- /dev/null +++ b/ext/mysqli/tests/mysqli_insert_id.phpt @@ -0,0 +1,140 @@ +--TEST-- +mysqli_insert_id() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_insert_id())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_insert_id($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (0 !== ($tmp = mysqli_insert_id($link))) + printf("[003] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 1")) { + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + if (0 !== ($tmp = mysqli_insert_id($link))) + printf("[005] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + mysqli_free_result($res); + + // no auto_increment column + if (!$res = mysqli_query($link, "INSERT INTO test(id, label) VALUES (100, 'a')")) { + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + if (0 !== ($tmp = mysqli_insert_id($link))) + printf("[007] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = mysqli_query($link, "ALTER TABLE test MODIFY id INT NOT NULL AUTO_INCREMENT")) { + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + if (!$res = mysqli_query($link, "INSERT INTO test(label) VALUES ('a')")) { + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + if (($last_id = mysqli_insert_id($link)) <= 0) + printf("[010] Expecting int/any >0, got %s/%s\n", gettype($last_id), $last_id); + + if (mysqli_query($link, "LOCK TABLE test WRITE")) { + /* we need exclusive access for a moment */ + /* let's hope nobody changes auto_increment_increment while this code executes */ + do { + if (mysqli_get_server_version($link) >= 50000) { + if (!$res = mysqli_query($link, 'SELECT @@auto_increment_increment AS inc')) { + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + break; + } + if (!$row = mysqli_fetch_assoc($res)) { + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + break; + } + mysqli_free_result($res); + $inc = $row['inc']; + } else { + $inc = 1; + } + + if (!mysqli_query($link, "INSERT INTO test(label) VALUES ('b')")) { + printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + break; + } + if (($next_id = mysqli_insert_id($link)) <= $last_id) + /* + very likely a bug, but someone could have done something on the server + between the second last insert and the lock, therefore don't stop just bail + */ + printf("[014] Expecting int/any > %d, got %s/%s\n", $last_id, gettype($next_id), $next_id); + + $last_id = $next_id; + if (!mysqli_query($link, "INSERT INTO test(label) VALUES ('c'), ('d'), ('e')")) { + printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + break; + } + /* + Note: For a multiple-row insert, LAST_INSERT_ID() and mysql_insert_id() actually + return the AUTO_INCREMENT key from the first of the inserted rows. This allows + multiple-row inserts to be reproduced correctly on other servers in a replication setup. + */ + if (($next_id = mysqli_insert_id($link)) != $last_id + $inc) { + printf("[016] Expecting int/%d, got %s/%s\n", $last_id + 1, gettype($next_id), $next_id); + break; + } + + if (!$res = mysqli_query($link, "SELECT LAST_INSERT_ID() AS last_id")) { + printf("[017] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + break; + } + if (!$row = mysqli_fetch_assoc($res)) { + printf("[018] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + break; + } + mysqli_free_result($res); + + if ($next_id != $row['last_id']) { + printf("[019] Something is wrong, check manually. Expecting %s got %s.\n", + $next_id, $row['last_id']); + break; + } + } while (false); + mysqli_query($link, "UNLOCK TABLE test"); + } + + if (!$res = mysqli_query($link, "INSERT INTO test(id, label) VALUES (1000, 'a')")) { + printf("[020] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + if (1000 !== ($tmp = mysqli_insert_id($link))) + printf("[021] Expecting int/1000, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = mysqli_query($link, "INSERT INTO test(label) VALUES ('b'), ('c')")) { + printf("[022] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + if (1000 >= ($tmp = mysqli_insert_id($link))) + printf("[023] Expecting int/>1000, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + var_dump(mysqli_insert_id($link)); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_insert_id(): Couldn't fetch mysqli in %s on line %d +NULL +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_insert_id_variation.phpt b/ext/mysqli/tests/mysqli_insert_id_variation.phpt new file mode 100644 index 0000000..e858ca0 --- /dev/null +++ b/ext/mysqli/tests/mysqli_insert_id_variation.phpt @@ -0,0 +1,103 @@ +--TEST-- +Checking last_insert_id after different operations +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +require_once("connect.inc"); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + +$link->query("DROP TABLE IF EXISTS test_insert_id_var"); +$link->query("CREATE TABLE test_insert_id_var (id INT auto_increment, PRIMARY KEY (id))"); +$link->query("INSERT INTO test_insert_id_var VALUES (null)"); +$i = $link->insert_id; + +if (!$i) { + printf("[001] Got no valid insert id: %s", var_export($i, true)); + die(); +} + + +$link->options(MYSQLI_OPT_LOCAL_INFILE, false); +if ($i != $link->insert_id || $i != mysqli_insert_id($link)) { + printf("[002] mysqli_option changes insert_id: %s", var_export($link->insert_id, true)); + die(); +} + +/* +$link->dump_debug_info(); +if ($i != $link->insert_id || $i != mysqli_insert_id($link)) { + printf("[003] mysqli_debug_info changes insert_id: %s", var_export($link->insert_id, true)); + die(); +} +*/ + +$link->stat(); +if ($i != $link->insert_id || $i != mysqli_insert_id($link)) { + printf("[004] mysqli_stat changes insert_id: %s", var_export($link->insert_id, true)); + die(); +} + +/*$link->kill($link->thread_id); +if ($i != $link->insert_id || $i != mysqli_insert_id($link)) { + printf("[005] mysqli_kill changes insert_id: %s", var_export($link->insert_id, true)); + die(); +}*/ + +$link->ping(); +if ($i != $link->insert_id || $i != mysqli_insert_id($link)) { + printf("[006] mysqli_ping changes insert_id: %s", var_export($link->insert_id, true)); + die(); +} + +/* +mysqlnd resets the IDE to 0 +libmysql doesn't + +$link->change_user ($user, $passwd, $db); +if (0 != $link->insert_id || 0 != mysqli_insert_id($link)) { + printf("[007] mysqli_change_user changes insert_id: %s", var_export($link->insert_id, true)); + die(); +} +*/ + +$stmt = $link->prepare("SELECT 1"); +if ($i != $link->insert_id || $i != mysqli_insert_id($link)) { + printf("[008a] mysqli_prepare changes insert_id: %s", var_export($link->insert_id, true)); + die(); +} +echo mysqli_error($link); +if (0 != $stmt->insert_id || 0 != mysqli_stmt_insert_id($stmt)) { + printf("[008b] mysqli_stmt doesn't initialise insert_id: %s", var_export($stmt->insert_id, true)); + die(); +} + +unset($stmt); +if ($i != $link->insert_id || $i != mysqli_insert_id($link)) { + printf("[009] stmt free changes insert_id: %s", var_export($link->insert_id, true)); + die(); +} + +$link->query("DROP TABLE IF EXISTS test_insert_id_var"); + +echo "DONE"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_insert_id_var")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +DONE
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_insert_packet_overflow.phpt b/ext/mysqli/tests/mysqli_insert_packet_overflow.phpt new file mode 100644 index 0000000..c7f38fa --- /dev/null +++ b/ext/mysqli/tests/mysqli_insert_packet_overflow.phpt @@ -0,0 +1,116 @@ +--TEST-- +INSERT and packet overflow +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die(sprintf("SKIP [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error())); + +$max_len = pow(2, 24); +if (!$res = mysqli_query($link, "SHOW GLOBAL VARIABLES LIKE 'max_allowed_packet'")) + die(sprintf("SKIP [%d] %s\n", mysqli_errno($link), mysqli_error($link))); + +if (!mysqli_query($link, "SET NAMES 'latin1'")) + die(sprintf("SKIP [%d] %s\n", mysqli_errno($link), mysqli_error($link))); + +mysqli_close($link); +?> +--INI-- +memory_limit=256M +--FILE-- +<?php + require('connect.inc'); + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (!$res = mysqli_query($link, "SHOW GLOBAL VARIABLES LIKE 'max_allowed_packet'")) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + + if (0 === ($org_max_allowed_packet = (int)$row['Value'])) + printf("[004] Cannot determine max_allowed_packet size and/or bogus max_allowed_packet setting used.\n"); + + $max_len = pow(2, 24); + if ($org_max_allowed_packet < $max_len) { + if (!mysqli_query($link, "SET GLOBAL max_allowed_packet = " . ($max_len + 100))) { + if (1227 == mysqli_errno($link)) { + /* [1227] Access denied; you need the SUPER privilege for this operation */ + print "done!"; + exit(0); + } else { + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + } + } + mysqli_close($link); + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[006] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (!mysqli_query($link, "SET NAMES 'latin1'")) + printf("[007] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (!$res = mysqli_query($link, "SHOW GLOBAL VARIABLES LIKE 'max_allowed_packet'")) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + + if (0 === ($max_allowed_packet = (int)$row['Value'])) + printf("[010] Cannot determine max_allowed_packet size and/or bogus max_allowed_packet setting used.\n"); + + $max_len = pow(2, 24); + if ($max_allowed_packet < $max_len) { + printf("[011] Failed to change max_allowed_packet"); + } + + if (!mysqli_query($link, "CREATE TABLE test(col_blob LONGBLOB) ENGINE=" . $engine)) + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $query_prefix = "INSERT INTO test(col_blob) VALUES ('"; + $query_postfix = "')"; + $query_len = strlen($query_prefix) + strlen($query_postfix); + $com_query_len = 2; + + + $blob = str_repeat('a', $max_len - $com_query_len - $query_len); + $query = sprintf("%s%s%s", $query_prefix, $blob, $query_postfix); + + if (!mysqli_query($link, $query)) + printf("[013] max_allowed_packet = %d, strlen(query) = %d, [%d] %s\n", $max_allowed_packet, strlen($query), mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, "SELECT col_blob FROM test")) + printf("[014] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) { + printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } else { + if ($row['col_blob'] != $blob) { + printf("[016] Blob seems wrong, dumping data\n"); + var_dump(strlen($row['col_blob'])); + var_dump(strlen($blob)); + } + mysqli_free_result($res); + } + + if (!mysqli_query($link, "SET GLOBAL max_allowed_packet = " . $org_max_allowed_packet)) + if (1227 != mysqli_errno($link)) + printf("[017] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_kill.phpt b/ext/mysqli/tests/mysqli_kill.phpt new file mode 100644 index 0000000..94e4e8f --- /dev/null +++ b/ext/mysqli/tests/mysqli_kill.phpt @@ -0,0 +1,145 @@ +--TEST-- +mysqli_kill() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_kill())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_kill($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + // Zend will cast the NULL to 0 + if (!is_bool($tmp = mysqli_kill($link, null))) + printf("[003] Expecting boolean/any, got %s/%s\n", gettype($tmp), $tmp); + + if (!$thread_id = mysqli_thread_id($link)) + printf("[004] Cannot determine thread id, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $tmp = mysqli_kill($link, $thread_id); + if (!is_bool($tmp)) + printf("[005] Expecting boolean/any, got %s/%s\n", gettype($tmp), $tmp); + + if ($res = mysqli_query($link, "SELECT id FROM test LIMIT 1")) + pintf("[006] Expecting boolean/false, got %s/%s\n", gettype($res), $res); + + var_dump($error = mysqli_error($link)); + if (!is_string($error) || ('' === $error)) + printf("[007] Expecting string/any non empty, got %s/%s\n", gettype($error), $error); + var_dump($res); + var_dump($link); + if ($IS_MYSQLND) { + if ($link->info != 'Records: 6 Duplicates: 0 Warnings: 0') { + printf("[008] mysqlnd used to be more verbose and used to support SELECT\n"); + } + if ($link->stat != NULL) { + printf("[009] NULL expected because of error.\n"); + } + } else { + if ($link->info != NULL) { + printf("[008] Time for wonders - libmysql has started to support SELECT, change test\n"); + } + } + + mysqli_close($link); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[010] Cannot connect, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + mysqli_kill($link, -1); + if ((!$res = mysqli_query($link, "SELECT id FROM test LIMIT 1")) || + (!$tmp = mysqli_fetch_assoc($res))) { + printf("[011] Connection should not be gone, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + var_dump($tmp); + mysqli_free_result($res); + mysqli_close($link); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[012] Cannot connect, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + mysqli_change_user($link, "This might work if you accept anonymous users in your setup", "password", $db); mysqli_kill($link, -1); + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_kill(): processid should have positive value in %s on line %d +%unicode|string%(%d) "%s" +bool(false) +object(mysqli)#%d (%d) { + [%u|b%"affected_rows"]=> + int(-1) + [%u|b%"client_info"]=> + %unicode|string%(%d) "%s" + [%u|b%"client_version"]=> + int(%d) + [%u|b%"connect_errno"]=> + int(0) + [%u|b%"connect_error"]=> + NULL + [%u|b%"errno"]=> + int(2006) + [%u|b%"error"]=> + %unicode|string%(%d) "%s" + [%u|b%"error_list"]=> + array(1) { + [0]=> + array(3) { + [%u|b%"errno"]=> + int(2006) + [%u|b%"sqlstate"]=> + %unicode|string%(5) "%s" + [%u|b%"error"]=> + %unicode|string%(%d) "%s" + } + } + [%u|b%"field_count"]=> + int(0) + [%u|b%"host_info"]=> + %unicode|string%(%d) "%s" + [%u|b%"info"]=> + %s + [%u|b%"insert_id"]=> + int(0) + [%u|b%"server_info"]=> + %unicode|string%(%d) "%s" + [%u|b%"server_version"]=> + int(%d) + [%u|b%"stat"]=> + %s + [%u|b%"sqlstate"]=> + %unicode|string%(5) "HY000" + [%u|b%"protocol_version"]=> + int(10) + [%u|b%"thread_id"]=> + int(%d) + [%u|b%"warning_count"]=> + int(0) +} + +Warning: mysqli_kill(): processid should have positive value in %s on line %d +array(1) { + [%u|b%"id"]=> + %unicode|string%(1) "1" +} + +Warning: mysqli_kill(): processid should have positive value in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_last_insert_id.phpt b/ext/mysqli/tests/mysqli_last_insert_id.phpt new file mode 100644 index 0000000..996c401 --- /dev/null +++ b/ext/mysqli/tests/mysqli_last_insert_id.phpt @@ -0,0 +1,194 @@ +--TEST-- +API vs. SQL LAST_INSERT_ID() +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + /* + CAUTION: the insert_id() API call is not supposed to return + the same value as a call to the LAST_INSERT_ID() SQL function. + It is not necessarily a bug if API and SQL function return different + values. Check the MySQL C API reference manual for details. + */ + require_once("connect.inc"); + + function get_sql_id($link) { + if (!($res = $link->query("SELECT LAST_INSERT_ID() AS _id"))) { + printf("[003] [%d] %s\n", $link->errno, $link->error); + return NULL; + } + $row = $res->fetch_assoc(); + $res->close(); + + return $row['_id']; + } + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!$link->query("DROP TABLE IF EXISTS test") || + !$link->query("CREATE TABLE test (id INT auto_increment, label varchar(10) not null, PRIMARY KEY (id)) ENGINE=MyISAM") || + !$link->query("INSERT INTO test (id, label) VALUES (null, 'a')")) { + printf("[002] [%d] %s\n", $link->errno, $link->error); + } + + $api_id = $link->insert_id; + $sql_id = get_sql_id($link); + printf("API: %d, SQL: %d\n", $api_id, $sql_id); + + if ($api_id < 1) + printf("[004] Expecting id > 0 got %d, [%d] %s\n", $api_id, $link->errno, $link->error) ; + if ($api_id != $sql_id) + printf("[005] SQL id %d should be equal to API id %d\n", $sql_id, $api_id); + + // Not an INSERT, API value must become 0 + if (!($res = $link->query("SELECT 1 FROM DUAL"))) + printf("[006] [%d] %s\n", $link->errno, $link->error); + else + $res->close(); + + $api_id = $link->insert_id; + $new_sql_id = get_sql_id($link); + if (0 !== $api_id) { + printf("[007] API id should have been reset to 0 because previous query was SELECT, got API %d, SQL %d\n", + $api_id, $new_sql_id); + } + if ($new_sql_id != $sql_id) { + printf("[008] The servers LAST_INSERT_ID() changed unexpectedly from %d to %d\n", $sql_id, $new_sql_id); + } + + // Insert fails, LAST_INSERT_ID shall not change, API shall return 0 + if ($link->query("INSERT INTO test (id, label) VALUES (null, null)")) { + printf("[009] The INSERT did not fail as planned, [%d] %s\n", $link->errno, $link->error); + } + $api_id = $link->insert_id; + $new_sql_id = get_sql_id($link); + + if (0 !== $api_id) { + printf("[010] API id should have been reset to 0 because previous query was SELECT, got API %d, SQL %d\n", + $api_id, $new_sql_id); + } + if ($new_sql_id != $sql_id) { + printf("[011] The servers LAST_INSERT_ID() changed unexpectedly from %d to %d\n", $sql_id, $new_sql_id); + } + + // Sequence counter pattern... + if (!$link->query("UPDATE test SET id=LAST_INSERT_ID(id+1)")) + printf("[012] [%d] %s\n", $link->errno, $link->error); + + $api_id = $link->insert_id; + $new_sql_id = get_sql_id($link); + if ($api_id < 1) + printf("[013] Expecting id > 0 got %d, [%d] %s\n", $api_id, $link->errno, $link->error) ; + if ($api_id != $new_sql_id) + printf("[014] SQL id %d should be equal to API id %d\n", $new_sql_id, $api_id); + if ($sql_id == $new_sql_id) + printf("[015] SQL id %d should have had changed, got %d\n", $sql_id, $new_sql_id); + + $sql_id = $new_sql_id; + + // Not an INSERT (after UPDATE), API value must become 0 + if (!$link->query("SET @myvar=1")) + printf("[016] [%d] %s\n", $link->errno, $link->error); + + $api_id = $link->insert_id; + $new_sql_id = get_sql_id($link); + if (0 !== $api_id) { + printf("[017] API id should have been reset to 0 because previous query was SET, got API %d, SQL %d\n", + $api_id, $new_sql_id); + } + if ($new_sql_id != $sql_id) { + printf("[018] The servers LAST_INSERT_ID() changed unexpectedly from %d to %d\n", $sql_id, $new_sql_id); + } + + if (!$link->query("INSERT INTO test(id, label) VALUES (LAST_INSERT_ID(id + 1), 'b')")) + printf("[019] [%d] %s\n", $link->errno, $link->error); + + $api_id = $link->insert_id; + $sql_id = get_sql_id($link); + if ($api_id != $sql_id) + printf("[020] SQL id %d should be equal to API id %d\n", $sql_id, $api_id); + + if (!$link->query("INSERT INTO test(label) VALUES ('c')")) + printf("[021] [%d] %s\n", $link->errno, $link->error); + + $api_id = $link->insert_id; + $sql_id = get_sql_id($link); + if ($api_id != $sql_id) + printf("[022] SQL id %d should be equal to API id %d\n", $sql_id, $api_id); + + if (!($res = $link->query("SELECT id, label FROM test ORDER BY id ASC"))) + printf("[023] [%d] %s\n", $link->errno, $link->error); + + printf("Dumping table contents before INSERT...SELECT experiments...\n"); + while ($row = $res->fetch_assoc()) { + printf("id = %d, label = '%s'\n", $row['id'], $row['label']); + } + $res->close(); + + if (!$link->query("INSERT INTO test(label) SELECT CONCAT(label, id) FROM test ORDER BY id ASC")) + printf("[024] [%d] %s\n", $link->errno, $link->error); + + $api_id = $link->insert_id; + $sql_id = get_sql_id($link); + if ($api_id != $sql_id) + printf("[025] SQL id %d should be equal to API id %d\n", $sql_id, $api_id); + + if ($link->query("INSERT INTO test(id, label) SELECT id, CONCAT(label, id) FROM test ORDER BY id ASC")) + printf("[026] INSERT should have failed because of duplicate PK value, [%d] %s\n", $link->errno, $link->error); + + $api_id = $link->insert_id; + $new_sql_id = get_sql_id($link); + if (0 !== $api_id) { + printf("[027] API id should have been reset to 0 because previous query failed, got API %d, SQL %d\n", + $api_id, $new_sql_id); + } + if ($new_sql_id != $sql_id) { + printf("[028] The servers LAST_INSERT_ID() changed unexpectedly from %d to %d\n", $sql_id, $new_sql_id); + } + + /* API insert id will be 101 because of UPDATE, SQL unchanged */ + if (!$link->query(sprintf("INSERT INTO test(id, label) VALUES (%d, 'z') ON DUPLICATE KEY UPDATE id = 101", $sql_id) )) + printf("[029] [%d] %s\n", $link->errno, $link->error); + + $api_id = $link->insert_id; + $new_sql_id = get_sql_id($link); + if ($api_id != 101) + printf("[030] API id should be %d got %d\n", $sql_id, $api_id); + if ($new_sql_id != $sql_id) { + printf("[031] The servers LAST_INSERT_ID() changed unexpectedly from %d to %d\n", $sql_id, $new_sql_id); + } + + if (!($res = $link->query("SELECT id, label FROM test ORDER BY id ASC"))) + printf("[032] [%d] %s\n", $link->errno, $link->error); + + printf("Dumping table contents after INSERT...SELECT...\n"); + while ($row = $res->fetch_assoc()) { + printf("id = %d, label = '%s'\n", $row['id'], $row['label']); + } + $res->close(); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +API: %d, SQL: %d +Dumping table contents before INSERT...SELECT experiments... +id = %d, label = 'b' +id = %d, label = 'a' +id = %d, label = 'c' +Dumping table contents after INSERT...SELECT... +id = %d, label = 'b' +id = %d, label = 'a' +id = %d, label = 'c' +id = %d, label = 'a%d' +id = %d, label = 'c%d' +id = 101, label = 'b%d' +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_max_links.phpt b/ext/mysqli/tests/mysqli_max_links.phpt new file mode 100644 index 0000000..7f49419 --- /dev/null +++ b/ext/mysqli/tests/mysqli_max_links.phpt @@ -0,0 +1,76 @@ +--TEST-- +Testing mysqli.max_links +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +mysqli.max_links=1 +--FILE-- +<?php + require_once("connect.inc"); + require_once("table.inc"); + + // to make sure we have at least one working connection... + var_dump(mysqli_ping($link)); + // to make sure that max_links is really set to one + var_dump((int)ini_get('mysqli.max_links')); + + $links = array(); + for ($i = 1; $i <= 5; $i++) + if ($links[$i] = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[%03d] One link is already open, it should not be possible to open more, [%d] %s, [%d] %s\n", + $i, mysqli_connect_errno(), mysqli_connect_error(), + mysqli_errno($links[$i]), mysqli_error($links[$i])); + + for ($i = 1; $i <= 5; $i++) { + if ($res = mysqli_query($links[$i], 'SELECT id FROM test LIMIT 1')) { + printf("[%03d] Can run query on link %d\n", 5 + $i, $i); + mysqli_free_result($res); + } + mysqli_close($links[$i]); + } + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +bool(true) +int(1) + +Warning: mysqli_%sonnect(): Too many open links (1) in %s on line %d + +Warning: mysqli_%sonnect(): Too many open links (1) in %s on line %d + +Warning: mysqli_%sonnect(): Too many open links (1) in %s on line %d + +Warning: mysqli_%sonnect(): Too many open links (1) in %s on line %d + +Warning: mysqli_%sonnect(): Too many open links (1) in %s on line %d + +Warning: mysqli_query() expects parameter 1 to be mysqli, boolean given in %s on line %d + +Warning: mysqli_close() expects parameter 1 to be mysqli, boolean given in %s on line %d + +Warning: mysqli_query() expects parameter 1 to be mysqli, boolean given in %s on line %d + +Warning: mysqli_close() expects parameter 1 to be mysqli, boolean given in %s on line %d + +Warning: mysqli_query() expects parameter 1 to be mysqli, boolean given in %s on line %d + +Warning: mysqli_close() expects parameter 1 to be mysqli, boolean given in %s on line %d + +Warning: mysqli_query() expects parameter 1 to be mysqli, boolean given in %s on line %d + +Warning: mysqli_close() expects parameter 1 to be mysqli, boolean given in %s on line %d + +Warning: mysqli_query() expects parameter 1 to be mysqli, boolean given in %s on line %d + +Warning: mysqli_close() expects parameter 1 to be mysqli, boolean given in %s on line %d +done! diff --git a/ext/mysqli/tests/mysqli_more_results.phpt b/ext/mysqli/tests/mysqli_more_results.phpt new file mode 100644 index 0000000..271c63e --- /dev/null +++ b/ext/mysqli/tests/mysqli_more_results.phpt @@ -0,0 +1,114 @@ +--TEST-- +mysqli_more_results() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $strict_on = false; + if (defined('E_STRICT')) { + error_reporting(((int)ini_get('error_reporting')) | E_STRICT ); + $strict_on = true; + } + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_more_results())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_more_results($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + print "[004]\n"; + var_dump(mysqli_more_results($link)); + + if (!mysqli_multi_query($link, "SELECT 1 AS a; SELECT 1 AS a, 2 AS b; SELECT id FROM test ORDER BY id LIMIT 3")) + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + print "[006]\n"; + $i = 1; + + if ($strict_on) + ob_start(); + + if (mysqli_get_server_version($link) > 41000 && !($ret = mysqli_more_results($link))) + printf("[007] Expecting boolean/true, got %s/%s\n", gettype($ret), $ret); + do { + $res = mysqli_store_result($link); + mysqli_free_result($res); + if (mysqli_more_results($link)) + printf("%d\n", $i++); + } while (mysqli_next_result($link)); + + if ($strict_on) { + $tmp = ob_get_contents(); + ob_end_clean(); + if (!preg_match('@Strict Standards: mysqli_next_result\(\): There is no next result set@ismU', $tmp)) { + printf("[008] Strict Standards warning missing\n"); + } else { + $tmp = trim(preg_replace('@Strict Standards: mysqli_next_result\(\).*on line \d+@ism', '', $tmp)); + } + print trim($tmp) . "\n"; + } + + if (!mysqli_multi_query($link, "SELECT 1 AS a; SELECT 1 AS a, 2 AS b; SELECT id FROM test ORDER BY id LIMIT 3")) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + print "[010]\n"; + $i = 1; + if (mysqli_get_server_version($link) > 41000 && !($ret = mysqli_more_results($link))) + printf("[011] Expecting boolean/true, got %s/%s\n", gettype($ret), $ret); + + if ($strict_on) + ob_start(); + do { + $res = mysqli_use_result($link); + // NOTE: if you use mysqli_use_result() with mysqli_more_results() or any other info function, + // you must fetch all rows before you can loop to the next result set! + // See also the MySQL Reference Manual: mysql_use_result() + while ($row = mysqli_fetch_array($res)) + ; + mysqli_free_result($res); + if (mysqli_more_results($link)) + printf("%d\n", $i++); + } while (mysqli_next_result($link)); + + if ($strict_on) { + $tmp = ob_get_contents(); + ob_end_clean(); + if (!preg_match('@Strict Standards: mysqli_next_result\(\): There is no next result set@ismU', $tmp)) { + printf("[008] Strict Standards warning missing\n"); + } else { + $tmp = trim(preg_replace('@Strict Standards: mysqli_next_result\(\).*on line \d+@ism', '', $tmp)); + } + print trim($tmp) . "\n"; + } + mysqli_close($link); + + var_dump(mysqli_more_results($link)); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +[004] +bool(false) +[006] +1 +2 +[010] +1 +2 + +Warning: mysqli_more_results(): Couldn't fetch mysqli in %s on line %d +NULL +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_multi_query.phpt b/ext/mysqli/tests/mysqli_multi_query.phpt new file mode 100644 index 0000000..91c07c2 --- /dev/null +++ b/ext/mysqli/tests/mysqli_multi_query.phpt @@ -0,0 +1,162 @@ +--TEST-- +mysqli_multi_query() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $strict_on = false; + if (defined('E_STRICT')) { + error_reporting(((int)ini_get('error_reporting')) | E_STRICT ); + $strict_on = true; + } + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_multi_query())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_multi_query($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (false !== ($tmp = mysqli_multi_query($link, ""))) + printf("[003] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_multi_query($link, "SELECT 1 AS a; SELECT 1 AS a, 2 AS b; SELECT id FROM test ORDER BY id LIMIT 3")) + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ($strict_on) + ob_start(); + + $i = 0; + do { + $res = mysqli_store_result($link); + while ($row = mysqli_fetch_array($res)) + ; + mysqli_free_result($res); + $i++; + } while (mysqli_next_result($link)); + + if ($strict_on) { + $tmp = ob_get_contents(); + ob_end_clean(); + if (!preg_match('@Strict Standards: mysqli_next_result\(\): There is no next result set@ismU', $tmp)) { + printf("[005a] Strict Standards warning missing\n"); + } else { + $tmp = trim(preg_replace('@Strict Standards: mysqli_next_result\(\).*on line \d+@ism', '', $tmp)); + } + print trim($tmp) . "\n"; + } + + printf("[006] %d\n", $i); + + if (!mysqli_multi_query($link, "ALTER TABLE test MODIFY id INT AUTO_INCREMENT; INSERT INTO test(label) VALUES ('a'); SELECT id, label FROM test ORDER BY id")) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $i = 0; + while (mysqli_next_result($link) && ($res = mysqli_store_result($link))) { + + while ($row = mysqli_fetch_array($res)) + ; + mysqli_free_result($res); + printf("%d/%d\n", $i, mysqli_insert_id($link)); + $i++; + } + printf("[008] %d\n", $i); + + if (!mysqli_multi_query($link, "SELECT id, label FROM test")) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ($strict_on) + ob_start(); + $i = 0; + while (mysqli_next_result($link) && ($res = mysqli_store_result($link))) { + while ($row = mysqli_fetch_array($res)) + $i++; + mysqli_free_result($res); + } + if ($strict_on) { + $tmp = ob_get_contents(); + ob_end_clean(); + if (!preg_match('@Strict Standards: mysqli_next_result\(\): There is no next result set@ismU', $tmp)) { + printf("[009a] Strict Standards warning missing\n"); + } else { + $tmp = trim(preg_replace('@Strict Standards: mysqli_next_result\(\).*on line \d+@ism', '', $tmp)); + } + print trim($tmp) . "\n"; + } + printf("[010] %d\n", $i); + + if (!mysqli_multi_query($link, "SELECT 1 AS num, 'a' AS somechar; SELECT 2 AS num, 'a' AS somechar; SELECT 3 AS num, 'a' AS somechar")) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $res_num = 1; + do { + if (!$res = mysqli_store_result($link)) { + printf("[012 - %d] [%d] %s\n", $res_num, mysqli_errno($link), mysqli_error($link)); + continue; + } + + $num_rows = 0; + while ($row = mysqli_fetch_array($res)) { + + $num_rows++; + if ($row['num'] != $res_num) + printf("[013 - %d] Expecting %s got %s\n", $res_num, $res_num, $row['num']); + if ($row['somechar'] != "a") + printf("[014 - %d] Expecting a got %s\n", $res_num, $row['somechar']); + + if (1 == $num_rows) { + /* simple metadata check */ + if (!($lengths = mysqli_fetch_lengths($res))) + printf("[015 - %d] [%d] %s\n", $res_num, mysqli_errno($link), mysqli_error($link)); + + if (count($lengths) != 2) + printf("[016 - %d] Expecting 2 column lengths got %d [%d] %s\n", $res_num, count($lengths)); + + foreach ($lengths as $k => $length) + if ($length <= 0) + printf("[017 - %d] Strange column lengths for column %d, got %d expecting any > 0\n", + $res_num, $k, $length); + } + } + + if ($num_rows != 1) + printf("[018 - %d] Expecting 1 row, got %d rows\n", $num_rows); + + $res_num++; + + mysqli_free_result($res); + + } while (@mysqli_next_result($link)); + + if ($res_num != 4) + printf("[015] Expecting 3 result sets got %d result set[s]\n", $res_num); + + mysqli_close($link); + + var_dump(mysqli_multi_query($link, "SELECT id, label FROM test")); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +[006] 3 +[008] 0 +[009] [2014] Commands out of sync; you can't run this command now + +[010] 7 + +Warning: mysqli_multi_query(): Couldn't fetch mysqli in %s on line %d +NULL +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_mysqli_result_invalid_mode.phpt b/ext/mysqli/tests/mysqli_mysqli_result_invalid_mode.phpt new file mode 100644 index 0000000..29ff657 --- /dev/null +++ b/ext/mysqli/tests/mysqli_mysqli_result_invalid_mode.phpt @@ -0,0 +1,30 @@ +--TEST-- +mysqli_result(), invalid mode +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require('connect.inc'); + require('table.inc'); + + $valid = array(MYSQLI_STORE_RESULT, MYSQLI_USE_RESULT); + do { + $mode = mt_rand(-1000, 1000); + } while (in_array($mode, $valid)); + + if (!is_object($res = new mysqli_result($link, $mode))) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_result::__construct(): Invalid value for resultmode in %s on line %d +done! diff --git a/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt new file mode 100644 index 0000000..67a5ab6 --- /dev/null +++ b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt @@ -0,0 +1,36 @@ +--TEST-- +mysqlnd.net_read_timeout limit check +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); +if (!$IS_MYSQLND) + /* The libmysql read_timeout limit default is 365 * 24 * 3600 seconds. It cannot be altered through PHP API calls */ + die("skip mysqlnd only test"); +?> +--INI-- +default_socket_timeout=60 +max_execution_time=60 +mysqlnd.net_read_timeout=1 +--FILE-- +<?php + include ("connect.inc"); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[001] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + } + + if (!$res = mysqli_query($link, "SELECT SLEEP(5)")) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_close($link); + + print "done!"; +?> +--EXPECTF-- +Warning: mysqli_query(): MySQL server has gone away in %s on line %d + +Warning: mysqli_query(): Error reading result set's header in %s on line %d +[002] [%d] %s +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_mysqlnd_read_timeout_long.phpt b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout_long.phpt new file mode 100644 index 0000000..fcbf4e6 --- /dev/null +++ b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout_long.phpt @@ -0,0 +1,48 @@ +--TEST-- +mysqlnd.net_read_timeout > default_socket_timeout +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!$IS_MYSQLND) { + die("skip: test applies only to mysqlnd"); +} + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf('skip Cannot connect to MySQL, [%d] %s.', mysqli_connect_errno(), mysqli_connect_error())); +} +if (mysqli_get_server_version($link) <= 50011) { + die(sprintf('skip Needs MySQL 5.0.12+, found version %d.', mysqli_get_server_version($link))); +} +?> +--INI-- +default_socket_timeout=1 +mysqlnd.net_read_timeout=12 +max_execution_time=12 +--FILE-- +<?php + set_time_limit(12); + include ("connect.inc"); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[001] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + } + + if (!$res = mysqli_query($link, "SELECT SLEEP(6)")) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + var_dump($res->fetch_assoc()); + + mysqli_free_result($res); + mysqli_close($link); + + print "done!"; +?> +--EXPECTF-- +array(1) { + [%u|b%"SLEEP(6)"]=> + %unicode|string%(1) "0" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_mysqlnd_read_timeout_zero.phpt b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout_zero.phpt new file mode 100644 index 0000000..eb4c431 --- /dev/null +++ b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout_zero.phpt @@ -0,0 +1,47 @@ +--TEST-- +mysqlnd.net_read_timeout = 0 +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!$IS_MYSQLND) { + die("skip: test applies only to mysqlnd"); +} + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf('skip Cannot connect to MySQL, [%d] %s.', mysqli_connect_errno(), mysqli_connect_error())); +} +if (mysqli_get_server_version($link) <= 50011) { + die(sprintf('skip Needs MySQL 5.0.12+, found version %d.', mysqli_get_server_version($link))); +} +?> +--INI-- +default_socket_timeout=10 +max_execution_time=10 +mysqlnd.net_read_timeout=0 +--FILE-- +<?php + include ("connect.inc"); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[001] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + } + + if (!$res = mysqli_query($link, "SELECT SLEEP(2)")) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + var_dump($res->fetch_assoc()); + + mysqli_free_result($res); + mysqli_close($link); + + print "done!"; +?> +--EXPECTF-- +array(1) { + [%u|b%"SLEEP(2)"]=> + %unicode|string%(1) "0" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_next_result.phpt b/ext/mysqli/tests/mysqli_next_result.phpt new file mode 100644 index 0000000..c36920e --- /dev/null +++ b/ext/mysqli/tests/mysqli_next_result.phpt @@ -0,0 +1,124 @@ +--TEST-- +mysqli_next_result() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $strict_on = false; + if (defined('E_STRICT')) { + error_reporting(((int)ini_get('error_reporting')) | E_STRICT ); + $strict_on = true; + } + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_next_result())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_next_result($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if ($strict_on) + ob_start(); + + if (false !== ($tmp = mysqli_next_result($link))) + printf("[003] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if ($strict_on) { + $tmp = ob_get_contents(); + ob_end_clean(); + if (!preg_match('@Strict Standards: mysqli_next_result\(\): There is no next result set@ismU', $tmp)) { + printf("[003a] Strict Standards warning missing\n"); + } else { + $tmp = trim(preg_replace('@Strict Standards: mysqli_next_result\(\).*on line \d+@ism', '', $tmp)); + } + print trim($tmp) . "\n"; + ob_start(); + } + + $res = mysqli_query($link, "SELECT 1 AS res"); + if (false !== ($tmp = mysqli_next_result($link))) + printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if ($strict_on) { + $tmp = ob_get_contents(); + ob_end_clean(); + if (!preg_match('@Strict Standards: mysqli_next_result\(\): There is no next result set@ismU', $tmp)) { + printf("[004a] Strict Standards warning missing\n"); + } else { + $tmp = trim(preg_replace('@Strict Standards: mysqli_next_result\(\).*on line \d+@ism', '', $tmp)); + } + print trim($tmp) . "\n"; + } + + mysqli_free_result($res); + + function func_test_mysqli_next_result($link, $query, $offset, $num_results, $strict_on) { + + if (!mysqli_multi_query($link, $query)) + printf("[%03d] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link)); + + $i = 0; + if ($strict_on) + ob_start(); + + do { + if ($res = mysqli_store_result($link)) { + mysqli_free_result($res); + $i++; + } + } while (true === mysqli_next_result($link)); + + if ($strict_on) { + $tmp = ob_get_contents(); + ob_end_clean(); + if (!preg_match('@Strict Standards: mysqli_next_result\(\): There is no next result set@ismU', $tmp)) { + printf("[%03d] Strict Standards warning missing\n", $offset + 1); + } else { + $tmp = trim(preg_replace('@Strict Standards: mysqli_next_result\(\).*on line \d+@ism', '', $tmp)); + } + print trim($tmp) . "\n"; + } + + if ($i !== $num_results) { + printf("[%03d] Expecting %d result(s), got %d result(s)\n", $offset + 2, $num_results, $i); + } + + if (mysqli_more_results($link)) + printf("[%03d] mysqli_more_results() indicates more results than expected\n", $offset + 3); + + if (!($res = mysqli_query($link, "SELECT 1 AS b"))) { + printf("[%03d] [%d] %s\n", $offset + 4, mysqli_errno($link), mysqli_error($link)); + } else { + mysqli_free_result($res); + } + + } + + func_test_mysqli_next_result($link, "SELECT 1 AS a; SELECT 1 AS a, 2 AS b; SELECT id FROM test ORDER BY id LIMIT 3", 5, 3, $strict_on); + func_test_mysqli_next_result($link, "SELECT 1 AS a; INSERT INTO test(id, label) VALUES (100, 'y'); SELECT 1 AS a, 2 AS b", 8, 2, $strict_on); + func_test_mysqli_next_result($link, "DELETE FROM test WHERE id >= 100; SELECT 1 AS a; ", 11, 1, $strict_on); + + mysqli_close($link); + + var_dump(mysqli_next_result($link)); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_next_result(): Couldn't fetch mysqli in %s on line %d +NULL +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_no_reconnect.phpt b/ext/mysqli/tests/mysqli_no_reconnect.phpt new file mode 100644 index 0000000..653c672 --- /dev/null +++ b/ext/mysqli/tests/mysqli_no_reconnect.phpt @@ -0,0 +1,127 @@ +--TEST-- +Trying implicit reconnect after wait_timeout and KILL using mysqli_ping() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +mysqli.reconnect=0 +--FILE-- +<?php + require_once("connect.inc"); + require_once("table.inc"); + + if (!$link2 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot create second database connection, [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error()); + + $thread_id_timeout = mysqli_thread_id($link); + $thread_id_control = mysqli_thread_id($link2); + + if (!$res = mysqli_query($link2, "SHOW FULL PROCESSLIST")) + printf("[002] Cannot get full processlist, [%d] %s\n", + mysqli_errno($link2), mysqli_error($link)); + + $running_threads = array(); + while ($row = mysqli_fetch_assoc($res)) + $running_threads[$row['Id']] = $row; + mysqli_free_result($res); + + if (!isset($running_threads[$thread_id_timeout]) || + !isset($running_threads[$thread_id_control])) + printf("[003] Processlist is borked, [%d] %s\n", + mysqli_errno($link2), mysqli_error($link)); + + if (!mysqli_query($link, "SET SESSION wait_timeout = 2")) + printf("[004] Cannot set wait_timeout, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, "SHOW VARIABLES LIKE 'wait_timeout'")) + printf("[005] Cannot check if wait_timeout has been set, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[006] Cannot get wait_timeout, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + + if ($row['Value'] != 2) + printf("[007] Failed setting the wait_timeout, test will not work, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + // after 2+ seconds the server should kill the connection + sleep(3); + + if (!$res = mysqli_query($link2, "SHOW FULL PROCESSLIST")) + printf("[008] Cannot get full processlist, [%d] %s\n", + mysqli_errno($link2), mysqli_error($link)); + + $running_threads = array(); + while ($row = mysqli_fetch_assoc($res)) + $running_threads[$row['Id']] = $row; + mysqli_free_result($res); + + if (isset($running_threads[$thread_id_timeout])) + printf("[009] Server should have killed the timeout connection, [%d] %s\n", + mysqli_errno($link2), mysqli_error($link)); + + if (false !== @mysqli_ping($link)) + printf("[010] Reconnect should not have happened"); + + if ($res = @mysqli_query($link, "SELECT DATABASE() as _dbname")) + printf("[011] Executing a query should not be possible, connection should be closed, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + if (!$link = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[012] Cannot create database connection, [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error()); + + $thread_id_timeout = mysqli_thread_id($link); + /* + Don't test for the mysqli_query() return value here. + It is undefined if the server replies to the query and how. + For example, it seems that on Linux when connecting to MySQL 5.1, + the server always manages to send a full a reply. Whereas MySQl 5.5 + may not. The behaviour is undefined. Any return value is fine. + */ + if ($IS_MYSQLND) { + /* + mysqlnd is a bit more verbose than libmysql. mysqlnd should print: + Warning: mysqli_query(): MySQL server has gone away in %s on line %d + + Warning: mysqli_query(): Error reading result set's header in %d on line %d + */ + @mysqli_query($link, sprintf('KILL %d', $thread_id_timeout)); + } else { + mysqli_query($link, sprintf('KILL %d', $thread_id_timeout)); + } + // Give the server a second to really kill the other thread... + sleep(1); + + if (!$res = mysqli_query($link2, "SHOW FULL PROCESSLIST")) + printf("[014] Cannot get full processlist, [%d] %s\n", + mysqli_errno($link2), mysqli_error($link)); + + $running_threads = array(); + while ($row = mysqli_fetch_assoc($res)) + $running_threads[$row['Id']] = $row; + mysqli_free_result($res); + + if (isset($running_threads[$thread_id_timeout]) || + !isset($running_threads[$thread_id_control])) + printf("[015] Processlist is borked, [%d] %s\n", + mysqli_errno($link2), mysqli_error($link)); + + if (false !== ($tmp = @mysqli_ping($link))) + printf("[016] Expecting boolean/false got %s/%s\n", gettype($tmp), $tmp); + + if ($res = @mysqli_query($link, "SELECT DATABASE() as _dbname")) + printf("[017] Running a query should not be possible, connection should be gone, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + mysqli_close($link2); + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_num_fields.phpt b/ext/mysqli/tests/mysqli_num_fields.phpt new file mode 100644 index 0000000..4c2510a --- /dev/null +++ b/ext/mysqli/tests/mysqli_num_fields.phpt @@ -0,0 +1,57 @@ +--TEST-- +mysqli_num_fields() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_num_fields())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_num_fields($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + function func_test_mysqli_num_fields($link, $query, $expected, $offset, $test_free = false) { + + if (!($res = mysqli_query($link, $query))) { + printf("[%03d] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link)); + return; + } + + if ($expected !== ($tmp = mysqli_num_fields($res))) + printf("[%03d] Expecting %s/%d, got %s/%d\n", $offset + 1, + gettype($expected), $expected, + gettype($tmp), $tmp); + + mysqli_free_result($res); + + if ($test_free && (NULL !== ($tmp = mysqli_num_fields($res)))) + printf("[%03d] Expecting NULL, got %s/%s\n", $offset + 2, gettype($tmp), $tmp); + } + + func_test_mysqli_num_fields($link, "SELECT 1 AS a", 1, 5); + func_test_mysqli_num_fields($link, "SELECT id, label FROM test", 2, 10); + func_test_mysqli_num_fields($link, "SELECT 1 AS a, NULL AS b, 'foo' AS c", 3, 15); + func_test_mysqli_num_fields($link, "SELECT id FROM test", 1, 20, true); + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_num_fields(): Couldn't fetch mysqli_result in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_num_rows.phpt b/ext/mysqli/tests/mysqli_num_rows.phpt new file mode 100644 index 0000000..376ddd4 --- /dev/null +++ b/ext/mysqli/tests/mysqli_num_rows.phpt @@ -0,0 +1,89 @@ +--TEST-- +mysqli_num_rows() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_num_rows())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_num_rows($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + function func_test_mysqli_num_rows($link, $query, $expected, $offset, $test_free = false) { + + if (!$res = mysqli_query($link, $query, MYSQLI_STORE_RESULT)) { + printf("[%03d] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link)); + return; + } + + if ($expected !== ($tmp = mysqli_num_rows($res))) + printf("[%03d] Expecting %s/%d, got %s/%d\n", $offset + 1, + gettype($expected), $expected, + gettype($tmp), $tmp); + + mysqli_free_result($res); + + if ($test_free && (NULL !== ($tmp = mysqli_num_rows($res)))) + printf("[%03d] Expecting NULL, got %s/%s\n", $offset + 2, gettype($tmp), $tmp); + + } + + func_test_mysqli_num_rows($link, "SELECT 1 AS a", 1, 5); + func_test_mysqli_num_rows($link, "SHOW VARIABLES LIKE '%nixnutz%'", 0, 10); + func_test_mysqli_num_rows($link, "INSERT INTO test(id, label) VALUES (100, 'z')", NULL, 15); + func_test_mysqli_num_rows($link, "SELECT id FROM test LIMIT 2", 2, 20, true); + + if ($res = mysqli_query($link, 'SELECT COUNT(id) AS num FROM test')) { + + $row = mysqli_fetch_assoc($res); + mysqli_free_result($res); + + func_test_mysqli_num_rows($link, "SELECT id, label FROM test", (int)$row['num'], 25); + + } else { + printf("[030] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + print "run_tests.php don't fool me with your 'ungreedy' expression '.+?'!\n"; + + if ($res = mysqli_query($link, 'SELECT id FROM test', MYSQLI_USE_RESULT)) { + + $row = mysqli_fetch_row($res); + if (0 !== ($tmp = mysqli_num_rows($res))) + printf("[031] Expecting int/0, got %s/%d\n", gettype($tmp), $tmp); + + mysqli_free_result($res); + + } else { + printf("[032] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given in %s on line %d + +Warning: mysqli_free_result() expects parameter 1 to be mysqli_result, boolean given in %s on line %d + +Warning: mysqli_num_rows(): Couldn't fetch mysqli_result in %s on line %d +run_tests.php don't fool me with your 'ungreedy' expression '.+?'! + +Warning: mysqli_num_rows(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_options.phpt b/ext/mysqli/tests/mysqli_options.phpt new file mode 100644 index 0000000..2f7986d --- /dev/null +++ b/ext/mysqli/tests/mysqli_options.phpt @@ -0,0 +1,143 @@ +--TEST-- +mysqli_options() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $valid_options = array( + MYSQLI_READ_DEFAULT_GROUP => "MYSQLI_READ_DEFAULT_GROUP", + MYSQLI_READ_DEFAULT_FILE => "MYSQLI_READ_DEFAUTL_FILE", + MYSQLI_OPT_CONNECT_TIMEOUT => "MYSQLI_OPT_CONNECT_TIMEOUT", + MYSQLI_OPT_LOCAL_INFILE => "MYSQLI_OPT_LOCAL_INFILE", + MYSQLI_INIT_COMMAND => "MYSQLI_INIT_COMMAND", + MYSQLI_SET_CHARSET_NAME => "MYSQLI_SET_CHARSET_NAME", + MYSQLI_OPT_SSL_VERIFY_SERVER_CERT => "MYSQLI_OPT_SSL_VERIFY_SERVER_CERT", + ); + + if ($IS_MYSQLND && defined('MYSQLI_OPT_NET_CMD_BUFFER_SIZE')) + $valid_options[] = constant('MYSQLI_OPT_NET_CMD_BUFFER_SIZE'); + if ($IS_MYSQLND && defined('MYSQLI_OPT_NET_READ_BUFFER_SIZE')) + $valid_options[] = constant('MYSQLI_OPT_NET_READ_BUFFER_SIZE'); + if ($IS_MYSQLND && defined('MYSQLI_OPT_INT_AND_FLOAT_NATIVE')) + $valid_options[] = constant('MYSQLI_OPT_INT_AND_FLOAT_NATIVE'); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_options())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_options($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + $link = mysqli_init(); + + /* set it twice, checking if memory for the previous one is correctly freed */ + mysqli_options($link, MYSQLI_SET_CHARSET_NAME, "utf8"); + mysqli_options($link, MYSQLI_SET_CHARSET_NAME, "latin1"); + + if (!is_null($tmp = @mysqli_options($link, MYSQLI_OPT_CONNECT_TIMEOUT))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_options($link, "s", 'extra_my.cnf'))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_options($link, MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT=0', 'foo'))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + // print "run_tests.php don't fool me with your 'ungreedy' expression '.+?'!\n"; + var_dump("MYSQLI_READ_DEFAULT_GROUP", mysqli_options($link, MYSQLI_READ_DEFAULT_GROUP, 'extra_my.cnf')); + var_dump("MYSQLI_READ_DEFAULT_FILE", mysqli_options($link, MYSQLI_READ_DEFAULT_FILE, 'extra_my.cnf')); + var_dump("MYSQLI_OPT_CONNECT_TIMEOUT", mysqli_options($link, MYSQLI_OPT_CONNECT_TIMEOUT, 10)); + var_dump("MYSQLI_OPT_LOCAL_INFILE", mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, 1)); + var_dump("MYSQLI_INIT_COMMAND", mysqli_options($link, MYSQLI_INIT_COMMAND, array('SET AUTOCOMMIT=0', 'SET AUTOCOMMIT=1'))); + + + if (!$link2 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[006] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!$res = mysqli_query($link2, 'SELECT version() AS server_version')) + printf("[007] [%d] %s\n", mysqli_errno($link2), mysqli_error($link2)); + $tmp = mysqli_fetch_assoc($res); + mysqli_free_result($res); + $version = explode('.', $tmp['server_version']); + if (empty($version)) + printf("[008] Cannot determine server version, need MySQL Server 4.1+ for the test!\n"); + + if ($version[0] <= 4 && $version[1] < 1) + printf("[009] Need MySQL Server 4.1+ for the test!\n"); + + if (!$res = mysqli_query($link2, "SHOW CHARACTER SET")) + printf("[010] Cannot get list of available character sets, [%d] %s\n", + mysqli_errno($link2), mysqli_error($link2)); + + $charsets = array(); + while ($row = mysqli_fetch_assoc($res)) + $charsets[] = $row; + mysqli_free_result($res); + mysqli_close($link2); + + foreach ($charsets as $charset) { + $k = $charset['Charset']; + /* The server currently 17.07.2007 can't handle data sent in ucs2 */ + /* The server currently 16.08.2010 can't handle data sent in utf16 and utf32 */ + if ($charset['Charset'] == 'ucs2' || $charset['Charset'] == 'utf16' || $charset['Charset'] == 'utf32') { + continue; + } + if (true !== mysqli_options($link, MYSQLI_SET_CHARSET_NAME, $charset['Charset'])) { + printf("[009] Setting charset name '%s' has failed\n", $charset['Charset']); + } + } + + var_dump("MYSQLI_READ_DEFAULT_GROUP", mysqli_options($link, MYSQLI_READ_DEFAULT_GROUP, 'extra_my.cnf')); + var_dump("MYSQLI_READ_DEFAULT_FILE", mysqli_options($link, MYSQLI_READ_DEFAULT_FILE, 'extra_my.cnf')); + var_dump("MYSQLI_OPT_CONNECT_TIMEOUT", mysqli_options($link, MYSQLI_OPT_CONNECT_TIMEOUT, 10)); + var_dump("MYSQLI_OPT_LOCAL_INFILE", mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, 1)); + var_dump("MYSQLI_INIT_COMMAND", mysqli_options($link, MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT=0')); + + /* mysqli_real_connect() */ + var_dump("MYSQLI_CLIENT_SSL", mysqli_options($link, MYSQLI_CLIENT_SSL, 'not a mysqli_option')); + + mysqli_close($link); + + echo "Link closed"; + var_dump("MYSQLI_INIT_COMMAND", mysqli_options($link, MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT=1')); + print "done!"; +?> +--EXPECTF-- +%s(25) "MYSQLI_READ_DEFAULT_GROUP" +bool(true) +%s(24) "MYSQLI_READ_DEFAULT_FILE" +bool(true) +%s(26) "MYSQLI_OPT_CONNECT_TIMEOUT" +bool(true) +%s(23) "MYSQLI_OPT_LOCAL_INFILE" +bool(true) + +Notice: Array to string conversion in %s on line %d +%s(19) "MYSQLI_INIT_COMMAND" +bool(true) +%s(25) "MYSQLI_READ_DEFAULT_GROUP" +bool(true) +%s(24) "MYSQLI_READ_DEFAULT_FILE" +bool(true) +%s(26) "MYSQLI_OPT_CONNECT_TIMEOUT" +bool(true) +%s(23) "MYSQLI_OPT_LOCAL_INFILE" +bool(true) +%s(19) "MYSQLI_INIT_COMMAND" +bool(true) +%s(17) "MYSQLI_CLIENT_SSL" +bool(false) +Link closed +Warning: mysqli_options(): Couldn't fetch mysqli in %s line %d +%s(19) "MYSQLI_INIT_COMMAND" +NULL +done! diff --git a/ext/mysqli/tests/mysqli_options_init_command.phpt b/ext/mysqli/tests/mysqli_options_init_command.phpt new file mode 100644 index 0000000..a78dfca --- /dev/null +++ b/ext/mysqli/tests/mysqli_options_init_command.phpt @@ -0,0 +1,78 @@ +--TEST-- +mysqli_options() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +<?php require_once('skipifemb.inc'); ?> +--FILE-- +<?php + /* see mysqli.c for details */ + require_once("connect.inc"); + + if (!($link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + /* TODO: test more options */ + if (!mysqli_query($link, "DROP TABLE IF EXISTS test") || + !mysqli_query($link, sprintf("CREATE TABLE test(id INT) ENGINE = %s\n", $engine)) || + !mysqli_query($link, "INSERT INTO test(id) VALUES (1)")) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, "SELECT COUNT(id) AS _num_rows FROM test")) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $row = mysqli_fetch_assoc($res); + mysqli_free_result($res); + + if ($row['_num_rows'] != 1) + printf("[003] Expecting 1 got %s\n", $row['_num_rows']); + + mysqli_close($link); + + $link = mysqli_init(); + if (true !== mysqli_options($link, MYSQLI_INIT_COMMAND, "INSERT INTO test(id) VALUES (2)")) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) + printf("[005] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!$res = mysqli_query($link, "SELECT COUNT(id) AS _num_rows FROM test")) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $row = mysqli_fetch_assoc($res); + mysqli_free_result($res); + + if ($row['_num_rows'] != 2) + printf("[007] Expecting 1 got %s\n", $row['_num_rows']); + + mysqli_close($link); + + $link = mysqli_init(); + if (true !== mysqli_options($link, MYSQLI_INIT_COMMAND, "INSERT INTO test(i_do_no_exist) VALUES (2)")) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_close($link); + + $link = mysqli_init(); + if (true !== mysqli_options($link, MYSQLI_INIT_COMMAND, "INSERT INTO test(i_do_no_exist) VALUES (2)")) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) + printf("[010] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_real_connect(): (%s/%d): %s in %s on line %d +[010] Cannot connect to the server using %s +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_options_int_and_float_native.phpt b/ext/mysqli/tests/mysqli_options_int_and_float_native.phpt new file mode 100644 index 0000000..4b0c947 --- /dev/null +++ b/ext/mysqli/tests/mysqli_options_int_and_float_native.phpt @@ -0,0 +1,109 @@ +--TEST-- +mysqli_options() - MYSQLI_OPT_INT_AND_FLOAT_NATIVE +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +require_once('connect.inc'); +if (!$IS_MYSQLND) + die("skip mysqlnd only test"); +?> +--FILE-- +<?php + require_once("connect.inc"); + + + $types = array( + 'BIT' => array('BIT(8)', 0), + 'TINYINT' => array('TINYINT', 120), + 'BOOL' => array('BOOL', 0), + 'BOOLEAN' => array('BOOLEAN', 1), + 'SMALLINT' => array('SMALLINT', 32000), + 'MEDIUMINT' => array('MEDIUMINT', 999), + 'INT' => array('INT', 999), + 'BIGINT' => array('BIGINT', 999), + 'FLOAT' => array('FLOAT', 1.3), + 'DOUBLE' => array('DOUBLE', -1.3), + ); + + foreach ($types as $name => $data) { + $link = mysqli_init(); + if (!mysqli_options($link, MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1)) { + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + continue; + } + + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) { + printf("[002] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + continue; + } + + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) { + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + continue; + } + + if (!mysqli_query($link, sprintf("CREATE TABLE test (id %s)", $data[0]))) { + printf("[004] TODO [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + continue; + } + + if (!mysqli_query($link, sprintf("INSERT INTO test(id) VALUES (%f)", $data[1]))) { + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + continue; + } + + if (!$res = mysqli_query($link, "SELECT id FROM test")) { + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + continue; + } + + $row = mysqli_fetch_assoc($res); + mysqli_free_result($res); + + if ($row['id'] !== $data[1]) { + printf("[007] Expecting %s - %s/%s got %s/%s\n", + $name, + $data[1], gettype($data[1]), $row['id'], gettype($row['id'])); + } + mysqli_close($link); + + $link = mysqli_init(); + if (!mysqli_options($link, MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 0)) { + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + continue; + } + + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) { + printf("[009] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + continue; + } + + if (!$res = mysqli_query($link, "SELECT id FROM test")) { + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + continue; + } + + $row = mysqli_fetch_assoc($res); + mysqli_free_result($res); + + if (!is_string($row['id']) || ($row['id'] != $data[1])) { + printf("[011] Expecting %s - %s/string got %s/%s\n", + $name, + $data[1], $row['id'], gettype($row['id'])); + } + mysqli_close($link); + + } + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_options_openbasedir.phpt b/ext/mysqli/tests/mysqli_options_openbasedir.phpt new file mode 100644 index 0000000..4c13ec1 --- /dev/null +++ b/ext/mysqli/tests/mysqli_options_openbasedir.phpt @@ -0,0 +1,23 @@ +--TEST-- +mysqli_options() - MYSQLI_OPT_LOCAL_INFILE and open_basedir +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once('connect.inc'); + ini_set("open_basedir", __DIR__); + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (false !== mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, 1)) + printf("[002] Can set MYSQLI_OPT_LOCAL_INFILE although open_basedir is set!\n"); + + mysqli_close($link); + print "done!"; +?> +--EXPECTF-- +done! diff --git a/ext/mysqli/tests/mysqli_pconn_conn_multiple.phpt b/ext/mysqli/tests/mysqli_pconn_conn_multiple.phpt new file mode 100644 index 0000000..adc2671 --- /dev/null +++ b/ext/mysqli/tests/mysqli_pconn_conn_multiple.phpt @@ -0,0 +1,161 @@ +--TEST-- +Calling connect() on an open persistent connection to create a new persistent connection +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +mysqli.allow_persistent=1 +mysqli.max_persistent=-1 +mysqli.max_links=-1 +--FILE-- +<?php + require_once("connect.inc"); + + $phost = 'p:' . $host; + + if (!$link = my_mysqli_connect($phost, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $phost, $user, $db, $port, $socket); + + if (!$thread_id = $link->thread_id) + printf("[002] Cannot determine thread id, test will fail, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (true !== ($tmp = my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket))) + printf("[003] Expecting boolean/true got %s/%s\n", gettype($tmp), $tmp); + + if (!is_int($new_thread_id = mysqli_thread_id($link)) || ($new_thread_id < 0)) + printf("[004] Expecting int/any got %s/%s\n", gettype($tmp), $tmp); + + if ($thread_id == $new_thread_id) + printf("[005] Expecting new connection and new thread id. Old thread id %d, new thread id %d\n", $thread_id, $new_thread_id); + + if (!($res = mysqli_query($link, "SELECT 'ok' AS it_works")) || + !($row = mysqli_fetch_assoc($res))) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + var_dump($row); + mysqli_free_result($res); + + mysqli_close($link); + + if (!$link = new my_mysqli($phost, $user, $passwd, $db, $port, $socket)) + printf("[007] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $phost, $user, $db, $port, $socket); + + if (!$thread_id = $link->thread_id) + printf("[008] Cannot determine thread id, test will fail, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (true !== ($tmp = $link->real_connect($host, $user, $passwd, $db, $port, $socket))) + printf("[009] Expecting boolean/true got %s/%s\n", gettype($tmp), $tmp); + + if (!is_int($new_thread_id = $link->thread_id) || ($new_thread_id < 0)) + printf("[010] Expecting int/any got %s/%s\n", gettype($tmp), $tmp); + + if ($thread_id == $new_thread_id) + printf("[011] Expecting new connection and new thread id. Old thread id %d, new thread id %d\n", $thread_id, $new_thread_id); + + if (!($res = $link->query("SELECT 'works also with oo' AS syntax")) || + !($row = $res->fetch_assoc())) + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + var_dump($row); + mysqli_free_result($res); + + mysqli_close($link); + + if (NULL !== ($tmp = $link->connect($phost, $user, $passwd, $db, $port, $socket))) + printf("[013] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = mysqli_connect($phost, $user, $passwd, $db, $port, $socket)) + printf("[014] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $phost, $user, $db, $port, $socket); + + if (NULL !== ($tmp = $link->connect($host, $user, $passwd, $db, $port, $socket))) + printf("[015] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + printf("Flipping phost/host order\n"); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[016] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!$thread_id = mysqli_thread_id($link)) + printf("[017] Cannot determine thread id, test will fail, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (true !== ($tmp = my_mysqli_real_connect($link, $phost, $user, $passwd, $db, $port, $socket))) + printf("[018] Expecting boolean/true got %s/%s\n", gettype($tmp), $tmp); + + if (!is_int($new_thread_id = mysqli_thread_id($link)) || ($new_thread_id < 0)) + printf("[019] Expecting int/any got %s/%s\n", gettype($tmp), $tmp); + + if ($thread_id == $new_thread_id) + printf("[020] Expecting new connection and new thread id. Old thread id %d, new thread id %d\n", $thread_id, $new_thread_id); + + if (!($res = mysqli_query($link, "SELECT 'ok' AS it_works")) || + !($row = mysqli_fetch_assoc($res))) + printf("[021] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + var_dump($row); + mysqli_free_result($res); + + mysqli_close($link); + + if (!$link = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[022] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!$thread_id = $link->thread_id) + printf("[023] Cannot determine thread id, test will fail, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (true !== ($tmp = $link->real_connect($phost, $user, $passwd, $db, $port, $socket))) + printf("[024] Expecting boolean/true got %s/%s\n", gettype($tmp), $tmp); + + if (!is_int($new_thread_id = $link->thread_id) || ($new_thread_id < 0)) + printf("[025] Expecting int/any got %s/%s\n", gettype($tmp), $tmp); + + if ($thread_id == $new_thread_id) + printf("[026] Expecting new connection and new thread id. Old thread id %d, new thread id %d\n", $thread_id, $new_thread_id); + + if (!($res = $link->query("SELECT 'works also with oo' AS syntax")) || + !($row = $res->fetch_assoc())) + printf("[027] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + var_dump($row); + mysqli_free_result($res); + + mysqli_close($link); + + if (NULL !== ($tmp = $link->connect($host, $user, $passwd, $db, $port, $socket))) + printf("[028] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[029] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (NULL !== ($tmp = $link->connect($phost, $user, $passwd, $db, $port, $socket))) + printf("[030] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +array(1) { + [%u|b%"it_works"]=> + %unicode|string%(2) "ok" +} +array(1) { + [%u|b%"syntax"]=> + %unicode|string%(18) "works also with oo" +} +Flipping phost/host order +array(1) { + [%u|b%"it_works"]=> + %unicode|string%(2) "ok" +} +array(1) { + [%u|b%"syntax"]=> + %unicode|string%(18) "works also with oo" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_pconn_disabled.phpt b/ext/mysqli/tests/mysqli_pconn_disabled.phpt new file mode 100644 index 0000000..7222212 --- /dev/null +++ b/ext/mysqli/tests/mysqli_pconn_disabled.phpt @@ -0,0 +1,62 @@ +--TEST-- +mysqli_pconnect() - mysqli.allow_persistent = 0 +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +die("skip TODO - we need to add a user level way to check if CHANGE_USER gets called by pconnect"); +?> +--INI-- +mysqli.allow_persistent=0 +mysqli.max_persistent=2 +mysqli.max_links=2 +--FILE-- +<?php + require_once("connect.inc"); + + $host = 'p:' . $host; + if (!$link1 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + // automatic downgrade to normal connections has failed + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s, [%d] %s\n", + $host, $user, $db, $port, $socket, mysqli_connect_errno(), mysqli_connect_error()); + } + if (!mysqli_query($link1, "SET @pcondisabled = 'Connection 1'")) + printf("[002] Cannot set user variable to check if we got the same persistent connection, [%d] %s\n", + mysqli_errno($link1), mysqli_error($link1)); + + if (!$link2 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + // automatic downgrade to normal connections has failed + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s, [%d] %s\n", + $host, $user, $db, $port, $socket, mysqli_connect_errno(), mysqli_connect_error()); + } + + if (!$res = mysqli_query($link1, 'SELECT @pcondisabled AS _test')) + printf("[004] [%d] %s\n", mysqli_errno($link2), mysqli_error($link2)); + + $row = mysqli_fetch_assoc($res); + printf("Connecction 1 - SELECT @pcondisabled -> '%s'\n", $row['_test']); + mysqli_free_result($res); + + if (!$res = mysqli_query($link2, 'SELECT @pcondisabled AS _test')) + printf("[005] [%d] %s\n", mysqli_errno($link2), mysqli_error($link2)); + + $row = mysqli_fetch_assoc($res); + printf("Connecction 2 - SELECT @pcondisabled -> '%s'\n", $row['_test']); + mysqli_free_result($res); + + if ($link1 === $link2) + printf("[006] Links should not be identical\n"); + + mysqli_close($link1); + mysqli_close($link2); + print "done!"; +?> +--EXPECTF-- +Warning: my_mysqli_connect(): Persistent connections are disabled. Downgrading to normal in %s on line %d + +Warning: my_mysqli_connect(): Persistent connections are disabled. Downgrading to normal in %s on line %d +Connecction 1 - SELECT @pcondisabled -> 'Connection 1' +Connecction 2 - SELECT @pcondisabled -> '' +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_pconn_kill.phpt b/ext/mysqli/tests/mysqli_pconn_kill.phpt new file mode 100644 index 0000000..f8d8d7e --- /dev/null +++ b/ext/mysqli/tests/mysqli_pconn_kill.phpt @@ -0,0 +1,95 @@ +--TEST-- +Killing a persistent connection. +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once("connect.inc"); +?> +--INI-- +mysqli.allow_persistent=1 +mysqli.max_persistent=2 +--FILE-- +<?php + require_once("connect.inc"); + require_once("table.inc"); + + $host = 'p:' . $host; + if (!$plink = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + // get the thread ids of the two connections... + $thread_id = mysqli_thread_id($link); + $pthread_id = mysqli_thread_id($plink); + + if (!$res = mysqli_query($link, 'SHOW FULL PROCESSLIST')) + printf("[002] Cannot get processlist, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $running_threads = array(); + while ($row = mysqli_fetch_assoc($res)) + $running_threads[$row['Id']] = $row; + mysqli_free_result($res); + + if (count($running_threads) < 2) + printf("[003] Processlist is too short, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!isset($running_threads[$thread_id])) + printf("[004] Cannot find thread id of the regular link, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!isset($running_threads[$pthread_id])) + printf("[005] Cannot find thread id of the persistent link, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + // Kill the persistent connection - don't use mysqli_kill, mysqlnd will catch that... + if (!mysqli_query($link, sprintf('KILL %d', $pthread_id))) + printf("[006] Cannot kill persistent connection, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_close($plink); + // Give the server think-time to kill the pthread + sleep(1); + + if (!$res = mysqli_query($link, 'SHOW FULL PROCESSLIST')) + printf("[007] Cannot get processlist, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $running_threads2 = array(); + while ($row = mysqli_fetch_assoc($res)) + $running_threads2[$row['Id']] = $row; + mysqli_free_result($res); + + if (isset($running_threads2[$pthread_id])) + printf("[008] Thread of the persistent connection should have been gone, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + if (!isset($running_threads2[$thread_id])) + printf("[009] Thread of the regular connection should be still there, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + // On PHP side this should do nothing. PHP should not try to close the connection or something. + @mysqli_close($plink); + + if (!$plink = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[011] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + if (!$res3 = @mysqli_query($plink, 'SELECT id FROM test ORDER BY id LIMIT 1')) { + printf("[012] New persistent connection cannot execute queries, [%d] %s\n", @mysqli_errno($plink), @mysqli_error($plink)); + } + + @mysqli_free_result($res3); + @mysqli_close($plink); + mysqli_close($link); + + // remove the "p:<host>" from the host variable + $host = substr($host, 2); + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[013] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + if (!$res4 = mysqli_query($link, 'SELECT id FROM test ORDER BY id LIMIT 1')) + printf("[014] New regular connection cannot execute queries, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res4); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_pconn_limits.phpt b/ext/mysqli/tests/mysqli_pconn_limits.phpt new file mode 100644 index 0000000..ee9e1f9 --- /dev/null +++ b/ext/mysqli/tests/mysqli_pconn_limits.phpt @@ -0,0 +1,98 @@ +--TEST-- +Persistent connections - limits (-1, unlimited) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once("connect.inc"); +?> +--INI-- +mysqli.allow_persistent=1 +mysqli.max_persistent=-1 +mysqli.max_links=-1 +--FILE-- +<?php + require_once("connect.inc"); + // opens a regular connection + require_once("table.inc"); + + if (!$res = mysqli_query($link, "SELECT 'works..' as _desc")) + printf("[001] Cannot run query, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + $row = mysqli_fetch_assoc($res); + mysqli_free_result($res); + printf("Regular connection 1 - '%s'\n", $row['_desc']); + + if (!$link2 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[002] Cannot open second regular connection, [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error()); + + if (!$res = mysqli_query($link2, "SELECT 'works...' as _desc")) + printf("[003] Cannot run query, [%d] %s\n", + mysqli_errno($link2), mysqli_error($link2)); + + $row = mysqli_fetch_assoc($res); + mysqli_free_result($res); + printf("Regular connection 2 - '%s'\n", $row['_desc']); + + $host = 'p:' . $host; + if (!$plink = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[004] Cannot create persistent connection using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s, [%d] %s\n", + $host, $user, $db, $port, $socket, + mysqli_connect_errno(), mysqli_connect_error()); + + if (!$res = mysqli_query($plink, "SELECT 'works...' as _desc")) + printf("[005] Cannot run query, [%d] %s\n", + mysqli_errno($plink), mysqli_error($plink)); + + $row = mysqli_fetch_assoc($res); + mysqli_free_result($res); + printf("Persistent connection 1 - '%s'\n", $row['_desc']); + + if (!$plink2 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[006] Cannot create persistent connection using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s, [%d] %s\n", + $host, $user, $db, $port, $socket, + mysqli_connect_errno(), mysqli_connect_error()); + + if (!$res = mysqli_query($plink2, "SELECT 'works...' as _desc")) + printf("[007] Cannot run query, [%d] %s\n", + mysqli_errno($plink2), mysqli_error($plink2)); + + $row = mysqli_fetch_assoc($res); + mysqli_free_result($res); + printf("Persistent connection 2 - '%s'\n", $row['_desc']); + + $plink3 = mysqli_init(); + if (!my_mysqli_real_connect($plink3, $host, $user, $passwd, $db, $port, $socket)) + printf("[008] Cannot create persistent connection using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s, [%d] %s\n", + $host, $user, $db, $port, $socket, + mysqli_connect_errno(), mysqli_connect_error()); + + if (!$res = mysqli_query($plink3, "SELECT 'works...' as _desc")) + printf("[009] Cannot run query, [%d] %s\n", + mysqli_errno($plink2), mysqli_error($plink2)); + + $row = mysqli_fetch_assoc($res); + mysqli_free_result($res); + printf("Persistent connection 3 - '%s'\n", $row['_desc']); + + mysqli_close($link); + mysqli_close($link2); + mysqli_close($plink); + mysqli_close($plink2); + mysqli_close($plink3); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Regular connection 1 - 'works..' +Regular connection 2 - 'works...' +Persistent connection 1 - 'works...' +Persistent connection 2 - 'works...' +Persistent connection 3 - 'works...' +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_pconn_max_links.phpt b/ext/mysqli/tests/mysqli_pconn_max_links.phpt new file mode 100644 index 0000000..e87ef00 --- /dev/null +++ b/ext/mysqli/tests/mysqli_pconn_max_links.phpt @@ -0,0 +1,196 @@ +--TEST-- +Persistent connections and mysqli.max_links +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifemb.inc'); + require_once('skipifconnectfailure.inc'); + require_once('table.inc'); + + mysqli_query($link, 'DROP USER pcontest'); + mysqli_query($link, 'DROP USER pcontest@localhost'); + + if (!mysqli_query($link, 'CREATE USER pcontest@"%" IDENTIFIED BY "pcontest"') || + !mysqli_query($link, 'CREATE USER pcontest@localhost IDENTIFIED BY "pcontest"')) { + printf("skip Cannot create second DB user [%d] %s", mysqli_errno($link), mysqli_error($link)); + mysqli_close($link); + die("skip CREATE USER failed"); + } + + // we might be able to specify the host using CURRENT_USER(), but... + if (!mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pcontest@'%%'", $db)) || + !mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pcontest@'localhost'", $db))) { + printf("skip Cannot GRANT SELECT to second DB user [%d] %s", mysqli_errno($link), mysqli_error($link)); + mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest'); + mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest@localhost'); + mysqli_query($link, 'DROP USER pcontest@localhost'); + mysqli_query($link, 'DROP USER pcontest'); + mysqli_close($link); + die("skip GRANT failed"); + } + + if (!($link_pcontest = @my_mysqli_connect($host, 'pcontest', 'pcontest', $db, $port, $socket))) { + mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest'); + mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest@localhost'); + mysqli_query($link, 'DROP USER pcontest@localhost'); + mysqli_query($link, 'DROP USER pcontest'); + mysqli_close($link); + die("skip CONNECT using new user failed"); + } + mysqli_close($link); +?> +--INI-- +mysqli.allow_persistent=1 +mysqli.max_persistent=2 +--FILE-- +<?php + require_once("connect.inc"); + require_once('table.inc'); + + + if (!mysqli_query($link, 'DROP USER pcontest') || + !mysqli_query($link, 'DROP USER pcontest@localhost') || + !mysqli_query($link, 'CREATE USER pcontest@"%" IDENTIFIED BY "pcontest"') || + !mysqli_query($link, 'CREATE USER pcontest@localhost IDENTIFIED BY "pcontest"') || + !mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pcontest@'%%'", $db)) || + !mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pcontest@'localhost'", $db))) { + printf("[000] Init failed, [%d] %s\n", + mysqli_errno($plink), mysqli_error($plink)); + } + + if (!$plink = my_mysqli_connect('p:' . $host, 'pcontest', 'pcontest', $db, $port, $socket)) + printf("[001] Cannot connect using the second DB user created during SKIPIF, [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error()); + + ob_start(); + phpinfo(); + $phpinfo = strip_tags(ob_get_contents()); + ob_end_clean(); + + $phpinfo = substr($phpinfo, strpos($phpinfo, 'MysqlI Support => enabled'), 500); + if (!preg_match('@Active Persistent Links\s+=>\s+(\d+)@ismU', $phpinfo, $matches)) + printf("[002] Cannot get # active persistent links from phpinfo()\n"); + $num_plinks = $matches[1]; + + if (!$res = mysqli_query($plink, 'SELECT id, label FROM test WHERE id = 1')) + printf("[003] Cannot run query on persistent connection of second DB user, [%d] %s\n", + mysqli_errno($plink), mysqli_error($plink)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[004] Cannot run fetch result, [%d] %s\n", + mysqli_errno($plink), mysqli_error($plink)); + mysqli_free_result($res); + var_dump($row); + + // change the password for the second DB user and kill the persistent connection + if (!mysqli_query($link, 'SET PASSWORD FOR pcontest = PASSWORD("newpass")') || + !mysqli_query($link, 'FLUSH PRIVILEGES')) + printf("[005] Cannot change PW of second DB user, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + // change the password for the second DB user and kill the persistent connection + if (!mysqli_query($link, 'SET PASSWORD FOR pcontest@localhost = PASSWORD("newpass")') || + !mysqli_query($link, 'FLUSH PRIVILEGES')) + printf("[006] Cannot change PW of second DB user, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + // persistent connections cannot be closed but only be killed + $pthread_id = mysqli_thread_id($plink); + if (!mysqli_query($link, sprintf('KILL %d', $pthread_id))) + printf("[007] Cannot KILL persistent connection of second DB user, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + // give the server a second to really kill the thread + sleep(1); + + if (!$res = mysqli_query($link, "SHOW FULL PROCESSLIST")) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $running_threads = array(); + while ($row = mysqli_fetch_assoc($res)) + $running_threads[$row['Id']] = $row; + mysqli_free_result($res); + + if (isset($running_threads[$pthread_id])) + printf("[009] Persistent connection has not been killed\n"); + + // this fails and we have 0 (<= $num_plinks) connections + if ($plink = @my_mysqli_connect('p:' . $host, 'pcontest', 'pcontest', $db, $port, $socket)) + printf("[010] Can connect using the old password, [%d] %s\n", + mysqli_connect_errno($link), mysqli_connect_error($link)); + + ob_start(); + phpinfo(); + $phpinfo = strip_tags(ob_get_contents()); + ob_end_clean(); + $phpinfo = substr($phpinfo, stripos($phpinfo, 'MysqlI Support => enabled'), 500); + if (!preg_match('@Active Persistent Links\s+=>\s+(\d+)@ismU', $phpinfo, $matches)) + printf("[010] Cannot get # of active persistent links from phpinfo()\n"); + + $num_plinks_kill = $matches[1]; + if ($num_plinks_kill > $num_plinks) + printf("[011] Expecting Active Persistent Links < %d, got %d\n", $num_plinks, $num_plinks_kill); + + if (!$plink = my_mysqli_connect('p:' . $host, 'pcontest', 'newpass', $db, $port, $socket)) + printf("[012] Cannot connect using the new password, [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error()); + + if (!$res = mysqli_query($plink, 'SELECT id, label FROM test WHERE id = 1')) + printf("[013] Cannot run query on persistent connection of second DB user, [%d] %s\n", + mysqli_errno($plink), mysqli_error($plink)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[014] Cannot run fetch result, [%d] %s\n", + mysqli_errno($plink), mysqli_error($plink)); + mysqli_free_result($res); + var_dump($row); + + if ($plink2 = my_mysqli_connect('p:' . $host, 'pcontest', 'newpass', $db, $port, $socket)) + printf("[015] Can open more persistent connections than allowed, [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error()); + + ob_start(); + phpinfo(); + $phpinfo = strip_tags(ob_get_contents()); + ob_end_clean(); + $phpinfo = substr($phpinfo, stripos($phpinfo, 'MysqlI Support => enabled'), 500); + if (!preg_match('@Active Persistent Links\s+=>\s+(\d+)@ismU', $phpinfo, $matches)) + printf("[016] Cannot get # of active persistent links from phpinfo()\n"); + + $num_plinks = $matches[1]; + if ($num_plinks > (int)ini_get('mysqli.max_persistent')) + printf("[017] mysqli.max_persistent=%d allows %d open connections!\n", ini_get('mysqli.max_persistent'),$num_plinks); + + mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest'); + mysqli_query($link, 'DROP USER pcontest'); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest'); +mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest@localhost'); +mysqli_query($link, 'DROP USER pcontest@localhost'); +mysqli_query($link, 'DROP USER pcontest'); + +mysqli_close($link); +?> +--EXPECTF-- +array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" +} + +Warning: %s: Too many open persistent links (%d) in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_pconn_reuse.phpt b/ext/mysqli/tests/mysqli_pconn_reuse.phpt new file mode 100644 index 0000000..6e210bd --- /dev/null +++ b/ext/mysqli/tests/mysqli_pconn_reuse.phpt @@ -0,0 +1,91 @@ +--TEST-- +mysqli_pconnect() - reusing/caching persistent connections - TODO +--SKIPIF-- +<?php +die("skip TODO - we need to add a user level way to check if CHANGE_USER gets called by pconnect"); + +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +mysqli.allow_persistent=1 +mysqli.max_persistent=2 +mysqli.max_links=2 +--FILE-- +<?php + require_once("connect.inc"); + + $host = 'p:' . $host; + if (!$link1 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s, [%d] %s\n", + $host, $user, $db, $port, $socket, mysqli_connect_errno(), mysqli_connect_error()); + } + if (!mysqli_query($link1, 'SET @pcondisabled = "Connection 1"')) + printf("[002] Cannot set user variable to check if we got the same persistent connection, [%d] %s\n", + mysqli_errno($link1), mysqli_error($link1)); + + if (!$link2 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s, [%d] %s\n", + $host, $user, $db, $port, $socket, mysqli_connect_errno(), mysqli_connect_error()); + } + + if (!$res = mysqli_query($link1, 'SELECT @pcondisabled AS _test')) + printf("[004] [%d] %s\n", mysqli_errno($link2), mysqli_error($link2)); + + $row = mysqli_fetch_assoc($res); + printf("Connection 1 - SELECT @pcondisabled -> '%s'\n", $row['_test']); + mysqli_free_result($res); + + if (!$res = mysqli_query($link2, 'SELECT @pcondisabled AS _test')) + printf("[005] [%d] %s\n", mysqli_errno($link2), mysqli_error($link2)); + + $row = mysqli_fetch_assoc($res); + printf("Connection 2 (no reuse) - SELECT @pcondisabled -> '%s'\n", $row['_test']); + $thread_id = mysqli_thread_id($link2); + printf("Connection 2 (no reuse) - Thread ID -> '%s'\n", $thread_id); + mysqli_free_result($res); + + if (!mysqli_query($link2, 'SET @pcondisabled = "Connection 2"')) + printf("[006] Cannot set user variable to check if we got the same persistent connection, [%d] %s\n", + mysqli_errno($link2), mysqli_error($link2)); + + if (!$res = mysqli_query($link2, 'SELECT @pcondisabled AS _test')) + printf("[007] [%d] %s\n", mysqli_errno($link2), mysqli_error($link2)); + + $row = mysqli_fetch_assoc($res); + printf("Connection 2 - SELECT @pcondisabled -> '%s'\n", $row['_test']); + mysqli_free_result($res); + + mysqli_close($link2); + + /* reuse of existing persistent connection expected! */ + if (!$link2 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[008] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s, [%d] %s\n", + $host, $user, $db, $port, $socket, mysqli_connect_errno(), mysqli_connect_error()); + } + + if (!$res = mysqli_query($link2, 'SELECT @pcondisabled AS _test')) + printf("[009] [%d] %s\n", mysqli_errno($link2), mysqli_error($link2)); + + $row = mysqli_fetch_assoc($res); + printf("Connection 2 (reuse) - SELECT @pcondisabled -> '%s'\n", $row['_test']); + $thread_id_reuse = mysqli_thread_id($link2); + printf("Connection 2 (reuse) - Thread ID -> '%s'\n", $thread_id_reuse); + mysqli_free_result($res); + + if ($thread_id != $thread_id_reuse) + printf("[010] Seems as if we have got a new connection, connections should have been cached and reused!\n"); + + mysqli_close($link1); + mysqli_close($link2); + print "done!"; +?> +--EXPECTF-- +Connection 1 - SELECT @pcondisabled -> 'Connection 1' +Connection 2 (no reuse) - SELECT @pcondisabled -> '' +Connection 2 (no reuse) - Thread ID -> '%d' +Connection 2 - SELECT @pcondisabled -> 'Connection 2' +Connection 2 (reuse) - SELECT @pcondisabled -> 'Connection 2' +Connection 2 (reuse) - Thread ID -> '%d' +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_pconn_twice.phpt b/ext/mysqli/tests/mysqli_pconn_twice.phpt new file mode 100644 index 0000000..5630d4e --- /dev/null +++ b/ext/mysqli/tests/mysqli_pconn_twice.phpt @@ -0,0 +1,77 @@ +--TEST-- +Calling connect() on an open persistent connection to create a new persistent connection +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +?> +--INI-- +mysqli.allow_persistent=1 +mysqli.max_persistent=-1 +mysqli.max_links=-1 +--FILE-- +<?php + require_once("connect.inc"); + + $host = 'p:' . $host; + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (true !== ($tmp = my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket))) + printf("[003] Expecting boolean/true got %s/%s\n", gettype($tmp), $tmp); + + /* it is undefined which pooled connection we get - thread ids may differ */ + + if (!($res = mysqli_query($link, "SELECT 'ok' AS it_works")) || + !($row = mysqli_fetch_assoc($res))) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + var_dump($row); + mysqli_free_result($res); + + mysqli_close($link); + + if (!$link = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[007] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + + if (true !== ($tmp = $link->real_connect($host, $user, $passwd, $db, $port, $socket))) + printf("[009] Expecting boolean/true got %s/%s\n", gettype($tmp), $tmp); + + /* it is undefined which pooled connection we get - thread ids may differ */ + + if (!($res = $link->query("SELECT 'works also with oo' AS syntax")) || + !($row = $res->fetch_assoc())) + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + var_dump($row); + mysqli_free_result($res); + + mysqli_close($link); + + if (NULL !== ($tmp = $link->connect($host, $user, $passwd, $db, $port, $socket))) + printf("[013] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[014] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (NULL !== ($tmp = $link->connect($host, $user, $passwd, $db, $port, $socket))) + printf("[015] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +array(1) { + [%u|b%"it_works"]=> + %unicode|string%(2) "ok" +} +array(1) { + [%u|b%"syntax"]=> + %unicode|string%(18) "works also with oo" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_pconnect.phpt b/ext/mysqli/tests/mysqli_pconnect.phpt new file mode 100644 index 0000000..734029a --- /dev/null +++ b/ext/mysqli/tests/mysqli_pconnect.phpt @@ -0,0 +1,72 @@ +--TEST-- +mysqli_pconnect() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $host = 'p:' . $host; + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + mysqli_close($link); + + $num = 20; + $connections = array(); + for ($i = 0; $i < $num; $i++) { + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[003] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + $connections[] = $link; + } + while (count($connections)) { + do { + $index = mt_rand(0, $num); + } while (!isset($connections[$index])); + mysqli_close($connections[$index]); + unset($connections[$index]); + } + + + $connections = array(); + $num = 20; + for ($i = 0; $i < $num; $i++) { + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[004] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + $connections[] = $link; + } + $left = $num; + + while (count($connections) && $left > 0) { + do { + $index = mt_rand(0, $num); + } while (!isset($connections[$index]) && $left > 0); + if (mt_rand(0, 1) > 0) { + $left--; + mysqli_close($connections[$index]); + unset($connections[$index]); + } else { + $left--; + if (!$connections[$index] = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[004] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + } + flush(); + } + + while (count($connections)) { + do { + $index = mt_rand(0, $num); + } while (!isset($connections[$index])); + mysqli_close($connections[$index]); + unset($connections[$index]); + } + + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_phpinfo.phpt b/ext/mysqli/tests/mysqli_phpinfo.phpt new file mode 100644 index 0000000..e23a5f6 --- /dev/null +++ b/ext/mysqli/tests/mysqli_phpinfo.phpt @@ -0,0 +1,72 @@ +--TEST-- +phpinfo() mysqli section +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + include("connect.inc"); + + @ob_clean(); + ob_start(); + phpinfo(); + $phpinfo = ob_get_contents(); + ob_end_clean(); + + /* all versions should at least dump this minimum information */ + if (!stristr($phpinfo, "mysqli support")) + printf("[001] ext/mysqli should have exposed itself.\n"); + + if (!stristr($phpinfo, "client api library version")) + printf("[002] ext/mysqli should have exposed the library version.\n"); + + if (!stristr($phpinfo, "mysqli.default_host")) + printf("[003] php.ini setting mysqli.default_host not shown.\n"); + + if (!stristr($phpinfo, "mysqli.default_port")) + printf("[004] php.ini setting mysqli.default_port not shown.\n"); + + if (!stristr($phpinfo, "mysqli.default_pw")) + printf("[005] php.ini setting mysqli.default_pw not shown.\n"); + + if (!stristr($phpinfo, "mysqli.default_socket")) + printf("[006] php.ini setting mysqli.default_socket not shown.\n"); + + if (!stristr($phpinfo, "mysqli.default_user")) + printf("[007] php.ini setting mysqli.default_user not shown.\n"); + + if (!stristr($phpinfo, "mysqli.max_links")) + printf("[008] php.ini setting mysqli.max_links not shown.\n"); + + if (!stristr($phpinfo, "mysqli.reconnect")) + printf("[009] php.ini setting mysqli.reconnect not shown.\n"); + + if ($IS_MYSQLND) { + $expected = array( + 'mysqlnd statistics', + 'bytes_sent', 'bytes_received', 'packets_sent', 'packets_received', + 'protocol_overhead_in', 'protocol_overhead_out', 'result_set_queries', + 'non_result_set_queries', 'no_index_used', 'bad_index_used', + 'buffered_sets', 'unbuffered_sets', 'ps_buffered_sets', 'ps_unbuffered_sets', + 'flushed_normal_sets', 'flushed_ps_sets', 'rows_fetched_from_server', + 'rows_fetched_from_client', 'rows_skipped', 'copy_on_write_saved', + 'copy_on_write_performed', 'command_buffer_too_small', 'connect_success', + 'connect_failure', 'connection_reused', 'explicit_close', 'implicit_close', + 'disconnect_close', 'in_middle_of_command_close', 'explicit_free_result', + 'implicit_free_result', 'explicit_stmt_close', 'implicit_stmt_close', + 'size', + 'mysqli.allow_local_infile', + 'mysqli.allow_persistent', 'mysqli.max_persistent' + ); + foreach ($expected as $k => $entry) + if (!stristr($phpinfo, $entry)) + printf("[010] Could not find entry for '%s'\n", $entry); + } + + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_ping.phpt b/ext/mysqli/tests/mysqli_ping.phpt new file mode 100644 index 0000000..d9a134c --- /dev/null +++ b/ext/mysqli/tests/mysqli_ping.phpt @@ -0,0 +1,47 @@ +--TEST-- +mysqli_ping() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_ping())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!is_null($tmp = @mysqli_ping($link, $link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + var_dump(mysqli_ping($link)); + + // provoke an error to check if mysqli_ping resets it + $res = mysqli_query($link, 'SELECT * FROM unknown_table'); + if (!($errno = mysqli_errno($link))) + printf("[003] Statement should have caused an error\n"); + + var_dump(mysqli_ping($link)); + if ($errno === mysqli_errno($link)) + printf("[004] Error codes should have been reset\n"); + + mysqli_close($link); + + if (!is_null($tmp = mysqli_ping($link))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +bool(true) +bool(true) + +Warning: mysqli_ping(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_poll.phpt b/ext/mysqli/tests/mysqli_poll.phpt new file mode 100644 index 0000000..dd4f9b9 --- /dev/null +++ b/ext/mysqli/tests/mysqli_poll.phpt @@ -0,0 +1,137 @@ +--TEST-- +int mysqli_poll() simple +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('connect.inc'); +require_once('skipifconnectfailure.inc'); + +if (!$IS_MYSQLND) + die("skip mysqlnd only feature, compile PHP using --with-mysqli=mysqlnd"); +?> +--FILE-- +<?php + require_once('connect.inc'); + + function get_connection() { + global $host, $user, $passwd, $db, $port, $socket; + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + return $link; + } + + if (!$link = get_connection()) + printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (NULL !== ($tmp = @mysqli_poll())) + printf("[002] Expecting NULL got %s\n", var_export($tmp, true)); + + $l = array($link); + if (NULL !== ($tmp = @mysqli_poll($l))) + printf("[003] Expecting NULL got %s\n", var_export($tmp, true)); + + $l = array($link); $n = NULL; + if (NULL !== ($tmp = @mysqli_poll($l, $n))) + printf("[004] Expecting NULL got %s\n", var_export($tmp, true)); + + $l = array($link); $n = NULL; + if (NULL !== ($tmp = @mysqli_poll($l, $n, $n))) + printf("[005] Expecting NULL got %s\n", var_export($tmp, true)); + + $l = array($link); $e = NULL; $r = NULL; + if (NULL !== ($tmp = @mysqli_poll($l, $e, $r, -1))) + printf("[007] Expecting boolean/false got %s/%s\n", gettype($tmp), var_export($tmp, true)); + + $l = array($link); $e = NULL; $r = NULL; + if (NULL !== ($tmp = @mysqli_poll($l, $e, $r, 0, -1))) + printf("[008] Expecting boolean/false got %s/%s\n", gettype($tmp), var_export($tmp, true)); + + $read = $error = $reject = array($link); + if (0 !== ($tmp = (mysqli_poll($read, $error, $reject, 0, 1)))) + printf("[009] Expecting int/0 got %s/%s\n", gettype($tmp), var_export($tmp, true)); + + + function poll_async($offset, $link, $links, $errors, $reject, $exp_ready, $use_oo_syntax) { + + if ($exp_ready !== ($tmp = mysqli_poll($links, $errors, $reject, 0, 1000))) + printf("[%03d + 1] There should be %d links ready to read from, %d ready\n", + $exp_ready, $tmp); + + foreach ($links as $mysqli) { + if ($use_oo_syntax) { + $res = $mysqli->reap_async_query(); + } else { + $res = mysqli_reap_async_query($mysqli); + } + if (is_object($res)) { + printf("[%03d + 2] Can fetch resultset although no query has been run!\n", $offset); + } else if (mysqli_errno($mysqli) > 0) { + printf("[%03d + 3] Error indicated through links array: %d/%s", + $offset, mysqli_errno($mysqli), mysqli_error($mysqli)); + } else { + printf("[%03d + 4] Cannot fetch and no error set - non resultset query (no SELECT)!\n", $offset); + } + } + + foreach ($errors as $mysqli) + printf("[%03d + 5] Error on %d: %d/%s\n", + $offset, mysqli_thread_id($mysqli), mysqli_errno($mysqli), mysqli_error($mysqli)); + + foreach ($reject as $mysqli) + printf("[%03d + 6] Rejecting thread %d: %d/%s\n", + $offset, mysqli_thread_id($mysqli), mysqli_errno($mysqli), mysqli_error($mysqli)); + + } + + // Connections on which no query has been send - 1 + $link = get_connection(); + $links = array($link); + $errors = array($link); + $reject = array($link); + poll_async(10, $link, $links, $errors, $reject, 0, false); + mysqli_close($link); + + $link = get_connection(); + $links = array($link); + $errors = array($link); + $reject = array($link); + poll_async(11, $link, $links, $errors, $reject, 0, true); + mysqli_close($link); + + // Connections on which no query has been send - 2 + // Difference: pass $links twice + $link = get_connection(); + $links = array($link, $link); + $errors = array($link, $link); + $reject = array(); + poll_async(12, $link, $links, $errors, $reject, 0, false); + + // Connections on which no query has been send - 3 + // Difference: pass two connections + $link = get_connection(); + $links = array($link, get_connection()); + $errors = array($link, $link); + $reject = array(); + poll_async(13, $link, $links, $errors, $reject, 0, false); + + // Reference mess... + $link = get_connection(); + $links = array($link); + $errors = array($link); + $ref_errors =& $errors; + $reject = array(); + poll_async(14, $link, $links, $ref_errors, $reject, 0, false); + + print "done!"; +?> +--EXPECTF-- +[010 + 6] Rejecting thread %d: 0/ +[011 + 6] Rejecting thread %d: 0/ +[012 + 6] Rejecting thread %d: 0/ +[012 + 6] Rejecting thread %d: 0/ +[013 + 6] Rejecting thread %d: 0/ +[013 + 6] Rejecting thread %d: 0/ +[014 + 6] Rejecting thread %d: 0/ +done! diff --git a/ext/mysqli/tests/mysqli_poll_kill.phpt b/ext/mysqli/tests/mysqli_poll_kill.phpt new file mode 100644 index 0000000..b068d64 --- /dev/null +++ b/ext/mysqli/tests/mysqli_poll_kill.phpt @@ -0,0 +1,199 @@ +--TEST-- +int mysqli_poll() and kill +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('connect.inc'); +require_once('skipifconnectfailure.inc'); + +if (!$IS_MYSQLND) + die("skip mysqlnd only feature, compile PHP using --with-mysqli=mysqlnd"); +?> +--FILE-- +<?php + require_once('connect.inc'); + + function get_connection() { + global $host, $user, $passwd, $db, $port, $socket; + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + return $link; + } + + // Killing connection - 1 + + $link = get_connection(); + if (true !== ($tmp = mysqli_query($link, "SELECT 1 AS 'processed before killed'", MYSQLI_ASYNC | MYSQLI_USE_RESULT))) + printf("[002] Expecting boolean/true got %s/%s\n", gettype($tmp), var_export($tmp, true)); + + // Sleep 0.1s - the asynchronous query should have been processed after the wait period + usleep(100000); + $thread_id = mysqli_thread_id($link); + mysqli_kill(get_connection(), $thread_id); + + $links = array($link); + $errors = array($link); + $reject = array($link); + + // Yes, 1 - the asynchronous query should have been processed + if (1 !== ($tmp = (mysqli_poll($links, $errors, $reject, 0, 10000)))) + printf("[003] Expecting int/1 got %s/%s\n", gettype($tmp), var_export($tmp, true)); + + if (!is_array($links) || empty($links)) + printf("[004] Expecting non-empty array got %s/%s\n", gettype($links), var_export($links, true)); + else + foreach ($links as $link) { + if (is_object($res = mysqli_reap_async_query($link))) { + // Yes, you can fetch a result - the query has been processed + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + } else if ($link->errno > 0) { + printf("[005] Error: %d\n", $link->errno); + } + } + + // No error! + if (!is_array($errors) || !empty($errors)) + printf("[006] Expecting non-empty array got %s/%s\n", gettype($errors), var_export($errors, true)); + + if (!is_array($reject) || !empty($reject)) + printf("[007] Expecting empty array got %s/%s\n", gettype($reject), var_export($reject, true)); + + // Lets pass a dead connection + $links = array($link); + $errors = array($link); + $reject = array($link); + if (0 !== ($tmp = mysqli_poll($links, $errors, $reject, 1))) + printf("[008] There should be no connection ready! Returned %s/%s, expecting int/0.\n", + gettype($tmp), var_export($tmp, true)); + + if (!empty($errors)) + printf("[009] There should be no errors but one rejected connection\n"); + + foreach ($reject as $mysqli) + if (mysqli_thread_id($mysqli) != $thread_id) { + printf("[010] Rejected thread %d should have rejected thread %d\n", + mysqli_thread_id($mysqli), $thread_id); + } + + // Killing connection - 2 + + $link = get_connection(); + if (true !== ($tmp = mysqli_query($link, "SELECT 1", MYSQLI_ASYNC | MYSQLI_USE_RESULT))) + printf("[011] Expecting boolean/true got %s/%s\n", gettype($tmp), var_export($tmp, true)); + + usleep(100000); + $thread_id = mysqli_thread_id($link); + mysqli_kill(get_connection(), $thread_id); + + // Yes, 1 - fetch OK packet of kill! + $processed = 0; + do { + $links = array($link, $link); + $errors = array($link, $link); + $reject = array($link, $link); + $ready = mysqli_poll($links, $errors, $reject, 1); + + if (!empty($errors)) { + foreach ($errors as $mysqli) { + printf("[012] Error on thread %d: %s/%s\n", + mysqli_thread_id($mysqli), + mysqli_errno($mysqli), + mysqli_error($mysqli)); + } + break; + } + + if (!empty($reject)) { + foreach ($reject as $mysqli) { + printf("[013] Rejecting thread %d: %s/%s\n", + mysqli_thread_id($mysqli), + mysqli_errno($mysqli), + mysqli_error($mysqli)); + } + $processed += count($reject); + } + + foreach ($links as $mysqli) { + if (is_object($res = mysqli_reap_async_query($mysqli))) { + printf("Fetching from thread %d...\n", mysqli_thread_id($mysqli)); + var_dump(mysqli_fetch_assoc($res)); + } else if (mysqli_errno($mysqli) > 0) { + printf("[014] %d/%s\n", mysqli_errno($mysqli), mysqli_error($mysqli)); + } + $processed++; + } + + } while ($processed < 2); + + + // Killing connection - 3 + + $link = get_connection(); + $thread_id = mysqli_thread_id($link); + mysqli_kill(get_connection(), $thread_id); + // Sleep 0.1s to ensure the KILL gets recognized + usleep(100000); + if (false !== ($tmp = mysqli_query($link, "SELECT 1 AS 'processed before killed'", MYSQLI_ASYNC | MYSQLI_USE_RESULT))) + printf("[015] Expecting boolean/false got %s/%s\n", gettype($tmp), var_export($tmp, true)); + + $links = array($link); + $errors = array($link); + $reject = array($link); + + if (0 !== ($tmp = (mysqli_poll($links, $errors, $reject, 0, 10000)))) + printf("[016] Expecting int/0 got %s/%s\n", gettype($tmp), var_export($tmp, true)); + + if (!is_array($links) || empty($links)) + printf("[017] Expecting non-empty array got %s/%s\n", gettype($links), var_export($links, true)); + else + foreach ($links as $link) { + if (is_object($res = mysqli_reap_async_query($link))) { + // No, you cannot fetch the result + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + } else if ($link->errno > 0) { + // But you are supposed to handle the error the way its shown here! + printf("[018] Error: %d/%s\n", $link->errno, $link->error); + } + } + + // None of these will indicate an error, check errno on the list of returned connections! + if (!is_array($errors) || !empty($errors)) + printf("[019] Expecting non-empty array got %s/%s\n", gettype($errors), var_export($errors, true)); + + if (!is_array($reject) || !empty($reject)) + printf("[020] Expecting empty array got %s/%s\n", gettype($reject), var_export($reject, true)); + + + mysqli_close($link); + print "done!"; +?> +--XFAIL-- +To be fixed later. Minor issue about fetching error message from killed line +--EXPECTF-- +array(1) { + [%u|b%"processed before killed"]=> + %unicode|string%(1) "1" +} +Fetching from thread %d... +array(1) { + [1]=> + %unicode|string%(1) "1" +} + +Warning: mysqli_reap_async_query(): Premature end of data (mysqlnd_wireprotocol.c:%d) in %s on line %d + +Warning: mysqli_reap_async_query(): RSET_HEADER %s + +Warning: mysqli_reap_async_query(): Error reading result set's header in %s on line %d + +Warning: Error while sending QUERY packet. %s + +Warning: mysqli_reap_async_query(): %s + +Warning: mysqli_reap_async_query(): Error reading result set's header in %s on line %d +[018] Error: %d/%s +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_poll_mixing_insert_select.phpt b/ext/mysqli/tests/mysqli_poll_mixing_insert_select.phpt new file mode 100644 index 0000000..9c02cf9 --- /dev/null +++ b/ext/mysqli/tests/mysqli_poll_mixing_insert_select.phpt @@ -0,0 +1,184 @@ +--TEST-- +mysqli_poll() & INSERT SELECT +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('connect.inc'); +require_once('skipifconnectfailure.inc'); + +if (!$IS_MYSQLND) + die("skip mysqlnd only feature, compile PHP using --with-mysqli=mysqlnd"); +?> +--FILE-- +<?php + require_once('table.inc'); + + function get_connection() { + global $host, $user, $passwd, $db, $port, $socket; + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + return $link; + } + + + // Note: some queries will fail! They are supposed to fail. + $queries = array( + 'CREATE TABLE IF NOT EXISTS bogus(id INT)', + 'SET @a = 1', + 'SELECT * FROM test ORDER BY id ASC LIMIT 2', + "INSERT INTO test(id, label) VALUES (100, 'z')", + 'SELECT * FROM test ORDER BY id ASC LIMIT 2', + 'SELECT', + 'UPDATE test SET id = 101 WHERE id > 3', + 'UPDATE_FIX test SET id = 101 WHERE id > 3', + 'DROP TABLE IF EXISTS bogus', + 'DELETE FROM test WHERE id = @a', + 'DELETE FROM test WHERE id = 1', + ); + + $link = get_connection(); + $have_proc = false; + mysqli_real_query($link, "DROP PROCEDURE IF EXISTS p"); + if (mysqli_real_query($link, 'CREATE PROCEDURE p(IN ver_in VARCHAR(25), OUT ver_out VARCHAR(25)) BEGIN SELECT ver_in INTO ver_out; END;')) { + $have_proc = true; + $queries[] = "CALL p('myversion', @version)"; + } + mysqli_close($link); + + $links = array(); + for ($i = 0; $i < count($queries); $i++) { + + $link = get_connection(); + + if (true !== ($tmp = mysqli_query($link, $queries[$i], MYSQLI_ASYNC | MYSQLI_USE_RESULT))) + printf("[002] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true)); + + // WARNING KLUDGE NOTE + // Add a tiny delay to ensure that queries get executed in a certain order + // If your MySQL server is very slow the test may randomly fail! + usleep(20000); + + $links[mysqli_thread_id($link)] = array( + 'query' => $queries[$i], + 'link' => $link, + 'processed' => false, + ); + } + + $saved_errors = array(); + do { + $poll_links = $poll_errors = $poll_reject = array(); + foreach ($links as $thread_id => $link) { + if (!$link['processed']) { + $poll_links[] = $link['link']; + $poll_errors[] = $link['link']; + $poll_reject[] = $link['link']; + } + } + if (0 == count($poll_links)) + break; + + if (0 == ($num_ready = mysqli_poll($poll_links, $poll_errors, $poll_reject, 0, 200000))) + continue; + + if (!empty($poll_errors)) { + die(var_dump($poll_errors)); + } + + foreach ($poll_links as $link) { + $thread_id = mysqli_thread_id($link); + $links[$thread_id]['processed'] = true; + + if (is_object($res = mysqli_reap_async_query($link))) { + // result set object + while ($row = mysqli_fetch_assoc($res)) { + // eat up all results + ; + } + mysqli_free_result($res); + } else { + // either there is no result (no SELECT) or there is an error + if (mysqli_errno($link) > 0) { + $saved_errors[$thread_id] = mysqli_errno($link); + printf("[003] '%s' caused %d\n", $links[$thread_id]['query'], mysqli_errno($link)); + } + } + } + + } while (true); + + // Checking if all lines are still usable + foreach ($links as $thread_id => $link) { + if (isset($saved_errors[$thread_id]) && + $saved_errors[$thread_id] != mysqli_errno($link['link'])) { + printf("[004] Error state not saved for query '%s', %d != %d\n", $link['query'], + $saved_errors[$thread_id], mysqli_errno($link['link'])); + } + + if (!$res = mysqli_query($link['link'], 'SELECT * FROM test WHERE id = 100')) + printf("[005] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true)); + if (!$row = mysqli_fetch_row($res)) + printf("[006] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true)); + + mysqli_free_result($res); + } + + if ($res = mysqli_query($link['link'], "SELECT * FROM test WHERE id = 100")) { + $row = mysqli_fetch_assoc($res); + var_dump($row); + mysqli_free_result($res); + } + + if ($have_proc && ($res = mysqli_query($link['link'], "SELECT @version as _version"))) { + $row = mysqli_fetch_assoc($res); + if ($row['_version'] != 'myversion') { + printf("[007] Check procedures\n"); + } + mysqli_free_result($res); + } + + foreach ($links as $link) + mysqli_close($link['link']); + + $link = get_connection(); + if (!mysqli_query($link, 'SELECT 1', MYSQLI_ASYNC)) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, 'SELECT 1', MYSQLI_ASYNC)) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS bogus")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_query($link, "DROP PROCEDURE IF EXISTS p"); + +mysqli_close($link); +?> + +--EXPECTF-- +[003] 'SELECT' caused 1064 +[003] 'UPDATE test SET id = 101 WHERE id > 3' caused 1062 +[003] 'UPDATE_FIX test SET id = 101 WHERE id > 3' caused 1064 +array(2) { + [%u|b%"id"]=> + %unicode|string%(3) "100" + [%u|b%"label"]=> + %unicode|string%(1) "z" +} +[009] [2014] %s +done! diff --git a/ext/mysqli/tests/mysqli_poll_reference.phpt b/ext/mysqli/tests/mysqli_poll_reference.phpt new file mode 100644 index 0000000..ab2ed2a --- /dev/null +++ b/ext/mysqli/tests/mysqli_poll_reference.phpt @@ -0,0 +1,220 @@ +--TEST-- +mysqli_poll() & references +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('connect.inc'); +require_once('skipifconnectfailure.inc'); + +if (!$IS_MYSQLND) + die("skip mysqlnd only feature, compile PHP using --with-mysqli=mysqlnd"); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die("skip cannot connect"); + +if (mysqli_get_server_version($link) < 50012) + die("skip Test needs SQL function SLEEP() available as of MySQL 5.0.12"); + +?> +--FILE-- +<?php + require_once('connect.inc'); + + function get_connection() { + global $host, $user, $passwd, $db, $port, $socket; + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + return $link; + } + + + $mysqli1 = get_connection(); + $mysqli2 = get_connection(); + + var_dump(mysqli_query($mysqli1, "SELECT SLEEP(0.10)", MYSQLI_ASYNC | MYSQLI_USE_RESULT)); + var_dump(mysqli_query($mysqli2, "SELECT SLEEP(0.20)", MYSQLI_ASYNC | MYSQLI_USE_RESULT)); + + $processed = $loops = 0; + do { + $loops++; + if ($loops > 10) { + printf("[002] The queries should have finished already\n"); + break; + } + // WARNING: All arrays point to the same object - this will give bogus results! + // The behaviour is in line with stream_select(). Be warned, be careful. + $links = $errors = $reject = array($mysqli1, $mysqli2); + if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) { + continue; + } + + foreach ($links as $link) { + if ($res = mysqli_reap_async_query($link)) { + mysqli_free_result($res); + } + $processed++; + } + } while ($processed < 2); + + mysqli_close($mysqli1); + mysqli_close($mysqli2); + + $mysqli1 = get_connection(); + $mysqli2 = get_connection(); + + var_dump(mysqli_query($mysqli1, "SELECT SLEEP(0.10)", MYSQLI_ASYNC | MYSQLI_USE_RESULT)); + var_dump(mysqli_query($mysqli2, "SELECT SLEEP(0.20)", MYSQLI_ASYNC | MYSQLI_USE_RESULT)); + + $processed = $loops = 0; + do { + $loops++; + if ($loops > 10) { + printf("[003] The queries should have finished already\n"); + break; + } + // WARNING: All arrays point to the same object - this will give bogus results! + $links = $errors = array($mysqli1, $mysqli2); + $reject = array($mysqli1, $mysqli2); + if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) { + continue; + } + foreach ($links as $link) { + if ($res = mysqli_reap_async_query($link)) { + mysqli_free_result($res); + } + $processed++; + } + } while ($processed < 2); + + mysqli_close($mysqli1); + mysqli_close($mysqli2); + + $mysqli1 = get_connection(); + $mysqli2 = get_connection(); + + var_dump(mysqli_query($mysqli1, "SELECT SLEEP(0.10)", MYSQLI_ASYNC | MYSQLI_USE_RESULT)); + var_dump(mysqli_query($mysqli2, "SELECT SLEEP(0.20)", MYSQLI_ASYNC | MYSQLI_USE_RESULT)); + + $processed = $loops = 0; + do { + $loops++; + if ($loops > 10) { + printf("[004] The queries should have finished already\n"); + break; + } + // WARNING: All arrays point to the same object - this will give bogus results! + $links = array($mysqli1, $mysqli2); + $errors = $reject = array($mysqli1, $mysqli2); + if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) { + continue; + } + foreach ($links as $link) { + if ($res = mysqli_reap_async_query($link)) { + mysqli_free_result($res); + } + $processed++; + } + } while ($processed < 2); + + mysqli_close($mysqli1); + mysqli_close($mysqli2); + + // This is bogus code and bogus usage - OK to throw no errors! + $mysqli1 = get_connection(); + $mysqli2 = get_connection(); + + var_dump(mysqli_query($mysqli1, "SELECT SLEEP(0.10)", MYSQLI_ASYNC | MYSQLI_USE_RESULT)); + $thread_id = mysqli_thread_id($mysqli2); + printf("Connection %d should be rejected...\n", $thread_id); + + $processed = $loops = 0; + do { + $loops++; + if ($loops > 10) { + printf("[005] The queries should have finished already\n"); + break; + } + $links = $errors = $reject = array($mysqli1, $mysqli2); + if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) { + continue; + } + // WARNING: Due to the reference issue none of these should ever fire! + foreach ($reject as $link) { + printf("Connection %d was rejected...\n", mysqli_thread_id($link)); + if (mysqli_thread_id($link) != $thread_id) { + printf("[006] Connector %d should have been rejected. But also %d has been rejected.", + $thread_id, mysqli_thread_id($link)); + } + $processed++; + } + foreach ($errors as $link) { + printf("Connection %d has an error...\n", mysqli_thread_id($link)); + $processed++; + } + foreach ($links as $link) { + if ($res = mysqli_reap_async_query($link)) { + mysqli_free_result($res); + $processed++; + } + } + } while ($processed < 2); + + mysqli_close($mysqli1); + mysqli_close($mysqli2); + + $mysqli1 = get_connection(); + $mysqli2 = get_connection(); + + var_dump(mysqli_query($mysqli1, "SELECT SLEEP(0.10)", MYSQLI_ASYNC | MYSQLI_USE_RESULT)); + var_dump(mysqli_query($mysqli2, "SELECT SLEEP(0.20)", MYSQLI_ASYNC | MYSQLI_USE_RESULT)); + + $processed = $loops = 0; + $all = array($mysqli1, $mysqli2); + do { + $loops++; + if ($loops > 10) { + printf("[006] The queries should have finished already\n"); + break; + } + $links = $errors = $reject = $all; + ob_start(); + if (0 == ($ready = mysqli_poll($links, $errors, $reject, 0, 50000))) { + $tmp = ob_get_contents(); + ob_end_clean(); + if ($tmp != '') { + printf("Expected error:\n%s\n", $tmp); + break; + } + continue; + } + foreach ($links as $link) { + if ($res = mysqli_reap_async_query($link)) { + mysqli_free_result($res); + } + $processed++; + } + } while ($processed < 2); + + $ready = mysqli_poll($links, $errors, $reject, 0, 50000); + mysqli_close($mysqli1); + mysqli_close($mysqli2); + + print "done!"; +?> +--EXPECTF-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +Connection %d should be rejected... +Connection %d was rejected... +bool(true) +bool(true) + +Warning: mysqli_poll(): All arrays passed are clear in %s on line %d +done! diff --git a/ext/mysqli/tests/mysqli_prepare.phpt b/ext/mysqli/tests/mysqli_prepare.phpt new file mode 100644 index 0000000..d6d6c09 --- /dev/null +++ b/ext/mysqli/tests/mysqli_prepare.phpt @@ -0,0 +1,135 @@ +--TEST-- +mysqli_prepare() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_prepare())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_prepare($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (false !== ($tmp = @mysqli_prepare($link, false))) + printf("[003] Expecting boolean/false, got %s\n", gettype($tmp)); + + if (!$res = mysqli_query($link, "SELECT id, label FROM test", MYSQLI_USE_RESULT)) + printf("[004] [%d] %s, next test will fail\n", mysqli_errno($link), mysqli_error($link)); + + if (false !== ($tmp = mysqli_prepare($link, 'SELECT id FROM test WHERE id > ?'))) + printf("[005] Expecting boolean/false, got %s, [%d] %s\n", gettype($tmp), mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + + if (!is_object(($stmt = mysqli_prepare($link, 'SELECT id FROM test'))) || !mysqli_stmt_execute($stmt)) + printf("[006][%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_stmt_close($stmt); + + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test2")) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_object(($stmt = mysqli_prepare($link, 'CREATE TABLE test2(id INT) ENGINE =' . $engine))) || !mysqli_stmt_execute($stmt)) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_stmt_close($stmt); + + + if (!is_object(($stmt = mysqli_prepare($link, 'INSERT INTO test2(id) VALUES(?)')))) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $id = 1; + if (!mysqli_stmt_bind_param($stmt, 'i', $id) || !mysqli_stmt_execute($stmt)) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_stmt_close($stmt); + + if (!is_object(($stmt = mysqli_prepare($link, 'REPLACE INTO test2(id) VALUES (?)')))) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $id = 2; + if (!mysqli_stmt_bind_param($stmt, 'i', $id) || !mysqli_stmt_execute($stmt)) + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_stmt_close($stmt); + + if (!is_object(($stmt = mysqli_prepare($link, 'UPDATE test2 SET id = ? WHERE id = ?')))) + printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $id = 3; + $where = 2; + if (!mysqli_stmt_bind_param($stmt, 'ii', $id, $where) || !mysqli_stmt_execute($stmt)) + printf("[014] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_stmt_close($stmt); + + if (!is_object(($stmt = mysqli_prepare($link, 'DELETE FROM test2 WHERE id = ?')))) + printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $where = 3; + if (!mysqli_stmt_bind_param($stmt, 'i', $where) || !mysqli_stmt_execute($stmt)) + printf("[016] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_stmt_close($stmt); + + if (!is_object(($stmt = mysqli_prepare($link, 'SET @testvar = ?')))) + printf("[017] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $testvar = 'testvar'; + if (!mysqli_stmt_bind_param($stmt, 's', $testvar) || !mysqli_stmt_execute($stmt)) + printf("[018] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_stmt_close($stmt); + + if (!is_object(($stmt = mysqli_prepare($link, "DO GET_LOCK('testlock', 1)")))) + printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_stmt_close($stmt); + + if (!is_object(($stmt = mysqli_prepare($link, 'SELECT id, @testvar FROM test2')))) + printf("[020] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $id = $testvar = null; + if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_bind_result($stmt, $id, $testvar)) + printf("[021] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + while (mysqli_stmt_fetch($stmt)) { + if (('testvar' !== $testvar) || (1 !== $id)) + printf("[022] Expecting 'testvar'/1, got %s/%s. [%d] %s\n", + $testvar, $id, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + var_dump(mysqli_stmt_prepare($stmt, 'SELECT 1; SELECT 2')); + + mysqli_stmt_close($stmt); + + if (!is_null($tmp = @mysqli_stmt_prepare($link, 'SELECT id FROM test', 'foo'))) + printf("[023] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + if (!is_null($tmp = @mysqli_stmt_prepare($link, 'SELECT id FROM test'))) + printf("[024] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test2")) + printf("[c003] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> +--EXPECTF-- +bool(false) +done! diff --git a/ext/mysqli/tests/mysqli_prepare_no_object.phpt b/ext/mysqli/tests/mysqli_prepare_no_object.phpt new file mode 100644 index 0000000..e45de69 --- /dev/null +++ b/ext/mysqli/tests/mysqli_prepare_no_object.phpt @@ -0,0 +1,46 @@ +--TEST-- +mysqli_prepare() - no object on failure +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require('table.inc'); + + if (false !== ($tmp = mysqli_prepare($link, false))) + printf("[001] Expecting boolean/false, got %s/%s\n", gettype($tmp), (is_object($tmp) ? var_dump($tmp, true) : $tmp)); + printf("a) [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (false !== ($tmp = mysqli_prepare($link, ''))) + printf("[002] Expecting boolean/false, got %s/%s\n", gettype($tmp), (is_object($tmp) ? var_dump($tmp, true) : $tmp)); + printf("b) [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_close($link); + + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (false !== ($tmp = $mysqli->prepare(false))) + printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), (is_object($tmp) ? var_dump($tmp, true) : $tmp)); + printf("c) [%d] %s\n", $mysqli->errno, $mysqli->error); + + if (false !== ($tmp = $mysqli->prepare(''))) + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), (is_object($tmp) ? var_dump($tmp, true) : $tmp)); + printf("c) [%d] %s\n", $mysqli->errno, $mysqli->error); + + print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +a) [1065] Query was empty +b) [1065] Query was empty +c) [1065] Query was empty +c) [1065] Query was empty +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_ps_select_union.phpt b/ext/mysqli/tests/mysqli_ps_select_union.phpt new file mode 100644 index 0000000..fed81b3 --- /dev/null +++ b/ext/mysqli/tests/mysqli_ps_select_union.phpt @@ -0,0 +1,275 @@ +--TEST-- +Prepared Statements and SELECT UNION +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + require_once("table.inc"); + + // Regular (non-prepared) queries + print "Using CAST('somestring' AS CHAR)...\n"; + if (!($res = $link->query("SELECT CAST('one' AS CHAR) AS column1 UNION SELECT CAST('three' AS CHAR) UNION SELECT CAST('two' AS CHAR)"))) + printf("[001] [%d] %s\n", $link->errno, $link->error); + + $data = array(); + while ($row = $res->fetch_assoc()) { + $data[] = $row['column1']; + var_dump($row['column1']); + } + $res->free(); + + // Prepared Statements + if (!($stmt = $link->prepare("SELECT CAST('one' AS CHAR) AS column1 UNION SELECT CAST('three' AS CHAR) UNION SELECT CAST('two' AS CHAR)"))) + printf("[002] [%d] %s\n", $link->errno, $link->error); + + $column1 = null; + if (!$stmt->execute() || !$stmt->bind_result($column1)) + printf("[003] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + while ($stmt->fetch()) { + if ($data[$index] != $column1) { + printf("[004] Row %d, expecting %s/%s got %s/%s\n", + $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + } + $index++; + } + $stmt->close(); + + if ($IS_MYSQLND) { + /* + Advantage mysqlnd - + The metadata mysqlnd has availabe after prepare is better than + the one made availabe by the MySQL Client Library (libmysql). + "libmysql" will give wrong results and that is OK - + http://bugs.mysql.com/bug.php?id=47483 + */ + if (!($stmt = $link->prepare("SELECT CAST('one' AS CHAR) AS column1 UNION SELECT CAST('three' AS CHAR) UNION SELECT CAST('two' AS CHAR)"))) + printf("[005] [%d] %s\n", $link->errno, $link->error); + + $column1 = null; + /* Note: bind_result before execute */ + if (!$stmt->bind_result($column1) || !$stmt->execute()) + printf("[006] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + while ($stmt->fetch()) { + if ($data[$index] != $column1) { + printf("[007] Row %d, expecting %s/%s got %s/%s\n", + $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + } + $index++; + } + $stmt->close(); + } + + // Regular (non-prepared) queries + print "Mixing CAST('somestring'AS CHAR), integer and CAST(integer AS CHAR)...\n"; + if (!($res = $link->query("SELECT 1 AS column1 UNION SELECT CAST('three' AS CHAR) UNION SELECT CAST(2 AS CHAR)"))) + printf("[008] [%d] %s\n", $link->errno, $link->error); + + $data = array(); + while ($row = $res->fetch_assoc()) { + $data[] = $row['column1']; + } + $res->free(); + + // Prepared Statements + if (!($stmt = $link->prepare("SELECT 1 AS column1 UNION SELECT CAST('three' AS CHAR) UNION SELECT CAST(2 AS CHAR)"))) + printf("[009] [%d] %s\n", $link->errno, $link->error); + + $column1 = null; + if (!$stmt->execute() || !$stmt->bind_result($column1)) + printf("[010] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + while ($stmt->fetch()) { + if ($data[$index] != $column1) { + printf("[011] Row %d, expecting %s/%s got %s/%s\n", + $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + } + var_dump($column1); + $index++; + } + $stmt->close(); + + if ($IS_MYSQLND) { + /* Advantage mysqlnd - see above... */ + if (!($stmt = $link->prepare("SELECT 1 AS column1 UNION SELECT CAST('three' AS CHAR) UNION SELECT CAST(2 AS CHAR)"))) + printf("[012] [%d] %s\n", $link->errno, $link->error); + + $column1 = null; + if (!$stmt->bind_result($column1) || !$stmt->execute()) + printf("[013] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + while ($stmt->fetch()) { + if ($data[$index] != $column1) { + printf("[014] Row %d, expecting %s/%s got %s/%s\n", + $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + } + $index++; + } + $stmt->close(); + } + + print "Using integer only...\n"; + if (!($res = $link->query("SELECT 1 AS column1 UNION SELECT 303 UNION SELECT 2"))) + printf("[015] [%d] %s\n", $link->errno, $link->error); + + $data = array(); + while ($row = $res->fetch_assoc()) { + $data[] = $row['column1']; + } + $res->free(); + + // Prepared Statements + if (!($stmt = $link->prepare("SELECT 1 AS column1 UNION SELECT 303 UNION SELECT 2"))) + printf("[016] [%d] %s\n", $link->errno, $link->error); + + $column1 = null; + if (!$stmt->execute() || !$stmt->bind_result($column1)) + printf("[017] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + while ($stmt->fetch()) { + if ($data[$index] != $column1) { + printf("[018] Row %d, expecting %s/%s got %s/%s\n", + $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + } + var_dump($column1); + $index++; + } + $stmt->close(); + + if ($IS_MYSQLND) { + /* Advantage mysqlnd - see above */ + if (!($stmt = $link->prepare("SELECT 1 AS column1 UNION SELECT 303 UNION SELECT 2"))) + printf("[019] [%d] %s\n", $link->errno, $link->error); + + $column1 = null; + if (!$stmt->bind_result($column1) || !$stmt->execute()) + printf("[020] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + while ($stmt->fetch()) { + if ($data[$index] != $column1) { + printf("[021] Row %d, expecting %s/%s got %s/%s\n", + $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + } + $index++; + } + $stmt->close(); + } + + print "Testing bind_param(), strings only...\n"; + $two = 'two'; + $three = 'three'; + if (!($stmt = $link->prepare("SELECT 'one' AS column1 UNION SELECT ? UNION SELECT ?"))) + printf("[022] [%d] %s\n", $stmt->errno, $stmt->error); + + $column1 = null; + if (!$stmt->bind_param('ss', $three, $two) || !$stmt->execute() || !$stmt->bind_result($column1)) + printf("[023] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + $data = array(); + while ($stmt->fetch()) { + $data[$index++] = $column1; + var_dump($column1); + } + $stmt->close(); + + if ($IS_MYSQLND) { + /* Advantage mysqlnd - see above */ + $two = 'two'; + $three = 'three'; + if (!($stmt = $link->prepare("SELECT 'one' AS column1 UNION SELECT ? UNION SELECT ?"))) + printf("[024] [%d] %s\n", $stmt->errno, $stmt->error); + + $column1 = null; + if (!$stmt->bind_param('ss', $three, $two) || !$stmt->bind_result($column1) || !$stmt->execute()) + printf("[025] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + while ($stmt->fetch()) { + if ($data[$index] != $column1) { + printf("[26] Row %d, expecting %s/%s, got %s/%s\n", + $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + } + $index++; + } + $stmt->close(); + } + + print "Testing bind_param(), strings only, with CAST AS CHAR...\n"; + $two = 'two'; + $three = 'three beers are more than enough'; + if (!($stmt = $link->prepare("SELECT CAST('one' AS CHAR) AS column1 UNION SELECT CAST(? AS CHAR) UNION SELECT CAST(? AS CHAR)"))) + printf("[027] [%d] %s\n", $stmt->errno, $stmt->error); + + $column1 = null; + if (!$stmt->bind_param('ss', $three, $two) || !$stmt->execute() || !$stmt->bind_result($column1)) + printf("[028] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + $data = array(); + while ($stmt->fetch()) { + $data[$index++] = $column1; + var_dump($column1); + } + $stmt->close(); + + if ($IS_MYSQLND) { + /* Advantage mysqlnd - see above */ + $two = 'two'; + $three = 'three beers are more than enough'; + if (!($stmt = $link->prepare("SELECT CAST('one' AS CHAR) AS column1 UNION SELECT CAST(? AS CHAR) UNION SELECT CAST(? AS CHAR)"))) + printf("[029] [%d] %s\n", $stmt->errno, $stmt->error); + + $column1 = null; + if (!$stmt->bind_param('ss', $three, $two) || !$stmt->bind_result($column1) || !$stmt->execute()) + printf("[030] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + while ($stmt->fetch()) { + if ($data[$index] != $column1) { + printf("[31] Row %d, expecting %s/%s, got %s/%s\n", + $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + } + $index++; + } + $stmt->close(); + } + + $link->close(); + + print "done!"; +?> +--EXPECTF-- +Using CAST('somestring' AS CHAR)... +%unicode|string%(3) "one" +%unicode|string%(5) "three" +%unicode|string%(3) "two" +Mixing CAST('somestring'AS CHAR), integer and CAST(integer AS CHAR)... +%unicode|string%(1) "1" +%unicode|string%(5) "three" +%unicode|string%(1) "2" +Using integer only... +int(1) +int(303) +int(2) +Testing bind_param(), strings only... +%unicode|string%(3) "one" +%unicode|string%(5) "three" +%unicode|string%(3) "two" +Testing bind_param(), strings only, with CAST AS CHAR... +%unicode|string%(3) "one" +%unicode|string%(32) "three beers are more than enough" +%unicode|string%(3) "two" +done! diff --git a/ext/mysqli/tests/mysqli_query.phpt b/ext/mysqli/tests/mysqli_query.phpt new file mode 100644 index 0000000..73bebe1 --- /dev/null +++ b/ext/mysqli/tests/mysqli_query.phpt @@ -0,0 +1,141 @@ +--TEST-- +mysqli_query() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_query())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_query($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (false !== ($tmp = @mysqli_query($link, ''))) + printf("[002a] Expecting boolean/false got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @mysqli_query($link, "SELECT 1 AS a", MYSQLI_USE_RESULT, "foo"))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = mysqli_query($link, 'THIS IS NOT SQL'))) + printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = mysqli_query($link, "SELECT 'this is sql but with backslash g'\g"))) + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if ((0 === mysqli_errno($link)) || ('' == mysqli_error($link))) + printf("[006] mysqli_errno()/mysqli_error should return some error\n"); + + if (!$res = mysqli_query($link, "SELECT 'this is sql but with semicolon' AS valid ; ")) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + + if (!$res = mysqli_query($link, "SELECT 'a' AS ''")) + printf("[007a] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + var_dump($tmp = mysqli_fetch_assoc($res)); + var_dump($tmp[""]); + mysqli_free_result($res); + + if (false !== ($res = mysqli_query($link, 'SELECT "this is sql but with semicolon" AS valid ; SHOW VARIABLES'))) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (mysqli_get_server_version($link) > 50000) { + // let's try to play with stored procedures + mysqli_query($link, 'DROP PROCEDURE IF EXISTS p'); + if (mysqli_query($link, 'CREATE PROCEDURE p(OUT ver_param VARCHAR(25)) BEGIN SELECT VERSION() INTO ver_param; END;')) { + $res = mysqli_query($link, 'CALL p(@version)'); + $res = mysqli_query($link, 'SELECT @version AS p_version'); + + $tmp = mysqli_fetch_assoc($res); + if (!is_array($tmp) || empty($tmp) || !isset($tmp['p_version']) || ('' == $tmp['p_version'])) { + printf("[008a] Expecting array [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump($tmp); + } + + mysqli_free_result($res); + } else { + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + mysqli_query($link, 'DROP FUNCTION IF EXISTS f'); + if (mysqli_query($link, 'CREATE FUNCTION f( ver_param VARCHAR(25)) RETURNS VARCHAR(25) DETERMINISTIC RETURN ver_param;')) { + $res = mysqli_query($link, 'SELECT f(VERSION()) AS f_version'); + + $tmp = mysqli_fetch_assoc($res); + if (!is_array($tmp) || empty($tmp) || !isset($tmp['f_version']) || ('' == $tmp['f_version'])) { + printf("[009a] Expecting array [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump($tmp); + } + + mysqli_free_result($res); + } else { + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + } + + if (!is_object($res = mysqli_query($link, "SELECT id FROM test ORDER BY id", MYSQLI_USE_RESULT))) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + + if (!is_object($res = mysqli_query($link, "SELECT id FROM test ORDER BY id", MYSQLI_STORE_RESULT))) + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + + $valid = array(MYSQLI_USE_RESULT, MYSQLI_STORE_RESULT); + do { + $mode = mt_rand(-1000, 1000); + } while (in_array($mode, $valid)); + + if (false !== ($res = @mysqli_query($link, "SELECT id FROM test ORDER BY id", $mode))) + printf("[013] Invalid mode should return false got %s/%s, [%d] %s\n", + gettype($res), (is_object($res)) ? 'object' : $res, + mysqli_errno($link), mysqli_error($link)); + + + mysqli_close($link); + + if (NULL !== ($tmp = mysqli_query($link, "SELECT id FROM test"))) + printf("[011] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +@mysqli_query($link, "DROP FUNCTION IF EXISTS f"); +@mysqli_query($link, 'DROP PROCEDURE IF EXISTS p'); + +mysqli_close($link); +?> +--EXPECTF-- +array(1) { + [%u|b%"valid"]=> + %unicode|string%(30) "this is sql but with semicolon" +} +array(1) { + [%u|b%""]=> + %unicode|string%(1) "a" +} +%unicode|string%(1) "a" + +Warning: mysqli_query(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_query_iterators.phpt b/ext/mysqli/tests/mysqli_query_iterators.phpt new file mode 100644 index 0000000..2577aa7 --- /dev/null +++ b/ext/mysqli/tests/mysqli_query_iterators.phpt @@ -0,0 +1,201 @@ +--TEST-- +mysqli iterators +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + require('table.inc'); + + echo "--- Testing default ---\n"; + if (!is_object($res = mysqli_query($link, "SELECT id FROM test ORDER BY id"))) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + else { + foreach ($res as $row) { + var_dump($row); + } + echo "======\n"; + foreach ($res as $row) { + var_dump($row); + } + mysqli_free_result($res); + foreach ($res as $row) { + var_dump($row); + } + } + echo "--- Testing USE_RESULT ---\n"; + if (!is_object($res = mysqli_query($link, "SELECT id FROM test ORDER BY id", MYSQLI_USE_RESULT))) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + else { + foreach ($res as $row) { + var_dump($row); + } + echo "======\n"; + foreach ($res as $row) { + var_dump($row); + } + mysqli_free_result($res); + } + + echo "--- Testing STORE_RESULT ---\n"; + if (!is_object($res = mysqli_query($link, "SELECT id FROM test ORDER BY id", MYSQLI_STORE_RESULT))) + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + else { + foreach ($res as $row) { + var_dump($row); + } + echo "======\n"; + foreach ($res as $row) { + var_dump($row); + } + mysqli_free_result($res); + } + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +--- Testing default --- +array(1) { + ["id"]=> + string(1) "1" +} +array(1) { + ["id"]=> + string(1) "2" +} +array(1) { + ["id"]=> + string(1) "3" +} +array(1) { + ["id"]=> + string(1) "4" +} +array(1) { + ["id"]=> + string(1) "5" +} +array(1) { + ["id"]=> + string(1) "6" +} +====== +array(1) { + ["id"]=> + string(1) "1" +} +array(1) { + ["id"]=> + string(1) "2" +} +array(1) { + ["id"]=> + string(1) "3" +} +array(1) { + ["id"]=> + string(1) "4" +} +array(1) { + ["id"]=> + string(1) "5" +} +array(1) { + ["id"]=> + string(1) "6" +} + +Warning: main(): Couldn't fetch mysqli_result in %s on line %d +--- Testing USE_RESULT --- +array(1) { + ["id"]=> + string(1) "1" +} +array(1) { + ["id"]=> + string(1) "2" +} +array(1) { + ["id"]=> + string(1) "3" +} +array(1) { + ["id"]=> + string(1) "4" +} +array(1) { + ["id"]=> + string(1) "5" +} +array(1) { + ["id"]=> + string(1) "6" +} +====== + +Warning: main(): Data fetched with MYSQLI_USE_RESULT can be iterated only once in %s on line %d +--- Testing STORE_RESULT --- +array(1) { + ["id"]=> + string(1) "1" +} +array(1) { + ["id"]=> + string(1) "2" +} +array(1) { + ["id"]=> + string(1) "3" +} +array(1) { + ["id"]=> + string(1) "4" +} +array(1) { + ["id"]=> + string(1) "5" +} +array(1) { + ["id"]=> + string(1) "6" +} +====== +array(1) { + ["id"]=> + string(1) "1" +} +array(1) { + ["id"]=> + string(1) "2" +} +array(1) { + ["id"]=> + string(1) "3" +} +array(1) { + ["id"]=> + string(1) "4" +} +array(1) { + ["id"]=> + string(1) "5" +} +array(1) { + ["id"]=> + string(1) "6" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_query_local_infile_large.phpt b/ext/mysqli/tests/mysqli_query_local_infile_large.phpt new file mode 100644 index 0000000..76bc415 --- /dev/null +++ b/ext/mysqli/tests/mysqli_query_local_infile_large.phpt @@ -0,0 +1,103 @@ +--TEST-- +mysql_query(LOAD DATA LOCAL INFILE) with large data set (10MB) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); + +$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); +if (!$link) + die(sprintf("skip Can't connect [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--INI-- +mysqli.allow_local_infile=1 +--FILE-- +<?php + // Create a large CVS file + $file = tempnam(sys_get_temp_dir(), 'mysqli_test.cvs'); + if (!$fp = fopen($file, 'w')) + printf("[001] Cannot create CVS file '%s'\n", $file); + + $data = str_repeat("a", 127) . ";" . str_repeat("b", 127) . "\n"; + + $runtime = 5; + $max_bytes = 1024 * 1024 * 10; + + $start = microtime(true); + $bytes = 0; + $rowno = 0; + while (($bytes < $max_bytes) && ((microtime(true) - $start) < $runtime)) { + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1)) + $bytes += fwrite($fp, (binary)(++$rowno . ";" . $data)); + else + $bytes += fwrite($fp, ++$rowno . ";" . $data); + } + fclose($fp); + printf("Filesize in bytes: %d\nRows: %d\n", $bytes, $rowno); + + require_once("connect.inc"); + if (!($link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))) + printf("[002] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test") || + !mysqli_query($link, "CREATE TABLE test(id INT, col1 VARCHAR(255), col2 VARCHAR(255)) ENGINE = " . $engine)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, sprintf("LOAD DATA LOCAL INFILE '%s' INTO TABLE test FIELDS TERMINATED BY ';'", mysqli_real_escape_string($link, $file)))) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ((!is_string(mysqli_info($link))) || ('' == mysqli_info($link))) { + printf("[005] [%d] %s, mysqli_info not set \n", mysqli_errno($link), mysqli_error($link)); + } + + if (!($res = mysqli_query($link, "SELECT COUNT(*) AS _num FROM test"))) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $row = mysqli_fetch_assoc($res); + if (($row["_num"] != $rowno)) + printf("[007] Expecting %d rows, found %d\n", $rowno, $row["_num"]); + + mysqli_free_result($res); + + $random = mt_rand(1, $rowno); + if (!$res = mysqli_query($link, "SELECT id, col1, col2 FROM test WHERE id = " . $random)) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $row = mysqli_fetch_assoc($res); + var_dump($row); + mysqli_free_result($res); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +$file = tempnam(sys_get_temp_dir(), 'mysqli_test.cvs'); +if (file_exists($file)) + unlink($file); + +require_once("connect.inc"); +if (!($link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[c002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); +?> +--EXPECTF-- +Filesize in bytes: %d +Rows: %d +array(3) { + [%u|b%"id"]=> + %unicode|string%(%d) "%d" + [%u|b%"col1"]=> + %unicode|string%(127) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + [%u|b%"col2"]=> + %unicode|string%(127) "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_query_stored_proc.phpt b/ext/mysqli/tests/mysqli_query_stored_proc.phpt new file mode 100644 index 0000000..10bf86b --- /dev/null +++ b/ext/mysqli/tests/mysqli_query_stored_proc.phpt @@ -0,0 +1,195 @@ +--TEST-- +mysqli_query() - Stored Procedures +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf('skip Cannot connect to MySQL, [%d] %s.', mysqli_connect_errno(), mysqli_connect_error())); +} +if (mysqli_get_server_version($link) <= 50000) { + die(sprintf('skip Needs MySQL 5.0+, found version %d.', mysqli_get_server_version($link))); +} +?> +--FILE-- +<?php + require_once('connect.inc'); + require_once('table.inc'); + + if (!mysqli_query($link, 'DROP PROCEDURE IF EXISTS p')) + printf("[001] [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + + if (mysqli_query($link, 'CREATE PROCEDURE p() READS SQL DATA BEGIN SELECT id, label FROM test ORDER BY id ASC; +END;')) { + /* stored proc which returns one result set */ + if (mysqli_multi_query($link, 'CALL p()')) { + do { + if ($res = mysqli_use_result($link)) { + // skip results, don't fetch all from server + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + } + } while (mysqli_more_results($link) && mysqli_next_result($link)); + + } else { + printf("[003] Cannot call SP, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + if (mysqli_multi_query($link, 'CALL p()')) { + do { + if ($res = mysqli_store_result($link)) { + // fetch all results from server, but skip on client side + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + } + } while (mysqli_more_results($link) && mysqli_next_result($link)); + + } else { + printf("[004] Cannot call SP, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + if (mysqli_multi_query($link, 'CALL p()')) { + do { + if ($res = mysqli_store_result($link)) { + // fetch all results from server, but skip on client side + var_dump(mysqli_fetch_assoc($res)); + while (mysqli_fetch_assoc($res)) + ; + mysqli_free_result($res); + } + } while (mysqli_more_results($link) && mysqli_next_result($link)); + + } else { + printf("[005] Cannot call SP, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + } else { + printf("[002] Cannot create SP, [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + } + + if (!mysqli_query($link, 'DROP PROCEDURE IF EXISTS p')) + printf("[006] [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + + if (mysqli_query($link, 'CREATE PROCEDURE p() READS SQL DATA BEGIN SELECT id, label FROM test ORDER BY id ASC; SELECT id FROM test ORDER BY id ASC; END;')) { + /* stored proc which returns two result sets */ + + if (mysqli_multi_query($link, 'CALL p()')) { + do { + if ($res = mysqli_store_result($link)) { + // fetch all results from server, but skip on client side + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + } + } while (mysqli_more_results($link) && mysqli_next_result($link)); + + } else { + printf("[008] Cannot call SP, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + } else { + printf("[007] Cannot create SP, [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + } + + if (!mysqli_query($link, 'DROP PROCEDURE IF EXISTS p')) + printf("[009] [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + + if (mysqli_real_query($link, 'CREATE PROCEDURE p(OUT ver_param VARCHAR(25)) BEGIN SELECT VERSION() INTO ver_param; END;')) { + /* no result set, just output parameter */ + if (!mysqli_query($link, 'CALL p(@version)')) + printf("[011] Cannot call SP, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "SET @version = 'unknown'")) + printf("[012] Cannot reset user variable, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, 'CALL p(@version)')) + printf("[013] Cannot call SP, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, 'SELECT @version as _vers')) + printf("[014] Cannot fetch user variable, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res) || + $row['_vers'] == 'unknown') + printf("[015] Results seem wrong, got %s, [%d] %s\n", + $row['_vers'], + mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + + } else { + printf("[010] Cannot create SP, [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + } + + if (!mysqli_query($link, 'DROP PROCEDURE IF EXISTS p')) + printf("[016] [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + + if (mysqli_real_query($link, 'CREATE PROCEDURE p(IN ver_in VARCHAR(25), OUT ver_out VARCHAR(25)) BEGIN SELECT ver_in INTO ver_out; END;')) { + /* no result set, one input, one output parameter */ + if (!mysqli_query($link, "CALL p('myversion', @version)")) + printf("[018] Cannot call SP, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "SET @version = 'unknown'")) + printf("[019] Cannot reset user variable, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "CALL p('myversion', @version)")) + printf("[020] Cannot call SP, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, 'SELECT @version as _vers')) + printf("[021] Cannot fetch user variable, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res) || + $row['_vers'] == 'myversion') + printf("[022] Results seem wrong, got %s, [%d] %s\n", + $row['_vers'], + mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + + } else { + printf("[017] Cannot create SP, [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + } + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +@mysqli_query($link, "DROP PROCEDURE IS EXISTS p"); + +mysqli_close($link); +?> +--EXPECTF-- +array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +array(1) { + [%u|b%"id"]=> + %unicode|string%(1) "1" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_query_unicode.phpt b/ext/mysqli/tests/mysqli_query_unicode.phpt new file mode 100644 index 0000000..478ccbd --- /dev/null +++ b/ext/mysqli/tests/mysqli_query_unicode.phpt @@ -0,0 +1,133 @@ +--TEST-- +mysqli_query() - unicode (cyrillic) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); +require_once('table.inc'); +if (!$res = mysqli_query($link, "SHOW CHARACTER SET LIKE 'utf8'")) + die("skip UTF8 chatset seems not available"); +mysqli_free_result($res); +mysqli_close($link); +?> +--FILE-- +<?php + include_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_query())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_query($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require_once('table.inc'); + + if (TRUE !== ($tmp = @mysqli_query($link, "set names utf8"))) + printf("[002.5] Expecting TRUE, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @mysqli_query($link, "SELECT 1 AS колона", MYSQLI_USE_RESULT, "foo"))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = mysqli_query($link, 'това не е еÑкюел'))) + printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = mysqli_query($link, "SELECT 'това е еÑкюел, но ÑÑŠÑ Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð° наклонена и g'\g"))) + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if ((0 === mysqli_errno($link)) || ('' == mysqli_error($link))) + printf("[006] mysqli_errno()/mysqli_error should return some error\n"); + + if (!$res = mysqli_query($link, "SELECT 'това еÑкюел, но Ñ Ñ‚Ð¾Ñ‡ÐºÐ° и запетаÑ' AS правилен ; ")) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + + if (false !== ($res = mysqli_query($link, "SELECT 'това еÑкюел, но Ñ Ñ‚Ð¾Ñ‡ÐºÐ° и запетаÑ' AS правилен ; SHOW VARIABLES"))) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (mysqli_get_server_version($link) > 50000) { + // let's try to play with stored procedures + mysqli_query($link, 'DROP PROCEDURE IF EXISTS процедурка'); + if (mysqli_query($link, 'CREATE PROCEDURE процедурка(OUT верÑÐ¸Ñ VARCHAR(25)) BEGIN SELECT VERSION() INTO верÑиÑ; END;')) { + $res = mysqli_query($link, 'CALL процедурка(@version)'); + $res = mysqli_query($link, 'SELECT @version AS п_верÑиÑ'); + + $tmp = mysqli_fetch_assoc($res); + if (!is_array($tmp) || empty($tmp) || !isset($tmp['п_верÑиÑ']) || ('' == $tmp['п_верÑиÑ'])) { + printf("[008a] Expecting array [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump($tmp); + } + + mysqli_free_result($res); + } else { + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + mysqli_query($link, 'DROP FUNCTION IF EXISTS функцийка'); + if (mysqli_query($link, 'CREATE FUNCTION функцийка( параметър_верÑÐ¸Ñ VARCHAR(25)) RETURNS VARCHAR(25) DETERMINISTIC RETURN параметър_верÑиÑ;')) { + $res = mysqli_query($link, 'SELECT функцийка(VERSION()) AS Ñ„_верÑиÑ'); + + $tmp = mysqli_fetch_assoc($res); + if (!is_array($tmp) || empty($tmp) || !isset($tmp['Ñ„_верÑиÑ']) || ('' == $tmp['Ñ„_верÑиÑ'])) { + printf("[009a] Expecting array [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump($tmp); + } + + mysqli_free_result($res); + } else { + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + } + + /* + Trying to test what Ramil suggests in http://bugs.mysql.com/bug.php?id=29576 + However, this won't work, because we're lacking MYSQLI_SET_CHARSET_NAME. + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1)) { + if (mysqli_get_server_version() > 50002) { + @mysqli_query($link, "DROP USER IF EXISTS 'теÑÑ‚'@'%'"); + if (TRUE !== mysqli_query($link, "CREATE USER 'теÑÑ‚'@'%'")) { + var_dump(mysqli_error($link); + } + } + if (TRUE !== mysqli_query($link, "GRANT SELECT ON $db.* TO 'теÑÑ‚'@'%' IDENTIFIED BY 'парола'")) { + var_dump(mysqli_error($link); + } else { + $link2 = mysqli_init(); + if (!(mysqli_real_connect($link2, $host, "теÑÑ‚", 'парола', $db, $port, $socket))) { + printf("[011] Cannot connect to the server using host=%s, user=%s, passwd=парола, dbname=%s, port=%s, socket=%s, [%d] %s\n", + $host, "теÑÑ‚", $db, $port, $socket, + mysqli_connect_errno(), mysqli_connect_error()); + } + mysqli_close($link2); + if (mysqli_get_server_version() > 50002) { + if (!mysqli_query($link, "DROP USER 'теÑÑ‚'@'%'")) + printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } else { + printf("[015] Cannot create user or grant privileges, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + } + } + } + */ + + mysqli_close($link); + + if (NULL !== ($tmp = mysqli_query($link, "SELECT id FROM test"))) + printf("[014] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +array(1) { + [%u|b%"правилен"]=> + %unicode|string%(%d) "това еÑкюел, но Ñ Ñ‚Ð¾Ñ‡ÐºÐ° и запетаÑ" +} + +Warning: mysqli_query(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_real_connect.phpt b/ext/mysqli/tests/mysqli_real_connect.phpt new file mode 100644 index 0000000..5477ea1 --- /dev/null +++ b/ext/mysqli/tests/mysqli_real_connect.phpt @@ -0,0 +1,221 @@ +--TEST-- +mysqli_real_connect() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + include("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (NULL !== ($tmp = @mysqli_real_connect($link))) + printf("[001a] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @mysqli_real_connect($link, $link))) + printf("[001b] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @mysqli_real_connect($link, $link, $link))) + printf("[001c] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @mysqli_real_connect($link, $link, $link, $link))) + printf("[001d] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @mysqli_real_connect($link, $link, $link, $link, $link))) + printf("[001e] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @mysqli_real_connect($link, $link, $link, $link, $link, $link))) + printf("[001f] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @mysqli_real_connect($link, $link, $link, $link, $link, $link, $link))) + printf("[001g] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + // ( mysqli link [, string hostname [, string username [, string passwd [, string dbname [, int port [, string socket [, int flags]]]]]]] + if (NULL !== ($tmp = @mysqli_real_connect($link, $link, $link, $link, $link, $link, $link, $link))) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = mysqli_init()) + printf("[002] mysqli_init() failed\n"); + + if (!mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + mysqli_close($link); + if (!$link = mysqli_init()) + printf("[004] mysqli_init() failed\n"); + + if (false !== ($tmp = mysqli_real_connect($link, $host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket))) + printf("[005] Expecting boolean/false got %s/%s. Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", gettype($tmp), $tmp, $host, $user . 'unknown_really', $db, $port, $socket); + + // Run the following tests without an anoynmous MySQL user and use a password for the test user! + ini_set('mysqli.default_socket', $socket); + if (!mysqli_real_connect($link, $host, $user, $passwd, $db, $port)) { + printf("[006] Usage of mysqli.default_socket failed\n"); + } else { + mysqli_close($link); + if (!$link = mysqli_init()) + printf("[007] mysqli_init() failed\n"); + } + + ini_set('mysqli.default_port', $port); + if (!mysqli_real_connect($link, $host, $user, $passwd, $db)) { + printf("[008] Usage of mysqli.default_port failed\n"); + } else { + mysqli_close($link); + if (!$link = mysqli_init()) + printf("[009] mysqli_init() failed\n"); + } + + ini_set('mysqli.default_pw', $passwd); + if (!mysqli_real_connect($link, $host, $user)) { + printf("[010] Usage of mysqli.default_pw failed\n") ; + } else { + mysqli_close($link); + if (!$link = mysqli_init()) + printf("[011] mysqli_init() failed\n"); + } + + ini_set('mysqli.default_user', $user); + if (!mysqli_real_connect($link, $host)) { + printf("[012] Usage of mysqli.default_user failed\n") ; + } else { + mysqli_close($link); + if (!$link = mysqli_init()) + printf("[011] mysqli_init() failed\n"); + } + + ini_set('mysqli.default_host', $host); + if (!mysqli_real_connect($link)) { + printf("[014] Usage of mysqli.default_host failed\n") ; + } else { + mysqli_close($link); + if (!$link = mysqli_init()) + printf("[015] mysqli_init() failed\n"); + } + + // CLIENT_MULTI_STATEMENTS - should be disabled silently + if (!mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket, 65536)) + printf("[016] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ($res = mysqli_query($link, "SELECT 1 AS a; SELECT 2 AS b")) { + printf("[017] Should have failed. CLIENT_MULTI_STATEMENT should have been disabled.\n"); + var_dump($res->num_rows); + mysqli_next_result($link); + $res = mysqli_store_result($link); + var_dump($res->num_rows); + } + + + mysqli_close($link); + if (!$link = mysqli_init()) + printf("[018] mysqli_init() failed\n"); + + if (ini_get('open_basedir')) { + // CLIENT_LOCAL_FILES should be blocked - but how to test it ?! + + if (!mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket, 128)) + printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $filename = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'mysqli_real_connect_phpt'; + if (!$fp = fopen($filename, 'w')) + printf("[020] Cannot open temporary file %s\n", $filename); + + fwrite($fp, '100;z'); + fclose($fp); + + // how do we test if gets forbidden because of a missing right or the flag, this test is partly bogus ? + if (mysqli_query($link, "LOAD DATA LOCAL INFILE '$filename' INTO TABLE test FIELDS TERMINATED BY ';'")) + printf("[021] LOAD DATA INFILE should have been forbidden!\n"); + + unlink($filename); + } + + mysqli_close($link); + @var_dump($link); + + if ($IS_MYSQLND) { + ini_set('mysqli.default_host', 'p:' . $host); + $link = mysqli_init(); + if (!@mysqli_real_connect($link)) { + printf("[022] Usage of mysqli.default_host=p:%s (persistent) failed\n", $host) ; + } else { + if (!$res = mysqli_query($link, "SELECT 'mysqli.default_host (persistent)' AS 'testing'")) + printf("[023] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + if ($tmp['testing'] !== 'mysqli.default_host (persistent)') { + printf("[024] Result looks strange - check manually, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + var_dump($tmp); + } + mysqli_free_result($res); + mysqli_close($link); + } + + ini_set('mysqli.default_host', 'p:'); + $link = mysqli_init(); + if (@mysqli_real_connect($link)) { + printf("[025] Usage of mysqli.default_host=p: did not fail\n") ; + mysqli_close($link); + } + @mysqli_close($link); + } + + if (NULL !== ($tmp = mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket))) + printf("[026] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_real_connect(): (%s/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d +object(mysqli)#%d (%d) { + [%u|b%"affected_rows"]=> + NULL + [%u|b%"client_info"]=> + %s + [%u|b%"client_version"]=> + int(%d) + [%u|b%"connect_errno"]=> + int(%d) + [%u|b%"connect_error"]=> + NULL + [%u|b%"errno"]=> + %s + [%u|b%"error"]=> + %s + [%u|b%"error_list"]=> + NULL + [%u|b%"field_count"]=> + NULL + [%u|b%"host_info"]=> + NULL + [%u|b%"info"]=> + NULL + [%u|b%"insert_id"]=> + NULL + [%u|b%"server_info"]=> + NULL + [%u|b%"server_version"]=> + NULL + [%u|b%"stat"]=> + NULL + [%u|b%"sqlstate"]=> + NULL + [%u|b%"protocol_version"]=> + NULL + [%u|b%"thread_id"]=> + NULL + [%u|b%"warning_count"]=> + NULL +} + +Warning: mysqli_real_connect(): Couldn't fetch mysqli in %s on line %d +done! diff --git a/ext/mysqli/tests/mysqli_real_connect_pconn.phpt b/ext/mysqli/tests/mysqli_real_connect_pconn.phpt new file mode 100644 index 0000000..4cc1819 --- /dev/null +++ b/ext/mysqli/tests/mysqli_real_connect_pconn.phpt @@ -0,0 +1,155 @@ +--TEST-- +mysqli_real_connect() - persistent connections +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); +if (!$IS_MYSQLND) + die("skip mysqlnd only test"); +?> +--INI-- +mysqli.allow_persistent=1 +mysqli.max_persistent=10 +--FILE-- +<?php + require_once("connect.inc"); + $host = 'p:' . $host; + + if (!$link = mysqli_init()) + printf("[002] mysqli_init() failed\n"); + + if (!mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + mysqli_close($link); + if (!$link = mysqli_init()) + printf("[004] mysqli_init() failed\n"); + + if (false !== ($tmp = mysqli_real_connect($link, $host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket))) + printf("[005] Expecting boolean/false got %s/%s. Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", gettype($tmp), $tmp, $host, $user . 'unknown_really', $db, $port, $socket); + + // Run the following tests without an anoynmous MySQL user and use a password for the test user! + ini_set('mysqli.default_socket', $socket); + if (!mysqli_real_connect($link, $host, $user, $passwd, $db, $port)) { + printf("[006] Usage of mysqli.default_socket failed\n"); + } else { + mysqli_close($link); + if (!$link = mysqli_init()) + printf("[007] mysqli_init() failed\n"); + } + + ini_set('mysqli.default_port', $port); + if (!mysqli_real_connect($link, $host, $user, $passwd, $db)) { + printf("[008] Usage of mysqli.default_port failed\n"); + } else { + mysqli_close($link); + if (!$link = mysqli_init()) + printf("[009] mysqli_init() failed\n"); + } + + ini_set('mysqli.default_pw', $passwd); + if (!mysqli_real_connect($link, $host, $user)) { + printf("[010] Usage of mysqli.default_pw failed\n") ; + } else { + mysqli_close($link); + if (!$link = mysqli_init()) + printf("[011] mysqli_init() failed\n"); + } + + ini_set('mysqli.default_user', $user); + if (!mysqli_real_connect($link, $host)) { + printf("[012] Usage of mysqli.default_user failed\n") ; + } else { + mysqli_close($link); + if (!$link = mysqli_init()) + printf("[011] mysqli_init() failed\n"); + } + + ini_set('mysqli.default_host', $host); + if (!mysqli_real_connect($link)) { + printf("[014] Usage of mysqli.default_host failed\n") ; + } else { + mysqli_close($link); + if (!$link = mysqli_init()) + printf("[015] mysqli_init() failed\n"); + } + + // CLIENT_MULTI_STATEMENTS - should be disabled silently + if (!mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket, 65536)) + printf("[016] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ($res = mysqli_query($link, "SELECT 1 AS a; SELECT 2 AS b")) { + printf("[017] Should have failed. CLIENT_MULTI_STATEMENT should have been disabled.\n"); + var_dump($res->num_rows); + mysqli_next_result($link); + $res = mysqli_store_result($link); + var_dump($res->num_rows); + } + + + mysqli_close($link); + if (!$link = mysqli_init()) + printf("[018] mysqli_init() failed\n"); + + if (ini_get('open_basedir')) { + // CLIENT_LOCAL_FILES should be blocked - but how to test it ?! + + if (!mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket, 128)) + printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $filename = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'mysqli_real_connect_phpt'; + if (!$fp = fopen($filename, 'w')) + printf("[020] Cannot open temporary file %s\n", $filename); + + fwrite($fp, '100;z'); + fclose($fp); + + // how do we test if gets forbidden because of a missing right or the flag, this test is partly bogus ? + if (mysqli_query($link, "LOAD DATA LOCAL INFILE '$filename' INTO TABLE test FIELDS TERMINATED BY ';'")) + printf("[021] LOAD DATA INFILE should have been forbidden!\n"); + + unlink($filename); + } + + mysqli_close($link); + + if ($IS_MYSQLND) { + $link = mysqli_init(); + if (!@mysqli_real_connect($link)) { + printf("[022] Usage of mysqli.default_host=p:%s (persistent) failed\n", $host) ; + } else { + if (!$res = mysqli_query($link, "SELECT 'mysqli.default_host (persistent)' AS 'testing'")) + printf("[023] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + if ($tmp['testing'] !== 'mysqli.default_host (persistent)') { + printf("[024] Result looks strange - check manually, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + var_dump($tmp); + } + mysqli_free_result($res); + mysqli_close($link); + } + + ini_set('mysqli.default_host', 'p:'); + $link = mysqli_init(); + if (@mysqli_real_connect($link)) { + printf("[025] Usage of mysqli.default_host=p: did not fail\n") ; + mysqli_close($link); + } + } + + if (NULL === ($tmp = mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket))) + printf("[026] Expecting not NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_real_connect(): (%s/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d +done! diff --git a/ext/mysqli/tests/mysqli_real_escape_string.phpt b/ext/mysqli/tests/mysqli_real_escape_string.phpt new file mode 100644 index 0000000..6c37258 --- /dev/null +++ b/ext/mysqli/tests/mysqli_real_escape_string.phpt @@ -0,0 +1,58 @@ +--TEST-- +mysqli_real_escape_string() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (NULL !== ($tmp = @mysqli_real_escape_string())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @mysqli_real_escape_string($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (NULL !== ($tmp =@mysqli_real_escape_string($link, "foo", "foo"))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if ('\\\\' !== ($tmp = mysqli_real_escape_string($link, '\\'))) + printf("[004] Expecting \\\\, got %s\n", $tmp); + + if ('\"' !== ($tmp = mysqli_real_escape_string($link, '"'))) + printf("[005] Expecting \", got %s\n", $tmp); + + if ("\'" !== ($tmp = mysqli_real_escape_string($link, "'"))) + printf("[006] Expecting ', got %s\n", $tmp); + + if ("\\n" !== ($tmp = mysqli_real_escape_string($link, "\n"))) + printf("[007] Expecting \\n, got %s\n", $tmp); + + if ("\\r" !== ($tmp = mysqli_real_escape_string($link, "\r"))) + printf("[008] Expecting \\r, got %s\n", $tmp); + + if ("foo\\0bar" !== ($tmp = mysqli_real_escape_string($link, "foo" . chr(0) . "bar"))) + printf("[009] Expecting %s, got %s\n", "foo\\0bar", $tmp); + + mysqli_close($link); + + if (NULL !== ($tmp = mysqli_real_escape_string($link, 'foo'))) + printf("[010] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + /* Make sure that the function alias exists */ + if (NULL !== ($tmp = @mysqli_escape_string())) + printf("[011] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +Warning: mysqli_real_escape_string(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_real_escape_string_big5.phpt b/ext/mysqli/tests/mysqli_real_escape_string_big5.phpt new file mode 100644 index 0000000..b177c1f --- /dev/null +++ b/ext/mysqli/tests/mysqli_real_escape_string_big5.phpt @@ -0,0 +1,82 @@ +--TEST-- +mysqli_real_escape_string() - big5 +--SKIPIF-- +<?php +if (ini_get('unicode.semantics')) + die("skip Test cannot be run in unicode mode"); + +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); + +if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf("skip Cannot connect to MySQL, [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error())); +} +if (!mysqli_set_charset($link, 'big5')) + die(sprintf("skip Cannot set charset 'big5'")); +mysqli_close($link); +?> +--FILE-- +<?php + require_once("connect.inc"); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) +{ + printf("[001] Cannot connect to the server using host=%s, user=%s, +passwd=***, dbname=%s, port=%s, socket=%s - [%d] %s\n", $host, $user, $db, +$port, $socket, mysqli_connect_errno(), mysqli_connect_error()); + } + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { + printf("Failed to drop old test table: [%d] %s\n", mysqli_errno($link), +mysqli_error($link)); + } + + if (!mysqli_query($link, 'CREATE TABLE test(id INT, label CHAR(1), PRIMARY +KEY(id)) ENGINE=' . $engine . " DEFAULT CHARSET=big5")) { + printf("Failed to create test table: [%d] %s\n", mysqli_errno($link), +mysqli_error($link)); + } + + var_dump(mysqli_set_charset($link, "big5")); + + if ('§ä¨ì¥H¤U¤º®e\\\\§ä¨ì¥H¤U¤º®e' !== ($tmp = mysqli_real_escape_string($link, +'§ä¨ì¥H¤U¤º®e\\§ä¨ì¥H¤U¤º®e'))) + printf("[004] Expecting \\\\, got %s\n", $tmp); + + if ('§ä¨ì¥H¤U¤º®e\"§ä¨ì¥H¤U¤º®e' !== ($tmp = mysqli_real_escape_string($link, +'§ä¨ì¥H¤U¤º®e"§ä¨ì¥H¤U¤º®e'))) + printf("[005] Expecting \", got %s\n", $tmp); + + if ("§ä¨ì¥H¤U¤º®e\'§ä¨ì¥H¤U¤º®e" !== ($tmp = mysqli_real_escape_string($link, +"§ä¨ì¥H¤U¤º®e'§ä¨ì¥H¤U¤º®e"))) + printf("[006] Expecting ', got %s\n", $tmp); + + if ("§ä¨ì¥H¤U¤º®e\\n§ä¨ì¥H¤U¤º®e" !== ($tmp = mysqli_real_escape_string($link, +"§ä¨ì¥H¤U¤º®e\n§ä¨ì¥H¤U¤º®e"))) + printf("[007] Expecting \\n, got %s\n", $tmp); + + if ("§ä¨ì¥H¤U¤º®e\\r§ä¨ì¥H¤U¤º®e" !== ($tmp = mysqli_real_escape_string($link, +"§ä¨ì¥H¤U¤º®e\r§ä¨ì¥H¤U¤º®e"))) + printf("[008] Expecting \\r, got %s\n", $tmp); + + if ("§ä¨ì¥H¤U¤º®e\\0§ä¨ì¥H¤U¤º®e" !== ($tmp = mysqli_real_escape_string($link, "§ä¨ì¥H¤U¤º®e" +. chr(0) . "§ä¨ì¥H¤U¤º®e"))) + printf("[009] Expecting %s, got %s\n", "§ä¨ì¥H¤U¤º®e\\0§ä¨ì¥H¤U¤º®e", $tmp); + + var_dump(mysqli_query($link, "INSERT INTO test(id, label) VALUES (100, +'§ä')")); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +bool(true) +bool(true) +done! diff --git a/ext/mysqli/tests/mysqli_real_escape_string_eucjpms.phpt b/ext/mysqli/tests/mysqli_real_escape_string_eucjpms.phpt new file mode 100644 index 0000000..cf4afb6 --- /dev/null +++ b/ext/mysqli/tests/mysqli_real_escape_string_eucjpms.phpt @@ -0,0 +1,75 @@ +--TEST-- +mysqli_real_escape_string() - eucjpms +--SKIPIF-- +<?php +if (ini_get('unicode.semantics')) + die("skip Test cannot be run in unicode mode"); + +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); + +if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf("skip Cannot connect to MySQL, [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error())); +} +if (!mysqli_set_charset($link, 'eucjpms')) + die(sprintf("skip Cannot set charset 'eucjpms'")); +mysqli_close($link); +?> +--FILE-- +<?php +require_once("connect.inc"); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) +{ + printf("[001] Cannot connect to the server using host=%s, user=%s, +passwd=***, dbname=%s, port=%s, socket=%s - [%d] %s\n", $host, $user, $db, +$port, $socket, mysqli_connect_errno(), mysqli_connect_error()); + } + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { + printf("Failed to drop old test table: [%d] %s\n", mysqli_errno($link), +mysqli_error($link)); + } + + if (!mysqli_query($link, 'CREATE TABLE test(id INT, label CHAR(1), PRIMARY +KEY(id)) ENGINE=' . $engine . " DEFAULT CHARSET=eucjpms")) { + printf("Failed to create test table: [%d] %s\n", mysqli_errno($link), +mysqli_error($link)); + } + + var_dump(mysqli_set_charset($link, "eucjpms")); + + if ('¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï\\\\¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï' !== ($tmp = mysqli_real_escape_string($link, '¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï\\¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï'))) + printf("[004] Expecting \\\\, got %s\n", $tmp); + + if ('¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï\"¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï' !== ($tmp = mysqli_real_escape_string($link, '¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï"¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï'))) + printf("[005] Expecting \", got %s\n", $tmp); + + if ("¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï\'¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï" !== ($tmp = mysqli_real_escape_string($link, "¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï'¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï"))) + printf("[006] Expecting ', got %s\n", $tmp); + + if ("¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï\\n¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï" !== ($tmp = mysqli_real_escape_string($link, "¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï\n¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï"))) + printf("[007] Expecting \\n, got %s\n", $tmp); + + if ("¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï\\r¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï" !== ($tmp = mysqli_real_escape_string($link, "¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï\r¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï"))) + printf("[008] Expecting \\r, got %s\n", $tmp); + + if ("¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï\\0¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï" !== ($tmp = mysqli_real_escape_string($link, "¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï" . chr(0) . "¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï"))) + printf("[009] Expecting %s, got %s\n", "¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï\\0¤³¤ÎÁȤ߹ç¤ï¤»¤Ç¤Ï", $tmp); + + var_dump(mysqli_query($link, "INSERT INTO test(id, label) VALUES (100, '¤³')")); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +bool(true) +bool(true) +done! diff --git a/ext/mysqli/tests/mysqli_real_escape_string_euckr.phpt b/ext/mysqli/tests/mysqli_real_escape_string_euckr.phpt new file mode 100644 index 0000000..7ac7497 --- /dev/null +++ b/ext/mysqli/tests/mysqli_real_escape_string_euckr.phpt @@ -0,0 +1,74 @@ +--TEST-- +mysqli_real_escape_string() - euckr +--SKIPIF-- +<?php +if (ini_get('unicode.semantics')) + die("skip Test cannot be run in unicode mode"); + +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); + +if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf("skip Cannot connect to MySQL, [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error())); +} +if (!mysqli_set_charset($link, 'euckr')) + die(sprintf("skip Cannot set charset 'euckr'")); +mysqli_close($link); +?> +--FILE-- +<?php + require_once("connect.inc"); + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) +{ + printf("[001] Cannot connect to the server using host=%s, user=%s, +passwd=***, dbname=%s, port=%s, socket=%s - [%d] %s\n", $host, $user, $db, +$port, $socket, mysqli_connect_errno(), mysqli_connect_error()); + } + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { + printf("Failed to drop old test table: [%d] %s\n", mysqli_errno($link), +mysqli_error($link)); + } + + if (!mysqli_query($link, 'CREATE TABLE test(id INT, label CHAR(1), PRIMARY +KEY(id)) ENGINE=' . $engine . " DEFAULT CHARSET=euckr")) { + printf("Failed to create test table: [%d] %s\n", mysqli_errno($link), +mysqli_error($link)); + } + + var_dump(mysqli_set_charset($link, "euckr")); + + if ('±Ç´ë¼º\\\\±Ç´ë¼º' !== ($tmp = mysqli_real_escape_string($link, '±Ç´ë¼º\\±Ç´ë¼º'))) + printf("[004] Expecting \\\\, got %s\n", $tmp); + + if ('±Ç´ë¼º\"±Ç´ë¼º' !== ($tmp = mysqli_real_escape_string($link, '±Ç´ë¼º"±Ç´ë¼º'))) + printf("[005] Expecting \", got %s\n", $tmp); + + if ("±Ç´ë¼º\'±Ç´ë¼º" !== ($tmp = mysqli_real_escape_string($link, "±Ç´ë¼º'±Ç´ë¼º"))) + printf("[006] Expecting ', got %s\n", $tmp); + + if ("±Ç´ë¼º\\n±Ç´ë¼º" !== ($tmp = mysqli_real_escape_string($link, "±Ç´ë¼º\n±Ç´ë¼º"))) + printf("[007] Expecting \\n, got %s\n", $tmp); + + if ("±Ç´ë¼º\\r±Ç´ë¼º" !== ($tmp = mysqli_real_escape_string($link, "±Ç´ë¼º\r±Ç´ë¼º"))) + printf("[008] Expecting \\r, got %s\n", $tmp); + + if ("±Ç´ë¼º\\0±Ç´ë¼º" !== ($tmp = mysqli_real_escape_string($link, "±Ç´ë¼º" . chr(0) . "±Ç´ë¼º"))) + printf("[009] Expecting %s, got %s\n", "±Ç´ë¼º\\0±Ç´ë¼º", $tmp); + + var_dump(mysqli_query($link, "INSERT INTO test(id, label) VALUES (100, '±Ç')")); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +bool(true) +bool(true) +done! diff --git a/ext/mysqli/tests/mysqli_real_escape_string_gb2312.phpt b/ext/mysqli/tests/mysqli_real_escape_string_gb2312.phpt new file mode 100644 index 0000000..b93d815 --- /dev/null +++ b/ext/mysqli/tests/mysqli_real_escape_string_gb2312.phpt @@ -0,0 +1,75 @@ +--TEST-- +mysqli_real_escape_string() - gb2312 +--SKIPIF-- +<?php +if (ini_get('unicode.semantics')) + die("skip Test cannot be run in unicode mode"); + +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); + +if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf("skip Cannot connect to MySQL, [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error())); +} +if (!mysqli_set_charset($link, 'gb2312')) + die(sprintf("skip Cannot set charset 'gb2312'")); +mysqli_close($link); +?> +--FILE-- +<?php + + require_once("connect.inc"); + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) +{ + printf("[001] Cannot connect to the server using host=%s, user=%s, +passwd=***, dbname=%s, port=%s, socket=%s - [%d] %s\n", $host, $user, $db, +$port, $socket, mysqli_connect_errno(), mysqli_connect_error()); + } + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { + printf("Failed to drop old test table: [%d] %s\n", mysqli_errno($link), +mysqli_error($link)); + } + + if (!mysqli_query($link, 'CREATE TABLE test(id INT, label CHAR(1), PRIMARY +KEY(id)) ENGINE=' . $engine . " DEFAULT CHARSET=gb2312")) { + printf("Failed to create test table: [%d] %s\n", mysqli_errno($link), +mysqli_error($link)); + } + + var_dump(mysqli_set_charset($link, "gb2312")); + + if ('Ê×ÏÈ\\\\Ê×ÏÈ' !== ($tmp = mysqli_real_escape_string($link, 'Ê×ÏÈ\\Ê×ÏÈ'))) + printf("[004] Expecting \\\\, got %s\n", $tmp); + + if ('Ê×ÏÈ\"Ê×ÏÈ' !== ($tmp = mysqli_real_escape_string($link, 'Ê×ÏÈ"Ê×ÏÈ'))) + printf("[005] Expecting \", got %s\n", $tmp); + + if ("Ê×ÏÈ\'Ê×ÏÈ" !== ($tmp = mysqli_real_escape_string($link, "Ê×ÏÈ'Ê×ÏÈ"))) + printf("[006] Expecting ', got %s\n", $tmp); + + if ("Ê×ÏÈ\\nÊ×ÏÈ" !== ($tmp = mysqli_real_escape_string($link, "Ê×ÏÈ\nÊ×ÏÈ"))) + printf("[007] Expecting \\n, got %s\n", $tmp); + + if ("Ê×ÏÈ\\rÊ×ÏÈ" !== ($tmp = mysqli_real_escape_string($link, "Ê×ÏÈ\rÊ×ÏÈ"))) + printf("[008] Expecting \\r, got %s\n", $tmp); + + if ("Ê×ÏÈ\\0Ê×ÏÈ" !== ($tmp = mysqli_real_escape_string($link, "Ê×ÏÈ" . chr(0) . "Ê×ÏÈ"))) + printf("[009] Expecting %s, got %s\n", "Ê×ÏÈ\\0Ê×ÏÈ", $tmp); + + var_dump(mysqli_query($link, "INSERT INTO test(id, label) VALUES (100, 'Ê×')")); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +bool(true) +bool(true) +done! diff --git a/ext/mysqli/tests/mysqli_real_escape_string_gbk.phpt b/ext/mysqli/tests/mysqli_real_escape_string_gbk.phpt new file mode 100644 index 0000000..2fd1121 --- /dev/null +++ b/ext/mysqli/tests/mysqli_real_escape_string_gbk.phpt @@ -0,0 +1,77 @@ +--TEST-- +mysqli_real_escape_string() - gbk +--SKIPIF-- +<?php +if (version_compare(PHP_VERSION, '5.9.9', '>') == 1) { + die('skip set character set not functional with PHP 6 (fomerly PHP 6 && unicode.semantics=On)'); +} + +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); + +if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf("skip Cannot connect to MySQL, [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error())); +} +if (!mysqli_set_charset($link, 'gbk')) + die(sprintf("skip Cannot set charset 'gbk'")); + +mysqli_close($link); +?> +--FILE-- +<?php + + require_once("connect.inc"); + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) +{ + printf("[001] Cannot connect to the server using host=%s, user=%s, +passwd=***, dbname=%s, port=%s, socket=%s - [%d] %s\n", $host, $user, $db, +$port, $socket, mysqli_connect_errno(), mysqli_connect_error()); + } + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { + printf("Failed to drop old test table: [%d] %s\n", mysqli_errno($link), +mysqli_error($link)); + } + + if (!mysqli_query($link, 'CREATE TABLE test(id INT, label CHAR(1), PRIMARY +KEY(id)) ENGINE=' . $engine . " DEFAULT CHARSET=gbk")) { + printf("Failed to create test table: [%d] %s\n", mysqli_errno($link), +mysqli_error($link)); + } + + var_dump(mysqli_set_charset($link, "gbk")); + + if ('�İ汾\\\\�İ汾' !== ($tmp = mysqli_real_escape_string($link, '�İ汾\\�İ汾'))) + printf("[004] Expecting \\\\, got %s\n", $tmp); + + if ('�İ汾\"�İ汾' !== ($tmp = mysqli_real_escape_string($link, '�İ汾"�İ汾'))) + printf("[005] Expecting \", got %s\n", $tmp); + + if ("�İ汾\'�İ汾" !== ($tmp = mysqli_real_escape_string($link, "�İ汾'�İ汾"))) + printf("[006] Expecting ', got %s\n", $tmp); + + if ("�İ汾\\n�İ汾" !== ($tmp = mysqli_real_escape_string($link, "�İ汾\n�İ汾"))) + printf("[007] Expecting \\n, got %s\n", $tmp); + + if ("�İ汾\\r�İ汾" !== ($tmp = mysqli_real_escape_string($link, "�İ汾\r�İ汾"))) + printf("[008] Expecting \\r, got %s\n", $tmp); + + if ("�İ汾\\0�İ汾" !== ($tmp = mysqli_real_escape_string($link, "�İ汾" . chr(0) . "�İ汾"))) + printf("[009] Expecting %s, got %s\n", "�İ汾\\0�İ汾", $tmp); + + var_dump(mysqli_query($link, "INSERT INTO test(id, label) VALUES (100, '��')")); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +bool(true) +bool(true) +done! diff --git a/ext/mysqli/tests/mysqli_real_escape_string_nobackslash.phpt b/ext/mysqli/tests/mysqli_real_escape_string_nobackslash.phpt new file mode 100644 index 0000000..db1acb4 --- /dev/null +++ b/ext/mysqli/tests/mysqli_real_escape_string_nobackslash.phpt @@ -0,0 +1,65 @@ +--TEST-- +mysqli_real_escape_string() - SQL Mode NO_BACKSLASH_ESCAPE +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + require_once('table.inc'); + + if (!mysqli_query($link, 'SET @@sql_mode="NO_BACKSLASH_ESCAPES"')) + printf("[001] Cannot set NO_BACKSLASH_ESCAPES, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ('\\' !== ($tmp = mysqli_real_escape_string($link, '\\'))) + printf("[002] Expecting \\, got %s\n", $tmp); + + if ('"' !== ($tmp = mysqli_real_escape_string($link, '"'))) + printf("[003] Expecting \", got %s\n", $tmp); + + if ("''" !== ($tmp = mysqli_real_escape_string($link, "'"))) + printf("[004] Expecting '', got %s\n", $tmp); + + if ("\n" !== ($tmp = mysqli_real_escape_string($link, "\n"))) + printf("[005] Expecting \\n, got %s\n", $tmp); + + if ("\r" !== ($tmp = mysqli_real_escape_string($link, "\r"))) + printf("[006] Expecting \\r, got %s\n", $tmp); + + assert("foo" . chr(0) . "bar" === "foo" . chr(0) . "bar"); + if ("foo" . chr(0) . "bar" !== ($tmp = mysqli_real_escape_string($link, "foo" . chr(0) . "bar"))) + printf("[007] Expecting %s, got %s\n", "foo" . chr(0) . "bar", $tmp); + + if (!mysqli_query($link, sprintf('INSERT INTO test(id, label) VALUES (100, "%s")', + mysqli_real_escape_string($link, "\\")))) + printf("[009] Cannot INSERT, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!($res = mysqli_query($link, 'SELECT label FROM test WHERE id = 100')) || + !($row = mysqli_fetch_assoc($res))) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + var_dump($row); + mysqli_free_result($res); + + if (!mysqli_query($link, 'SET @@sql_mode=""')) + printf("[011] Cannot disable NO_BACKSLASH_ESCAPES, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ('\\\\' !== ($tmp = mysqli_real_escape_string($link, '\\'))) + printf("[012] Expecting \\, got %s\n", $tmp); + + if ("foo\\0bar" !== ($tmp = mysqli_real_escape_string($link, "foo" . chr(0) . "bar"))) + printf("[013] Expecting %s, got %s\n", "foo" . chr(0) . "bar", $tmp); + + mysqli_close($link); + + print "done!"; +?> +--EXPECTF-- +array(1) { + [%u|b%"label"]=> + %unicode|string%(1) "\" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_real_escape_string_sjis.phpt b/ext/mysqli/tests/mysqli_real_escape_string_sjis.phpt new file mode 100644 index 0000000..2ed2b8b --- /dev/null +++ b/ext/mysqli/tests/mysqli_real_escape_string_sjis.phpt @@ -0,0 +1,56 @@ +--TEST-- +mysqli_real_escape_string() - sjis +--SKIPIF-- +<?php +if (version_compare(PHP_VERSION, '5.9.9', '>') == 1) { + die('skip set character set not functional with PHP 6 (fomerly PHP 6 && unicode.semantics=On)'); +} + +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); + +if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf("skip Cannot connect to MySQL, [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error())); +} +if (!mysqli_set_charset($link, 'sjis')) + die(sprintf("skip Cannot set charset 'sjis'")); +mysqli_close($link); +?> +--FILE-- +<?php + + require_once("connect.inc"); + require_once('table.inc'); + + var_dump(mysqli_set_charset($link, "sjis")); + + if ('?p??\\\\?p??' !== ($tmp = mysqli_real_escape_string($link, '?p??\\?p??'))) + printf("[004] Expecting \\\\, got %s\n", $tmp); + + if ('?p??\"?p??' !== ($tmp = mysqli_real_escape_string($link, '?p??"?p??'))) + printf("[005] Expecting \", got %s\n", $tmp); + + if ("?p??\'?p??" !== ($tmp = mysqli_real_escape_string($link, "?p??'?p??"))) + printf("[006] Expecting ', got %s\n", $tmp); + + if ("?p??\\n?p??" !== ($tmp = mysqli_real_escape_string($link, "?p??\n?p??"))) + printf("[007] Expecting \\n, got %s\n", $tmp); + + if ("?p??\\r?p??" !== ($tmp = mysqli_real_escape_string($link, "?p??\r?p??"))) + printf("[008] Expecting \\r, got %s\n", $tmp); + + if ("?p??\\0?p??" !== ($tmp = mysqli_real_escape_string($link, "?p??" . chr(0) . "?p??"))) + printf("[009] Expecting %s, got %s\n", "?p??\\0?p??", $tmp); + + var_dump(mysqli_query($link, "INSERT INTO test(id, label) VALUES (100, '?p')")); + + mysqli_close($link); + print "done!"; +?> +--EXPECTF-- +bool(true) +bool(true) +done! diff --git a/ext/mysqli/tests/mysqli_real_escape_string_unicode.phpt b/ext/mysqli/tests/mysqli_real_escape_string_unicode.phpt new file mode 100644 index 0000000..72d171f --- /dev/null +++ b/ext/mysqli/tests/mysqli_real_escape_string_unicode.phpt @@ -0,0 +1,88 @@ +--TEST-- +mysqli_real_escape_string() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (NULL !== ($tmp = @mysqli_real_escape_string())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @mysqli_real_escape_string($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (NULL !== ($tmp =@mysqli_real_escape_string($link, "фуу", "бар"))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if ('фу\\\\бар' !== ($tmp = mysqli_real_escape_string($link, 'фу\\бар'))) + printf("[004] Expecting фу\\\\бар, got %s\n", $tmp); + + if ('бар\"фуÑ' !== ($tmp = mysqli_real_escape_string($link, 'бар"фуÑ'))) + printf("[005] Expecting бар\"фуÑ, got %s\n", $tmp); + + if ("лала\'лали" !== ($tmp = mysqli_real_escape_string($link, "лала'лали"))) + printf("[006] Expecting лала'лали, got %s\n", $tmp); + + if ("абра\\nкадабра" !== ($tmp = mysqli_real_escape_string($link, "абра\nкадабра"))) + printf("[007] Expecting абра\\nкадабра, got %s\n", $tmp); + + if ("манда\\rин" !== ($tmp = mysqli_real_escape_string($link, "манда\rин"))) + printf("[008] Expecting \\r, got %s\n", $tmp); + + if ("иху\\0аху" !== ($tmp = mysqli_real_escape_string($link, "иху" . chr(0) . "аху"))) + printf("[009] Expecting %s, got %s\n", "иху\\0аху", $tmp); + + if (($exp='абра\\\\ка\"да\\'."'".'бра\ZÑим\\nÑала\\rби\\0м') !== + ($tmp = mysqli_real_escape_string($link, "абра\\ка\"да'бра\032Ñим\nÑала\rби" . chr(0) . "м"))) + { + printf("[010] Expecting %s, got %s\n", $exp, $tmp, var_dump($exp, $tmp)); + } + + if ('富\\\\é…’å§' !== ($tmp = mysqli_real_escape_string($link, '富\\é…’å§'))) + printf("[011] Expecting 富\\\\é…’å§, got %s\n", $tmp); + + if ('é…’å§\"å°é¢˜å¤§åš' !== ($tmp = mysqli_real_escape_string($link, 'é…’å§"å°é¢˜å¤§åš'))) + printf("[012] Expecting é…’å§\"å°é¢˜å¤§åš, got %s\n", $tmp); + + if ("拉拉\'西雅图" !== ($tmp = mysqli_real_escape_string($link, "拉拉'西雅图"))) + printf("[013] Expecting 拉拉'西雅图, got %s\n", $tmp); + + if ("é˜¿åœæ‹‰\\nè½»" !== ($tmp = mysqli_real_escape_string($link, "é˜¿åœæ‹‰\nè½»"))) + printf("[014] Expecting é˜¿åœæ‹‰\\nè½», got %s\n", $tmp); + + if ("å¼ æ˜Žå®‰\\r在" !== ($tmp = mysqli_real_escape_string($link, "å¼ æ˜Žå®‰\r在"))) + printf("[015] Expecting å¼ æ˜Žå®‰\\r在, got %s\n", $tmp); + + if ("ç«ºå¯æ¡¢\\0空调器" !== ($tmp = mysqli_real_escape_string($link, "ç«ºå¯æ¡¢" . chr(0) . "空调器"))) + printf("[016] Expecting %s, got %s\n", "ç«ºå¯æ¡¢\\0空调器", $tmp); + + if (($exp='é˜¿åœæ‹‰\\\\嘉\"达丰\\'."'".'乳罩\Zè¾›\\nè¨æ‹‰\\r毕\\0ç±³') !== + ($tmp = mysqli_real_escape_string($link, "é˜¿åœæ‹‰\\嘉\"达丰'乳罩\032è¾›\nè¨æ‹‰\r毕" . chr(0) . "ç±³"))) + { + printf("[017] Expecting %s, got %s\n", $exp, $tmp, var_dump($exp, $tmp)); + } + + mysqli_close($link); + + if (NULL !== ($tmp = mysqli_real_escape_string($link, 'foo'))) + printf("[018] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_real_escape_string(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_real_query.phpt b/ext/mysqli/tests/mysqli_real_query.phpt new file mode 100644 index 0000000..866ad6a --- /dev/null +++ b/ext/mysqli/tests/mysqli_real_query.phpt @@ -0,0 +1,113 @@ +--TEST-- +mysqli_real_query() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_real_query())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_real_query($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (NULL !== ($tmp = @mysqli_real_query($link, "SELECT 1 AS a", MYSQLI_USE_RESULT, "foo"))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = mysqli_real_query($link, 'THIS IS NOT SQL'))) + printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = mysqli_real_query($link, "SELECT 'this is sql but with backslash g'\g"))) + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if ((0 === mysqli_errno($link)) || ('' == mysqli_error($link))) + printf("[006] mysqli_errno()/mysqli_error should return some error\n"); + + if (!mysqli_real_query($link, "SELECT 'this is sql but with semicolon' AS valid ; ")) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_object($res = mysqli_use_result($link))) + printf("[008] Expecting reseult object, got %s/%s [%d] %s\n", gettype($res), $res, mysqli_errno($link), mysqli_error($link)); + + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + + if (false !== ($res = mysqli_real_query($link, "SELECT 'this is sql but with semicolon' AS valid ; SHOW VARIABLES"))) + printf("[008] Expecting boolean/false, got %s/%s, [%d] %s\n", gettype($res), $res, + mysqli_errno($link), mysqli_error($link)); + + if (mysqli_get_server_version($link) > 50000) { + // let's try to play with stored procedures + mysqli_real_query($link, 'DROP PROCEDURE IF EXISTS p'); + if (mysqli_real_query($link, 'CREATE PROCEDURE p(OUT ver_param VARCHAR(25)) BEGIN SELECT VERSION() INTO ver_param; +END;')) { + mysqli_real_query($link, 'CALL p(@version)'); + mysqli_real_query($link, 'SELECT @version AS p_version'); + $res = mysqli_store_result($link); + + $tmp = mysqli_fetch_assoc($res); + if (!is_array($tmp) || empty($tmp) || !isset($tmp['p_version']) || ('' == $tmp['p_version'])) { + printf("[008a] Expecting array [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump($tmp); + } + + mysqli_free_result($res); + } else { + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + mysqli_real_query($link, 'DROP FUNCTION IF EXISTS f'); + if (mysqli_real_query($link, 'CREATE FUNCTION f( ver_param VARCHAR(25)) RETURNS VARCHAR(25) DETERMINISTIC RETURN +ver_param;')) { + mysqli_real_query($link, 'SELECT f(VERSION()) AS f_version'); + $res = mysqli_store_result($link); + + $tmp = mysqli_fetch_assoc($res); + if (!is_array($tmp) || empty($tmp) || !isset($tmp['f_version']) || ('' == $tmp['f_version'])) { + printf("[009a] Expecting array [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + var_dump($tmp); + } + + mysqli_free_result($res); + } else { + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + } + + mysqli_close($link); + + if (NULL !== ($tmp = mysqli_real_query($link, "SELECT id FROM test"))) + printf("[011] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +@mysqli_query($link, "DROP PROCEDURE IF EXISTS p"); +@mysqli_query($link, "DROP FUNCTION IF EXISTS f"); + +mysqli_close($link); +?> +--EXPECTF-- +array(1) { + [%u|b%"valid"]=> + %unicode|string%(30) "this is sql but with semicolon" +} + +Warning: mysqli_real_query(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_reconnect.phpt b/ext/mysqli/tests/mysqli_reconnect.phpt new file mode 100644 index 0000000..7f05a20 --- /dev/null +++ b/ext/mysqli/tests/mysqli_reconnect.phpt @@ -0,0 +1,130 @@ +--TEST-- +Trying implicit reconnect after wait_timeout and KILL using mysqli_ping() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +if (stristr(mysqli_get_client_info(), 'mysqlnd')) + die("skip: test for libmysql"); +?> +--INI-- +mysqli.reconnect=1 +--FILE-- +<?php + require_once("connect.inc"); + require_once("table.inc"); + + if (!$link2 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot create second database connection, [%d] %s\n", + mysqli_connect_errno(), mysqli_connect_error()); + + $thread_id_timeout = mysqli_thread_id($link); + $thread_id_control = mysqli_thread_id($link2); + + if (!$res = mysqli_query($link2, "SHOW FULL PROCESSLIST")) + printf("[002] Cannot get full processlist, [%d] %s\n", + mysqli_errno($link2), mysqli_error($link)); + + $running_threads = array(); + while ($row = mysqli_fetch_assoc($res)) + $running_threads[$row['Id']] = $row; + mysqli_free_result($res); + + if (!isset($running_threads[$thread_id_timeout]) || + !isset($running_threads[$thread_id_control])) + printf("[003] Processlist is borked, [%d] %s\n", + mysqli_errno($link2), mysqli_error($link)); + + if (!mysqli_query($link, "SET SESSION wait_timeout = 2")) + printf("[004] Cannot set wait_timeout, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, "SHOW VARIABLES LIKE 'wait_timeout'")) + printf("[005] Cannot check if wait_timeout has been set, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[006] Cannot get wait_timeout, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + + if ($row['Value'] != 2) + printf("[007] Failed setting the wait_timeout, test will not work, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + // after 2+ seconds the server should kill the connection + sleep(3); + + if (!$res = mysqli_query($link2, "SHOW FULL PROCESSLIST")) + printf("[008] Cannot get full processlist, [%d] %s\n", + mysqli_errno($link2), mysqli_error($link)); + + $running_threads = array(); + while ($row = mysqli_fetch_assoc($res)) + $running_threads[$row['Id']] = $row; + mysqli_free_result($res); + + if (isset($running_threads[$thread_id_timeout])) + printf("[009] Server should have killed the timeout connection, [%d] %s\n", + mysqli_errno($link2), mysqli_error($link)); + + if (true !== mysqli_ping($link)) + printf("[010] Reconnect should have happened"); + + if (!$res = mysqli_query($link, "SELECT DATABASE() as _dbname")) + printf("[011] Cannot get database name, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[012] Cannot get database name, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + if ($row['_dbname'] != $db) + printf("[013] Connection should has been made to DB/Schema '%s', expecting '%s', [%d] %s\n", + $row['_dbname'], $db, mysqli_errno($link), mysqli_error($link)); + + // ... and now we try KILL + $thread_id_timeout = mysqli_thread_id($link); + + if (!mysqli_query($link2, sprintf('KILL %d', $thread_id_timeout))) + printf("[014] Cannot KILL timeout connection, [%d] %s\n", mysqli_errno($link2), mysqli_error($link2)); + // Give the server a second to really kill the other thread... + sleep(1); + + if (!$res = mysqli_query($link2, "SHOW FULL PROCESSLIST")) + printf("[015] Cannot get full processlist, [%d] %s\n", + mysqli_errno($link2), mysqli_error($link)); + + $running_threads = array(); + while ($row = mysqli_fetch_assoc($res)) + $running_threads[$row['Id']] = $row; + mysqli_free_result($res); + + if (isset($running_threads[$thread_id_timeout]) || + !isset($running_threads[$thread_id_control])) + printf("[016] Processlist is borked, [%d] %s\n", + mysqli_errno($link2), mysqli_error($link)); + + if (true !== ($tmp = mysqli_ping($link))) + printf("[017] Expecting boolean/true got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = mysqli_query($link, "SELECT DATABASE() as _dbname")) + printf("[018] Cannot get database name, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[019] Cannot get database name, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + if ($row['_dbname'] != $db) + printf("[020] Connection should has been made to DB/Schema '%s', expecting '%s', [%d] %s\n", + $row['_dbname'], $db, mysqli_errno($link), mysqli_error($link)); + + mysqli_close($link); + mysqli_close($link2); + print "done!"; +?> +--EXPECTF-- +done! diff --git a/ext/mysqli/tests/mysqli_report.phpt b/ext/mysqli/tests/mysqli_report.phpt new file mode 100644 index 0000000..f5d77e3 --- /dev/null +++ b/ext/mysqli/tests/mysqli_report.phpt @@ -0,0 +1,307 @@ +--TEST-- +mysqli_report() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (NULL !== ($tmp = @mysqli_report())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_report(-1))) + printf("[002] Expecting boolean/true even for invalid flags, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_report(MYSQLI_REPORT_ERROR))) + printf("[003] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_report(MYSQLI_REPORT_STRICT))) + printf("[004] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_report(MYSQLI_REPORT_INDEX))) + printf("[005] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_report(MYSQLI_REPORT_ALL))) + printf("[007] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_report(MYSQLI_REPORT_OFF))) + printf("[008] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + /* + Internal macro MYSQL_REPORT_ERROR + */ + mysqli_report(MYSQLI_REPORT_ERROR); + + mysqli_multi_query($link, "BAR; FOO;"); + mysqli_query($link, "FOO"); + /* This might work if you accept anonymous users in your setup */ + mysqli_change_user($link, "0123456789-10-456789-20-456789-30-456789-40-456789-50-456789-60-456789-70-456789-80-456789-90-456789", "password", $db); + mysqli_kill($link, -1); + + // mysqli_ping() cannot be tested, because one would need to cause an error inside the C function to test it + mysqli_prepare($link, "FOO"); + mysqli_real_query($link, "FOO"); + if (@mysqli_select_db($link, "Oh lord, let this be an unknown database name")) + printf("[009] select_db should have failed\n"); + // mysqli_store_result() and mysqli_use_result() cannot be tested, because one would need to cause an error inside the C function to test it + + + // Check that none of the above would have caused any error messages if MYSQL_REPORT_ERROR would + // not have been set. If that would be the case, the test would be broken. + mysqli_report(MYSQLI_REPORT_OFF); + + mysqli_multi_query($link, "BAR; FOO;"); + mysqli_query($link, "FOO"); + mysqli_change_user($link, "This might work if you accept anonymous users in your setup", "password", $db); + mysqli_kill($link, -1); + mysqli_prepare($link, "FOO"); + mysqli_real_query($link, "FOO"); + mysqli_select_db($link, "Oh lord, let this be an unknown database name"); + + /* + Internal macro MYSQL_REPORT_STMT_ERROR + */ + + mysqli_report(MYSQLI_REPORT_ERROR); + + $stmt = mysqli_stmt_init($link); + mysqli_stmt_prepare($stmt, "FOO"); + + $stmt = mysqli_stmt_init($link); + mysqli_stmt_prepare($stmt, "SELECT id FROM test WHERE id > ?"); + $id = 1; + mysqli_kill($link, mysqli_thread_id($link)); + mysqli_stmt_bind_param($stmt, "i", $id); + mysqli_stmt_close($stmt); + mysqli_close($link); + + /* mysqli_stmt_execute() = mysql_stmt_execute cannot be tested from PHP */ + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[008] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + $stmt = mysqli_stmt_init($link); + mysqli_stmt_prepare($stmt, "SELECT id FROM test WHERE id > ?"); + $id = 1; + mysqli_stmt_bind_param($stmt, "i", $id); + // mysqli_kill($link, mysqli_thread_id($link)); + mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + mysqli_close($link); + + /* mysqli_kill() "trick" does not work for any of the following because of an E_COMMANDS_OUT_OF_SYNC */ + /* mysqli_stmt_bind_result() = mysql_stmt_bind_result() cannot be tested from PHP */ + /* mysqli_stmt_fetch() = mysql_stmt_fetch() cannot be tested from PHP */ + /* mysqli_stmt_result_metadata() = mysql_stmt_result_metadata() cannot be tested from PHP */ + /* mysqli_stmt_store_result() = mysql_stmt_store_result() cannot be tested from PHP */ + + // Check + mysqli_report(MYSQLI_REPORT_OFF); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[010] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + $stmt = mysqli_stmt_init($link); + mysqli_stmt_prepare($stmt, "FOO"); + + $stmt = mysqli_stmt_init($link); + mysqli_stmt_prepare($stmt, "SELECT id FROM test WHERE id > ?"); + $id = 1; + mysqli_kill($link, mysqli_thread_id($link)); + mysqli_stmt_bind_param($stmt, "i", $id); + mysqli_stmt_close($stmt); + mysqli_close($link); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[011] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + $stmt = mysqli_stmt_init($link); + mysqli_stmt_prepare($stmt, "SELECT id FROM test WHERE id > ?"); + $id = 1; + mysqli_stmt_bind_param($stmt, "i", $id); + mysqli_kill($link, mysqli_thread_id($link)); + mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + mysqli_close($link); + + /* + MYSQLI_REPORT_STRICT + + MYSQLI_REPORT_STRICT ---> + php_mysqli_report_error() -> + MYSQLI_REPORT_MYSQL_ERROR, + MYSQLI_REPORT_STMT_ERROR -> + already tested + + php_mysqli_throw_sql_exception() -> + my_mysqli_real_connect() + my_mysqli_connect() + + can't be tested: mysqli_query() via mysql_use_result()/mysql_store_result() + */ + mysqli_report(MYSQLI_REPORT_OFF); + mysqli_report(MYSQLI_REPORT_STRICT); + + try { + + if ($link = my_mysqli_connect($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) + printf("[012] Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", + $host, $user . 'unknown_really', $db, $port, $socket); + mysqli_close($link); + + } catch (mysqli_sql_exception $e) { + printf("[013] %s\n", $e->getMessage()); + } + + try { + if (!$link = mysqli_init()) + printf("[014] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if ($link = my_mysqli_real_connect($link, $host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) + printf("[015] Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", + $host, $user . 'unknown_really', $db, $port, $socket); + mysqli_close($link); + } catch (mysqli_sql_exception $e) { + printf("[016] %s\n", $e->getMessage()); + } + + /* + MYSQLI_REPORT_INDEX ---> + mysqli_query() + mysqli_stmt_execute() + mysqli_prepare() + mysqli_real_query() + mysqli_store_result() + mysqli_use_result() + + No test, because of to many prerequisites: + - Server needs to be started with and + --log-slow-queries --log-queries-not-using-indexes + - query must cause the warning on all MySQL versions + + TODO: + */ + $log_slow_queries = false; + $log_queries_not_using_indexes = false; + mysqli_report(MYSQLI_REPORT_OFF); + mysqli_report(MYSQLI_REPORT_INDEX); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[017] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (mysqli_get_server_version($link) <= 50600) { + // this might cause a warning - no index used + if (!$res = @mysqli_query($link, "SHOW VARIABLES LIKE 'log_slow_queries'")) + printf("[018] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $log_slow_query = ('ON' == $row['Value']); + + if (mysqli_get_server_version($link) >= 50111) { + // this might cause a warning - no index used + if (!$res = @mysqli_query($link, "SHOW VARIABLES LIKE 'log_queries_not_using_indexes'")) + printf("[020] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[021] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $log_queries_not_using_indexes = ('ON' == $row['Value']); + + if ($log_slow_queries && $log_queries_not_using_indexes) { + + for ($i = 100; $i < 20000; $i++) { + if (!mysqli_query($link, "INSERT INTO test(id, label) VALUES ($i, 'z')")) + printf("[022 - %d] [%d] %s\n", $i - 99, mysqli_errno($link), mysqli_error($link)); + } + + // this might cause a warning - no index used + if (!$res = @mysqli_query($link, "SELECT id, label FROM test WHERE id = 1323")) + printf("[023] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + } + } + } + + // Maybe we've provoked an index message, maybe not. + // All we can do is make a few dummy calls to ensure that all codes gets executed which + // checks the flag. Functions to check: mysqli_query() - done above, + // mysqli_stmt_execute(), mysqli_prepare(), mysqli_real_query(), mysqli_store_result() + // mysqli_use_result(), mysqli_thread_safe(), mysqli_thread_id() + mysqli_report(MYSQLI_REPORT_OFF); + mysqli_close($link); + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[024] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[025] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test')) + printf("[026] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[027] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + mysqli_stmt_close($stmt); + + if (!mysqli_real_query($link, 'SELECT label, id FROM test')) + printf("[028] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_use_result($link)) + printf("[029] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + + if (!mysqli_real_query($link, 'SELECT label, id FROM test')) + printf("[030] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_store_result($link)) + printf("[031] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + + if (!$stmt = mysqli_prepare($link, 'SELECT id * 3 FROM test')) + printf("[032] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + else + mysqli_stmt_close($stmt); + + if (!mysqli_query($link, "INSERT INTO test(id, label) VALUES (100, 'z')", MYSQLI_USE_RESULT) || + !mysqli_query($link, 'DELETE FROM test WHERE id > 50', MYSQLI_USE_RESULT)) + printf("[033] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $tmp = mysqli_thread_safe($link); + $tmp = mysqli_thread_id($link); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_multi_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'BAR; FOO' at line 1 in %s on line %d + +Warning: mysqli_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FOO' at line 1 in %s on line %d + +Warning: mysqli_change_user(): (%d/%d): Access denied for user '%s'@'%s' (using password: %s) in %s on line %d + +Warning: mysqli_kill(): processid should have positive value in %s on line %d + +Warning: mysqli_prepare(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FOO' at line 1 in %s on line %d + +Warning: mysqli_real_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FOO' at line 1 in %s on line %d + +Warning: mysqli_kill(): processid should have positive value in %s on line %d + +Warning: mysqli_stmt_prepare(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FOO' at line 1 in %s on line %d +[013] Access denied for user '%s'@'%s' (using password: YES) +[016] Access denied for user '%s'@'%s' (using password: YES) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_report_wo_ps.phpt b/ext/mysqli/tests/mysqli_report_wo_ps.phpt new file mode 100644 index 0000000..cc57511 --- /dev/null +++ b/ext/mysqli/tests/mysqli_report_wo_ps.phpt @@ -0,0 +1,113 @@ +--TEST-- +mysqli_report() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (NULL !== ($tmp = @mysqli_report())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_report(-1))) + printf("[002] Expecting boolean/true even for invalid flags, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_report(MYSQLI_REPORT_ERROR))) + printf("[003] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_report(MYSQLI_REPORT_STRICT))) + printf("[004] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_report(MYSQLI_REPORT_INDEX))) + printf("[005] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_report(MYSQLI_REPORT_ALL))) + printf("[007] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_report(MYSQLI_REPORT_OFF))) + printf("[008] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + /* + Internal macro MYSQL_REPORT_ERROR + */ + mysqli_report(MYSQLI_REPORT_ERROR); + + mysqli_multi_query($link, "BAR; FOO;"); + mysqli_query($link, "FOO"); + mysqli_change_user($link, "0123456789-10-456789-20-456789-30-456789-40-456789-50-456789-60-456789-70-456789-80-456789-90-456789", "password", $db); + mysqli_kill($link, -1); + + // mysqli_ping() cannot be tested, because one would need to cause an error inside the C function to test it + mysqli_real_query($link, "FOO"); + if (@mysqli_select_db($link, "Oh lord, let this be an unknown database name")) + printf("[009] select_db should have failed\n"); + // mysqli_store_result() and mysqli_use_result() cannot be tested, because one would need to cause an error inside the C function to test it + + + // Check that none of the above would have caused any error messages if MYSQL_REPORT_ERROR would + // not have been set. If that would be the case, the test would be broken. + mysqli_report(MYSQLI_REPORT_OFF); + + mysqli_multi_query($link, "BAR; FOO;"); + mysqli_query($link, "FOO"); + mysqli_change_user($link, "This might work if you accept anonymous users in your setup", "password", $db); + mysqli_kill($link, -1); + mysqli_real_query($link, "FOO"); + mysqli_select_db($link, "Oh lord, let this be an unknown database name"); + + mysqli_report(MYSQLI_REPORT_OFF); + mysqli_report(MYSQLI_REPORT_STRICT); + + try { + + if ($link = my_mysqli_connect($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) + printf("[010] Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", + $host, $user . 'unknown_really', $db, $port, $socket); + mysqli_close($link); + + } catch (mysqli_sql_exception $e) { + printf("[011] %s\n", $e->getMessage()); + } + + try { + if (!$link = mysqli_init()) + printf("[012] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if ($link = my_mysqli_real_connect($link, $host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) + printf("[013] Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", + $host, $user . 'unknown_really', $db, $port, $socket); + mysqli_close($link); + } catch (mysqli_sql_exception $e) { + printf("[014] %s\n", $e->getMessage()); + } + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_multi_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'BAR; FOO' at line 1 in %s on line %d + +Warning: mysqli_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FOO' at line 1 in %s on line %d + +Warning: mysqli_change_user(): (%d/%d): Access denied for user '%s'@'%s' (using password: %s) in %s on line %d + +Warning: mysqli_kill(): processid should have positive value in %s on line %d + +Warning: mysqli_real_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FOO' at line 1 in %s on line %d + +Warning: mysqli_kill(): processid should have positive value in %s on line %d +[011] Access denied for user '%s'@'%s' (using password: YES) +[014] Access denied for user '%s'@'%s' (using password: YES) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_result_references.phpt b/ext/mysqli/tests/mysqli_result_references.phpt new file mode 100644 index 0000000..b6bce0d --- /dev/null +++ b/ext/mysqli/tests/mysqli_result_references.phpt @@ -0,0 +1,154 @@ +--TEST-- +References to result sets +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once('connect.inc'); + require_once('table.inc'); + + $references = array(); + + if (!(mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id ASC LIMIT 2")) || + !($res = mysqli_store_result($link))) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $idx = 0; + while ($row = mysqli_fetch_assoc($res)) { + /* mysqlnd: force seperation - create copies */ + $references[$idx] = array( + 'id' => &$row['id'], + 'label' => $row['label'] . ''); + $references[$idx++]['id'] += 0; + } + + mysqli_close($link); + + mysqli_data_seek($res, 0); + while ($row = mysqli_fetch_assoc($res)) { + /* mysqlnd: force seperation - create copies */ + $references[$idx] = array( + 'id' => &$row['id'], + 'label' => $row['label'] . ''); + $references[$idx++]['id'] += 0; + } + + mysqli_free_result($res); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!(mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id ASC LIMIT 2")) || + !($res = mysqli_use_result($link))) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + while ($row = mysqli_fetch_assoc($res)) { + /* mysqlnd: force seperation - create copies*/ + $references[$idx] = array( + 'id' => &$row['id'], + 'label' => $row['label'] . ''); + $references[$idx]['id2'] = &$references[$idx]['id']; + $references[$idx]['id'] += 1; + $references[$idx++]['id2'] += 1; + } + + $references[$idx++] = &$res; + mysqli_free_result($res); + @debug_zval_dump($references); + + if (!(mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id ASC LIMIT 1")) || + !($res = mysqli_use_result($link))) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $tmp = array(); + while ($row = mysqli_fetch_assoc($res)) { + $tmp[] = $row; + } + $tmp = unserialize(serialize($tmp)); + debug_zval_dump($tmp); + mysqli_free_result($res); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +array(7) refcount(2){ + [0]=> + array(2) refcount(1){ + [%u|b%"id"]=> + long(1) refcount(1) + [%u|b%"label"]=> + %unicode|string%(1) "a" refcount(1) + } + [1]=> + array(2) refcount(1){ + [%u|b%"id"]=> + long(2) refcount(1) + [%u|b%"label"]=> + %unicode|string%(1) "b" refcount(1) + } + [2]=> + array(2) refcount(1){ + [%u|b%"id"]=> + long(1) refcount(1) + [%u|b%"label"]=> + %unicode|string%(1) "a" refcount(1) + } + [3]=> + array(2) refcount(1){ + [%u|b%"id"]=> + long(2) refcount(1) + [%u|b%"label"]=> + %unicode|string%(1) "b" refcount(1) + } + [4]=> + array(3) refcount(1){ + [%u|b%"id"]=> + &long(3) refcount(2) + [%u|b%"label"]=> + %unicode|string%(1) "a" refcount(1) + [%u|b%"id2"]=> + &long(3) refcount(2) + } + [5]=> + array(3) refcount(1){ + [%u|b%"id"]=> + &long(4) refcount(2) + [%u|b%"label"]=> + %unicode|string%(1) "b" refcount(1) + [%u|b%"id2"]=> + &long(4) refcount(2) + } + [6]=> + &object(mysqli_result)#2 (5) refcount(2){ + [%u|b%"current_field"]=> + NULL refcount(1) + [%u|b%"field_count"]=> + NULL refcount(1) + [%u|b%"lengths"]=> + NULL refcount(1) + [%u|b%"num_rows"]=> + NULL refcount(1) + [%u|b%"type"]=> + NULL refcount(1) + } +} +array(1) refcount(2){ + [0]=> + array(2) refcount(1){ + [%u|b%"id"]=> + %unicode|string%(1) "1" refcount(1) + [%u|b%"label"]=> + %unicode|string%(1) "a" refcount(1) + } +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_result_references_mysqlnd.phpt b/ext/mysqli/tests/mysqli_result_references_mysqlnd.phpt new file mode 100644 index 0000000..384f85f --- /dev/null +++ b/ext/mysqli/tests/mysqli_result_references_mysqlnd.phpt @@ -0,0 +1,119 @@ +--TEST-- +References to result sets - mysqlnd (no copies but references) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +require_once('connect.inc'); +if (!$IS_MYSQLND) + die("skip Test for mysqlnd only"); + +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1)) + die("skip (TODO) PHP 6.0 has a difference debug_zval_dump output format"); +?> +<?php require_once('skipifemb.inc'); ?> +--FILE-- +<?php + require_once('connect.inc'); + require_once('table.inc'); + + $references = array(); + + if (!(mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id ASC LIMIT 1")) || + !($res = mysqli_store_result($link))) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $idx = 0; + while ($row = mysqli_fetch_assoc($res)) { + /* will overwrite itself */ + $references[$idx]['row_ref'] = &$row; + $references[$idx]['row_copy'] = $row; + $references[$idx]['id_ref'] = &$row['id']; + $references[$idx++]['id_copy'] = $row['id']; + } + + debug_zval_dump($references); + mysqli_free_result($res); + + if (!(mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id ASC LIMIT 2")) || + !($res = mysqli_use_result($link))) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $rows = array(); + for ($i = 0; $i < 2; $i++) { + $rows[$i] = mysqli_fetch_assoc($res); + $references[$idx]['row_ref'] = &$rows[$i]; + $references[$idx]['row_copy'] = $rows[$i]; + $references[$idx]['id_ref'] = &$rows[$i]['id']; + $references[$idx]['id_copy'] = $rows[$i]['id']; + /* enforce seperation */ + $references[$idx]['id_copy_mod']= $rows[$i]['id'] + 0; + } + mysqli_free_result($res); + + debug_zval_dump($references); + print "done!"; +?> +--EXPECTF-- +array(1) refcount(2){ + [0]=> + array(4) refcount(1){ + [%u|b%"row_ref"]=> + &NULL refcount(2) + [%u|b%"row_copy"]=> + array(2) refcount(1){ + [%u|b%"id"]=> + %unicode|string%(1) "1" refcount(2) + [%u|b%"label"]=> + %unicode|string%(1) "a" refcount(2) + } + [%u|b%"id_ref"]=> + %unicode|string%(1) "1" refcount(1) + [%u|b%"id_copy"]=> + %unicode|string%(1) "1" refcount(1) + } +} +array(2) refcount(2){ + [0]=> + array(4) refcount(1){ + [%u|b%"row_ref"]=> + &NULL refcount(2) + [%u|b%"row_copy"]=> + array(2) refcount(1){ + [%u|b%"id"]=> + %unicode|string%(1) "1" refcount(1) + [%u|b%"label"]=> + %unicode|string%(1) "a" refcount(1) + } + [%u|b%"id_ref"]=> + %unicode|string%(1) "1" refcount(1) + [%u|b%"id_copy"]=> + %unicode|string%(1) "1" refcount(1) + } + [1]=> + array(5) refcount(1){ + [%u|b%"row_ref"]=> + &array(2) refcount(2){ + [%u|b%"id"]=> + &%unicode|string%(1) "2" refcount(2) + [%u|b%"label"]=> + %unicode|string%(1) "b" refcount(2) + } + [%u|b%"row_copy"]=> + array(2) refcount(1){ + [%u|b%"id"]=> + %unicode|string%(1) "2" refcount(1) + [%u|b%"label"]=> + %unicode|string%(1) "b" refcount(2) + } + [%u|b%"id_ref"]=> + &%unicode|string%(1) "2" refcount(2) + [%u|b%"id_copy"]=> + %unicode|string%(1) "2" refcount(1) + [%u|b%"id_copy_mod"]=> + long(2) refcount(1) + } +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_result_unclonable.phpt b/ext/mysqli/tests/mysqli_result_unclonable.phpt new file mode 100644 index 0000000..0ecc30b --- /dev/null +++ b/ext/mysqli/tests/mysqli_result_unclonable.phpt @@ -0,0 +1,24 @@ +--TEST-- +Trying to clone mysqli_result object +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!($res = mysqli_query($link, "SELECT 'good' AS morning"))) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $res_clone = clone $res; + print "done!"; +?> +--EXPECTF-- +Fatal error: Trying to clone an uncloneable object of class mysqli_result in %s on line %d
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_rollback.phpt b/ext/mysqli/tests/mysqli_rollback.phpt new file mode 100644 index 0000000..be49000 --- /dev/null +++ b/ext/mysqli/tests/mysqli_rollback.phpt @@ -0,0 +1,77 @@ +--TEST-- +mysqli_rollback() +--SKIPIF-- +<?php ?> +<?php ?> +<?PHP + require_once('skipif.inc'); + require_once('skipifemb.inc'); + require_once('skipifconnectfailure.inc'); + + require_once('connect.inc'); + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die(sprintf("Cannot connect, [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); + + if (!have_innodb($link)) + die(sprintf("Needs InnoDB support, [%d] %s", $link->errno, $link->error)); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_rollback())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_rollback($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!is_null($tmp = @mysqli_rollback($link, 'foo'))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_autocommit($link, false))) + printf("[005] Cannot turn off autocommit, expecting true, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, 'CREATE TABLE test(id INT) ENGINE = InnoDB')) + printf("[007] Cannot create test table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, 'INSERT INTO test(id) VALUES (1)')) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $tmp = mysqli_rollback($link); + if ($tmp !== true) + printf("[009] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = mysqli_query($link, 'SELECT COUNT(*) AS num FROM test')) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + if (0 != $tmp['num']) + printf("[12] Expecting 0 rows in table test, found %d rows\n", $tmp['num']); + mysqli_free_result($res); + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) + printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_close($link); + + if (!is_null($tmp = mysqli_rollback($link))) + printf("[014] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!\n"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_rollback(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_select_db.phpt b/ext/mysqli/tests/mysqli_select_db.phpt new file mode 100644 index 0000000..f58a19b --- /dev/null +++ b/ext/mysqli/tests/mysqli_select_db.phpt @@ -0,0 +1,112 @@ +--TEST-- +mysqli_select_db() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + require_once("table.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_select_db())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_select_db($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!is_null($tmp = @mysqli_select_db($link, $db, "foo"))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + /* does not make too much sense, unless we have access to at least one more database than $db */ + if (!mysqli_select_db($link, $db)) + printf("[005] Cannot select DB %s, [%d] %s\n", $db, mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, "SELECT DATABASE() AS dbname")) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ($row['dbname'] !== (string)$db) + printf("[008] Expecting database '%s', found '%s'\n", $db, $row['dbname']); + mysqli_free_result($res); + + if (mysqli_select_db($link, 'mysql')) { + // Yippie, a second database to play with - that's great because mysqli_select_db + // ($db) was done by mysqli__connect() already and the previous test + // was quite useless + if (!$res = mysqli_query($link, "SELECT DATABASE() AS dbname")) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (strtolower($row['dbname']) !== 'mysql') + printf("[011] Expecting database 'mysql', found '%s'\n", $row['dbname']); + mysqli_free_result($res); + } + + if (!$link->select_db($db)) + printf("[012] Failed to set '%s' as current DB; [%d] %s\n", $link->errno, $link->error); + + if (!$res = mysqli_query($link, "SELECT DATABASE() AS dbname")) + printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[014] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $current_db = $row['dbname']; + + mysqli_report(MYSQLI_REPORT_OFF); + mysqli_select_db($link, 'I can not imagine that this database exists'); + mysqli_report(MYSQLI_REPORT_ERROR); + + ob_start(); + mysqli_select_db($link, 'I can not imagine that this database exists'); + $output = ob_get_contents(); + ob_end_clean(); + if (!stristr($output, "1049") && !stristr($output, "1044") && !stristr($output, "1045")) { + /* Error: 1049 SQLSTATE: 42000 (ER_BAD_DB_ERROR) Message: Unknown database '%s' */ + /* Error: 1044 SQLSTATE: 42000 (ER_DBACCESS_DENIED_ERROR) Message: Access denied for user '%s'@'%s' to database '%s' */ + /* Error: 1045 SQLSTATE: 28000 (ER_ACCESS_DENIED_ERROR) Message: Access denied for user '%s'@'%s' (using password: %s) */ + echo $output; + } + + if (!$res = mysqli_query($link, "SELECT DATABASE() AS dbname")) + printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[016] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (strtolower($row['dbname']) != strtolower($current_db)) + printf("[017] Current DB should not change if set fails\n"); + + + if (!$res = $link->query("SELECT id FROM test WHERE id = 1")) + printf("[018] [%d] %s\n"); + + $row = $res->fetch_assoc(); + $res->free(); + + mysqli_close($link); + + if (NULL !== ($tmp = mysqli_select_db($link, $db))) + printf("[017] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!\n"; +?> +--CLEAN-- +<?php require_once("clean_table.inc"); ?> +--EXPECTF-- +Warning: mysqli_select_db(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_send_query.phpt b/ext/mysqli/tests/mysqli_send_query.phpt new file mode 100644 index 0000000..7de2bfc --- /dev/null +++ b/ext/mysqli/tests/mysqli_send_query.phpt @@ -0,0 +1,50 @@ +--TEST-- +mysqli_send_query() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +if (!function_exists('mysqli_send_query')) { + die("skip mysqli_send_query() not available"); +} +require_once('connect.inc'); +if (!$TEST_EXPERIMENTAL) + die("skip - experimental (= unsupported) feature"); +?> +--FILE-- +<?php + /* NOTE: tests is a stub, but function is deprecated, as long as it does not crash when invoking it... */ + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (NULL !== ($tmp = @mysqli_send_query())) + printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @mysqli_send_query($link))) + printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } + + $query = array(); + if (NULL !== ($tmp = @mysqli_send_query($link, $query))) + printf("[004] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_int($tmp = mysqli_send_query($link, 'SELECT 1'))) + printf("[005] Expecting integer/any value, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + if (NULL !== ($tmp = mysqli_send_query($link, 'SELECT 1'))) + printf("[006] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +Warning: mysqli_send_query(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_set_charset.phpt b/ext/mysqli/tests/mysqli_set_charset.phpt new file mode 100644 index 0000000..38fe568 --- /dev/null +++ b/ext/mysqli/tests/mysqli_set_charset.phpt @@ -0,0 +1,134 @@ +--TEST-- +mysqli_set_charset() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (version_compare(PHP_VERSION, '5.9.9', '>') == 1) { + die('skip set character set not functional with PHP 6 (fomerly PHP 6 && unicode.semantics=On)'); +} + +if (!function_exists('mysqli_set_charset')) + die("skip Function not available"); + +require_once('connect.inc'); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die(sprintf("skip Cannot connect, [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); + +if (!($res = mysqli_query($link, 'SELECT version() AS server_version')) || + !($tmp = mysqli_fetch_assoc($res))) { + mysqli_close($link); + die(sprintf("skip Cannot check server version, [%d] %s\n", + mysqli_errno($link), mysqli_error($link))); +} +mysqli_free_result($res); +$version = explode('.', $tmp['server_version']); +if (empty($version)) { + mysqli_close($link); + die(sprintf("skip Cannot check server version, based on '%s'", + $tmp['server_version'])); +} + +if ($version[0] <= 4 && $version[1] < 1) { + mysqli_close($link); + die(sprintf("skip Requires MySQL Server 4.1+\n")); +} + +if ((($res = mysqli_query($link, 'SHOW CHARACTER SET LIKE "latin1"', MYSQLI_STORE_RESULT)) && + (mysqli_num_rows($res) == 1)) || + (($res = mysqli_query($link, 'SHOW CHARACTER SET LIKE "latin2"', MYSQLI_STORE_RESULT)) && + (mysqli_num_rows($res) == 1)) + ) { + // ok, required latin1 or latin2 are available + mysqli_close($link); +} else { + die(sprintf("skip Requires character set latin1 or latin2\n")); + mysqli_close($link); +} +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_set_charset())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_set_charset($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_set_charset($link, $link))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$res = mysqli_query($link, 'SELECT @@character_set_connection AS charset, @@collation_connection AS collation')) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + mysqli_free_result($res); + if (!$character_set_connection = $tmp['charset']) + printf("[008] Cannot determine current character set and collation\n"); + + $new_charset = ('latin1' == $character_set_connection) ? 'latin2' : 'latin1'; + if (!$res = mysqli_query($link, sprintf('SHOW CHARACTER SET LIKE "%s"', $new_charset), MYSQLI_STORE_RESULT)) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (mysqli_num_rows($res) == 0) + printf("[010] Test will fail, because alternative test character set '%s' seems not supported\n", $new_charset); + + if (false !== ($ret = mysqli_set_charset($link, "this is not a valid character set"))) + printf("[011] Expecting boolean/false because of invalid character set, got %s/%s\n", gettype($ret), $ret); + + mysqli_close($link); + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[012] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (true !== ($ret = mysqli_set_charset($link, $new_charset))) + printf("[013] Expecting boolean/true, got %s/%s\n", gettype($ret), $ret); + + if (!$res = mysqli_query($link, 'SELECT @@character_set_connection AS charset, @@collation_connection AS collation')) + printf("[014] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $tmp = mysqli_fetch_assoc($res); + mysqli_free_result($res); + if ($new_charset !== $tmp['charset']) + printf("[015] Character set not changed? Expecting %s, got %s\n", $new_charset, $tmp['charset']); + + if (!$res = mysqli_query($link, "SHOW CHARACTER SET")) + printf("[016] Cannot get list of character sets\n"); + + while ($tmp = mysqli_fetch_assoc($res)) { + if ('ucs2' == $tmp['Charset'] || 'utf16' == $tmp['Charset'] || 'utf32' == $tmp['Charset'] || 'utf16le' == $tmp['Charset']) + continue; + + /* Uncomment to see where it hangs - var_dump($tmp); flush(); */ + if (!@mysqli_set_charset($link, $tmp['Charset'])) { + printf("[017] Cannot set character set to '%s', [%d] %s\n", $tmp['Charset'], + mysqli_errno($link), mysqli_error($link)); + continue; + } + + /* Uncomment to see where it hangs - var_dump($tmp); flush(); */ + if (!mysqli_query($link, sprintf("SET NAMES %s", mysqli_real_escape_string($link, $tmp['Charset'])))) + printf("[018] Cannot run SET NAMES %s, [%d] %s\n", $tmp['Charset'], mysqli_errno($link), mysqli_error($link)); + } + mysqli_free_result($res); + + mysqli_close($link); + + if (NULL !== ($tmp = mysqli_set_charset($link, $new_charset))) + printf("[016] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_set_charset(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_set_local_infile_default.phpt b/ext/mysqli/tests/mysqli_set_local_infile_default.phpt new file mode 100644 index 0000000..0348b01 --- /dev/null +++ b/ext/mysqli/tests/mysqli_set_local_infile_default.phpt @@ -0,0 +1,132 @@ +--TEST-- +mysqli_set_local_infile_default() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_set_local_infile_handler')) + die("skip - function not available."); + +$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); +if (!$link) + die(sprintf("skip Can't connect [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--INI-- +mysqli.allow_local_infile=1 +--FILE-- +<?php + require_once('connect.inc'); + require_once('local_infile_tools.inc'); + + $link = $tmp = null; + if (!is_null($tmp = @mysqli_set_local_infile_default())) + printf("[001] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_set_local_infile_default($link))) + printf("[002] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + $link = new mysqli(); + if (!is_null($tmp = @mysqli_set_local_infile_default($link))) + printf("[002a] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + include("table.inc"); + + if (!is_null($tmp = @mysqli_set_local_infile_default($link, 'foo'))) + printf("[003] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + + function callback_simple($fp, &$buffer, $buflen, &$error) { + static $invocation = 0; + + printf("Callback: %d\n", $invocation); + + $invocation++; + if (!is_resource($fp)) + printf("[012] First argument passed to callback is not a resource but %s/%s\n", + $fp, gettype($fp)); + + if (!$buffer = fread($fp, $buflen)) { + if ($invocation == 1) { + printf("[013] Cannot read from stream\n"); + $error = 'Cannot read from stream'; + } else { + return strlen($buffer); + } + } + + $lines = explode("\n", $buffer); + if (count($lines) != 4 && strlen($buffer) > 0) { + printf("[014] Test is too simple to handle a buffer of size %d that cannot hold all lines\n", $buflen); + $error = 'Parser too simple'; + } + + $buffer = ''; + foreach ($lines as $k => $line) { + if ('' === trim($line)) + continue; + + $columns = explode(';', $line); + if (empty($columns)) { + printf("[015] Cannot parse columns\n"); + $error = 'Cannot parse columns'; + } + + // increase id column value + $columns[0] += 1; + $buffer .= implode(';', $columns); + $buffer .= "\n"; + } + + return strlen($buffer); + } + + $file = create_standard_csv(4); + $expected = array( + array('id' => 98, 'label' => 'x'), + array('id' => 99, 'label' => 'y'), + array('id' => 100, 'label' => 'z'), + ); + try_handler(10, $link, $file, 'callback_simple', $expected); + + $expected = array( + array('id' => 97, 'label' => 'x'), + array('id' => 98, 'label' => 'y'), + array('id' => 99, 'label' => 'z'), + ); + try_handler(20, $link, $file, 'default', $expected); + + $expected = array( + array('id' => 98, 'label' => 'x'), + array('id' => 99, 'label' => 'y'), + array('id' => 100, 'label' => 'z'), + ); + try_handler(30, $link, $file, 'callback_simple', $expected); + + mysqli_close($link); + + if (!is_null($tmp = @mysqli_set_local_infile_default($link))) + printf("[300] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp)); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Callback set to 'callback_simple' +Callback: 0 +Callback: 1 +Callback set to 'default' +Callback set to 'callback_simple' +Callback: 2 +Callback: 3 +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler.phpt new file mode 100644 index 0000000..58f4c70 --- /dev/null +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler.phpt @@ -0,0 +1,196 @@ +--TEST-- +mysqli_set_local_infile_handler() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_set_local_infile_handler')) + die("skip - function not available."); + +require_once('connect.inc'); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die("skip Cannot connect to MySQL"); + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--INI-- +mysqli.allow_local_infile=1 +--FILE-- +<?php + require_once('connect.inc'); + require_once('local_infile_tools.inc'); + require_once('table.inc'); + + function callback_simple($fp, &$buffer, $buflen, &$error) { + static $invocation = 0; + + printf("Callback: %d\n", $invocation); + + $invocation++; + if (!is_resource($fp)) + printf("[012] First argument passed to callback is not a resource but %s/%s\n", + $fp, gettype($fp)); + + if (!$buffer = fread($fp, $buflen)) { + if ($invocation == 1) { + printf("[013] Cannot read from stream\n"); + $error = 'Cannot read from stream'; + } else { + return strlen($buffer); + } + } + + $lines = explode("\n", $buffer); + if (count($lines) != 4 && strlen($buffer) > 0) { + printf("[014] Test is too simple to handle a buffer of size %d that cannot hold all lines\n", $buflen); + $error = 'Parser too simple'; + } + + $buffer = ''; + foreach ($lines as $k => $line) { + if ('' === trim($line)) + continue; + + $columns = explode(';', $line); + if (empty($columns)) { + printf("[015] Cannot parse columns\n"); + $error = 'Cannot parse columns'; + } + + // increase id column value + $columns[0] += 1; + $buffer .= implode(';', $columns); + $buffer .= "\n"; + } + + return strlen($buffer); + } + + function callback_fclose($fp, &$buffer, $buflen, &$error) { + static $invocation = 0; + + printf("Callback: %d\n", $invocation++); + + fclose($fp); + return strlen($buffer); + } + + function callback_closefile($fp, &$buffer, $buflen, &$error) { + static $invocation = 0; + + printf("Callback: %d\n", $invocation++); + flush(); + if (is_resource($fp)) + fclose($fp); + $buffer = "1;'a';\n"; + if ($invocation > 10) + return 0; + + return strlen($buffer); + } + + function callback_invalid_args($fp, &$buffer, $buflen) { + static $invocation = 0; + + printf("Callback: %d\n", $invocation++); + $buffer = fread($fp, $buflen); + + return strlen($buffer); + } + + function callback_error($fp, &$buffer, $buflen, &$error) { + static $invocation = 0; + + printf("Callback: %d\n", $invocation++); + $buffer = fread($fp, $buflen); + $error = 'How to access this error?'; + + return -1; + } + + if (!is_null($tmp = @mysqli_set_local_infile_handler())) + printf("[001] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp)); + + $handle = null; + if (!is_null($tmp = @mysqli_set_local_infile_handler($handle))) + printf("[002] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp)); + + $handle = @new mysqli(); + if (!is_null($tmp = @mysqli_set_local_infile_handler($handle, 'callback_simple'))) + printf("[003] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp)); + + if (false !== ($tmp = @mysqli_set_local_infile_handler($link, 'unknown'))) + printf("[004] Expecting false/boolean got %s/%s\n", $tmp, gettype($tmp)); + + $file = create_standard_csv(5); + + $expected = array( + array('id' => 98, 'label' => 'x'), + array('id' => 99, 'label' => 'y'), + array('id' => 100, 'label' => 'z'), + ); + try_handler(10, $link, $file, 'callback_simple', $expected); + + $expected = array(); + try_handler(20, $link, $file, 'callback_fclose', $expected); + + // FIXME - TODO - KLUDGE - + // IMHO this is wrong. ext/mysqli should bail as the function signature + // is not complete. That's a BC break, OK, but it makes perfectly sense. + $expected = array(); + try_handler(30, $link, $file, 'callback_invalid_args', $expected); + + $expected = array(); + try_handler(40, $link, $file, 'callback_error', $expected); + + + mysqli_close($link); + + if (!is_null($tmp = @mysqli_set_local_infile_handler($link, 'callback_simple'))) + printf("[300] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp)); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Callback set to 'callback_simple' +Callback: 0 +Callback: 1 +Callback set to 'callback_fclose' +Callback: 0 +[022] LOAD DATA failed, [2000] File handle close%s +Callback set to 'callback_invalid_args' +Callback: 0 +Callback: 1 +[037] More results than expected! +array(2) { + [%u|b%"id"]=> + %unicode|string%(2) "97" + [%u|b%"label"]=> + %unicode|string%(1) "x" +} +array(2) { + [%u|b%"id"]=> + %unicode|string%(2) "98" + [%u|b%"label"]=> + %unicode|string%(1) "y" +} +array(2) { + [%u|b%"id"]=> + %unicode|string%(2) "99" + [%u|b%"label"]=> + %unicode|string%(1) "z" +} +Callback set to 'callback_error' +Callback: 0 +[042] LOAD DATA failed, [2000] How to access this error? +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_bad_character.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_bad_character.phpt new file mode 100644 index 0000000..b8f51c2 --- /dev/null +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_bad_character.phpt @@ -0,0 +1,82 @@ +--TEST-- +mysqli_set_local_infile_handler() - random ASCII character including \0 +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); + +if (!function_exists('mysqli_set_local_infile_handler')) + die("skip - function not available."); + +if (!$TEST_EXPERIMENTAL) + die("skip - experimental (= unsupported) feature"); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die("skip Cannot connect to MySQL"); + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--INI-- +mysqli.allow_local_infile=1 +--FILE-- +<?php + require_once('connect.inc'); + require_once('local_infile_tools.inc'); + require_once('table.inc'); + + function callback_bad_character($fp, &$buffer, $buflen, &$error) { + static $invocation = 0; + + printf("Callback: %d\n", $invocation++); + + $num_chars = (version_compare(PHP_VERSION, '5.9.9', '>') == 1) ? (floor($buflen / 2) - 10) : ($buflen - 5); + $part1 = floor($num_chars / 2); + $part2 = $num_chars - $part1; + + $buffer = ''; + for ($i = 0; $i < $part1; $i++) + $buffer .= chr(mt_rand(0, 255)); + + $buffer .= ';"'; + + for ($i = 0; $i < $part2; $i++) + $buffer .= chr(mt_rand(0, 255)); + + $buffer .= '";'; + if ($invocation > 10) + return 0; + + return strlen($buffer); + } + + $file = create_standard_csv(5); + /* we feed the handler with random data, therefore we cannot specify and expected rows */ + try_handler(20, $link, $file, 'callback_bad_character'); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Callback set to 'callback_bad_character' +Callback: 0 +Callback: 1 +Callback: 2 +Callback: 3 +Callback: 4 +Callback: 5 +Callback: 6 +Callback: 7 +Callback: 8 +Callback: 9 +Callback: 10 +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_buffer_overflow.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_buffer_overflow.phpt new file mode 100644 index 0000000..a3c8801 --- /dev/null +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_buffer_overflow.phpt @@ -0,0 +1,60 @@ +--TEST-- +mysqli_set_local_infile_handler() - buffer overflow +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_set_local_infile_handler')) + die("skip - function not available."); + +require_once('connect.inc'); +if (!$TEST_EXPERIMENTAL) + die("skip - experimental (= unsupported) feature"); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die("skip Cannot connect to MySQL"); + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--INI-- +mysqli.allow_local_infile=1 +--FILE-- +<?php + require_once('connect.inc'); + require_once('local_infile_tools.inc'); + require_once('table.inc'); + + function callback_buffer_overflow($fp, &$buffer, $buflen, &$error) { + static $invocation = 0; + + printf("Callback: %d\n", $invocation); + $buffer = fread($fp, $buflen); + + $buffer = str_repeat(';', $buflen * 2); + return strlen($buffer); + } + + $file = create_standard_csv(5); + $expected = array(); + try_handler(20, $link, $file, 'callback_buffer_overflow', $expected); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Callback set to 'callback_buffer_overflow' +Callback: 0 + +Warning: mysqli_query(): Too much data returned in %s on line %d +[022] LOAD DATA failed, [%d] Too much data returned +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_close_link.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_close_link.phpt new file mode 100644 index 0000000..408bb29 --- /dev/null +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_close_link.phpt @@ -0,0 +1,61 @@ +--TEST-- +mysqli_set_local_infile_handler() - close database link +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_set_local_infile_handler')) + die("skip - function not available."); + +require_once('connect.inc'); +if (!$TEST_EXPERIMENTAL) + die("skip - experimental (= unsupported) feature"); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die("skip Cannot connect to MySQL"); + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--INI-- +mysqli.allow_local_infile=1 +--FILE-- +<?php + require("table.inc"); + require_once('local_infile_tools.inc'); + + function callback_close_link($fp, &$buffer, $buflen, &$error) { + global $link; + static $invocation = 0; + + printf("Callback: %d\n", $invocation++); + flush(); + if (is_object($link)) + mysqli_close($link); + + $buffer = "1;'a';\n"; + if ($invocation > 10) + return 0; + + return strlen($buffer); + } + + $file = create_standard_csv(1); + $expected = array(array('id' => 1, 'label' => 'a')); + try_handler(20, $link, $file, 'callback_close_link', $expected); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Callback set to 'callback_close_link' +Callback: 0 +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_closefile.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_closefile.phpt new file mode 100644 index 0000000..168cbc1 --- /dev/null +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_closefile.phpt @@ -0,0 +1,70 @@ +--TEST-- +mysqli_set_local_infile_handler() - do not use the file pointer +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_set_local_infile_handler')) + die("skip - function not available."); + +require_once('connect.inc'); +if (!$TEST_EXPERIMENTAL) + die("skip - experimental (= unsupported) feature"); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die("skip Cannot connect to MySQL"); + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--INI-- +mysqli.allow_local_infile=1 +--FILE-- +<?php + require_once("table.inc"); + require_once('local_infile_tools.inc'); + + function callback_closefile($fp, &$buffer, $buflen, &$error) { + static $invocation = 0; + + printf("Callback: %d\n", $invocation++); + flush(); + if (is_resource($fp)) + fclose($fp); + $buffer = "1;'a';\n"; + if ($invocation > 10) + return 0; + + return strlen($buffer); + } + + $file = create_standard_csv(1); + $expected = array(array('id' => 1, 'label' => 'a')); + try_handler(20, $link, $file, 'callback_closefile', $expected); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Callback set to 'callback_closefile' +Callback: 0 +Callback: 1 +Callback: 2 +Callback: 3 +Callback: 4 +Callback: 5 +Callback: 6 +Callback: 7 +Callback: 8 +Callback: 9 +Callback: 10 +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_closures.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_closures.phpt new file mode 100644 index 0000000..ad7ab32 --- /dev/null +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_closures.phpt @@ -0,0 +1,62 @@ +--TEST-- +mysqli_set_local_infile_handler() - use closures as handler +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_set_local_infile_handler')) + die("skip - function not available."); + +require_once('connect.inc'); +if (!$TEST_EXPERIMENTAL) + die("skip - experimental (= unsupported) feature"); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die("skip Cannot connect to MySQL"); + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--INI-- +mysqli.allow_local_infile=1 +--FILE-- +<?php + require_once('connect.inc'); + require_once('local_infile_tools.inc'); + require_once('table.inc'); + + $callback_replace_buffer = function ($fp, &$buffer, $buflen, &$error) { + static $invocation = 0; + + printf("Callback: %d\n", $invocation++); + flush(); + + $buffer = fread($fp, $buflen); + + if ($invocation > 10) + return 0; + + return strlen($buffer); + }; + + $file = create_standard_csv(1); + if (!try_handler(20, $link, $file, $callback_replace_buffer, null)) + printf("[008] Failure\n"); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Callback set to 'Closure object' +Callback: 0 +Callback: 1 +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_kill_link.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_kill_link.phpt new file mode 100644 index 0000000..b2b42a2 --- /dev/null +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_kill_link.phpt @@ -0,0 +1,61 @@ +--TEST-- +mysqli_set_local_infile_handler() - kill database link +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_set_local_infile_handler')) + die("skip - function not available."); + +require_once('connect.inc'); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die("skip Cannot connect to MySQL"); + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--INI-- +mysqli.allow_local_infile=1 +--FILE-- +<?php + require("table.inc"); + require_once('local_infile_tools.inc'); + + function callback_kill_link($fp, &$buffer, $buflen, &$error) { + global $link; + static $invocation = 0; + + printf("Callback: %d\n", $invocation++); + flush(); + if (is_object($link)) + mysqli_kill($link, mysqli_thread_id($link)); + + $buffer = "1;'a';\n"; + if ($invocation > 10) + return 0; + + mysqli_set_local_infile_default($link); + return strlen($buffer); + } + + $file = create_standard_csv(1); + $expected = array(array('id' => 1, 'label' => 'a')); + try_handler(20, $link, $file, 'callback_kill_link', $expected); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Callback set to 'callback_kill_link' +Callback: 0 +[022] LOAD DATA failed, [2000] Can't execute load data local init callback function +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_negative_len.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_negative_len.phpt new file mode 100644 index 0000000..16e38c5 --- /dev/null +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_negative_len.phpt @@ -0,0 +1,58 @@ +--TEST-- +mysqli_set_local_infile_handler() - negative return value/buflen to indicate an error +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_set_local_infile_handler')) + die("skip - function not available."); + +require_once('connect.inc'); +if (!$TEST_EXPERIMENTAL) + die("skip - experimental (= unsupported) feature"); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die("skip Cannot connect to MySQL"); + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--INI-- +mysqli.allow_local_infile=1 +--FILE-- +<?php + require_once('connect.inc'); + require_once('local_infile_tools.inc'); + require_once('table.inc'); + + function callback_negative_len($fp, &$buffer, $buflen, &$error) { + static $invocation = 0; + + printf("Callback: %d\n", $invocation); + $buffer = fread($fp, $buflen); + + $error = "negative length means error"; + return -1; + } + + $file = create_standard_csv(1); + $expected = array(); + try_handler(20, $link, $file, 'callback_negative_len', $expected); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Callback set to 'callback_negative_len' +Callback: 0 +[022] LOAD DATA failed, [2000] negative length means error +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_nested_call.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_nested_call.phpt new file mode 100644 index 0000000..4663fe2 --- /dev/null +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_nested_call.phpt @@ -0,0 +1,107 @@ +--TEST-- +mysqli_set_local_infile_handler() - nested calls +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_set_local_infile_handler')) + die("skip - function not available."); + +require_once('connect.inc'); +if (!$TEST_EXPERIMENTAL) + die("skip - experimental (= unsupported) feature"); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die("skip Cannot connect to MySQL"); + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--INI-- +mysqli.allow_local_infile=1 +--FILE-- +<?php + require_once('connect.inc'); + require_once('local_infile_tools.inc'); + require_once('table.inc'); + + function callback_simple($fp, &$buffer, $buflen, &$error) { + static $invocation = 0; + + printf("Callback - callback_simple(): %d\n", $invocation); + + $invocation++; + if (!is_resource($fp)) + printf("[012] First argument passed to callback is not a resource but %s/%s\n", + $fp, gettype($fp)); + + if (!$buffer = fread($fp, $buflen)) { + if ($invocation == 1) { + printf("[013] Cannot read from stream\n"); + $error = 'Cannot read from stream'; + } else { + return strlen($buffer); + } + } + + $lines = explode("\n", $buffer); + if (count($lines) != 4 && strlen($buffer) > 0) { + printf("[014] Test is too simple to handle a buffer of size %d that cannot hold all lines\n", $buflen); + $error = 'Parser too simple'; + } + + $buffer = ''; + foreach ($lines as $k => $line) { + if ('' === trim($line)) + continue; + + $columns = explode(';', $line); + if (empty($columns)) { + printf("[015] Cannot parse columns\n"); + $error = 'Cannot parse columns'; + } + + // increase id column value + $columns[0] += 1; + $buffer .= implode(';', $columns); + $buffer .= "\n"; + } + + /* report the wrong length */ + return strlen($buffer); + } + + function callback_report_short_len($fp, &$buffer, $buflen, &$error) { + static $invocation = 0; + + printf("Callback - report_short_len(): %d\n", $invocation++); + return callback_simple($fp, $buffer, $buflen, $error); + } + + $file = create_standard_csv(1); + $expected = array( + array('id' => 98, 'label' => 'x'), + array('id' => 99, 'label' => 'y'), + array('id' => 100, 'label' => 'z'), + ); + try_handler(20, $link, $file, 'callback_report_short_len', $expected); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Callback set to 'callback_report_short_len' +Callback - report_short_len(): 0 +Callback - callback_simple(): 0 +Callback - report_short_len(): 1 +Callback - callback_simple(): 1 +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_new_query.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_new_query.phpt new file mode 100644 index 0000000..ca06435 --- /dev/null +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_new_query.phpt @@ -0,0 +1,71 @@ +--TEST-- +mysqli_set_local_infile_handler() - run new query on db link +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_set_local_infile_handler')) + die("skip - function not available."); + +require_once('connect.inc'); +if (!$TEST_EXPERIMENTAL) + die("skip - experimental (= unsupported) feature"); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die("skip Cannot connect to MySQL"); + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--INI-- +mysqli.allow_local_infile=1 +--FILE-- +<?php + require_once('connect.inc'); + require_once('local_infile_tools.inc'); + require_once('table.inc'); + + function callback_new_query($fp, &$buffer, $buflen, &$error) { + global $link; + static $invocation = 0; + + printf("Callback: %d\n", $invocation++); + flush(); + if (is_object($link)) { + if (!$res = mysqli_query($link, "SELECT id, label FROM test")) { + printf("[Callback 001 - %03d] Cannot run query, [%d] %s\n", + $invocation, mysqli_errno($link), mysqli_error($link)); + } + if ($res) + mysqli_free_result($res); + } + $buffer = "1;'a';\n"; + if ($invocation > 10) + return 0; + + mysqli_set_local_infile_default($link); + return strlen($buffer); + } + + $file = create_standard_csv(1); + $expected = array(array('id' => 1, 'label' => 'a')); + try_handler(20, $link, $file, 'callback_new_query', $expected); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Callback set to 'callback_new_query' +Callback: 0 +[Callback 001 - 001] Cannot run query, [2014] Commands out of sync; you can't run this command now +[022] LOAD DATA failed, [2000] Can't execute load data local init callback function +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_nofileop.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_nofileop.phpt new file mode 100644 index 0000000..601a09e --- /dev/null +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_nofileop.phpt @@ -0,0 +1,70 @@ +--TEST-- +mysqli_set_local_infile_handler() - do not use the file pointer +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_set_local_infile_handler')) + die("skip - function not available."); + +require_once('connect.inc'); +if (!$TEST_EXPERIMENTAL) + die("skip - experimental (= unsupported) feature"); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die("skip Cannot connect to MySQL"); + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--INI-- +mysqli.allow_local_infile=1 +--FILE-- +<?php + require_once('connect.inc'); + require_once('local_infile_tools.inc'); + require_once('table.inc'); + + function callback_nofileop($fp, &$buffer, $buflen, &$error) { + static $invocation = 0; + + printf("Callback: %d\n", $invocation++); + flush(); + + $buffer = "1;'a';\n"; + if ($invocation > 10) + return 0; + + return strlen($buffer); + } + + $file = create_standard_csv(1); + $expected = array(array('id' => 1, 'label' => 'a')); + try_handler(20, $link, $file, 'callback_nofileop', $expected); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Callback set to 'callback_nofileop' +Callback: 0 +Callback: 1 +Callback: 2 +Callback: 3 +Callback: 4 +Callback: 5 +Callback: 6 +Callback: 7 +Callback: 8 +Callback: 9 +Callback: 10 +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_openbasedir.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_openbasedir.phpt new file mode 100644 index 0000000..7163aca --- /dev/null +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_openbasedir.phpt @@ -0,0 +1,115 @@ +--TEST-- +mysqli_set_local_infile_handler() - open basedir restrictions +--SKIPIF-- +<?php +if (!$fp = @fopen('skipif.inc', 'r')) + die("skip open_basedir restrictions forbid opening include files"); + +include_once('skipif.inc'); +include_once('skipifemb.inc'); +include_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_set_local_infile_handler')) + die("skip - function not available."); + +include_once('connect.inc'); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die("skip Cannot connect to MySQL"); + +if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) { + mysqli_close($link); + die("skip Cannot check if Server variable 'local_infile' is set to 'ON'"); +} + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--INI-- +open_basedir="." +--FILE-- +<?php + @include('connect.inc'); + if (!isset($db)) { + // stupid run-tests.php - any idea how to set system ini setting dynamically??? + print "Warning: tempnam(): open_basedir restriction in effect. File(grrr) is not within the allowed path(s): (grrr) in grrr on line 0 +[005 + 1] Cannot create CVS file '' +Callback set to 'callback_simple' +[012] LOAD DATA failed, [0] grrr +[014/0] [0] '' +done!"; + die(); + } + + require_once('connect.inc'); + require_once('local_infile_tools.inc'); + require_once('table.inc'); + + function callback_simple($fp, &$buffer, $buflen, &$error) { + static $invocation = 0; + + printf("Callback: %d\n", $invocation); + + $invocation++; + if (!is_resource($fp)) + printf("[012] First argument passed to callback is not a resource but %s/%s\n", + $fp, gettype($fp)); + + if (!$buffer = fread($fp, $buflen)) { + if ($invocation == 1) { + printf("[013] Cannot read from stream\n"); + $error = 'Cannot read from stream'; + } else { + return strlen($buffer); + } + } + + $lines = explode("\n", $buffer); + if (count($lines) != 4 && strlen($buffer) > 0) { + printf("[014] Test is too simple to handle a buffer of size %d that cannot hold all lines\n", $buflen); + $error = 'Parser too simple'; + } + + $buffer = ''; + foreach ($lines as $k => $line) { + if ('' === trim($line)) + continue; + + $columns = explode(';', $line); + if (empty($columns)) { + printf("[015] Cannot parse columns\n"); + $error = 'Cannot parse columns'; + } + + // increase id column value + $columns[0] += 1; + $buffer .= implode(';', $columns); + $buffer .= "\n"; + } + + return strlen($buffer); + } + + $file = create_standard_csv(5); + $expected = array( + array('id' => 98, 'label' => 'x'), + array('id' => 99, 'label' => 'y'), + array('id' => 100, 'label' => 'z'), + ); + try_handler(10, $link, $file, 'callback_simple', $expected); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: tempnam(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (%s) in %s on line %d +[005 + 1] Cannot create CVS file '' +Callback set to 'callback_simple' +[012] LOAD DATA failed, [%d] %s +[014/0] [0] '' +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_replace_buffer.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_replace_buffer.phpt new file mode 100644 index 0000000..0d4024e --- /dev/null +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_replace_buffer.phpt @@ -0,0 +1,78 @@ +--TEST-- +mysqli_set_local_infile_handler() - replace buffer pointer +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_set_local_infile_handler')) + die("skip - function not available."); + +require_once('connect.inc'); +if (!$TEST_EXPERIMENTAL) + die("skip - experimental (= unsupported) feature"); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die("skip Cannot connect to MySQL"); + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--INI-- +mysqli.allow_local_infile=1 +--FILE-- +<?php + require_once('connect.inc'); + require_once('local_infile_tools.inc'); + require_once('table.inc'); + + function callback_replace_buffer($fp, &$buffer, $buflen, &$error) { + static $invocation = 0; + + printf("Callback: %d\n", $invocation++); + flush(); + + $buffer = fread($fp, $buflen); + + $ret = "1;'a';\n"; + $buffer = $ret; + + $num_chars = ((version_compare(PHP_VERSION, '5.9.9', '>') == 1)) ? floor($buflen / 2) : $buflen; + assert(strlen($buffer) < $num_chars); + + if ($invocation > 10) + return 0; + + return strlen($buffer); + } + + $file = create_standard_csv(1); + $expected = array(array('id' => 1, 'label' => 'a')); + if (!try_handler(20, $link, $file, 'callback_replace_buffer', $expected)) + printf("[008] Failure\n"); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Callback set to 'callback_replace_buffer' +Callback: 0 +Callback: 1 +Callback: 2 +Callback: 3 +Callback: 4 +Callback: 5 +Callback: 6 +Callback: 7 +Callback: 8 +Callback: 9 +Callback: 10 +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_short_len.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_short_len.phpt new file mode 100644 index 0000000..b3144e4 --- /dev/null +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_short_len.phpt @@ -0,0 +1,101 @@ +--TEST-- +mysqli_set_local_infile_handler() - report shorter buffer +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_set_local_infile_handler')) + die("skip - function not available."); + +require_once('connect.inc'); +if (!$TEST_EXPERIMENTAL) + die("skip - experimental (= unsupported) feature"); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die("skip Cannot connect to MySQL"); + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--INI-- +mysqli.allow_local_infile=1 +--FILE-- +<?php + require_once('connect.inc'); + require_once('local_infile_tools.inc'); + require_once('table.inc'); + + function callback_short_len($fp, &$buffer, $buflen, &$error) { + static $invocation = 0; + + printf("Callback: %d\n", $invocation); + + $invocation++; + if (!is_resource($fp)) + printf("[012] First argument passed to callback is not a resource but %s/%s\n", + $fp, gettype($fp)); + + if (!$buffer = fread($fp, $buflen)) { + if ($invocation == 1) { + printf("[013] Cannot read from stream\n"); + $error = 'Cannot read from stream'; + } else { + return strlen($buffer); + } + } + + $lines = explode("\n", $buffer); + if (count($lines) != 4 && strlen($buffer) > 0) { + printf("[014] Test is too simple to handle a buffer of size %d that cannot hold all lines\n", $buflen); + $error = 'Parser too simple'; + } + + $buffer = ''; + foreach ($lines as $k => $line) { + if ('' === trim($line)) + continue; + + $columns = explode(';', $line); + if (empty($columns)) { + printf("[015] Cannot parse columns\n"); + $error = 'Cannot parse columns'; + } + + // increase id column value + $columns[0] += 1; + $buffer .= implode(';', $columns); + $buffer .= "\n"; + } + + /* report the wrong length */ + return strlen($buffer) - 1; + } + + $file = create_standard_csv(1); + $expected = array( + array('id' => 98, 'label' => 'x'), + array('id' => 99, 'label' => 'y'), + array('id' => 100, 'label' => 'z'), + ); + try_handler(20, $link, $file, 'callback_short_len', $expected); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Callback set to 'callback_short_len' +Callback: 0 + +Warning: mysqli_query(): Mismatch between the return value of the callback and the content length of the buffer. in %s on line %d +[022] LOAD DATA failed, [2000] Mismatch between the return value of the callback and the content length of the buffer. +[024/0] [0] '' +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_unregister.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_unregister.phpt new file mode 100644 index 0000000..f287f4d --- /dev/null +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_unregister.phpt @@ -0,0 +1,64 @@ +--TEST-- +mysqli_set_local_infile_handler() - do not use the file pointer +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_set_local_infile_handler')) + die("skip - function not available."); + +require_once('connect.inc'); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + die("skip Cannot connect to MySQL"); + +include_once("local_infile_tools.inc"); +if ($msg = check_local_infile_support($link, $engine)) + die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); + +mysqli_close($link); +?> +--INI-- +mysqli.allow_local_infile=1 +--FILE-- +<?php + require_once('connect.inc'); + require_once('local_infile_tools.inc'); + require_once('table.inc'); + + function callback_unregister($fp, &$buffer, $buflen, &$error) { + global $link; + static $invocation = 0; + + printf("Callback: %d\n", $invocation++); + flush(); + if (is_resource($fp)) + fclose($fp); + $buffer = "1;'a';\n"; + if ($invocation > 10) + return 0; + + mysqli_set_local_infile_default($link); + return strlen($buffer); + } + + $file = create_standard_csv(1); + $expected = array(array('id' => 1, 'label' => 'a')); + try_handler(20, $link, $file, 'callback_unregister', $expected); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Callback set to 'callback_unregister' +Callback: 0 + +Warning: mysqli_query(): File handle closed in %s on line %d +[022] LOAD DATA failed, [2000] File handle closed +[024/0] [0] '' +done! diff --git a/ext/mysqli/tests/mysqli_set_opt.phpt b/ext/mysqli/tests/mysqli_set_opt.phpt new file mode 100644 index 0000000..7c96d59 --- /dev/null +++ b/ext/mysqli/tests/mysqli_set_opt.phpt @@ -0,0 +1,69 @@ +--TEST-- +mysqli_set_opt() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_set_opt())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_set_opt($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + $link = mysqli_init(); + + if (!is_null($tmp = @mysqli_set_opt($link, MYSQLI_OPT_CONNECT_TIMEOUT))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_set_opt($link, "s", 'extra_my.cnf'))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_set_opt($link, MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT=0', 'foo'))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + // print "run_tests.php don't fool me with your 'ungreedy' expression '.+?'!\n"; + var_dump(mysqli_set_opt($link, MYSQLI_READ_DEFAULT_GROUP, 'extra_my.cnf')); + var_dump(mysqli_set_opt($link, MYSQLI_READ_DEFAULT_FILE, 'extra_my.cnf')); + var_dump(mysqli_set_opt($link, MYSQLI_OPT_CONNECT_TIMEOUT, 10)); + var_dump(mysqli_set_opt($link, MYSQLI_OPT_LOCAL_INFILE, 1)); + var_dump(mysqli_set_opt($link, MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT=0')); + var_dump(my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)); + var_dump(mysqli_set_opt($link, MYSQLI_READ_DEFAULT_GROUP, 'extra_my.cnf')); + var_dump(mysqli_set_opt($link, MYSQLI_READ_DEFAULT_FILE, 'extra_my.cnf')); + var_dump(mysqli_set_opt($link, MYSQLI_OPT_CONNECT_TIMEOUT, 10)); + var_dump(mysqli_set_opt($link, MYSQLI_OPT_LOCAL_INFILE, 1)); + var_dump(mysqli_set_opt($link, MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT=0')); + var_dump(mysqli_set_opt($link, MYSQLI_CLIENT_SSL, 'not an mysqli_option')); + + mysqli_close($link); + + var_dump(mysqli_set_opt($link, MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT=1')); + + print "done!"; +?> +--EXPECTF-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(false) + +Warning: mysqli_set_opt(): Couldn't fetch mysqli in %s on line %d +NULL +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_sqlstate.phpt b/ext/mysqli/tests/mysqli_sqlstate.phpt new file mode 100644 index 0000000..56580cd --- /dev/null +++ b/ext/mysqli/tests/mysqli_sqlstate.phpt @@ -0,0 +1,50 @@ +--TEST-- +mysqli_sqlstate() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_sqlstate())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_sqlstate($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + var_dump(@mysqli_sqlstate($link, "foo")); + + var_dump(mysqli_sqlstate($link)); + mysqli_query($link, "SELECT unknown_column FROM test"); + var_dump(mysqli_sqlstate($link)); + mysqli_free_result(mysqli_query($link, "SELECT id FROM test")); + var_dump(mysqli_sqlstate($link)); + + mysqli_close($link); + + var_dump(mysqli_sqlstate($link)); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +NULL +%s(5) "00000" +%s(5) "42S22" +%s(5) "00000" + +Warning: mysqli_sqlstate(): Couldn't fetch mysqli in %s on line %d +NULL +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_ssl_set.phpt b/ext/mysqli/tests/mysqli_ssl_set.phpt new file mode 100644 index 0000000..2abae55 --- /dev/null +++ b/ext/mysqli/tests/mysqli_ssl_set.phpt @@ -0,0 +1,61 @@ +--TEST-- +mysqli_ssl_set() - test is a stub! +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +if (!function_exists('mysqli_ssl_set')) + die("skip function not available"); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_ssl_set())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_ssl_set($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_ssl_set($link, $link))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_ssl_set($link, $link, $link))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_ssl_set($link, $link, $link, $link))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_ssl_set($link, $link, $link, $link, $link))) + printf("[006] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + /* + This function always returns TRUE value. + + $link = mysqli_init(); + if (NULL !== ($tmp = @mysqli_ssl_set( + $link, + 'The path name to the key file.', + 'The path name to the certificate file.', + 'The path name to the certificate authority file.', + 'The pathname to a directory that contains trusted SSL CA certificates in PEM format.', + 'A list of allowable ciphers to use for SSL encryption.'))) + printf("[007] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + + If SSL setup is incorrect my_mysqli_real_connect() + will return an error when you attempt to connect. + + ... and the above SSL setup should be always incorrect. + + if (false !== ($tmp = my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket))) + printf("[008] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + */ + print "done!\n"; +?> +--EXPECTF-- +done! diff --git a/ext/mysqli/tests/mysqli_stat.phpt b/ext/mysqli/tests/mysqli_stat.phpt new file mode 100644 index 0000000..f1cd56c --- /dev/null +++ b/ext/mysqli/tests/mysqli_stat.phpt @@ -0,0 +1,40 @@ +--TEST-- +mysqli_stat() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stat())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stat($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!is_null($tmp = @mysqli_stat($link, "foo"))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if ((!is_string($tmp = mysqli_stat($link))) || ('' === $tmp)) + printf("[004] Expecting non empty string, got %s/'%s', [%d] %s\n", + gettype($tmp), $tmp, mysqli_errno($link), mysql_error($link)); + + mysqli_close($link); + + if (!is_null($tmp = mysqli_stat($link))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +Warning: mysqli_stat(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_affected_rows.phpt b/ext/mysqli/tests/mysqli_stmt_affected_rows.phpt new file mode 100644 index 0000000..7fc32f7 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_affected_rows.phpt @@ -0,0 +1,252 @@ +--TEST-- +mysqli_stmt_affected_rows() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_affected_rows())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_affected_rows($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } + $stmt = mysqli_stmt_init($link); + + if (!mysqli_stmt_prepare($stmt, 'DROP TABLE IF EXISTS test') || + !mysqli_stmt_execute($stmt)) { + printf("[003] Failed to drop old test table: [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + if (!mysqli_stmt_prepare($stmt, 'CREATE TABLE test(id INT, label CHAR(1), PRIMARY KEY(id)) ENGINE = ' . $engine) || + !mysqli_stmt_execute($stmt)) { + printf("[004] Failed to create test table: [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + if (0 !== ($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[005] Expecting int/0, got %s/'%s'\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + $stmt = mysqli_stmt_init($link); + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (1, 'a')") || + !mysqli_stmt_execute($stmt)) + printf("[006] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + mysqli_stmt_close($stmt); + $stmt = mysqli_stmt_init($link); + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (100, 'z')") || + !mysqli_stmt_execute($stmt)) + printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (1 !== ($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[008] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + $stmt = mysqli_stmt_init($link); + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (100, 'z')") || + !mysqli_stmt_execute($stmt)) + // NOTE: the error message varies with the MySQL Server version, dump only the error code! + printf("[009] [%d] (error message varies with the MySQL Server version, check the error code)\n", mysqli_stmt_errno($stmt)); + + /* an error occurred: affected rows should return -1 */ + if (-1 !== ($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[010] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + $stmt = mysqli_stmt_init($link); + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (1, 'a') ON DUPLICATE KEY UPDATE id = 4") || + !mysqli_stmt_execute($stmt)) + printf("[011] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (2 !== ($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[012] Expecting int/2, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + $stmt = mysqli_stmt_init($link); + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (2, 'b'), (3, 'c')") || + !mysqli_stmt_execute($stmt)) + printf("[013] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (2 !== ($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[014] Expecting int/2, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + $stmt = mysqli_stmt_init($link); + + if (!mysqli_stmt_prepare($stmt, "INSERT IGNORE INTO test(id, label) VALUES (1, 'a')") || + !mysqli_stmt_execute($stmt)) + printf("[015] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (1 !== ($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[016] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + + if (!($res = mysqli_query($link, "SELECT count(id) AS num FROM test")) || + !($tmp = mysqli_fetch_assoc($res))) + printf("[017] [%d] %s\n", mysqli_error($link), mysqli_error($link)); + $num = (int)$tmp['num']; + mysqli_free_result($res); + + mysqli_stmt_close($stmt); + $stmt = mysqli_stmt_init($link); + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) SELECT id + 10, label FROM test") || + !mysqli_stmt_execute($stmt)) + printf("[018] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if ($num !== ($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[019] Expecting int/%d, got %s/%s\n", $num, gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + $stmt = mysqli_stmt_init($link); + + if (!mysqli_stmt_prepare($stmt, "REPLACE INTO test(id, label) values (4, 'd')") || + !mysqli_stmt_execute($stmt)) + printf("[020] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (2 !== ($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[021] Expecting int/2, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + $stmt = mysqli_stmt_init($link); + + if (!mysqli_stmt_prepare($stmt, "REPLACE INTO test(id, label) values (5, 'e')") || + !mysqli_stmt_execute($stmt)) + printf("[022] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (1 !== ($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[023] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + $stmt = mysqli_stmt_init($link); + + if (!mysqli_stmt_prepare($stmt, "UPDATE test SET label = 'a' WHERE id = 2") || + !mysqli_stmt_execute($stmt)) + printf("[024] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (1 !== ($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[025] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, "UPDATE test SET label = 'a' WHERE id = 2") || + !mysqli_stmt_execute($stmt)) + printf("[026] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (0 !== ($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[027] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + $stmt = mysqli_stmt_init($link); + + if (!mysqli_stmt_prepare($stmt, "UPDATE test SET label = 'a' WHERE id = 100") || + !mysqli_stmt_execute($stmt)) + printf("[028] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (1 !== ($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[029] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, 'SELECT label FROM test WHERE id = 100') || + !mysqli_stmt_execute($stmt)) + printf("[030] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + /* use it like num_rows */ + /* PS are unbuffered, num_rows cannot determine the row count before all rows have been fetched and/or buffered */ + if (-1 !== ($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[031] Expecting int/-1, got %s/%s\n", gettype($tmp), $tmp); + + if (0 !== ($tmp = mysqli_stmt_num_rows($stmt))) + printf("[032] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_store_result($stmt)) + printf("[033] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (1 !== ($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[034] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + if (1 !== ($tmp = mysqli_stmt_num_rows($stmt))) + printf("[035] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_free_result($stmt); + mysqli_stmt_close($stmt); + $stmt = mysqli_stmt_init($link); + + if (!mysqli_stmt_prepare($stmt, 'SELECT label FROM test WHERE 1 = 2') || + !mysqli_stmt_execute($stmt)) + printf("[036] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + /* use it like num_rows */ + if (-1 !== ($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[037] Expecting int/-1, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_stmt_store_result($stmt))) + printf("[038] Expecting boolean/true, got %s\%s\n", gettype($tmp), $tmp); + + if (0 !== ($tmp = mysqli_stmt_num_rows($stmt))) + printf("[039] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + if (0 !== ($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[040] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + /* try to use stmt_affected_rows like stmt_num_rows */ + /* stmt_affected_rows is not really meant for SELECT! */ + if (mysqli_stmt_prepare($stmt, 'SELECT unknown_column FROM this_table_does_not_exist') || + mysqli_stmt_execute($stmt)) + printf("[041] The invalid SELECT statement is issued on purpose\n"); + + if (-1 !== ($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[042] Expecting int/-1, got %s/%s\n", gettype($tmp), $tmp); + + if ($IS_MYSQLND) { + if (false !== ($tmp = mysqli_stmt_store_result($stmt))) + printf("[043] Expecting boolean/false, got %s\%s\n", gettype($tmp), $tmp); + } else { + if (true !== ($tmp = mysqli_stmt_store_result($stmt))) + printf("[043] Libmysql does not care if the previous statement was bogus, expecting boolean/true, got %s\%s\n", gettype($tmp), $tmp); + } + + if (0 !== ($tmp = mysqli_stmt_num_rows($stmt))) + printf("[044] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + if (-1 !== ($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[045] Expecting int/-1, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + $stmt = mysqli_stmt_init($link); + + if (!mysqli_stmt_prepare($stmt, "DROP TABLE IF EXISTS test") || + !mysqli_stmt_execute($stmt)) + printf("[046] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + mysqli_stmt_close($stmt); + + if (!is_null($tmp = mysqli_stmt_affected_rows($stmt))) + printf("[047] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +[009] [%d] (error message varies with the MySQL Server version, check the error code) + +Warning: mysqli_stmt_affected_rows(): Couldn't fetch mysqli_stmt in %s on line %d +done! diff --git a/ext/mysqli/tests/mysqli_stmt_attr_get.phpt b/ext/mysqli/tests/mysqli_stmt_attr_get.phpt new file mode 100644 index 0000000..a4eb4d0 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_attr_get.phpt @@ -0,0 +1,70 @@ +--TEST-- +mysqli_stmt_attr_get() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_attr_get())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_attr_get($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_attr_get($link, $link))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!is_null($tmp = @mysqli_stmt_attr_get($link, $link))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + $valid_attr = array("max_length" => MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH); + if (mysqli_get_client_version() > 50003) + $valid_attr["cursor_type"] = MYSQLI_STMT_ATTR_CURSOR_TYPE; + + if ($IS_MYSQLND && mysqli_get_client_version() > 50007) + $valid_attr["prefetch_rows"] = MYSQLI_STMT_ATTR_PREFETCH_ROWS; + + do { + $invalid_attr = mt_rand(0, 10000); + } while (in_array($invalid_attr, $valid_attr)); + + $stmt = mysqli_stmt_init($link); + mysqli_stmt_prepare($stmt, 'SELECT * FROM test'); + if (false !== ($tmp = @mysqli_stmt_attr_get($stmt, $invalid_attr))) + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + foreach ($valid_attr as $k => $attr) { + if (false === ($tmp = mysqli_stmt_attr_get($stmt, $attr))) { + printf("[006] Expecting any type, but not boolean/false, got %s/%s for attribute %s/%s\n", + gettype($tmp), $tmp, $k, $attr); + } + } + + $stmt->close(); + + foreach ($valid_attr as $k => $attr) { + if (!is_null($tmp = @mysqli_stmt_attr_get($stmt, $attr))) { + printf("[007] Expecting NULL/NULL, got %s/%s for attribute %s/%s\n", + gettype($tmp), $tmp, $k, $attr); + } + } + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done! diff --git a/ext/mysqli/tests/mysqli_stmt_attr_get_prefetch.phpt b/ext/mysqli/tests/mysqli_stmt_attr_get_prefetch.phpt new file mode 100644 index 0000000..0d5e8f9 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_attr_get_prefetch.phpt @@ -0,0 +1,29 @@ +--TEST-- +mysqli_stmt_attr_get() - prefetch +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +die("SKIP: prefetch isn't supported at the moment"); +?> +--FILE-- +<?php + require('table.inc'); + + $stmt = mysqli_stmt_init($link); + mysqli_stmt_prepare($stmt, 'SELECT * FROM test'); + if (1 !== ($tmp = mysqli_stmt_attr_get($stmt, MYSQLI_STMT_ATTR_PREFETCH_ROWS))) { + printf("[001] Expecting int/1, got %s/%s for attribute %s/%s\n", + gettype($tmp), $tmp, $k, $attr); + } + $stmt->close(); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_attr_set.phpt b/ext/mysqli/tests/mysqli_stmt_attr_set.phpt new file mode 100644 index 0000000..c2ddd21 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_attr_set.phpt @@ -0,0 +1,277 @@ +--TEST-- +mysqli_stmt_attr_set() - mysqlnd does not check for invalid codes +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_attr_set())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_attr_set($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_attr_set($link, $link))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_attr_set($link, $link, $link))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + $valid_attr = array(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH); + if ((mysqli_get_client_version() > 50003) || $IS_MYSQLND) { + $valid_attr[] = MYSQLI_STMT_ATTR_CURSOR_TYPE; + $valid_attr[] = MYSQLI_CURSOR_TYPE_NO_CURSOR; + $valid_attr[] = MYSQLI_CURSOR_TYPE_READ_ONLY; + $valid_attr[] = MYSQLI_CURSOR_TYPE_FOR_UPDATE; + $valid_attr[] = MYSQLI_CURSOR_TYPE_SCROLLABLE; + } + + if ((mysqli_get_client_version() > 50007) || $IS_MYSQLND) + $valid_attr[] = MYSQLI_STMT_ATTR_PREFETCH_ROWS; + + + $stmt = mysqli_stmt_init($link); + if (!is_null($tmp = @mysqli_stmt_attr_set($stmt, 0, 0))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + $stmt->prepare("SELECT * FROM test"); + + mt_srand(microtime(true)); + + for ($i = -100; $i < 1000; $i++) { + if (in_array($i, $valid_attr)) + continue; + $invalid_attr = $i; + if (false !== ($tmp = @mysqli_stmt_attr_set($stmt, $invalid_attr, 0))) { + printf("[006a] Expecting boolean/false for attribute %d, got %s/%s\n", $invalid_attr, gettype($tmp), $tmp); + } + } + + for ($i = 0; $i < 2; $i++) { + do { + $invalid_attr = mt_rand(-1 * (min(4294967296, PHP_INT_MAX) + 1), min(4294967296, PHP_INT_MAX)); + } while (in_array($invalid_attr, $valid_attr)); + if (false !== ($tmp = @mysqli_stmt_attr_set($stmt, $invalid_attr, 0))) { + printf("[006b] Expecting boolean/false for attribute %d, got %s/%s\n", $invalid_attr, gettype($tmp), $tmp); + } + } + $stmt->close(); + + // + // MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH + // + + + // expecting max_length not to be set and be 0 in all cases + $stmt = mysqli_stmt_init($link); + $stmt->prepare("SELECT label FROM test"); + $stmt->execute(); + $stmt->store_result(); + $res = $stmt->result_metadata(); + $fields = $res->fetch_fields(); + $max_lengths = array(); + foreach ($fields as $k => $meta) { + $max_lengths[$meta->name] = $meta->max_length; + if ($meta->max_length !== 0) + printf("[007] max_length should be not set (= 0), got %s for field %s\n", $meta->max_length, $meta->name); + } + $res->close(); + $stmt->close(); + + // expecting max_length to _be_ set + $stmt = mysqli_stmt_init($link); + $stmt->prepare("SELECT label FROM test"); + $stmt->attr_set(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, 1); + $res = $stmt->attr_get(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH); + if ($res !== 1) + printf("[007.1] max_length should be 1, got %s\n", $res); + $stmt->execute(); + $stmt->store_result(); + $res = $stmt->result_metadata(); + $fields = $res->fetch_fields(); + $max_lengths = array(); + foreach ($fields as $k => $meta) { + $max_lengths[$meta->name] = $meta->max_length; + if ($meta->max_length === 0) + printf("[008] max_length should be set (!= 0), got %s for field %s\n", $meta->max_length, $meta->name); + } + $res->close(); + $stmt->close(); + + // expecting max_length not to be set + $stmt = mysqli_stmt_init($link); + $stmt->prepare("SELECT label FROM test"); + $stmt->attr_set(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, 0); + $res = $stmt->attr_get(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH); + if ($res !== 0) + printf("[008.1] max_length should be 0, got %s\n", $res); + $stmt->execute(); + $stmt->store_result(); + $res = $stmt->result_metadata(); + $fields = $res->fetch_fields(); + $max_lengths = array(); + foreach ($fields as $k => $meta) { + $max_lengths[$meta->name] = $meta->max_length; + if ($meta->max_length !== 0) + printf("[009] max_length should not be set (= 0), got %s for field %s\n", $meta->max_length, $meta->name); + } + $res->close(); + $stmt->close(); + + // + // Cursors + // + + if (mysqli_get_client_version() > 50003) { + + $cursor_types = array( + MYSQLI_CURSOR_TYPE_NO_CURSOR, + MYSQLI_CURSOR_TYPE_READ_ONLY, + MYSQLI_CURSOR_TYPE_FOR_UPDATE, + MYSQLI_CURSOR_TYPE_SCROLLABLE + ); + do { + $invalid_cursor_type = mt_rand(-1000, 1000); + } while (in_array($invalid_cursor_type, $cursor_types)); + + $stmt = mysqli_stmt_init($link); + $stmt->prepare("SELECT id, label FROM test"); + + if (false !== ($tmp = @$stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, $invalid_cursor_type))) + printf("[010] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_FOR_UPDATE))) + printf("[011] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_SCROLLABLE))) + printf("[012] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_NO_CURSOR))) + printf("[013] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_READ_ONLY))) + printf("[014] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + $stmt->close(); + + $stmt = mysqli_stmt_init($link); + $stmt->prepare("SELECT id, label FROM test"); + $stmt->execute(); + $id = $label = NULL; + $stmt->bind_result($id, $label); + $results = array(); + while ($stmt->fetch()) + $results[$id] = $label; + $stmt->close(); + if (empty($results)) + printf("[015] Results should not be empty, subsequent tests will probably fail!\n"); + + $stmt = mysqli_stmt_init($link); + $stmt->prepare("SELECT id, label FROM test"); + if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_NO_CURSOR))) + printf("[016] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + $stmt->execute(); + $id = $label = NULL; + $stmt->bind_result($id, $label); + $results2 = array(); + while ($stmt->fetch()) + $results2[$id] = $label; + $stmt->close(); + if ($results != $results2) { + printf("[017] Results should not differ. Dumping both result sets.\n"); + var_dump($results); + var_dump($results2); + } + + $stmt = mysqli_stmt_init($link); + $stmt->prepare("SELECT id, label FROM test"); + if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_READ_ONLY))) + printf("[018] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + $stmt->execute(); + $id = $label = NULL; + $stmt->bind_result($id, $label); + $results2 = array(); + while ($stmt->fetch()) + $results2[$id] = $label; + $stmt->close(); + if ($results != $results2) { + printf("[019] Results should not differ. Dumping both result sets.\n"); + var_dump($results); + var_dump($results2); + } + + } + + + // + // MYSQLI_STMT_ATTR_PREFETCH_ROWS + // + + if (mysqli_get_client_version() > 50007) { + + $stmt = mysqli_stmt_init($link); + $stmt->prepare("SELECT id, label FROM test"); + if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, 1))) + printf("[020] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + $stmt->execute(); + $id = $label = NULL; + $stmt->bind_result($id, $label); + $results = array(); + while ($stmt->fetch()) + $results[$id] = $label; + $stmt->close(); + if (empty($results)) + printf("[021] Results should not be empty, subsequent tests will probably fail!\n"); + + /* prefetch is not supported + $stmt = mysqli_stmt_init($link); + $stmt->prepare("SELECT label FROM test"); + if (false !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, -1))) + printf("[022] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + $stmt->close(); + + $stmt = mysqli_stmt_init($link); + $stmt->prepare("SELECT label FROM test"); + if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, PHP_INT_MAX))) + printf("[023] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + $stmt->close(); + + $stmt = mysqli_stmt_init($link); + $stmt->prepare("SELECT id, label FROM test"); + if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, 2))) + printf("[024] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + $stmt->execute(); + $id = $label = NULL; + $stmt->bind_result($id, $label); + $results2 = array(); + while ($stmt->fetch()) + $results2[$id] = $label; + $stmt->close(); + if ($results != $results2) { + printf("[025] Results should not differ. Dumping both result sets.\n"); + var_dump($results); + var_dump($results2); + } + */ + + } + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done! diff --git a/ext/mysqli/tests/mysqli_stmt_bind_limits.phpt b/ext/mysqli/tests/mysqli_stmt_bind_limits.phpt new file mode 100644 index 0000000..39c6020 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_bind_limits.phpt @@ -0,0 +1,129 @@ +--TEST-- +Bind limits +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + function bind_many($offset, $link, $num_params, $rows, $eval = true) { + + $drop = "DROP TABLE IF EXISTS test"; + $create = "CREATE TABLE test(id INT AUTO_INCREMENT PRIMARY KEY, "; + $insert = "INSERT INTO test"; + $columns = ""; + $values = ""; + $stmt_params = ""; + $params = array(); + for ($i = 0; $i < $num_params; $i++) { + $create .= "col" . $i . " INT, "; + $columns .= "col" . $i . ", "; + $values .= "?, "; + $stmt_params .= '$params[' . $i . '], '; + for ($j = 0; $j < $rows; $j++) + $params[($j * $rows) + $i] = $i; + } + $create = substr($create, 0, -2) . ")"; + + $stmt_types = str_repeat("i", $num_params * $rows); + $stmt_params = substr(str_repeat($stmt_params, $rows), 0, -2); + $values = substr($values, 0, -2); + $insert .= "(" . substr($columns, 0, -2) . ") VALUES "; + $insert .= substr(str_repeat("(" . $values . "), ", $rows), 0, -2); + + $stmt_bind_param = 'return mysqli_stmt_bind_param($stmt, "' . $stmt_types . '", ' . $stmt_params . ');'; + + printf("Testing %d columns with %d rows...\n", $num_params, $rows); + + if (!$link->query($drop) || !$link->query($create)) { + printf("[%03d + 01] [%d] %s\n", $offset, $link->errno, $link->error); + return false; + } + printf("... table created\n"); + + if (!$stmt = $link->prepare($insert)) { + printf("[%03d + 02] [%d] %s\n", $offset, $link->errno, $link->error); + return false; + } + if ($stmt->param_count != $num_params * $rows) { + printf("[%03d + 03] Parameter count should be %d but got %d\n", $offset, $num_params * $rows, $stmt->param_count); + return false; + } + printf("... statement with %d parameters prepared\n", $stmt->param_count); + + if ($eval) { + if (!eval($stmt_bind_param)) { + printf("[%03d + 03] [%d] %s\n", $offset, $stmt->errno, $stmt->error); + return false; + } + } else { + $param_ref = array($stmt_types); + for ($i = 0; $i < $rows; $i++) + for ($j = 0; $j < $num_params; $j++) + $param_ref[] = &$params[($i * $rows) + $j]; + + if (!call_user_func_array(array($stmt, 'bind_param'), $param_ref)) { + printf("[%03d + 03] [%d] %s\n", $offset, $stmt->errno, $stmt->error); + return false; + } + } + if ($stmt->param_count != $num_params * $rows) { + printf("[%03d + 03] Parameter count should be %d but got %d\n", $offset, $num_params * $rows, $stmt->param_count); + return false; + } + + if (!$stmt->execute()) { + printf("[%03d + 04] [%d] %s\n", $offset, $stmt->errno, $stmt->error); + return false; + } + printf("Statement done\n"); + + $stmt->close(); + + if (!($res = $link->query("SELECT * FROM test"))) { + printf("[%03d + 05] [%d] %s\n", $offset, $link->errno, $link->error); + return false; + } + + $row = $res->fetch_row(); + $res->close(); + + for ($i = 0; $i < $num_params; $i++) { + if ($row[$i + 1] != $i) { + printf("[%03d + 06] [%d] %s\n", $offset, $link->errno, $link->error); + } + } + + return true; + } + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } + + var_dump(bind_many(10, $link, 273, 240, true)); + var_dump(bind_many(20, $link, 273, 240, false)); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +Testing 273 columns with 240 rows... +... table created +... statement with 65520 parameters prepared +Statement done +bool(true) +Testing 273 columns with 240 rows... +... table created +... statement with 65520 parameters prepared +Statement done +bool(true) +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_bind_param.phpt b/ext/mysqli/tests/mysqli_stmt_bind_param.phpt new file mode 100644 index 0000000..d2d8254 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_bind_param.phpt @@ -0,0 +1,404 @@ +--TEST-- +mysqli_stmt_bind_param() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + /* + The way we test the INSERT and data types overlaps with + the mysqli_stmt_bind_result test in large parts. There is only + one difference. This test uses mysqli_query()/mysqli_fetch_assoc() to + fetch the inserted values. This way we test + mysqli_query()/mysqli_fetch_assoc() for all possible data types + in this file and we test mysqli_stmt_bind_result() in the other + test -- therefore the "duplicate" makes some sense to me. + */ + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_bind_param())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_bind_param($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_bind_param($link, $link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + $stmt = mysqli_stmt_init($link); + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)")) + printf("[003] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = null; + $label = null; + + /* + libmysql gives a less descriptive error message but mysqlnd, + we did not unify the error messages but ignore this slight difference silently + */ + if (!false === ($tmp = @mysqli_stmt_bind_param($stmt, " ", $tmp))) + printf("[003d] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (!false === ($tmp = @mysqli_stmt_bind_param($stmt, "", $id, $label))) + printf("[003a] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + /* TODO: somehwhat undocumented syntax! */ + $param = array($id); + if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "is", $param))) + printf("[003b] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + $param = array($id, $label, $id); + if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "is", $param))) + printf("[003c] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "a", $id))) + printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "a", $id, $label))) + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "aa", $id, $label))) + printf("[006] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "ia", $id, $label))) + printf("[007] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (!true === ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label))) + printf("[008] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (function_exists("memory_get_usage")) { + $mem = memory_get_usage(); + for ($i = 0; $i < 20000; $i++) { + if (!true === ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label))) + printf("[008][$i] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + } + if (($tmp = (memory_get_usage() - $mem)) > 600) + printf("[009] Function seems to be leaking, because it used %d bytes. During tests it used only 92 bytes.", $tmp); + } + + $id = 100; + $label = "z"; + if (!mysqli_stmt_execute($stmt)) + printf("[010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + mysqli_stmt_close($stmt); + + if (!($res = mysqli_query($link, "SELECT id, label FROM test WHERE id = " . $id))) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + $row = mysqli_fetch_assoc($res); + if (($row['id'] != $id) || ($row['label'] != $label)) + printf("[012] Expecting '%s'/%s', got '%s'/%s'!\n", $id, $label, $row['id'], $row['label']); + mysqli_free_result($res); + + function func_mysqli_stmt_bind_datatype($link, $engine, $bind_type, $sql_type, $bind_value, $offset, $alternative = null) { + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) { + printf("[%03d] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!mysqli_query($link, sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { + // don't bail - it might be that the server does not support the data type + return false; + } + + if (!$stmt = mysqli_stmt_init($link)) { + printf("[%03d] [%d] %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUE (?, ?)")) { + printf("[%03d] [%d] %s\n", $offset + 2, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + $id = 1; + if (!mysqli_stmt_bind_param($stmt, "i" . $bind_type, $id, $bind_value)) { + printf("[%03d] [%d] %s\n", $offset + 3, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if (!mysqli_stmt_execute($stmt)) { + printf("[%03d] [%d] %s\n", $offset + 4, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + mysqli_stmt_close($stmt); + + if (!$res = mysqli_query($link, "SELECT id, label FROM test")) { + printf("[%03d] [%d] %s\n", $offset + 5, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!$row = mysqli_fetch_assoc($res)) { + printf("[%03d] [%d] %s\n", $offset + 5, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if ($alternative) { + if (($row['id'] != $id) || (($row['label'] != $bind_value) && ($row['label'] != $alternative))) { + printf("[%03d] Testing '%s', '%s': expecting '%s'/'%s' (%s), got '%s'/'%s'\n", + $offset + 6, $bind_type, $sql_type, + $id, $bind_value, gettype($bind_value), $row['id'], $row['label']); + return false; + } + } else { + if (($row['id'] != $id) || ($row['label'] != $bind_value)) { + printf("[%03d] Testing '%s', '%s': expecting '%s'/'%s', got '%s'/'%s'\n", + $offset + 6, $bind_type, $sql_type, + $id, $bind_value, $row['id'], $row['label']); + return false; + } + } + + mysqli_free_result($res); + return true; + } + + function func_mysqli_stmt_bind_make_string($len) { + + $ret = ''; + for ($i = 0; $i < $len; $i++) + $ret .= chr(mt_rand(65, 90)); + + return $ret; + } + + func_mysqli_stmt_bind_datatype($link, $engine, "i", "TINYINT", -11, 20); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "TINYINT", NULL, 30); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "TINYINT UNSIGNED", 1, 40); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "TINYINT UNSIGNED", NULL, 50); + + func_mysqli_stmt_bind_datatype($link, $engine, "i", "BOOL", 1, 60); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "BOOL", NULL, 70); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "BOOLEAN", 0, 80); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "BOOLEAN", NULL, 90); + + func_mysqli_stmt_bind_datatype($link, $engine, "i", "SMALLINT", -32768, 100); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "SMALLINT", 32767, 110); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "SMALLINT", NULL, 120); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "SMALLINT UNSIGNED", 65535, 130); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "SMALLINT UNSIGNED", NULL, 140); + + func_mysqli_stmt_bind_datatype($link, $engine, "i", "MEDIUMINT", -8388608, 150); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "MEDIUMINT", 8388607, 160); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "MEDIUMINT", NULL, 170); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "MEDIUMINT UNSIGNED", 16777215, 180); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "MEDIUMINT UNSIGNED", NULL, 190); + + func_mysqli_stmt_bind_datatype($link, $engine, "i", "INTEGER", -2147483648, 200); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "INTEGER", 2147483647, 210); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "INTEGER", NULL, 220); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "INTEGER UNSIGNED", (defined("PHP_INT_MAX")) ? min(4294967295, PHP_INT_MAX) : 1, 230); + func_mysqli_stmt_bind_datatype($link, $engine, "d", "INTEGER UNSIGNED", 4294967295, 240); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "INTEGER UNSIGNED", NULL, 250); + + func_mysqli_stmt_bind_datatype($link, $engine, "i", "BIGINT", -1 * PHP_INT_MAX + 1, 260); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "BIGINT", NULL, 270); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "BIGINT", PHP_INT_MAX, 280); + func_mysqli_stmt_bind_datatype($link, $engine, "i", "BIGINT UNSIGNED", NULL, 290); + + func_mysqli_stmt_bind_datatype($link, $engine, "s", "BIGINT", "-9223372036854775808", 900); + // ?? func_mysqli_stmt_bind_datatype($link, $engine, "d", "BIGINT", -9223372036854775808, 910); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "BIGINT UNSIGNED", "18446744073709551615", 920); + +/* + ?? + func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT", -9223372036854775808 - 1.1, 300); + func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT UNSIGNED", 18446744073709551615 + 1.1, 320); + */ + func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT", NULL, 310); + func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT UNSIGNED ", NULL, 330); + if (2147483647 == PHP_INT_MAX) { + func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT UNSIGNED", PHP_INT_MAX, 930, '2.14748e+09'); + func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT", -1 * PHP_INT_MAX + 1, 940, '-2.14748e+09'); + } + func_mysqli_stmt_bind_datatype($link, $engine, "s", "FLOAT", "-9223372036854775808", 300, '-9.22337e+18'); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "FLOAT UNSIGNED", "18446744073709551615", 320, '1.84467e+19'); + func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT", -10.01, 950); + func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT UNSIGNED", 10.01, 960); + + func_mysqli_stmt_bind_datatype($link, $engine, "d", "DOUBLE(10,2)", NULL, 350); + func_mysqli_stmt_bind_datatype($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", NULL, 370); + func_mysqli_stmt_bind_datatype($link, $engine, "d", "DOUBLE(10,2)", -99999999.99, 340); + func_mysqli_stmt_bind_datatype($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", 99999999.99, 360); + + /* + func_mysqli_stmt_bind_datatype($link, $engine, "d", "DOUBLE(10,2)", -99999999.99, 340); + func_mysqli_stmt_bind_datatype($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", 99999999.99, 360); + */ + func_mysqli_stmt_bind_datatype($link, $engine, "d", "DECIMAL(10,2)", -99999999.99, 380); + func_mysqli_stmt_bind_datatype($link, $engine, "d", "DECIMAL(10,2)", NULL, 390); + func_mysqli_stmt_bind_datatype($link, $engine, "d", "DECIMAL(10,2)", 99999999.99, 400); + func_mysqli_stmt_bind_datatype($link, $engine, "d", "DECIMAL(10,2)", NULL, 410); + + // don't care about date() strict TZ warnings... + func_mysqli_stmt_bind_datatype($link, $engine, "s", "DATE", @date('Y-m-d'), 420); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "DATE NOT NULL", @date('Y-m-d'), 430); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "DATE", NULL, 440); + + func_mysqli_stmt_bind_datatype($link, $engine, "s", "DATETIME", @date('Y-m-d H:i:s'), 450); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "DATETIME NOT NULL", @date('Y-m-d H:i:s'), 460); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "DATETIME", NULL, 470); + + func_mysqli_stmt_bind_datatype($link, $engine, "s", "TIMESTAMP", @date('Y-m-d H:i:s'), 480); + + func_mysqli_stmt_bind_datatype($link, $engine, "s", "TIME", @date('H:i:s'), 490); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "TIME NOT NULL", @date('H:i:s'), 500); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "TIME", NULL, 510); + + func_mysqli_stmt_bind_datatype($link, $engine, "s", "YEAR", @date('Y'), 520); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "YEAR NOT NULL", @date('Y'), 530); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "YEAR", NULL, 540); + + $string255 = func_mysqli_stmt_bind_make_string(255); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "CHAR(1)", "a", 550); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "CHAR(255)", $string255, 560); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "CHAR(1) NOT NULL", "a", 570); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "CHAR(1)", NULL, 580); + + $string65k = func_mysqli_stmt_bind_make_string(65535); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARCHAR(1)", "a", 590); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARCHAR(255)", $string255, 600); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARCHAR(65635)", $string65k, 610); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARCHAR(1) NOT NULL", "a", 620); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARCHAR(1)", NULL, 630); + + func_mysqli_stmt_bind_datatype($link, $engine, "s", "BINARY(1)", "a", 640); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "BINARY(1)", chr(0), 650); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "BINARY(1) NOT NULL", "b", 660); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "BINARY(1)", NULL, 670); + + func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARBINARY(1)", "a", 680); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARBINARY(1)", chr(0), 690); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARBINARY(1) NOT NULL", "b", 700); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARBINARY(1)", NULL, 710); + + func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYBLOB", "a", 720); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYBLOB", chr(0), 730); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYBLOB NOT NULL", "b", 740); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYBLOB", NULL, 750); + + func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYTEXT", "a", 760); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYTEXT NOT NULL", "a", 770); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYTEXT", NULL, 780); + + // Note: you cannot insert any blob values this way. But you can check the API at least partly this way + // Extra BLOB tests are in mysqli_stmt_send_long() + func_mysqli_stmt_bind_datatype($link, $engine, "b", "BLOB", "", 790); + func_mysqli_stmt_bind_datatype($link, $engine, "b", "TEXT", "", 800); + func_mysqli_stmt_bind_datatype($link, $engine, "b", "MEDIUMBLOB", "", 810); + func_mysqli_stmt_bind_datatype($link, $engine, "b", "MEDIUMTEXT", "", 820); + func_mysqli_stmt_bind_datatype($link, $engine, "b", "LONGBLOB", "", 830); + func_mysqli_stmt_bind_datatype($link, $engine, "b", "LONGTEXT", "", 840); + + func_mysqli_stmt_bind_datatype($link, $engine, "s", "ENUM('a', 'b')", "a", 850); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "ENUM('a', 'b')", NULL, 860); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "SET('a', 'b')", "a", 870); + func_mysqli_stmt_bind_datatype($link, $engine, "s", "SET('a', 'b')", NULL, 880); + + if (mysqli_get_server_version($link) >= 50600) + func_mysqli_stmt_bind_datatype($link, $engine, "s", "TIME", "13:27:34.123456", 890, "13:27:34"); + + $stmt = mysqli_stmt_init($link); + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)")) + printf("[2000] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = null; + $label = null; + if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label))) + printf("[2001] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + mysqli_stmt_execute($stmt); + + if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label))) + printf("[2002] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + mysqli_stmt_close($stmt); + include("table.inc"); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[2003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)")) + printf("[2004] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $label = null; + if (true !== ($tmp = $stmt->bind_param('is', $id, $label))) + printf("[2005] Expecting boolean/true got %s/%s, [%d] %s\n", + gettype($tmp), $tmp, + $stmt->errno, $stmt->error); + + $id = 100; $label = 'z'; + if (!$stmt->execute()) + printf("[2006] [%d] %s\n", $stmt->errno, $stmt->error); + + if (!$res = mysqli_query($link, "SELECT id, label FROM test WHERE id = 100")) + printf("[2007] Expecting record 100/z, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[2008] Expecting row, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ($row['id'] != 100 || $row['label'] != 'z') { + printf("[2009] Row seems wrong, dumping record\n"); + var_dump($row); + } + mysqli_free_result($res); + + $value_list = array(array('id' => 101, 'label' => 'a'), array('id' => 102, 'label' => 'b')); + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)")) + printf("[2010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + foreach ($value_list as $k => $values) { + if (!mysqli_stmt_bind_param($stmt, 'is', $values['id'], $values['label'])) { + printf("[2011] bind_param() failed for id = %d, [%d] %s\n", + $values['id'], mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + continue; + } + if (!$stmt->execute()) + printf("[2012] [%d] execute() failed for id = %d, [%d] %s\n", + $values['id'], mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!$res = mysqli_query($link, sprintf("SELECT label FROM test WHERE id = %d", $values['id']))) + printf("[2013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + if (!$row = mysqli_fetch_assoc($res)) + printf("[2014] Cannot find row id = %d\n", $values['id']); + else if (isset($row['label']) && ($values['label'] != $row['label'])) + printf("[2015] Expecting label = %s, got label = %s\n", $values['label'], $row['label']); + + mysqli_free_result($res); + } + + mysqli_stmt_close($stmt); + mysqli_close($link); + + /* Check that the function alias exists. It's a deprecated function, + but we have not announce the removal so far, therefore we need to check for it */ + if (!is_null($tmp = @mysqli_stmt_bind_param())) + printf("[021] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_bind_param(): Number of elements in type definition string doesn't match number of bind variables in %s on line %d + +Warning: mysqli_stmt_bind_param(): Number of elements in type definition string doesn't match number of bind variables in %s on line %d + +Warning: mysqli_stmt_bind_param(): Number of variables doesn't match number of parameters in prepared statement in %s on line %d + +Warning: mysqli_stmt_bind_param(): Number of elements in type definition string doesn't match number of bind variables in %s on line %d + +Warning: mysqli_stmt_bind_param(): Undefined fieldtype a (parameter 3) in %s on line %d + +Warning: mysqli_stmt_bind_param(): Undefined fieldtype a (parameter 4) in %s on line %d +done! diff --git a/ext/mysqli/tests/mysqli_stmt_bind_param_call_user_func.phpt b/ext/mysqli/tests/mysqli_stmt_bind_param_call_user_func.phpt new file mode 100644 index 0000000..8f4a989 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_bind_param_call_user_func.phpt @@ -0,0 +1,366 @@ +--TEST-- +mysqli_stmt_bind_param used with call_user_func_array() (see also bug #43568) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +// TODO remove once a decision has been made on call_user_func_array() +if (version_compare(PHP_VERSION, '5.3.0-dev') == -1) + die("skip needs PHP 5.3.0-dev+, see http://bugs.php.net/bug.php?id=43568"); +?> +--FILE-- +<?php + require('connect.inc'); + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?')) + printf("[002] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = 1; + if (!mysqli_stmt_bind_param($stmt, 'i', $id) || + !mysqli_stmt_execute($stmt)) + printf("[003] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $label = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label) || + (true !== mysqli_stmt_fetch($stmt))) + printf("[004] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + print "Regular, procedural, using variables\n"; + var_dump($id); + var_dump($label); + + mysqli_stmt_close($stmt); + if (!$stmt = mysqli_stmt_init($link)) + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?')) + printf("[006] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $types = 'i'; + $id = 1; + $params = array( + 0 => &$stmt, + 1 => &$types, + 2 => &$id + ); + if (!call_user_func_array('mysqli_stmt_bind_param', $params)) + printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $label = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label) || + (true !== mysqli_stmt_fetch($stmt))) + printf("[009] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + print "Call user func, procedural, using references for everything\n"; + var_dump($id); + var_dump($label); + + mysqli_stmt_close($stmt); + if (!$stmt = mysqli_stmt_init($link)) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?')) + printf("[011] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $types = 'i'; + $id = 1; + $params = array( + 0 => &$types, + 1 => &$id + ); + if (!call_user_func_array(array($stmt, 'bind_param'), $params)) + printf("[012] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[013] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $label = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label) || + (true !== mysqli_stmt_fetch($stmt))) + printf("[014] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + print "Call user func, object oriented, using references for everything\n"; + var_dump($id); + var_dump($label); + + mysqli_stmt_close($stmt); + if (!$stmt = mysqli_stmt_init($link)) + printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?')) + printf("[016] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $types = 'i'; + $id = 1; + $params = array( + 0 => $types, + 1 => &$id + ); + if (!call_user_func_array(array($stmt, 'bind_param'), $params)) + printf("[017] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[018] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $label = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label) || + (true !== mysqli_stmt_fetch($stmt))) + printf("[019] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + print "Call user func, object oriented, using variable for types. using references for bound parameter\n"; + var_dump($id); + var_dump($label); + + mysqli_stmt_close($stmt); + if (!$stmt = mysqli_stmt_init($link)) + printf("[020] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?')) + printf("[021] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = 1; + $params = array( + 0 => 'i', + 1 => &$id + ); + if (!call_user_func_array(array($stmt, 'bind_param'), $params)) + printf("[022] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[023] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $label = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label) || + (true !== mysqli_stmt_fetch($stmt))) + printf("[024] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + print "Call user func, object oriented, using constant for types. using references for bound parameter\n"; + var_dump($id); + var_dump($label); + + mysqli_stmt_close($stmt); + if (!$stmt = mysqli_stmt_init($link)) + printf("[025] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?')) + printf("[026] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $types = 'i'; + $id = 1; + $params = array( + 0 => &$stmt, + 1 => $types, + 2 => &$id + ); + if (!call_user_func_array('mysqli_stmt_bind_param', $params)) + printf("[027] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[028] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $label = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label) || + (true !== mysqli_stmt_fetch($stmt))) + printf("[029] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + print "Call user func, procedural, using references for everything but using variable for types\n"; + var_dump($id); + var_dump($label); + + mysqli_stmt_close($stmt); + if (!$stmt = mysqli_stmt_init($link)) + printf("[025] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?')) + printf("[026] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $types = 'i'; + $id = 1; + $params = array( + 0 => $stmt, + 1 => $types, + 2 => &$id + ); + if (!call_user_func_array('mysqli_stmt_bind_param', $params)) + printf("[027] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[028] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $label = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label) || + (true !== mysqli_stmt_fetch($stmt))) + printf("[029] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + print "Call user func, procedural, using references for bound parameter, using variables for resource and types\n"; + var_dump($id); + var_dump($label); + + mysqli_stmt_close($stmt); + if (!$stmt = mysqli_stmt_init($link)) + printf("[030] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?')) + printf("[031] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $types = 'i'; + $id = 1; + $params = array( + 0 => $stmt, + 1 => $types, + 2 => &$id + ); + if (!call_user_func_array('mysqli_stmt_bind_param', $params)) + printf("[032] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[033] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $label = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label) || + (true !== mysqli_stmt_fetch($stmt))) + printf("[034] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + print "Call user func, procedural, using references for bound parameter, using variables for resource and types\n"; + var_dump($id); + var_dump($label); + + mysqli_stmt_close($stmt); + if (!$stmt = mysqli_stmt_init($link)) + printf("[035] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?')) + printf("[036] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = 1; + $params = array( + 0 => $stmt, + 1 => 'i', + 2 => &$id + ); + if (!call_user_func_array('mysqli_stmt_bind_param', $params)) + printf("[037] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[038] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $label = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label) || + (true !== mysqli_stmt_fetch($stmt))) + printf("[039] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + print "Call user func, procedural, using references for bound parameter, using variable for resource, using constant for types\n"; + var_dump($id); + var_dump($label); + + mysqli_stmt_close($stmt); + if (!$stmt = mysqli_stmt_init($link)) + printf("[040] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?')) + printf("[041] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = 1; + if (!call_user_func_array('mysqli_stmt_bind_param', array($stmt, 'i', &$id))) + printf("[042] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[043] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $label = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label) || + (true !== mysqli_stmt_fetch($stmt))) + printf("[044] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + print "Call user func, procedural, using references for bound parameter, using variable for resource, using constant for types, array\n"; + var_dump($id); + var_dump($label); + + // + // Any of those shall fail - see also bugs.php.net/43568 + // + mysqli_stmt_close($stmt); + if (!$stmt = mysqli_stmt_init($link)) + printf("[045] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?')) + printf("[046] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = 1; + $params = array( + 0 => 'i', + 1 => &$id + ); + if (!call_user_func_array(array($stmt, 'bind_param'), $params)) + printf("[047] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[048] [%d] (Message might vary with MySQL Server version, e.g. No data supplied for parameters in prepared statement)\n", mysqli_stmt_errno($stmt)); + + mysqli_stmt_close($stmt); + if (!$stmt = mysqli_stmt_init($link)) + printf("[049] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?')) + printf("[050] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $types = 'i'; + $id = 1; + $params = array( + 0 => $stmt, + 1 => 'i', + 2 => &$id + ); + if (!call_user_func_array('mysqli_stmt_bind_param', $params)) + printf("[051] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[052] [%d] (Message might vary with MySQL Server version, e.g. No data supplied for parameters in prepared statement)\n", mysqli_stmt_errno($stmt)); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Regular, procedural, using variables +int(1) +%unicode|string%(1) "a" +Call user func, procedural, using references for everything +int(1) +%unicode|string%(1) "a" +Call user func, object oriented, using references for everything +int(1) +%unicode|string%(1) "a" +Call user func, object oriented, using variable for types. using references for bound parameter +int(1) +%unicode|string%(1) "a" +Call user func, object oriented, using constant for types. using references for bound parameter +int(1) +%unicode|string%(1) "a" +Call user func, procedural, using references for everything but using variable for types +int(1) +%unicode|string%(1) "a" +Call user func, procedural, using references for bound parameter, using variables for resource and types +int(1) +%unicode|string%(1) "a" +Call user func, procedural, using references for bound parameter, using variables for resource and types +int(1) +%unicode|string%(1) "a" +Call user func, procedural, using references for bound parameter, using variable for resource, using constant for types +int(1) +%unicode|string%(1) "a" +Call user func, procedural, using references for bound parameter, using variable for resource, using constant for types, array +int(1) +%unicode|string%(1) "a" +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_bind_param_check_param_no_change.phpt b/ext/mysqli/tests/mysqli_stmt_bind_param_check_param_no_change.phpt new file mode 100644 index 0000000..03d1590 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_bind_param_check_param_no_change.phpt @@ -0,0 +1,110 @@ +--TEST-- +mysqli_stmt_bind_param() - checking whether the parameters are modified (bug#44390) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require('table.inc'); + $link->set_charset('latin1'); + + class foo { + // @var $bar string + public $bar; + } + + $foo = new foo; + $foo->bar = "фубар"; + + echo "Test 1:\n"; + $stmt = $link->prepare("SELECT ? FOO"); + var_dump($foo); // here you can see the bar member var beeing a string + $stmt->bind_param("s", $foo->bar); + var_dump($foo); // this will show $foo->bar beeing a reference string + $stmt->bind_result($one); + $stmt->execute(); + $stmt->fetch(); + $stmt->free_result(); + echo("$one\n\n"); + + // it is getting worse. Binding the same var twice with different + // types you can get unexpected results (e.g. binary trash for the + // string and misc data for the integer. See next 2 tests. + + echo "Test 2:\n"; + $stmt = $link->prepare("SELECT ? FOO, ? BAR"); + var_dump($foo); + $stmt->bind_param("si", $foo->bar, $foo->bar); + echo "---\n"; + var_dump($foo); + echo "---\n"; + $stmt->execute(); + var_dump($foo); + echo "---\n"; + $stmt->bind_result($one, $two); + $stmt->fetch(); + $stmt->free_result(); + echo("$one - $two\n\n"); + + + echo "Test 3:\n"; + $stmt = $link->prepare("SELECT ? FOO, ? BAR"); + var_dump($foo); + $stmt->bind_param("is", $foo->bar, $foo->bar); + var_dump($foo); + $stmt->bind_result($one, $two); + $stmt->execute(); + $stmt->fetch(); + $stmt->free_result(); + echo("$one - $two\n\n"); + echo "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Test 1: +object(foo)#%d (1) { + [%u|b%"bar"]=> + %unicode|string%(%d) "фубар" +} +object(foo)#%d (1) { + [%u|b%"bar"]=> + &%unicode|string%(%d) "фубар" +} +фубар + +Test 2: +object(foo)#%d (1) { + [%u|b%"bar"]=> + %unicode|string%(%d) "фубар" +} +--- +object(foo)#%d (1) { + [%u|b%"bar"]=> + &%unicode|string%(%d) "фубар" +} +--- +object(foo)#%d (1) { + [%u|b%"bar"]=> + &%unicode|string%(%d) "фубар" +} +--- +фубар - 0 + +Test 3: +object(foo)#%d (1) { + [%u|b%"bar"]=> + %unicode|string%(%d) "фубар" +} +object(foo)#%d (1) { + [%u|b%"bar"]=> + &%unicode|string%(%d) "фубар" +} +0 - фубар + +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_bind_param_many_columns.phpt b/ext/mysqli/tests/mysqli_stmt_bind_param_many_columns.phpt new file mode 100644 index 0000000..29a5ee3 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_bind_param_many_columns.phpt @@ -0,0 +1,103 @@ +--TEST-- +mysqli_stmt_bind_param() - Binding with very high number of columns +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +memory_limit=256M +--FILE-- +<?php + /* + The way we test the INSERT and data types overlaps with + the mysqli_stmt_bind_result test in large parts. There is only + one difference. This test uses mysqli_query()/mysqli_fetch_assoc() to + fetch the inserted values. This way we test + mysqli_query()/mysqli_fetch_assoc() for all possible data types + in this file and we test mysqli_stmt_bind_result() in the other + test -- therefore the "duplicate" makes some sense to me. + */ + require_once("connect.inc"); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + exit(1); + } + + $cols = 2500; + + list($old_max_allowed_packet) = $link->query("SELECT @@max_allowed_packet")->fetch_row(); + if (!$link->query("SET GLOBAL max_allowed_packet=(2<<29)")) { + if (1227 == mysqli_errno($link)) { + /* [1227] Access denied; you need the SUPER privilege for this operation */ + $cols = 10; + } else { + $cols = 10; + printf("[002] Failed to set max_allowed_packet the test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + } + mysqli_close($link); + + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + exit(1); + } + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { + printf("Failed to drop old test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + exit(1); + } + + $str = array(); + for ($i = 1; $i <= $cols; $i++) { + $str[] ="a$i BLOB"; + } + $link->query("CREATE TABLE test(" . implode(" , ", $str) . ") ENGINE=MyISAM"); + if (mysqli_errno($link)) { + printf("Failed to create the test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + die(""); + } + $stmt = $link->prepare("INSERT INTO test VALUES(".str_repeat("?, ", $cols-1) . "?)"); + var_dump($stmt->id); + $s = str_repeat("a", 2 << 12); + $eval_str="\$stmt->bind_param(\"".str_repeat("s",$cols)."\", "; + for ($i = 1; $i < $cols; $i++) { + $eval_str.="\$s,"; + } + $eval_str.="\$s"; + $eval_str.=");"; + eval($eval_str); + printf("executing\n"); + if (!$stmt->execute()) { + printf("failed"); + printf("Failed to execute: [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } else { + var_dump(true); + } + + mysqli_stmt_close($stmt); + + + if (!$link->query("SET GLOBAL max_allowed_packet=$old_max_allowed_packet")) { + if (1227 != mysqli_errno($link)) + printf("Failed to set max_allowed_packet the test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +int(1) +executing +bool(true) +done! diff --git a/ext/mysqli/tests/mysqli_stmt_bind_param_references.phpt b/ext/mysqli/tests/mysqli_stmt_bind_param_references.phpt new file mode 100644 index 0000000..91cb9d0 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_bind_param_references.phpt @@ -0,0 +1,207 @@ +--TEST-- +mysqli_stmt_bind_param() - playing with references +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require('table.inc'); + + function findRow($offset, $link, $id, $label) { + + $sql = sprintf("SELECT id, label FROM test WHERE id = '%d' AND label = '%s'", + $id, $label); + if (!$res = mysqli_query($link, $sql)) { + printf("[%03d + 1] %s failed, [%d] %s\n", + $offset, $sql, mysqli_errno($link), mysqli_error($link)); + return false; + } + if (!$row = mysqli_fetch_assoc($res)) { + printf("[%03d + 2] fetch for %s failed, [%d] %s\n", + $offset, $sql, mysqli_errno($link), mysqli_error($link)); + return false; + } + + mysqli_free_result($res); + if ($row['id'] != $id) { + printf("[%03d + 3] Expecting %s/%s got %s/%s\n", + $offset, gettype($id), $id, + gettype($row['id']), $row['id'] + ); + return false; + } + + if ($row['label'] != $label) { + printf("[%03d + 4] Expecting %s/%s got %s/%s\n", + $offset, gettype($label), $label, + gettype($row['label']), $row['label'] + ); + return false; + } + + $sql = sprintf("DELETE FROM test WHERE id = '%d' AND label = '%s'", + $id, $label); + if (!mysqli_query($link, $sql)) { + printf("[%03d + 5] %s failed, [%d] %s\n", + $offset, $sql, mysqli_errno($link), mysqli_error($link)); + return false; + } + + return true; + } + // or we will get dups around [28] + mysqli_query($link, "ALTER TABLE test DROP PRIMARY KEY"); + + $stmt = mysqli_stmt_init($link); + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)")) + printf("[001] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = 100; + $label = 'v'; + if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label))) + printf("[002] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== mysqli_stmt_execute($stmt)) + printf("[003] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + // no need to check the return value, will bail and make EXPECTF fail if need be + findRow(4, $link, $id, $label); + + $id++; + $label_ref = &$label; + $label = 'w'; + if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label_ref))) + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== mysqli_stmt_execute($stmt)) + printf("[006] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + findRow(7, $link, $id, $label_ref); + + $id++; + $label_ref_ref = &$label_ref; + $label = 'x'; + + if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label_ref_ref))) + printf("[007] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== mysqli_stmt_execute($stmt)) + printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + findRow(9, $link, $id, $label_ref_ref); + + $id = 9; + $label = $id; + $label_num = &$label; + + if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label_num))) + printf("[010] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== mysqli_stmt_execute($stmt)) + printf("[011] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + findRow(12, $link, $id, $label_num); + + $label_num = &$id; + if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label_num))) + printf("[013] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== mysqli_stmt_execute($stmt)) + printf("[014] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + findRow(15, $link, $id, $label_num); + + $label = 9; + $id = &$label; + + if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label))) + printf("[015] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== mysqli_stmt_execute($stmt)) + printf("[016] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + findRow(17, $link, $id, $label); + + $base = 9; + $id = &$base; + $label = &$id; + + if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label))) + printf("[018] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== mysqli_stmt_execute($stmt)) + printf("[019] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + findRow(20, $link, $id, $label); + + $id_ref = &$id; + $label_ref = &$label; + + if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id_ref, $label_ref))) + printf("[021] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== mysqli_stmt_execute($stmt)) + printf("[022] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + findRow(23, $link, $id_ref, $label_ref); + + $id_ref_ref = &$GLOBALS['id_ref']; + $label_ref_ref = &$GLOBALS['label_ref_ref']; + + if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id_ref_ref, $label_ref_ref))) + printf("[024] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== mysqli_stmt_execute($stmt)) + printf("[025] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + findRow(26, $link, $id_ref_ref, $label_ref_ref); + + unset($id); + unset($label); + $id = 102; + $label = new stdClass(); + $label->label = 'y'; + $id_ref = &$GLOBALS['id']; + $label_ref = &$label->label; + if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id_ref, $label_ref))) + printf("[027] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + if (true !== @mysqli_stmt_execute($stmt)) + printf("[028] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + findRow(29, $link, $id_ref, $label_ref); + + $id = 103; + $label_a = &$label_b; + $label_b = &$label_a; + $label_a = 'z'; + + if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label_b))) + printf("[030] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== mysqli_stmt_execute($stmt)) + printf("[031] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + findRow(32, $link, $id, $label_b); + + class foo { + public $foo; + function foo() { + $this->foo = &$this->bar; + } + } + class bar extends foo { + public $bar = 'v'; + } + $bar = new bar(); + $id++; + $label = &$GLOBALS['bar']->foo; + + if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label))) + printf("[033] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== mysqli_stmt_execute($stmt)) + printf("[034] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + findRow(35, $link, $id, $label); + + mysqli_stmt_close($stmt); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_bind_param_type_juggling.phpt b/ext/mysqli/tests/mysqli_stmt_bind_param_type_juggling.phpt new file mode 100644 index 0000000..daab40c --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_bind_param_type_juggling.phpt @@ -0,0 +1,127 @@ +--TEST-- +mysqli_stmt_bind_param() - binding variable twice +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require('table.inc'); + + function bind_twice($link, $engine, $sql_type1, $sql_type2, $bind_type1, $bind_type2, $bind_value1, $bind_value2, $offset) { + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) { + printf("[%03d + 1] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link)); + return false; + } + mysqli_autocommit($link, true); + + $sql = sprintf("CREATE TABLE test(col1 %s, col2 %s) ENGINE=%s", $sql_type1, $sql_type2, $engine); + if (!mysqli_query($link, $sql)) { + printf("[%03d + 2] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!$stmt = mysqli_stmt_init($link)) { + printf("[%03d + 3] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(col1, col2) VALUES (?, ?)")) { + printf("[%03d + 4] [%d] %s\n", $offset, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if (!mysqli_stmt_bind_param($stmt, $bind_type1 . $bind_type2, $bind_value1, $bind_value1)) { + printf("[%03d + 5] [%d] %s\n", $offset, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if (!mysqli_stmt_execute($stmt)) { + printf("[%03d + 6] [%d] %s\n", $offset, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if (!mysqli_stmt_bind_param($stmt, $bind_type1 . $bind_type2, $bind_value1, $bind_value2)) { + printf("[%03d + 7] [%d] %s\n", $offset, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + if (!mysqli_stmt_execute($stmt)) { + printf("[%03d + 8] [%d] %s\n", $offset, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + mysqli_stmt_close($stmt); + if (!$res = mysqli_query($link, "SELECT col1, col2 FROM test")) { + printf("[%03d + 9] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (2 !== ($tmp = mysqli_num_rows($res))) { + printf("[%03d + 10] Expecting 2 rows, got %d rows [%d] %s\n", $offset, $tmp, mysqli_errno($link), mysqli_error($link)); + } + + $row = mysqli_fetch_assoc($res); + if (($row['col1'] != $bind_value1) || ($row['col2'] != $bind_value1)) { + printf("[%03d + 11] Expecting col1 = %s, col2 = %s got col1 = %s, col2 = %s - [%d] %s\n", + $offset, $bind_value1, $bind_value1, + $row['col1'], $row['col2'], + mysqli_errno($link), mysqli_error($link)); + return false; + } + + $row = mysqli_fetch_assoc($res); + if (($row['col1'] != $bind_value1) || ($row['col2'] != $bind_value2)) { + printf("[%03d + 12] Expecting col1 = %s, col2 = %s got col1 = %s, col2 = %s - [%d] %s\n", + $offset, $bind_value1, $bind_value2, + $row['col1'], $row['col2'], + mysqli_errno($link), mysqli_error($link)); + return false; + } + mysqli_free_result($res); + return true; + } + + bind_twice($link, $engine, 'CHAR(1)', 'CHAR(1)', 's', 's', 'a', 'b', 10); + bind_twice($link, $engine, 'INT', 'INT', 'i', 'i', 1, 2, 20); + bind_twice($link, $engine, 'FLOAT', 'FLOAT', 'd', 'd', 1.01, 1.02, 30); + + /* type juggling - note that int->char works */ + bind_twice($link, $engine, 'CHAR(1)', 'CHAR(1)', 's', 's', 1, 2, 40); + /* type juggling - note that string->integer works */ + bind_twice($link, $engine, 'INT', 'INT', 'i', 'i', '1', '2', 50); + /* type juggling - note that string->float works*/ + bind_twice($link, $engine, 'FLOAT', 'FLOAT', 'd', 'd', '1.01', '1.02', 60); + + /* now, let's have two columns of different type and do type juggling */ + /* + what the test will do is: + 1) col1 INT, col2 CHAR(1) + 2) bind_param('is', 1, 1) + 3) execute() + 4) bind_param('is', 1, 'a') + 5) execute() + + col1 INT, col2 INT + bind_param('ii', '1', '2') --> OK (int column, string value) + bind_param('ii', 1, 2) --> OK (int column, int value) + col1 CHAR(1), col2 CHAR(2) + bind_param('ss', 1, 2) --> OK (string column, int value) + + So, what about: + col1 INT, COL2 CHAR(1) + bind_param('is', 1, 1) ---> ?? + */ + bind_twice($link, $engine, 'INT', 'CHAR(1)', 'i', 's', 1, 'a', 70); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_bind_result.phpt b/ext/mysqli/tests/mysqli_stmt_bind_result.phpt new file mode 100644 index 0000000..553e71a --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_bind_result.phpt @@ -0,0 +1,331 @@ +--TEST-- +mysqli_stmt_bind_result() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $hint_str_or_unicode = (version_compare(PHP_VERSION, '5.9.9', '>') == 1) ? "unicode":"string"; + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_bind_result())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_bind_result($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + $stmt = mysqli_stmt_init($link); + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 1")) + printf("[002a] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!is_null($tmp = @mysqli_stmt_bind_result($stmt))) + printf("[002b] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + $stmt = mysqli_stmt_init($link); + + $id = null; + $label = null; + $foo = null; + + if (!is_null($tmp = mysqli_stmt_bind_result($stmt))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 1")) + printf("[004] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (false !== ($tmp = mysqli_stmt_bind_result($stmt, $id))) + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label))) + printf("[006] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label, $foo))) + printf("[007] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_execute($stmt)) + printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + while (mysqli_stmt_fetch($stmt)) { + var_dump($id); + var_dump($label); + } + mysqli_stmt_close($stmt); + + + function func_mysqli_stmt_bind_result($link, $engine, $bind_type, $sql_type, $bind_value, $offset, $type_hint = null) { + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) { + printf("[%04d] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!mysqli_query($link, sprintf("CREATE TABLE test(id INT, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { + // don't bail - column type might not be supported by the server, ignore this + return false; + } + + if (!$stmt = mysqli_stmt_init($link)) { + printf("[%04d] [%d] %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)")) { + printf("[%04d] [%d] %s\n", $offset + 2, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + $id = null; + if (!mysqli_stmt_bind_param($stmt, "i" . $bind_type, $id, $bind_value)) { + printf("[%04d] [%d] %s\n", $offset + 3, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + mysqli_stmt_close($stmt); + return false; + } + + for ($id = 1; $id < 4; $id++) { + if (!mysqli_stmt_execute($stmt)) { + printf("[%04d] [%d] %s\n", $offset + 3 + $id, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + mysqli_stmt_close($stmt); + return false; + } + } + mysqli_stmt_close($stmt); + + $stmt = mysqli_stmt_init($link); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test")) { + printf("[%04d] [%d] %s\n", $offset + 7, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + mysqli_stmt_close($stmt); + return false; + } + + if (!mysqli_stmt_execute($stmt)) { + printf("[%04d] [%d] %s\n", $offset + 8, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + mysqli_stmt_close($stmt); + return false; + } + + $result = mysqli_stmt_result_metadata($stmt); + + $bind_res = null; + if (!mysqli_stmt_bind_result($stmt, $id, $bind_res)) { + printf("[%04d] [%d] %s\n", $offset + 9, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + mysqli_stmt_close($stmt); + return false; + } + $num = 0; + $fields = mysqli_fetch_fields($result); + + while (mysqli_stmt_fetch($stmt)) { + if (!gettype($bind_res)=="unicode") { + if ($bind_res !== $bind_value && (!$type_hint || ($type_hint !== gettype($bind_res)))) { + printf("[%04d] [%d] Expecting %s/'%s' [type hint = %s], got %s/'%s'\n", + $offset + 10, $num, + gettype($bind_value), $bind_value, $type_hint, + gettype($bind_res), $bind_res); + mysqli_stmt_close($stmt); + return false; + } + } + $num++; + } + + if ($num != 3) { + printf("[%04d] [%d] %s, expecting 3 results, got only %d results\n", + $offset + 11, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), $num); + mysqli_stmt_close($stmt); + return false; + } + + mysqli_stmt_close($stmt); + return true; + } + + + function func_mysqli_stmt_bind_make_string($len) { + + $ret = ''; + for ($i = 0; $i < $len; $i++) + $ret .= chr(mt_rand(65, 90)); + + return $ret; + } + + func_mysqli_stmt_bind_result($link, $engine, "i", "TINYINT", -11, 20); + func_mysqli_stmt_bind_result($link, $engine, "i", "TINYINT", NULL, 40); + func_mysqli_stmt_bind_result($link, $engine, "i", "TINYINT UNSIGNED", 1, 60); + func_mysqli_stmt_bind_result($link, $engine, "i", "TINYINT UNSIGNED", NULL, 80); + + func_mysqli_stmt_bind_result($link, $engine, "i", "BOOL", 1, 100); + func_mysqli_stmt_bind_result($link, $engine, "i", "BOOL", NULL, 120); + func_mysqli_stmt_bind_result($link, $engine, "i", "BOOLEAN", 0, 140); + func_mysqli_stmt_bind_result($link, $engine, "i", "BOOLEAN", NULL, 160); + + func_mysqli_stmt_bind_result($link, $engine, "i", "SMALLINT", -32768, 180); + func_mysqli_stmt_bind_result($link, $engine, "i", "SMALLINT", 32767, 200); + func_mysqli_stmt_bind_result($link, $engine, "i", "SMALLINT", NULL, 220); + func_mysqli_stmt_bind_result($link, $engine, "i", "SMALLINT UNSIGNED", 65535, 240); + func_mysqli_stmt_bind_result($link, $engine, "i", "SMALLINT UNSIGNED", NULL, 260); + + func_mysqli_stmt_bind_result($link, $engine, "d", "MEDIUMINT", -8388608, 280, "integer"); + func_mysqli_stmt_bind_result($link, $engine, "d", "MEDIUMINT", 8388607, 300, "integer"); + func_mysqli_stmt_bind_result($link, $engine, "d", "MEDIUMINT", NULL, 320); + func_mysqli_stmt_bind_result($link, $engine, "d", "MEDIUMINT UNSIGNED", 16777215, 340, "integer"); + func_mysqli_stmt_bind_result($link, $engine, "d", "MEDIUMINT UNSIGNED", NULL, 360); + + func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER", (defined("PHP_INT_MAX")) ? max(-1 * PHP_INT_MAX + 1, -2147483648) : 1, 380); + func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER", -2147483647, 400, "integer"); + func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER", (defined("PHP_INT_MAX")) ? min(2147483647, PHP_INT_MAX) : 1, 420); + func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER", NULL, 440); + func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER UNSIGNED", (defined("PHP_INT_MAX")) ? min(4294967295, 2147483647) : 1, 460); + func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER UNSIGNED", 4294967295, 480, (defined("PHP_INT_MAX") && (4294967295 > PHP_INT_MAX)) ? "string" : null); + func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER UNSIGNED", NULL, 500); + + /* test is broken too: we bind "integer" but value is a float + func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT", -9223372036854775808, 520); + func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT UNSIGNED", 18446744073709551615, 560); + */ + func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT", NULL, 540); + func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT UNSIGNED", NULL, 580); + func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT", -1, 1780); + func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT UNSIGNED", 1, 1800); + func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT", -1 * PHP_INT_MAX + 1, 1820); + func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT UNSIGNED", PHP_INT_MAX, 1840); + func_mysqli_stmt_bind_result($link, $engine, "s", "BIGINT UNSIGNED", "18446744073709551615", 1860); + func_mysqli_stmt_bind_result($link, $engine, "s", "BIGINT", "-9223372036854775808", 1880); + + func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT", -9223372036854775808 - 1.1, 600); + func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT", NULL, 620); + func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT UNSIGNED", 18446744073709551615 + 1.1, 640); + func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT UNSIGNED ", NULL, 660); + + // Yes, we need the temporary variable. The PHP casting will fouls us otherwise. + $tmp = strval('-99999999.99'); + func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2)", $tmp, 680, "string"); + func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2)", NULL, 700); + $tmp = strval('99999999.99'); + func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", $tmp , 720, "string"); + func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", NULL, 740); + $tmp = strval('-99999999.99'); + func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", $tmp, 760, "string"); + func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", NULL, 780); + $tmp = strval('99999999.99'); + func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", $tmp, 800, "string"); + func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", NULL, 820); + + // don't care about date() strict TZ warnings... + func_mysqli_stmt_bind_result($link, $engine, "s", "DATE", @date('Y-m-d'), 840); + func_mysqli_stmt_bind_result($link, $engine, "s", "DATE NOT NULL", @date('Y-m-d'), 860); + func_mysqli_stmt_bind_result($link, $engine, "s", "DATE", NULL, 880); + + func_mysqli_stmt_bind_result($link, $engine, "s", "DATETIME", @date('Y-m-d H:i:s'), 900); + func_mysqli_stmt_bind_result($link, $engine, "s", "DATETIME NOT NULL", @date('Y-m-d H:i:s'), 920); + func_mysqli_stmt_bind_result($link, $engine, "s", "DATETIME", NULL, 940); + + func_mysqli_stmt_bind_result($link, $engine, "s", "TIMESTAMP", @date('Y-m-d H:i:s'), 960); + + func_mysqli_stmt_bind_result($link, $engine, "s", "TIME", @date('H:i:s'), 980); + func_mysqli_stmt_bind_result($link, $engine, "s", "TIME NOT NULL", @date('H:i:s'), 1000); + func_mysqli_stmt_bind_result($link, $engine, "s", "TIME", NULL, 1020); + + $tmp = intval(@date('Y')); + func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR", $tmp, 1040, "integer"); + func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR NOT NULL", $tmp, 1060, "integer"); + func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR", NULL, 1080); + + $string255 = func_mysqli_stmt_bind_make_string(255); + func_mysqli_stmt_bind_result($link, $engine, "s", "CHAR(1)", "a", 1110, $hint_str_or_unicode); + func_mysqli_stmt_bind_result($link, $engine, "s", "CHAR(255)", $string255, 1120, $hint_str_or_unicode); + func_mysqli_stmt_bind_result($link, $engine, "s", "CHAR(1) NOT NULL", "a", 1140, $hint_str_or_unicode); + func_mysqli_stmt_bind_result($link, $engine, "s", "CHAR(1)", NULL, 1160); + + $string65k = func_mysqli_stmt_bind_make_string(65535); + func_mysqli_stmt_bind_result($link, $engine, "s", "VARCHAR(1)", "a", 1180, $hint_str_or_unicode); + func_mysqli_stmt_bind_result($link, $engine, "s", "VARCHAR(255)", $string255, 1200, $hint_str_or_unicode); + func_mysqli_stmt_bind_result($link, $engine, "s", "VARCHAR(65635)", $string65k, 1220, $hint_str_or_unicode); + func_mysqli_stmt_bind_result($link, $engine, "s", "VARCHAR(1) NOT NULL", "a", 1240, $hint_str_or_unicode); + func_mysqli_stmt_bind_result($link, $engine, "s", "VARCHAR(1)", NULL, 1260); + + func_mysqli_stmt_bind_result($link, $engine, "s", "BINARY(1)", "a", 1280); + func_mysqli_stmt_bind_result($link, $engine, "s", "BINARY(1)", chr(0), 1300); + func_mysqli_stmt_bind_result($link, $engine, "s", "BINARY(1) NOT NULL", "b", 1320); + func_mysqli_stmt_bind_result($link, $engine, "s", "BINARY(1)", NULL, 1340); + + func_mysqli_stmt_bind_result($link, $engine, "s", "VARBINARY(1)", "a", 1360); + func_mysqli_stmt_bind_result($link, $engine, "s", "VARBINARY(1)", chr(0), 1380); + func_mysqli_stmt_bind_result($link, $engine, "s", "VARBINARY(1) NOT NULL", "b", 1400); + func_mysqli_stmt_bind_result($link, $engine, "s", "VARBINARY(1)", NULL, 1420); + + func_mysqli_stmt_bind_result($link, $engine, "s", "TINYBLOB", "a", 1440); + func_mysqli_stmt_bind_result($link, $engine, "s", "TINYBLOB", chr(0), 1460); + func_mysqli_stmt_bind_result($link, $engine, "s", "TINYBLOB NOT NULL", "b", 1480); + func_mysqli_stmt_bind_result($link, $engine, "s", "TINYBLOB", NULL, 1500); + + func_mysqli_stmt_bind_result($link, $engine, "s", "TINYTEXT", "a", 1520, $hint_str_or_unicode); + func_mysqli_stmt_bind_result($link, $engine, "s", "TINYTEXT NOT NULL", "a", 1540, $hint_str_or_unicode); + func_mysqli_stmt_bind_result($link, $engine, "s", "TINYTEXT", NULL, 1560, $hint_str_or_unicode); + + // Note: you cannot insert any blob values this way. But you can check the API at least partly this way + // Extra BLOB tests are in mysqli_stmt_send_long() + func_mysqli_stmt_bind_result($link, $engine, "b", "BLOB", b"", 1580); + func_mysqli_stmt_bind_result($link, $engine, "b", "TEXT", "", 1600, $hint_str_or_unicode); + func_mysqli_stmt_bind_result($link, $engine, "b", "MEDIUMBLOB", b"", 1620); + func_mysqli_stmt_bind_result($link, $engine, "b", "MEDIUMTEXT", "", 1640, $hint_str_or_unicode); + + /* Is this one related? http://bugs.php.net/bug.php?id=35759 */ + if (($IS_MYSQLND) || (!$IS_MYSQLND && (ini_get('memory_limit') > 4294967296))) { + /* NOTE: the MySQL Client Library - not mysqlnd - will allocate + a hugge max_length(type) = 4GB bind buffer */ + func_mysqli_stmt_bind_result($link, $engine, "b", "LONGBLOB", "", 1660); + func_mysqli_stmt_bind_result($link, $engine, "b", "LONGTEXT", "", 1680, $hint_str_or_unicode); + } + + func_mysqli_stmt_bind_result($link, $engine, "s", "ENUM('a', 'b')", "a", 1700, $hint_str_or_unicode); + func_mysqli_stmt_bind_result($link, $engine, "s", "ENUM('a', 'b')", NULL, 1720, $hint_str_or_unicode); + func_mysqli_stmt_bind_result($link, $engine, "s", "SET('a', 'b')", "a", 1740, $hint_str_or_unicode); + func_mysqli_stmt_bind_result($link, $engine, "s", "SET('a', 'b')", NULL, 1760, $hint_str_or_unicode); + + if (mysqli_get_server_version($link) >= 50600) + func_mysqli_stmt_bind_result($link, $engine, "s", "TIME", "13:31:34.123456", 1770, "13:31:34"); + + /* Check that the function alias exists. It's a deprecated function, + but we have not announce the removal so far, therefore we need to check for it */ + if (!is_null($tmp = @mysqli_stmt_bind_result())) + printf("[3000] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + $stmt = mysqli_stmt_init($link); + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (1000, 'z')")) + printf("[3001] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = null; + if (false !== @mysqli_stmt_bind_result($stmt, $id)) + printf("[3002] Bind result should not be allowed"); + + mysqli_stmt_close($stmt); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_bind_result(): invalid object or resource mysqli_stmt + in %s on line %d + +Warning: mysqli_stmt_bind_result(): Number of bind variables doesn't match number of fields in prepared statement in %s on line %d + +Warning: mysqli_stmt_bind_result(): Number of bind variables doesn't match number of fields in prepared statement in %s on line %d +int(1) +%s(1) "a" +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_bind_result_bit.phpt b/ext/mysqli/tests/mysqli_stmt_bind_result_bit.phpt new file mode 100644 index 0000000..acf0d0b --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_bind_result_bit.phpt @@ -0,0 +1,159 @@ +--TEST-- +mysqli_stmt_bind_result() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + function dec32bin($dec, $bits) { + + $maxval = pow(2, $bits); + $bin = ''; + for ($bitval = $maxval; $bitval >= 1; $bitval = $bitval / 2) { + if (($dec / $bitval) >= 1) { + $bin .= '1'; + $dec -= $bitval; + } else { + $bin .= '0'; + } + } + return $bin; + } + + if (!$link_ins = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!$link_sel = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + for ($bits = 1; $bits <= 46; $bits++) { + + if (1 == $bits) + $max_value = 1; + else + $max_value = pow(2, $bits) - 1; + + if (!mysqli_query($link_ins, "DROP TABLE IF EXISTS test")) { + printf("[003 - %d] [%d] %s\n", $bits, mysqli_errno($link_ins), mysqli_error($link_ins)); + } + + if (!mysqli_query($link_ins, sprintf("CREATE TABLE test(id BIGINT, bit_value BIT(%d) NOT NULL, bit_null BIT(%d) DEFAULT NULL) ENGINE = %s", $bits, $bits, $engine))) { + // don't bail - column type might not be supported by the server, ignore this + continue; + } + if (!$stmt_ins = mysqli_stmt_init($link_ins)) { + printf("[004 - %d] [%d] %s\n", $bits, mysqli_errno($link_ins), mysqli_error($link_ins)); + continue; + } + + if (!mysqli_stmt_prepare($stmt_ins, "INSERT INTO test(id, bit_value) VALUES (?, ?)")) { + printf("[005 - %d] [%d] %s\n", $bits, mysqli_stmt_errno($stmt_ins), mysqli_stmt_error($stmt_ins)); + mysqli_stmt_close($stmt_ins); + continue; + } + + if (!($stmt_sel = mysqli_stmt_init($link_sel))) { + printf("[006 - %d] [%d] %s\n", $bits, mysqli_errno($link_sel), mysqli_error($link_sel)); + mysqli_stmt_close($stmt_ins); + continue; + } + + $tests = 0; + $rand_max = mt_getrandmax(); + while ($tests < 10) { + + $tests++; + if (1 == $tests) + $value = 0; + else if (2 == $tests) + $value = $max_value; + else { + if ($max_value > $rand_max) { + $max_loops = floor($max_value/$rand_max); + $num_loops = mt_rand(1, $max_loops); + $value = 0; + for ($i = 0; $i < $num_loops; $i++) + $value += mt_rand(0, $rand_max); + } else { + $value = mt_rand(0, $max_value); + } + } + + $bin = ($bits < 32) ? decbin($value) : dec32bin($value, $bits); + for ($i = 0; ($i < strlen($bin)) && ($bin[$i] == '0'); $i++) + ; + $bin2 = substr($bin, $i, strlen($bin)); + + if (!mysqli_stmt_bind_param($stmt_ins, "dd", $value, $value)) { + printf("[007 - %d] [%d] %s\n", $bits, mysqli_stmt_errno($stmt_ins), mysqli_stmt_error($stmt_ins)); + mysqli_stmt_close($stmt_ins); + continue; + } + if (!mysqli_stmt_execute($stmt_ins)) { + printf("[008 - %d] [%d] %s\n", $bits, mysqli_stmt_errno($stmt_ins), mysqli_stmt_error($stmt_ins)); + break; + } + $sql = sprintf("SELECT id, BIN(bit_value) AS _bin, bit_value, bit_value + 0 AS _bit_value0, bit_null FROM test WHERE id = %s", $value); + if ((!mysqli_stmt_prepare($stmt_sel, $sql)) || + (!mysqli_stmt_execute($stmt_sel))) { + printf("[009 - %d] [%d] %s\n", $bits, mysqli_stmt_errno($stmt_sel), mysqli_stmt_error($stmt_sel)); + break; + } + + $row = array('id' => -1, '_bin' => - 1, 'bit_value' => -1, '_bit_value0' => -1, 'bit_null' => -1); + if (!mysqli_stmt_bind_result($stmt_sel, $row['id'], $row['_bin'], $row['bit_value'], $row['_bit_value0'], $row['bit_null'])) { + printf("[010 - %d] [%d] %s\n", $bits, mysqli_stmt_errno($stmt_sel), mysqli_stmt_error($stmt_sel)); + break; + } + + if (!($ret = mysqli_stmt_fetch($stmt_sel))) { + printf("[011 - %d] mysqli_stmt_fetch() has failed for %d bits - ret = %s/%s, [%d] %s, [%d] %s\n", + $bits, $bits, + gettype($ret), $ret, + mysqli_stmt_errno($stmt_sel), mysqli_stmt_error($stmt_sel), + mysqli_errno($link_sel), mysqli_errno($link_sel) + ); + break; + } + + if (($value != $row['id']) || (($bin != $row['_bin']) && ($bin2 != $row['_bin']))) { + debug_zval_dump($row); + printf("[012 - %d] Insert of %s in BIT(%d) column might have failed. id = %s, bin = %s (%s/%s)\n", + $bits, $value, $bits, $row['id'], $row['_bin'], $bin, $bin2); + break; + } + if ($value != $row['bit_value']) { + debug_zval_dump($row); + printf("[013 - %d] Expecting %s got %s\n", $bits, $value, $row['bit_value']); + break; + } + + if (null !== $row['bit_null']) { + debug_zval_dump($row); + printf("[014 - %d] Expecting null got %s/%s\n", $bits, gettype($row['bit_value']), $row['bit_value']); + break; + } + + } + + mysqli_stmt_close($stmt_ins); + mysqli_stmt_close($stmt_sel); + } + + mysqli_close($link_ins); + mysqli_close($link_sel); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_bind_result_format.phpt b/ext/mysqli/tests/mysqli_stmt_bind_result_format.phpt new file mode 100644 index 0000000..dee5a7e --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_bind_result_format.phpt @@ -0,0 +1,337 @@ +--TEST-- +Playing with SELECT FORMAT(...) AS _format - see also bugs.php.net/42378 +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +memory_limit=83886080 +--FILE-- +<?php + require_once("connect.inc"); + + function create_table($link, $column, $min, $max, $engine, $offset) { + + if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { + printf("[%03d] Cannot drop table test, [%d] %s\n", + $offset, + mysqli_errno($link), mysqli_error($link)); + return array(); + } + + $sql = sprintf("CREATE TABLE test(id INT AUTO_INCREMENT PRIMARY KEY, col1 %s) ENGINE=%s", + $column, $engine); + if (!mysqli_query($link, $sql)) { + printf("[%03d] Cannot create table test, [%d] %s\n", + $offset + 1, + mysqli_errno($link), mysqli_error($link)); + return array(); + } + + $values = array(); + for ($i = 1; $i <= 100; $i++) { + $col1 = mt_rand($min, $max); + $values[$i] = $col1; + $sql = sprintf("INSERT INTO test(id, col1) VALUES (%d, %f)", + $i, $col1); + if (!mysqli_query($link, $sql)) { + printf("[%03d] Cannot insert data, [%d] %s\n", + $offset + 2, + mysqli_errno($link), mysqli_error($link)); + return array(); + } + } + + return $values; + } + + function test_format($link, $format, $from, $order_by, $expected, $offset) { + + if (!$stmt = mysqli_stmt_init($link)) { + printf("[%03d] Cannot create PS, [%d] %s\n", + $offset, + mysqli_errno($link), mysqli_error($link)); + return false; + } + + if ($order_by) + $sql = sprintf('SELECT %s AS _format FROM %s ORDER BY %s', $format, $from, $order_by); + else + $sql = sprintf('SELECT %s AS _format FROM %s', $format, $from); + + if (!mysqli_stmt_prepare($stmt, $sql)) { + printf("[%03d] Cannot prepare PS, [%d] %s\n", + $offset + 1, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if (!mysqli_stmt_execute($stmt)) { + printf("[%03d] Cannot execute PS, [%d] %s\n", + $offset + 2, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if (!mysqli_stmt_store_result($stmt)) { + printf("[%03d] Cannot store result set, [%d] %s\n", + $offset + 3, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if (!is_array($expected)) { + + $result = null; + if (!mysqli_stmt_bind_result($stmt, $result)) { + printf("[%03d] Cannot bind result, [%d] %s\n", + $offset + 4, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if (!mysqli_stmt_fetch($stmt)) { + printf("[%03d] Cannot fetch result,, [%d] %s\n", + $offset + 5, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if ($result !== $expected) { + printf("[%03d] Expecting %s/%s got %s/%s with %s - %s.\n", + $offset + 6, + gettype($expected), $expected, + gettype($result), $result, + $format, $sql); + } + + } else { + + $order_by_col = $result = null; + if (!mysqli_stmt_bind_result($stmt, $order_by_col, $result)) { + printf("[%03d] Cannot bind result, [%d] %s\n", + $offset + 7, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + reset($expected); + while ((list($k, $v) = each($expected)) && mysqli_stmt_fetch($stmt)) { + if ($result !== $v) { + printf("[%03d] Row %d - expecting %s/%s got %s/%s [%s] with %s - %s.\n", + $offset + 8, + $k, + gettype($v), $v, + gettype($result), $result, + $order_by_col, + $format, $sql); + } + } + + } + + mysqli_stmt_free_result($stmt); + mysqli_stmt_close($stmt); + + return true; + } + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect - [%d] %s\n", + mysqli_connect_errno(), + mysqli_connect_error()); + + /* select from dual - pseudo table */ + test_format($link, 'FORMAT(1.01, 0)', 'DUAL', null, '1', 10); + test_format($link, 'FORMAT(1.23, 1)', 'DUAL', null, '1.2', 20); + test_format($link, 'FORMAT(1.23, 2)', 'DUAL', null, '1.23', 30); + test_format($link, 'FORMAT(1234.567, 3)', 'DUAL', null, '1,234.567', 40); + /* no typo! */ + test_format($link, 'FORMAT(1234.567, 4)', 'DUAL', null, '1,234.5670', 50); + + mysqli_close($link); + require_once('table.inc'); + + /* select from existing table */ + test_format($link, 'FORMAT(id, 0)', 'test', null, '1', 60); + test_format($link, 'FORMAT(id + 0.1, 1)', 'test', null, '1.1', 70); + test_format($link, 'FORMAT(id + 0.01, 2)', 'test', null, '1.01', 80); + + /* create new table and select from it */ + $expected = create_table($link, 'FLOAT', -10000, 10000, $engine, 90); + foreach ($expected as $k => $v) + $expected[$k] = number_format(round($v), 0, '.', ','); + test_format($link, 'id AS order_by_col, FORMAT(col1, 0)', 'test', 'id', $expected, 100); + + $expected = create_table($link, 'FLOAT UNSIGNED', 0, 10000, $engine, 110); + foreach ($expected as $k => $v) + $expected[$k] = number_format(round($v), 0, '.', ','); + test_format($link, 'id AS order_by_col, FORMAT(col1, 0)', 'test', 'id', $expected, 120); + + $expected = create_table($link, 'TINYINT', -128, 127, $engine, 130); + foreach ($expected as $k => $v) + $expected[$k] = number_format(round($v), 0, '.', ','); + test_format($link, 'id AS order_by_col, FORMAT(col1, 0)', 'test', 'id', $expected, 140); + + $expected = create_table($link, 'SMALLINT UNSIGNED', 0, 65535, $engine, 150); + foreach ($expected as $k => $v) + $expected[$k] = number_format(round($v), 0, '.', ','); + test_format($link, 'id AS order_by_col, FORMAT(col1, 0)', 'test', 'id', $expected, 160); + + $expected = create_table($link, 'MEDIUMINT', 0, 8388607, $engine, 170); + foreach ($expected as $k => $v) + $expected[$k] = number_format(round($v), 0, '.', ','); + test_format($link, 'id AS order_by_col, FORMAT(col1, 0)', 'test', 'id', $expected, 180); + + $expected = create_table($link, 'INT UNSIGNED', 0, 1000, $engine, 190); + foreach ($expected as $k => $v) + $expected[$k] = number_format(round($v), 0, '.', ','); + test_format($link, 'id AS order_by_col, FORMAT(col1, 0)', 'test', 'id', $expected, 200); + + $expected = create_table($link, 'BIGINT', -1000, 1000, $engine, 210); + foreach ($expected as $k => $v) + $expected[$k] = number_format(round($v), 0, '.', ','); + test_format($link, 'id AS order_by_col, FORMAT(col1, 0)', 'test', 'id', $expected, 220); + + $expected = create_table($link, 'DECIMAL(5,0)', -1000, 1000, $engine, 230); + foreach ($expected as $k => $v) + $expected[$k] = number_format(round($v), 0, '.', ','); + test_format($link, 'id AS order_by_col, FORMAT(col1, 0)', 'test', 'id', $expected, 240); + + // http://bugs.php.net/bug.php?id=42378 + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) { + printf("[300] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + if (mysqli_query($link, "CREATE TABLE `test` ( + `targetport` int(11) NOT NULL default '0', + `sources` double(17,4) default NULL, + `current_sources` double(17,0) default NULL, + `reports` double(17,4) default NULL, + `current_reports` double(17,0) default NULL, + `targets` double(17,4) default NULL, + `current_targets` double(17,0) default NULL, + `maxsources` int(11) default NULL, + `maxtargets` int(11) default NULL, + `maxreports` int(11) default NULL, + `trend` float default NULL, + PRIMARY KEY (`targetport`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1")) { + + do { + $values = array(); + for ($i = 0; $i < 200; $i++) { + $current_targets = mt_rand(-100000, 100000) / 10; + do { + $trend = (mt_rand(0, 3) > 1) ? (mt_rand(-10000, 10000) / 100) : 'NULL'; + } while (isset($values[$trend])); + + $sql = sprintf('INSERT INTO test(targetport, current_targets, maxreports, trend) VALUES (%d, %f, %s, %s)', + $i, + $current_targets, + (mt_rand(0, 1) > 0) ? mt_rand(0, 1000) : 'NULL', + $trend); + if (!mysqli_query($link, $sql)) { + printf("[301] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + break 2; + } + if ($current_targets > 0 && $trend != 'NULL') + $values[$trend] = $i; + } + krsort($values); + + if (!$stmt = mysqli_stmt_init($link)) { + printf("[302] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + break; + } + + if (!mysqli_stmt_prepare($stmt, 'SELECT trend, targetport, FORMAT(trend, 2) FROM test WHERE current_targets > 0 AND trend IS NOT NULL ORDER BY trend DESC LIMIT 100')) { + printf("[303] [%d] %s\n", mysqli_stmt_errno($link), mysqli_stmt_error($link)); + break; + } + + if (!mysqli_stmt_execute($stmt)) { + printf("[304] [%d] %s\n", mysqli_stmt_errno($link), mysqli_stmt_error($link)); + break; + } + + if (!mysqli_stmt_store_result($stmt)) { + printf("[305] [%d] %s\n", mysqli_stmt_errno($link), mysqli_stmt_error($link)); + break; + } + + $trend = $targetport = $format = null; + if (!mysqli_stmt_bind_result($stmt, $trend, $targetport, $format)) { + + printf("[305] [%d] %s\n", mysqli_stmt_errno($link), mysqli_stmt_error($link)); + break; + } + + reset($values); + while (mysqli_stmt_fetch($stmt)) { + list($exp_trend, $exp_targetport) = each($values); + if ($targetport != $exp_targetport) { + printf("[306] Values fetched from MySQL seem to be wrong, check manually\n"); + printf("%s/%s - %s/%s - '%s'\n", $trend, $exp_trend, $targetport, $exp_targetport, $format); + } + } + mysqli_stmt_free_result($stmt); + mysqli_stmt_close($stmt); + + // same but OO interface + if (!$stmt = mysqli_stmt_init($link)) { + printf("[307] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + break; + } + + if (!$stmt->prepare('SELECT trend, targetport, FORMAT(trend, 2) FROM test WHERE current_targets > 0 AND trend IS NOT NULL ORDER BY trend DESC LIMIT 100')) { + printf("[308] [%d] %s\n", mysqli_stmt_errno($link), mysqli_stmt_error($link)); + break; + } + + if (!$stmt->execute()) { + printf("[309] [%d] %s\n", mysqli_stmt_errno($link), mysqli_stmt_error($link)); + break; + } + + if (!$stmt->store_result()) { + printf("[310] [%d] %s\n", mysqli_stmt_errno($link), mysqli_stmt_error($link)); + break; + } + + $trend = $targetport = $format = null; + if (!$stmt->bind_result($trend, $targetport, $format)) { + + printf("[311] [%d] %s\n", mysqli_stmt_errno($link), mysqli_stmt_error($link)); + break; + } + + reset($values); + while ($stmt->fetch()) { + list($exp_trend, $exp_targetport) = each($values); + if ($targetport != $exp_targetport) { + printf("[312] Values fetched from MySQL seem to be wrong, check manually\n"); + printf("%s/%s - %s/%s - '%s'\n", $trend, $exp_trend, $targetport, $exp_targetport, $format); + } + } + $stmt->free_result(); + $stmt->close(); + + } while (false); + + } else { + var_dump(mysqli_error($link)); + } + + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_bind_result_references.phpt b/ext/mysqli/tests/mysqli_stmt_bind_result_references.phpt new file mode 100644 index 0000000..ee659d4 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_bind_result_references.phpt @@ -0,0 +1,314 @@ +--TEST-- +mysqli_stmt_bind_result() - playing with references +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require('table.inc'); + + $stmt = mysqli_stmt_init($link); + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 1")) + printf("[001] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 1")) + printf("[001] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + + print "plain vanilla...\n"; + unset($id); unset($label); + $id = $label = null; + if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label))) + printf("[002] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt)) + printf("[003] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + var_dump($id); + var_dump($label); + + + print "reference, one level...\n"; + unset($id); unset($id_ref); unset($label); unset($label_ref); + $id = null; + $id_ref = &$id; + $label = null; + $label_ref = &$label; + + if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id_ref, $label_ref))) + printf("[004] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt)) + printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + var_dump($id_ref); + var_dump($id); + var_dump($label_ref); + var_dump($label); + + + print "reference, two levels...\n"; + unset($id); unset($id_ref); unset($id_ref_ref); unset($label); unset($label_ref); unset($label_ref_ref); + $id = null; + $id_ref = &$id; + $id_ref_ref = &$id_ref; + $label = null; + $label_ref = &$label; + $label_ref_ref = &$label_ref; + + if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id_ref_ref, $label_ref_ref))) + printf("[006] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt)) + printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + var_dump($id_ref_ref); + var_dump($id_ref); + var_dump($id); + var_dump($label_ref_ref); + var_dump($label_ref); + var_dump($label); + + print "reference, \$GLOBALS...\n"; + unset($id); unset($id_ref); unset($label); unset($label_ref); + $id = 100; + $id_ref = &$GLOBALS['id']; + $label = null; + $label_ref = &$GLOBALS['label']; + + if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id_ref, $label_ref))) + printf("[008] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt)) + printf("[009] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + var_dump($id_ref); + var_dump($id); + var_dump($label_ref); + var_dump($label); + + print "reference, same target...\n"; + $id = null; + $label = &$id; + + if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label))) + printf("[010] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt)) + printf("[011] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + var_dump($id); + var_dump($label); + + print "reference, simple object...\n"; + unset($obj); + $obj = new stdClass(); + $obj->id = null; + $obj->label = null; + + if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $obj->id, $obj->label))) + printf("[012] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt)) + printf("[013] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + var_dump($obj->id); + var_dump($obj->label); + + + print "reference, simple object w reference...\n"; + unset($id); unset($label); unset($obj); + $obj = new stdClass(); + $obj->id = null; + $obj->label = null; + $id = &$obj->id; + $label = &$obj->label; + + if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label))) + printf("[012] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt)) + printf("[013] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + var_dump($obj->id); + var_dump($obj->label); + + print "reference, simple object w reference, change after bind...\n"; + unset($id); unset($label); unset($obj); + $obj = new stdClass(); + $obj->id = null; + $obj->label = null; + $id = &$obj->id; + $label = &$obj->label; + + if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label))) + printf("[012] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + $label = &$obj->id; + $id = null; + + if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt)) + printf("[013] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + var_dump($obj->id); + var_dump($id); + var_dump($obj->label); + var_dump($label); + + print "reference, one level, change after bind...\n"; + unset($id); unset($label); unset($id_ref); unset($label_ref); + $id = null; + $id_ref = &$id; + $label = null; + $label_ref = &$label; + + if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id_ref, $label_ref))) + printf("[014] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + $id_ref = 1; + $label_ref = 1; + + if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt)) + printf("[015] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + var_dump($id_ref); + var_dump($id); + var_dump($label_ref); + var_dump($label); + + print "reference, circle...\n"; + unset($id); unset($label_a); unset($label_b); + $id = null; + $label_a = &$label_b; + $label_b = &$label_a; + + if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label_a))) + printf("[016] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt)) + printf("[017] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + var_dump($id); + var_dump($label_a); + var_dump($label_b); + + print "reference, object, forward declaration...\n"; + unset($bar); unset($id); unset($label_ref); + class foo { + public $foo; + public function foo() { + $this->foo = &$this->bar; + } + } + class bar extends foo { + public $bar = null; + } + $bar = new bar(); + $id = null; + $label_ref = &$bar->bar; + + if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label_ref))) + printf("[018] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt)) + printf("[019] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + var_dump($id); + var_dump($bar); + var_dump($label_ref); + + print "references, object, private...\n"; + unset($bar); unset($id); unset($label); + class mega_bar extends bar { + private $id; + public $id_ref; + public function mega_bar() { + $this->foo(); + $this->id_ref = &$this->id; + } + } + $bar = new mega_bar(); + $id = &$bar->id_ref; + $label = &$bar->foo; + + if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label))) + printf("[020] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt)) + printf("[021] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + var_dump($id); + var_dump($label); + var_dump($bar); + + mysqli_stmt_close($stmt); + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +plain vanilla... +int(1) +%unicode|string%(1) "a" +reference, one level... +int(1) +int(1) +%unicode|string%(1) "a" +%unicode|string%(1) "a" +reference, two levels... +int(1) +int(1) +int(1) +%unicode|string%(1) "a" +%unicode|string%(1) "a" +%unicode|string%(1) "a" +reference, $GLOBALS... +int(1) +int(1) +%unicode|string%(1) "a" +%unicode|string%(1) "a" +reference, same target... +%unicode|string%(1) "a" +%unicode|string%(1) "a" +reference, simple object... +int(1) +%unicode|string%(1) "a" +reference, simple object w reference... +int(1) +%unicode|string%(1) "a" +reference, simple object w reference, change after bind... +int(1) +int(1) +%unicode|string%(1) "a" +int(1) +reference, one level, change after bind... +int(1) +int(1) +%unicode|string%(1) "a" +%unicode|string%(1) "a" +reference, circle... +int(1) +%unicode|string%(1) "a" +%unicode|string%(1) "a" +reference, object, forward declaration... +int(1) +object(bar)#%d (2) { + [%u|b%"bar"]=> + &%unicode|string%(1) "a" + [%u|b%"foo"]=> + &%unicode|string%(1) "a" +} +%unicode|string%(1) "a" +references, object, private... +int(1) +%unicode|string%(1) "a" +object(mega_bar)#5 (4) { + [%s]=> + &int(1) + [%u|b%"id_ref"]=> + &int(1) + [%u|b%"bar"]=> + &%unicode|string%(1) "a" + [%u|b%"foo"]=> + &%unicode|string%(1) "a" +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_bind_result_zerofill.phpt b/ext/mysqli/tests/mysqli_stmt_bind_result_zerofill.phpt new file mode 100644 index 0000000..5650853 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_bind_result_zerofill.phpt @@ -0,0 +1,97 @@ +--TEST-- +mysqli_stmt_bind_result() - ZEROFILL +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once('connect.inc'); + require_once('table.inc'); + + function zerofill($offset, $link, $datatype, $insert = 1) { + + mysqli_query($link, 'ALTER TABLE test DROP zero'); + $sql = sprintf('ALTER TABLE test ADD zero %s UNSIGNED ZEROFILL', $datatype); + if (!mysqli_query($link, $sql)) { + // no worries - server might not support it + return true; + } + + if (!mysqli_query($link, sprintf('UPDATE test SET zero = %s', $insert))) { + printf("[%03d] UPDATE failed, [%d] %s\n", + $offset, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!($stmt = mysqli_prepare($link, 'SELECT zero FROM test LIMIT 1'))) { + printf("[%03d] SELECT failed, [%d] %s\n", + $offset, mysqli_errno($link), mysqli_error($link)); + return false; + } + + $result = null; + if (!mysqli_stmt_bind_result($stmt, $result)) { + printf("[%03d] Bind failed, [%d] %s\n", + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt)) { + printf("[%03d] Execute or fetch failed, [%d] %s\n", + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + $res = mysqli_stmt_result_metadata($stmt); + $meta = mysqli_fetch_fields($res); + mysqli_stmt_free_result($stmt); + + $meta = $meta[0]; + $length = $meta->length; + if ($length > strlen($insert)) { + + $expected = str_repeat('0', $length - strlen($insert)); + $expected .= $insert; + if ($expected !== $result) { + printf("[%03d] Expecting '%s' got '%s'\n", $offset, $expected, $result); + return false; + } + + } else if ($length <= 1) { + printf("[%03d] Length reported is too small to run test\n", $offset); + return false; + } + + + return true; + } + + /* + We map those to PHP numeric types - + no padding/filling done. Neither with libmysql nor with mysqlnd. + zerofill(2, $link, 'TINYINT'); + zerofill(3, $link, 'SMALLINT'); + zerofill(4, $link, 'MEDIUMINT'); + zerofill(5, $link, 'INT'); + zerofill(6, $link, 'INTEGER'); + zerofill(7, $link, 'BIGINT'); + zerofill(8, $link, 'FLOAT'); + zerofill(9, $link, 'DOUBLE'); + zerofill(10, $link, 'DOUBLE PRECISION'); + */ + zerofill(11, $link, 'DECIMAL'); + zerofill(12, $link, 'DEC'); + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_close.phpt b/ext/mysqli/tests/mysqli_stmt_close.phpt new file mode 100644 index 0000000..64e76e5 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_close.phpt @@ -0,0 +1,91 @@ +--TEST-- +mysqli_stmt_close() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_close())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_close($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + // Yes, amazing, eh? AFAIK a work around of a constructor bug... + if (!is_null($tmp = mysqli_stmt_close($stmt))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test")) + printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (true !== ($tmp = mysqli_stmt_close($stmt))) + printf("[006] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = mysqli_stmt_close($stmt))) + printf("[007] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)")) + printf("[009] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $label = null; + if (!mysqli_stmt_bind_param($stmt, "is", $id, $label)) + printf("[010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = 100; $label = 'z'; + if (!mysqli_stmt_execute($stmt)) + printf("[011] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + mysqli_kill($link, mysqli_thread_id($link)); + + if (true !== ($tmp = mysqli_stmt_close($stmt))) + printf("[012] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + require('table.inc'); + if (!$stmt = mysqli_stmt_init($link)) + printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test")) + printf("[014] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $label = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label)) + printf("[015] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt)) + printf("[016] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + mysqli_kill($link, mysqli_thread_id($link)); + + if (true !== ($tmp = mysqli_stmt_close($stmt))) + printf("[017] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_close(): invalid object or resource mysqli_stmt + in %s on line %d + +Warning: mysqli_stmt_close(): Couldn't fetch mysqli_stmt in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_data_seek.phpt b/ext/mysqli/tests/mysqli_stmt_data_seek.phpt new file mode 100644 index 0000000..a1cebea --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_data_seek.phpt @@ -0,0 +1,99 @@ +--TEST-- +mysqli_stmt_data_seek() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_data_seek())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_data_seek($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_null($tmp = mysqli_stmt_data_seek($stmt, 1))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, "SELECT id FROM test ORDER BY id")) + printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (true !== ($tmp = mysqli_stmt_execute($stmt))) + printf("[006] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + + $id = null; + if (!mysqli_stmt_bind_result($stmt, $id)) + printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_store_result($stmt)) + printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!is_null($tmp = mysqli_stmt_data_seek($stmt, 2))) + printf("[009] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_fetch($stmt)) + printf("[010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + var_dump($id); + + if (!is_null($tmp = mysqli_stmt_data_seek($stmt, 0))) + printf("[011] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_fetch($stmt)) + printf("[012] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + var_dump($id); + + if (!is_null($tmp = mysqli_stmt_data_seek($stmt, mysqli_stmt_num_rows($stmt) + 100))) + printf("[013] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (mysqli_stmt_fetch($stmt)) + printf("[014] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + var_dump($id); + + if (false !== ($tmp = mysqli_stmt_data_seek($stmt, -1))) + printf("[015] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (mysqli_stmt_fetch($stmt)) + printf("[016] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + var_dump($id); + + mysqli_stmt_close($stmt); + + if (NULL !== ($tmp = mysqli_stmt_data_seek($stmt, 0))) + printf("[017] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_data_seek(): invalid object or resource mysqli_stmt + in %s on line %d +int(3) +int(1) +int(1) + +Warning: mysqli_stmt_data_seek(): Offset must be positive in %s on line %d +int(1) + +Warning: mysqli_stmt_data_seek(): Couldn't fetch mysqli_stmt in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_datatype_change.phpt b/ext/mysqli/tests/mysqli_stmt_datatype_change.phpt new file mode 100644 index 0000000..b23f94d --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_datatype_change.phpt @@ -0,0 +1,94 @@ +--TEST-- +Playing with datatype change between prepare and execute +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + if (!$c1 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + exit(1); + } + if (!$c2 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + exit(1); + } + + $c1->query("use $db"); + $c2->query("use $db"); + $c1->query("drop table if exists type_change"); + $c1->query("create table type_change(a int, b char(10)) ENGINE = " . $engine); + $c1->query("insert into type_change values (1, 'one'), (2, 'two')"); + $s1 = $c1->prepare("select a from type_change order by a"); + var_dump($s1->execute(), $s1->bind_result($col1)); + echo "---- Row 1\n"; + var_dump($s1->fetch()); + var_dump($col1); + echo "---- Row 2\n"; + var_dump($s1->fetch()); + var_dump($col1); + echo "---- Row 3\n"; + var_dump($s1->fetch()); + echo "----\n"; + + echo "ALTER\n"; + var_dump($c2->query("alter table type_change drop a")); + var_dump($s1->execute()); + var_dump($c1->error); + + echo "---- Row 1\n"; + var_dump($s1->fetch()); + var_dump($col1); + echo "---- Row 2\n"; + var_dump($s1->fetch()); + var_dump($col1); + echo "---- Row 3\n"; + var_dump($s1->fetch()); + echo "----\n"; + + echo "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS type_change")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysqli_close($link); +?> + +--EXPECTF-- +bool(true) +bool(true) +---- Row 1 +bool(true) +int(1) +---- Row 2 +bool(true) +int(2) +---- Row 3 +NULL +---- +ALTER +bool(true) +bool(false) +%unicode|string%(34) "Unknown column 'a' in 'field list'" +---- Row 1 +bool(false) +int(2) +---- Row 2 +bool(false) +int(2) +---- Row 3 +bool(false) +---- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_errno.phpt b/ext/mysqli/tests/mysqli_stmt_errno.phpt new file mode 100644 index 0000000..070f251 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_errno.phpt @@ -0,0 +1,68 @@ +--TEST-- +mysqli_stmt_errno() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_errno())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_errno($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + // properly initialized? + if (0 !== ($tmp = mysqli_stmt_errno($stmt))) + printf("[004] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + if (mysqli_stmt_prepare($stmt, "SELECT i_do_not_exist_believe_me FROM test ORDER BY id")) + printf("[005] Statement should have failed!\n"); + + // set after error server? + if (0 === ($tmp = mysqli_stmt_errno($stmt))) + printf("[006] Expecting int/any non zero, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, "SELECT id FROM test ORDER BY id")) + printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + // reset after error & success + if (0 != ($tmp = mysqli_stmt_errno($stmt))) + printf("[008] Expecting zero, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_kill($link, mysqli_thread_id($link)); + + if (true === ($tmp = mysqli_stmt_execute($stmt))) + printf("[009] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + // set after client error + if (0 === ($tmp = mysqli_stmt_errno($stmt))) + printf("[010] Execting int/any non zero, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + + if (NULL !== ($tmp = mysqli_stmt_errno($stmt))) + printf("[011] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_errno(): Couldn't fetch mysqli_stmt in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_error.phpt b/ext/mysqli/tests/mysqli_stmt_error.phpt new file mode 100644 index 0000000..e18aa07 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_error.phpt @@ -0,0 +1,68 @@ +--TEST-- +mysqli_stmt_error() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_error())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_error($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + // properly initialized? + if ('' !== ($tmp = mysqli_stmt_error($stmt))) + printf("[004] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + if (mysqli_stmt_prepare($stmt, "SELECT i_do_not_exist_believe_me FROM test ORDER BY id")) + printf("[005] Statement should have failed!\n"); + + // set after error server? + if ('' === ($tmp = mysqli_stmt_error($stmt))) + printf("[006] Expecting string/any non empty, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, "SELECT id FROM test ORDER BY id")) + printf("[007] [%d] %s\n", mysqli_stmt_error($stmt), mysqli_stmt_error($stmt)); + + // reset after error & success + if ('' !== ($tmp = mysqli_stmt_error($stmt))) + printf("[008] Expecting empty string, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_kill($link, mysqli_thread_id($link)); + + if (true === ($tmp = mysqli_stmt_execute($stmt))) + printf("[009] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + // set after client error + if ('' === ($tmp = mysqli_stmt_error($stmt))) + printf("[010] Execting string/any non empty, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + + if (NULL !== ($tmp = mysqli_stmt_error($stmt))) + printf("[011] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_error(): Couldn't fetch mysqli_stmt in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_execute.phpt b/ext/mysqli/tests/mysqli_stmt_execute.phpt new file mode 100644 index 0000000..85ae80c --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_execute.phpt @@ -0,0 +1,150 @@ +--TEST-- +mysqli_stmt_execute() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf('skip Cannot connect to MySQL, [%d] %s.', mysqli_connect_errno(), mysqli_connect_error())); +} +if (mysqli_get_server_version($link) <= 40100) { + die(sprintf('skip Needs MySQL 4.1+, found version %d.', mysqli_get_server_version($link))); +} +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_execute())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_execute($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + // stmt object status test + if (NULL !== ($tmp = mysqli_stmt_execute($stmt))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (mysqli_stmt_prepare($stmt, "SELECT i_do_not_exist_believe_me FROM test ORDER BY id")) + printf("[005] Statement should have failed!\n"); + + // stmt object status test + if (NULL !== ($tmp = mysqli_stmt_execute($stmt))) + printf("[006] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, "SELECT id FROM test ORDER BY id LIMIT 1")) + printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (true !== ($tmp = mysqli_stmt_execute($stmt))) + printf("[008] Expecting boolean/true, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)")) + printf("[009] [%d] %s\n", mysqli_stmt_execute($stmt), mysqli_stmt_execute($stmt)); + + // no input variables bound + if (false !== ($tmp = mysqli_stmt_execute($stmt))) + printf("[010] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + $id = 100; + $label = "z"; + if (!mysqli_stmt_bind_param($stmt, "is", $id, $label)) + printf("[011] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (true !== ($tmp = mysqli_stmt_execute($stmt))) + printf("[012] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + // calling reset between executions + mysqli_stmt_close($stmt); + if (!$stmt = mysqli_stmt_init($link)) + printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, "SELECT id FROM test ORDER BY id LIMIT ?")) + printf("[014] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $limit = 1; + if (!mysqli_stmt_bind_param($stmt, "i", $limit)) + printf("[015] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (true !== ($tmp = mysqli_stmt_execute($stmt))) + printf("[016] Expecting boolean/true, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = null; + if (!mysqli_stmt_bind_result($stmt, $id) || !mysqli_stmt_fetch($stmt)) + printf("[017] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if ($id !== 1) + printf("[018] Expecting int/1 got %s/%s\n", gettype($id), $id); + + if (true !== ($tmp = mysqli_stmt_reset($stmt))) + printf("[019] Expecting boolean/true, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (true !== ($tmp = mysqli_stmt_execute($stmt))) + printf("[020] Expecting boolean/true after reset to prepare status, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = null; + if (!mysqli_stmt_fetch($stmt)) + printf("[021] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if ($id !== 1) + printf("[022] Expecting int/1 got %s/%s\n", gettype($id), $id); + + mysqli_stmt_close($stmt); + if (!$stmt = mysqli_stmt_init($link)) + printf("[023] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, "SELECT id FROM test ORDER BY id LIMIT 1")) + printf("[024] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (true !== ($tmp = mysqli_stmt_execute($stmt))) + printf("[025] Expecting boolean/true, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (true !== ($tmp = mysqli_stmt_reset($stmt))) + printf("[026] Expecting boolean/true, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + var_dump(mysqli_stmt_execute($stmt)); + var_dump(mysqli_stmt_fetch($stmt)); + + mysqli_kill($link, mysqli_thread_id($link)); + + if (false !== ($tmp = mysqli_stmt_execute($stmt))) + printf("[027] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + + if (NULL !== ($tmp = mysqli_stmt_execute($stmt))) + printf("[028] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_execute(): invalid object or resource mysqli_stmt + in %s on line %d + +Warning: mysqli_stmt_execute(): invalid object or resource mysqli_stmt + in %s on line %d +bool(true) +bool(true) +[027] Expecting boolean/false, got boolean/1 + +Warning: mysqli_stmt_execute(): Couldn't fetch mysqli_stmt in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_execute_stored_proc.phpt b/ext/mysqli/tests/mysqli_stmt_execute_stored_proc.phpt new file mode 100644 index 0000000..29e3947 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_execute_stored_proc.phpt @@ -0,0 +1,198 @@ +--TEST-- +mysqli_stmt_execute() - Stored Procedures +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf('skip Cannot connect to MySQL, [%d] %s.', mysqli_connect_errno(), mysqli_connect_error())); +} +if (mysqli_get_server_version($link) <= 50000) { + die(sprintf('skip Needs MySQL 5.0+, found version %d.', mysqli_get_server_version($link))); +} +?> +--FILE-- +<?php + require_once('connect.inc'); + require_once('table.inc'); + + if (!mysqli_query($link, 'DROP PROCEDURE IF EXISTS p')) + printf("[009] [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + + if (mysqli_real_query($link, 'CREATE PROCEDURE p(OUT ver_param VARCHAR(25)) BEGIN SELECT VERSION() INTO ver_param; END;')) { + /* no result set, one output parameter */ + if (!$stmt = mysqli_prepare($link, 'CALL p(@version)')) + printf("[011] Cannot prepare CALL, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_execute($stmt)) + printf("[012] Cannot execute CALL, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + /* yes, I really want to call it twice! */ + if (!mysqli_stmt_execute($stmt)) + printf("[013] Cannot execute CALL, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_close($stmt)) + printf("[014] Cannot close statement, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!$stmt = mysqli_prepare($link, 'SELECT @version AS _version')) + printf("[015] Cannot prepare SELECT, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_execute($stmt)) + printf("[016] Cannot execute SELECT, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $version = 'unknown'; + if (!mysqli_stmt_bind_result($stmt, $version) || + !mysqli_stmt_fetch($stmt)) + printf("[017] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (($version == "unknown") || ($version == "")) + printf("[018] Results seem wrong, got %s, [%d] %s\n", + $version, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + mysqli_stmt_free_result($stmt); + mysqli_stmt_close($stmt); + + } else { + printf("[010] Cannot create SP, [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + } + + + if (function_exists('mysqli_stmt_get_result')) { + + if (!mysqli_query($link, 'DROP PROCEDURE IF EXISTS p')) + printf("[019] [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + + if (mysqli_real_query($link, 'CREATE PROCEDURE p(OUT ver_param VARCHAR(25)) BEGIN SELECT VERSION() INTO ver_param; END;')) { + // no result set, one output parameter + if (!$stmt = mysqli_prepare($link, 'CALL p(@version)')) + printf("[020] Cannot prepare CALL, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_execute($stmt)) + printf("[021] Cannot execute CALL, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_close($stmt)) + printf("[022] Cannot close statement, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!$stmt = mysqli_prepare($link, 'SELECT @version AS _version')) + printf("[023] Cannot prepare SELECT, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_execute($stmt)) + printf("[024] Cannot execute SELECT, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!$res = mysqli_stmt_get_result($stmt)) + printf("[025] Cannot get result set, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if ((!($row = mysqli_fetch_assoc($res))) || ($row['_version'] == "")) + printf("[026] Results seem wrong, got %s, [%d] %s\n", + $row['_version'], + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + mysqli_free_result($res); + mysqli_stmt_close($stmt); + + } else { + printf("[027] Cannot create SP, [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + } + + } + + if (!mysqli_query($link, 'DROP PROCEDURE IF EXISTS p')) + printf("[028] [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + + if (mysqli_real_query($link, 'CREATE PROCEDURE p(IN ver_in VARCHAR(25), OUT ver_out VARCHAR(25)) BEGIN SELECT ver_in INTO ver_out; END;')) { + // no result set, one input parameter, output parameter + // yes, I really do not want to bind input values... + if (!$stmt = mysqli_prepare($link, "CALL p('myversion', @version)")) + printf("[029] Cannot prepare CALL, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_execute($stmt)) + printf("[030] Cannot execute CALL, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_close($stmt)) + printf("[031] Cannot close statement, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!$stmt = mysqli_prepare($link, 'SELECT @version AS _version')) + printf("[032] Cannot prepare SELECT, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_execute($stmt)) + printf("[033] Cannot execute SELECT, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $version = 'unknown'; + if (!mysqli_stmt_bind_result($stmt, $version) || + !mysqli_stmt_fetch($stmt)) + printf("[034] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if ($version != "myversion") + printf("[035] Results seem wrong, got %s, [%d] %s\n", + $version, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + mysqli_stmt_free_result($stmt); + mysqli_stmt_close($stmt); + + } else { + printf("[036] Cannot create SP, [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + } + + if (!mysqli_query($link, 'DROP PROCEDURE IF EXISTS p')) + printf("[037] [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + + if (mysqli_real_query($link, 'CREATE PROCEDURE p(IN ver_in VARCHAR(25), OUT ver_out VARCHAR(25)) BEGIN SELECT ver_in INTO ver_out; END;')) { + // no result set, one input parameter, output parameter + // yes, I really do not want to bind input values... + if (!$stmt = mysqli_prepare($link, 'CALL p(?, @version)')) + printf("[038] Cannot prepare CALL, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $version = 'myversion'; + if (!mysqli_stmt_bind_param($stmt, 's', $version)) + printf("[039] Cannot bind input parameter, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[040] Cannot execute CALL, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_close($stmt)) + printf("[041] Cannot close statement, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!$stmt = mysqli_prepare($link, 'SELECT @version AS _version')) + printf("[042] Cannot prepare SELECT, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_execute($stmt)) + printf("[043] Cannot execute SELECT, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $version = 'unknown'; + if (!mysqli_stmt_bind_result($stmt, $version) || + !mysqli_stmt_fetch($stmt)) + printf("[044] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if ($version !== "myversion") + printf("[045] Results seem wrong, got %s, [%d] %s\n", + $version, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + mysqli_stmt_free_result($stmt); + mysqli_stmt_close($stmt); + + } else { + printf("[046] Cannot create SP, [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + } + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) + printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +@mysqli_query($link, 'DROP PROCEDURE IF EXISTS p'); + +mysqli_close($link); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_execute_stored_proc_next_result.phpt b/ext/mysqli/tests/mysqli_stmt_execute_stored_proc_next_result.phpt new file mode 100644 index 0000000..35433b1 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_execute_stored_proc_next_result.phpt @@ -0,0 +1,131 @@ +--TEST-- +mysqli_stmt_execute() - SP, next result +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf('skip Cannot connect to MySQL, [%d] %s.', mysqli_connect_errno(), mysqli_connect_error())); +} +if (mysqli_get_server_version($link) < 50503) { + die(sprintf('skip Needs MySQL 5.5.3+, found version %d.', mysqli_get_server_version($link))); +} +?> +--FILE-- +<?php + require_once('connect.inc'); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } + + if (!mysqli_query($link, 'DROP PROCEDURE IF EXISTS p')) + printf("[003] [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + + if (mysqli_real_query($link, 'CREATE PROCEDURE p(IN ver_in VARCHAR(25)) BEGIN SELECT ver_in AS _ver_out; END;')) { + // one result set + if (!$stmt = mysqli_prepare($link, 'CALL p(?)')) + printf("[005] Cannot prepare CALL, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $version = 'myversion'; + if (!mysqli_stmt_bind_param($stmt, 's', $version)) + printf("[006] Cannot bind input parameter, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[007] Cannot execute CALL, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $version = 'unknown'; + if (!mysqli_stmt_bind_result($stmt, $version) || + !mysqli_stmt_fetch($stmt)) + printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if ($version !== "myversion") + printf("[009] Results seem wrong, got %s, [%d] %s\n", + $version, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + mysqli_stmt_free_result($stmt); + + printf("[010] More results: %s\n", (mysqli_more_results($link)) ? "yes" : "no"); + printf("[011] Next result: %s\n", (mysqli_next_result($link)) ? "yes" : "no"); + + if (!mysqli_stmt_close($stmt)) + printf("[012] Cannot close statement, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!$link->query("SELECT 1")) + printf("[013] [%d] %s\n", $link->errno, $link->error); + + } else { + printf("[004] Cannot create SP, [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + } + + if (!mysqli_query($link, 'DROP PROCEDURE IF EXISTS p')) + printf("[014] [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + + if (mysqli_real_query($link, 'CREATE PROCEDURE p(IN ver_in VARCHAR(25)) BEGIN SELECT ver_in AS _ver_out; SELECT 1 AS _more; END;')) { + // two result sets + if (!$stmt = mysqli_prepare($link, 'CALL p(?)')) + printf("[015] Cannot prepare CALL, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $version = 'myversion'; + if (!mysqli_stmt_bind_param($stmt, 's', $version)) + printf("[016] Cannot bind input parameter, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[017] Cannot execute CALL, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $version = NULL; + if (!mysqli_stmt_bind_result($stmt, $version) || + !mysqli_stmt_fetch($stmt)) + printf("[018] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if ($version !== "myversion") + printf("[019] Results seem wrong, got %s, [%d] %s\n", + $version, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_more_results($link) || !mysqli_next_result($link)) + printf("[020] [%d] %s\n", $link->errno, $link->error); + + $more = NULL; + if (!mysqli_stmt_bind_result($stmt, $more) || + !mysqli_stmt_fetch($stmt)) + printf("[021] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if ($more !== 1) + printf("[022] Results seem wrong, got %s, [%d] %s\n", + $more, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_close($stmt)) + printf("[023] Cannot close statement, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + + if (!$link->query("SELECT 1")) + printf("[024] [%d] %s\n", $link->errno, $link->error); + + } else { + printf("[025] Cannot create SP, [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + } + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +@mysqli_query($link, 'DROP PROCEDURE IF EXISTS p'); + +mysqli_close($link); +?> +--XFAIL-- +Unsupported and undefined, under development +--EXPECTF-- +[010] More results: yes +[011] Next result: yes +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_execute_stored_proc_out.phpt b/ext/mysqli/tests/mysqli_stmt_execute_stored_proc_out.phpt new file mode 100644 index 0000000..8c7c799 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_execute_stored_proc_out.phpt @@ -0,0 +1,81 @@ +--TEST-- +mysqli_stmt_execute() - OUT +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf('skip Cannot connect to MySQL, [%d] %s.', mysqli_connect_errno(), mysqli_connect_error())); +} +if (mysqli_get_server_version($link) < 50503) { + die(sprintf('skip Needs MySQL 5.5.3+, found version %d.', mysqli_get_server_version($link))); +} +/* +if ($IS_MYSQLND) { + die(sprintf("skip WHY ?!")); +} +*/ +?> +--FILE-- +<?php + require_once('connect.inc'); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + } + + if (!mysqli_query($link, 'DROP PROCEDURE IF EXISTS p')) + printf("[003] [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + + if (mysqli_real_query($link, 'CREATE PROCEDURE p(IN ver_in VARCHAR(25), OUT ver_out VARCHAR(25)) BEGIN SELECT ver_in INTO ver_out; END;')) { + if (!$stmt = mysqli_prepare($link, 'CALL p(?, ?)')) + printf("[005] Cannot prepare CALL, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $ver_in = 'myversion'; + $ver_out = ''; + if (!mysqli_stmt_bind_param($stmt, 'ss', $ver_in, $ver_out)) + printf("[006] Cannot bind parameter, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[007] Cannot execute CALL, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + printf("[008] More results: %s\n", (mysqli_more_results($link) ? "yes" : "no")); + printf("[009] Next results: %s\n", (mysqli_next_result($link) ? "yes" : "no")); + + if (!mysqli_stmt_bind_result($stmt, $ver_out) || !mysqli_stmt_fetch($stmt)) + printf("[010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if ("myversion" !== $ver_out) + printf("[011] Results seem wrong got '%s'\n", $ver_out); + + if (!mysqli_stmt_close($stmt)) + printf("[012] Cannot close statement, [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!$res = $link->query("SELECT 1")) + printf("[013] [%d] %s\n", $link->errno, $link->error); + + } else { + printf("[004] Cannot create SP, [%d] %s.\n", mysqli_errno($link), mysqli_error($link)); + } + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("connect.inc"); +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + +@mysqli_query($link, 'DROP PROCEDURE IF EXISTS p'); + +mysqli_close($link); +?> +--XFAIL-- +Unsupported and undefined, under development +--EXPECTF-- +[008] More results: %s +[009] Next results: %s +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_fetch.phpt b/ext/mysqli/tests/mysqli_stmt_fetch.phpt new file mode 100644 index 0000000..7598ffe --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_fetch.phpt @@ -0,0 +1,98 @@ +--TEST-- +mysqli_stmt_fetch() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + /* + NOTE: no datatype tests here! This is done by + mysqli_stmt_bind_result.phpt already. Restrict + this test case to the basics. + */ + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_fetch())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_fetch($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + // stmt object status test + if (NULL !== ($tmp = mysqli_stmt_fetch($stmt))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2")) + printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + // FIXME - different versions return different values ?! + if ((NULL !== ($tmp = mysqli_stmt_fetch($stmt))) && (false !== $tmp)) + printf("[006] Expecting NULL or boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_execute($stmt)) + printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (true !== ($tmp = mysqli_stmt_fetch($stmt))) + printf("[008] NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + if (!$stmt = mysqli_stmt_init($link)) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2")) + printf("[010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[011] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = NULL; + $label = NULL; + if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label))) + printf("[012] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_stmt_fetch($stmt))) + printf("[013] Expecting boolean/true, got %s/%s, [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_kill($link, mysqli_thread_id($link))) + printf("[014] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (true !== ($tmp = mysqli_stmt_fetch($stmt))) + printf("[015] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + + if (NULL !== ($tmp = mysqli_stmt_fetch($stmt))) + printf("[016] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + /* Check that the function alias exists. It's a deprecated function, + but we have not announce the removal so far, therefore we need to check for it */ + if (!is_null($tmp = @mysqli_stmt_fetch())) + printf("[017] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_fetch(): invalid object or resource mysqli_stmt + in %s on line %d +[014] [%d] Commands out of sync; you can't run this command now + +Warning: mysqli_stmt_fetch(): Couldn't fetch mysqli_stmt in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_fetch_bit.phpt b/ext/mysqli/tests/mysqli_stmt_fetch_bit.phpt new file mode 100644 index 0000000..2a2914a --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_fetch_bit.phpt @@ -0,0 +1,76 @@ +--TEST-- +Fetching BIT column values using the PS API +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifemb.inc'); + require_once('skipifconnectfailure.inc'); + require_once('connect.inc'); + require_once('table.inc'); + if (mysqli_get_server_version($link) < 50003) + // b'001' syntax not supported before 5.0.3 + die("skip Syntax used for test not supported with MySQL Server before 5.0.3"); + if (!$IS_MYSQLND && (mysqli_get_client_version() < 50003)) + // better don't trust libmysql before 5.0.3 + die("skip Syntax used for test not supported with MySQL Server before 5.0.3"); +?> +--FILE-- +<?php + require('connect.inc'); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + /* NOTE: works only for up to 31 bits! This limitation should be documented. */ + for ($bits = 1; $bits < 32; $bits++) { + $max_value = pow(2, $bits) - 1; + $tests = 0; + if (!mysqli_query($link, "DROP TABLE IF EXISTS test") || + !mysqli_query($link, $sql = sprintf('CREATE TABLE test(id INT, label BIT(%d)) ENGINE="%s"', $bits, $engine))) + printf("[002 - %d] [%d] %s\n",$bits, mysqli_errno($link), mysqli_error($link)); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[003 - %d] [%d] %s\n", $bits, mysqli_errno($link), mysqli_error($link)); + + while ($tests < min($max_value, 20)) { + $tests++; + $value = mt_rand(0, $max_value); + $sql = sprintf("INSERT INTO test(id, label) VALUES (%d, b'%s')", $value, decbin($value)); + + if (!mysqli_stmt_prepare($stmt, $sql) || + !mysqli_stmt_execute($stmt)) + printf("[004 - %d] [%d] %s\n", $bits, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $_label0 = $label = null; + $sql = sprintf("SELECT id, label + 0 AS _label0, label FROM test WHERE id = %d", $value); + if (!mysqli_stmt_prepare($stmt, $sql) || + !mysqli_stmt_execute($stmt) || + !mysqli_stmt_bind_result($stmt, $id, $_label0, $label)) + printf("[005 - %d] [%d] %s\n", $bits, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_fetch($stmt)) + printf("[006 - %d] [%d] %s\n", $bits, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (($id !== $_label0) || ($value !== $_label0)) { + printf("[007 - %d] Insert of %d in BIT(%d) column might have failed. MySQL reports odd values, id = %s, _label0 = %s, label = %s.\n", $bits, $value, $bits, $id, $_label0, $label); + } + if ($value != $label) { + printf("[008 - %d] Wrong values, (original) value = %s, id = %s, label + 0 AS label0 = %s, label = %s\n", + $bits, $value, $id, $_label0, $label); + } + } + + mysqli_stmt_close($stmt); + + } + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_fetch_fields_win32_unicode.phpt b/ext/mysqli/tests/mysqli_stmt_fetch_fields_win32_unicode.phpt new file mode 100644 index 0000000..0cbc05f --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_fetch_fields_win32_unicode.phpt @@ -0,0 +1,56 @@ +--TEST-- +mysqli_stmt_fetch_fields() unicode, win32 +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + require_once('table.inc'); + + $bind_res = $id = null; + if (!($stmt = mysqli_stmt_init($link)) || + !mysqli_stmt_prepare($stmt, "SELECT id, label FROM test") || + !mysqli_stmt_execute($stmt) || + !($result = mysqli_stmt_result_metadata($stmt)) || + !mysqli_stmt_bind_result($stmt, $id, $bind_res) || + !($fields = mysqli_fetch_fields($result))) { + printf("FAIL 1\n"); + } + while (mysqli_stmt_fetch($stmt)) { + ; + } + mysqli_free_result($result); + mysqli_stmt_close($stmt); + + if (!($stmt = mysqli_stmt_init($link)) || + !mysqli_stmt_prepare($stmt, "SELECT id, label FROM test") || + !mysqli_stmt_execute($stmt) || + !($result = mysqli_stmt_result_metadata($stmt)) || + !mysqli_stmt_bind_result($stmt, $id, $bind_res)) { + printf("FAIL 2\n"); + } + print "OK: 1\n"; + if (!($fields = mysqli_fetch_fields($result))) + printf("Aua 3\n"); + print "OK: 2\n"; + while (mysqli_stmt_fetch($stmt)) { + ; + } + mysqli_free_result($result); + mysqli_stmt_close($stmt); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +OK: 1 +OK: 2 +done! diff --git a/ext/mysqli/tests/mysqli_stmt_fetch_geom.phpt b/ext/mysqli/tests/mysqli_stmt_fetch_geom.phpt new file mode 100644 index 0000000..84998b9 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_fetch_geom.phpt @@ -0,0 +1,141 @@ +--TEST-- +mysqli_stmt_fetch - geometry / spatial types +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifemb.inc'); + require_once('skipifconnectfailure.inc'); + + if (!defined("MYSQLI_TYPE_GEOMETRY")) + die("skip MYSQLI_TYPE_GEOMETRY not defined"); +?> +--FILE-- +<?php + require('connect.inc'); + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + function func_mysqli_stmt_fetch_geom($link, $engine, $sql_type, $bind_value, $offset) { + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) { + printf("[%04d] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!mysqli_query($link, sprintf("CREATE TABLE test(id INT, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { + // don't bail - column type might not be supported by the server, ignore this + return false; + } + + for ($id = 1; $id < 4; $id++) { + $sql = sprintf("INSERT INTO test(id, label) VALUES (%d, %s)", $id, $bind_value); + if (!mysqli_query($link, $sql)) { + printf("[%04d] [%d] %s\n", $offset + 2 + $id, mysqli_errno($link), mysqli_error($link)); + } + } + + if (!$stmt = mysqli_stmt_init($link)) { + printf("[%04d] [%d] %s\n", $offset + 6, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test")) { + printf("[%04d] [%d] %s\n", $offset + 7, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + mysqli_stmt_close($stmt); + return false; + } + + if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_store_result($stmt)) { + printf("[%04d] [%d] %s\n", $offset + 8, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + mysqli_stmt_close($stmt); + return false; + } + + if (!mysqli_stmt_bind_result($stmt, $id, $bind_res)) { + printf("[%04d] [%d] %s\n", $offset + 9, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + mysqli_stmt_close($stmt); + return false; + } + + $result = mysqli_stmt_result_metadata($stmt); + $fields = mysqli_fetch_fields($result); + if ($fields[1]->type != MYSQLI_TYPE_GEOMETRY) { + printf("[%04d] [%d] %s wrong type %d\n", $offset + 10, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), $fields[1]->type); + } + + $num = 0; + $rows = array(); + while (true === @mysqli_stmt_fetch($stmt)) { + $rows[] = array('id' => $id, 'label' => $bind_res); + $num++; + } + + if ($num != 3) { + printf("[%04d] [%d] %s, expecting 3 results, got only %d results\n", + $offset + 17, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), $num); + return false; + } + mysqli_stmt_close($stmt); + + foreach ($rows as $row) { + if (!$stmt = mysqli_stmt_init($link)) { + printf("[%04d] [%d] %s\n", $offset + 10, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)")) { + printf("[%04d] [%d] %s\n", $offset + 11, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + $new_id = $row['id'] + 10; + if (!mysqli_stmt_bind_param($stmt, "is", $new_id, $row['label'])) { + printf("[%04d] [%d] %s\n", $offset + 12, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if (!mysqli_stmt_execute($stmt)) { + printf("[%04d] [%d] %s\n", $offset + 13, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + mysqli_stmt_close($stmt); + + if (!$res_normal = mysqli_query($link, sprintf("SELECT id, label FROM test WHERE id = %d", + $new_id))) { + printf("[%04d] [%d] %s\n", $offset + 14, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!$row_normal = mysqli_fetch_assoc($res_normal)) { + printf("[%04d] [%d] %s\n", $offset + 15, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if ($row_normal['label'] != $row['label']) { + printf("[%04d] PS and non-PS return different data.\n", $offset + 16); + return false; + } + mysqli_free_result($res_normal); + } + + return true; + } + + func_mysqli_stmt_fetch_geom($link, $engine, "GEOMETRY", "GeomFromText('POINT(2 2)')", 20); + func_mysqli_stmt_fetch_geom($link, $engine, "POINT", "GeomFromText('POINT(1 1)')", 40); + func_mysqli_stmt_fetch_geom($link, $engine, "LINESTRING", "GeomFromText('LINESTRING(0 0,1 1,2 2)')", 60); + func_mysqli_stmt_fetch_geom($link, $engine, "POLYGON", "GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))')", 80); + func_mysqli_stmt_fetch_geom($link, $engine, "MULTIPOINT", "GeomFromText('MULTIPOINT(1 1, 2 2)')", 100); + func_mysqli_stmt_fetch_geom($link, $engine, "MULTILINESTRING", "GeomFromText('MULTILINESTRING((0 0,1 1,2 2),(0 0,1 1,3 3))')", 120); + func_mysqli_stmt_fetch_geom($link, $engine, "MULTIPOLYGON", "GeomFromText('MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5)),((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5)))')", 140); + func_mysqli_stmt_fetch_geom($link, $engine, "GEOMETRYCOLLECTION", "GeomFromText('GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))')", 160); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_field_count.phpt b/ext/mysqli/tests/mysqli_stmt_field_count.phpt new file mode 100644 index 0000000..7dfd3a4 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_field_count.phpt @@ -0,0 +1,100 @@ +--TEST-- +mysqli_stmt_field_counts() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_field_count())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_field_count($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + $stmt = mysqli_stmt_init($link); + if (!is_null($tmp = mysqli_stmt_field_count($stmt))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (mysqli_stmt_prepare($stmt, '')) + printf("[004] Prepare should fail for an empty statement\n"); + if (!is_null($tmp = mysqli_stmt_field_count($stmt))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, 'SELECT 1')) + printf("[006] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + if (1 !== ($tmp = mysqli_stmt_field_count($stmt))) + printf("[007] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, 'SELECT 1, 2')) + printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + if (2 !== ($tmp = mysqli_stmt_field_count($stmt))) + printf("[009] Expecting int/2, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test')) + printf("[010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + if (2 !== ($tmp = mysqli_stmt_field_count($stmt))) + printf("[011] Expecting int/2, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, 'SELECT label FROM test') || + !mysqli_stmt_execute($stmt)) + printf("[012] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + if (1 !== ($tmp = mysqli_stmt_field_count($stmt))) + printf("[013] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + + $label = null; + if (mysqli_stmt_bind_param($stmt, "s", $label)) + printf("[014] expected error - got ok\n"); + while (mysqli_stmt_fetch($stmt)) + if (1 !== ($tmp = mysqli_stmt_field_count($stmt))) + printf("[015] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, 'INSERT INTO test(id) VALUES (100)')) + printf("[016] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + if (0 !== ($tmp = mysqli_stmt_field_count($stmt))) + printf("[017] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, "UPDATE test SET label = 'z' WHERE id = 1") || + !mysqli_stmt_execute($stmt)) + printf("[018] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (0 !== ($tmp = mysqli_stmt_field_count($stmt))) + printf("[019] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + + if (mysqli_stmt_prepare($stmt, 'SELECT id FROM test')) + printf("[020] Prepare should fail, statement has been closed\n"); + if (!is_null($tmp = mysqli_stmt_field_count($stmt))) + printf("[011] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_field_count(): invalid object or resource mysqli_stmt + in %s on line %d + +Warning: mysqli_stmt_field_count(): invalid object or resource mysqli_stmt + in %s on line %d + +Warning: mysqli_stmt_bind_param(): Number of variables doesn't match number of parameters in prepared statement in %s on line %d + +Warning: mysqli_stmt_prepare(): Couldn't fetch mysqli_stmt in %s on line %d + +Warning: mysqli_stmt_field_count(): Couldn't fetch mysqli_stmt in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_free_result.phpt b/ext/mysqli/tests/mysqli_stmt_free_result.phpt new file mode 100644 index 0000000..08b33b7 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_free_result.phpt @@ -0,0 +1,86 @@ +--TEST-- +mysqli_stmt_free_result() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + /* + NOTE: no datatype tests here! This is done by + mysqli_stmt_bind_result.phpt already. Restrict + this test case to the basics. + */ + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_free_result())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_free_result($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + // stmt object status test + if (NULL !== ($tmp = mysqli_stmt_free_result($stmt))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id")) + printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (NULL !== ($tmp = mysqli_stmt_free_result($stmt))) + printf("[006] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_execute($stmt)) + printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (NULL !== ($tmp = mysqli_stmt_free_result($stmt))) + printf("[008] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = mysqli_stmt_store_result($stmt))) + printf("[009] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id")) + printf("[011] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[012] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (true !== ($tmp = mysqli_stmt_store_result($stmt))) + printf("[013] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = mysqli_stmt_free_result($stmt))) + printf("[014] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + + if (NULL !== ($tmp = mysqli_stmt_free_result($stmt))) + printf("[015] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_free_result(): invalid object or resource mysqli_stmt + in %s on line %d + +Warning: mysqli_stmt_free_result(): Couldn't fetch mysqli_stmt in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_get_result.phpt b/ext/mysqli/tests/mysqli_stmt_get_result.phpt new file mode 100644 index 0000000..fe18be4 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_get_result.phpt @@ -0,0 +1,187 @@ +--TEST-- +mysqli_stmt_get_result() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_stmt_get_result')) + die('skip mysqli_stmt_get_result not available'); +?> +--FILE-- +<?php + /* + NOTE: no datatype tests here! This is done by + mysqli_stmt_bind_result.phpt already. Restrict + this test case to the basics. + */ + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_get_result())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_get_result($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + // stmt object status test + if (NULL !== ($tmp = mysqli_stmt_fetch($stmt))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2")) + printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + // FIXME - different versions return different values ?! + if ((NULL !== ($tmp = mysqli_stmt_get_result($stmt))) && (false !== $tmp)) + printf("[006] Expecting NULL or boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + + if (!mysqli_stmt_execute($stmt)) + printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_store_result($stmt)) + printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (is_object($tmp = mysqli_stmt_store_result($stmt))) + printf("[009] non-object, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + + mysqli_stmt_close($stmt); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + // stmt object status test + if (NULL !== ($tmp = mysqli_stmt_fetch($stmt))) + printf("[011] Expecting NULL, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2")) + printf("[012] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + // FIXME - different versions return different values ?! + if ((NULL !== ($tmp = mysqli_stmt_get_result($stmt))) && (false !== $tmp)) + printf("[013] Expecting NULL or boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + + if (!mysqli_stmt_execute($stmt)) + printf("[014] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!is_object($tmp = mysqli_stmt_get_result($stmt))) + printf("[016] NULL, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + + mysqli_free_result($tmp); + mysqli_stmt_close($stmt); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[017] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + // stmt object status test + if (NULL !== ($tmp = mysqli_stmt_get_result($stmt))) + printf("[018] Expecting NULL, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2")) + printf("[019] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (false !== ($tmp = mysqli_stmt_get_result($stmt))) + printf("[020] Expecting false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + + if (!mysqli_stmt_execute($stmt)) + printf("[023] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!is_object($tmp = mysqli_stmt_get_result($stmt))) + printf("[024] Expecting object, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + + if (false !== ($tmp = mysqli_stmt_fetch($stmt))) + printf("[025] false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + + if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label))) { + printf("[026] [%d] [%s]\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + printf("[027] [%d] [%s]\n", mysqli_errno($link), mysqli_error($link)); + printf("[028] Expecting boolean/true, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + } + + if (false !== ($tmp = mysqli_stmt_fetch($stmt))) + printf("[029] false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + + mysqli_stmt_close($stmt); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[032] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2")) + printf("[033] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[034] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = NULL; + $label = NULL; + if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label))) + printf("[035] Expecting boolean/true, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + + if (!is_object($tmp = $result = mysqli_stmt_get_result($stmt))) + printf("[036] Expecting array, got %s/%s, [%d] %s\n", + gettype($tmp), var_export($tmp, 1), + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (false !== ($tmp = mysqli_stmt_fetch($stmt))) + printf("[037] Expecting boolean/false, got %s/%s, [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + printf("[038] [%d] [%s]\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + printf("[039] [%d] [%s]\n", mysqli_errno($link), mysqli_error($link)); + while ($row = mysqli_fetch_assoc($result)) { + var_dump($row); + } + mysqli_free_result($result); + + if (!mysqli_kill($link, mysqli_thread_id($link))) + printf("[040] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (false !== ($tmp = mysqli_stmt_get_result($stmt))) + printf("[041] Expecting false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + + mysqli_stmt_close($stmt); + + if (NULL !== ($tmp = mysqli_stmt_fetch($stmt))) + printf("[042] Expecting NULL, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_fetch(): invalid object or resource mysqli_stmt + in %s on line %d + +Warning: mysqli_stmt_fetch(): invalid object or resource mysqli_stmt + in %s on line %d + +Warning: mysqli_stmt_get_result(): invalid object or resource mysqli_stmt + in %s on line %d +[038] [2014] [Commands out of sync; you can't run this command now] +[039] [0] [] +array(2) { + [%u|b%"id"]=> + int(1) + [%u|b%"label"]=> + %s(1) "a" +} +array(2) { + [%u|b%"id"]=> + int(2) + [%u|b%"label"]=> + %s(1) "b" +} + +Warning: mysqli_stmt_fetch(): Couldn't fetch mysqli_stmt in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_get_result2.phpt b/ext/mysqli/tests/mysqli_stmt_get_result2.phpt new file mode 100644 index 0000000..8c2aad1 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_get_result2.phpt @@ -0,0 +1,176 @@ +--TEST-- +mysqli_stmt_get_result() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +if (!function_exists('mysqli_stmt_get_result')) + die('skip mysqli_stmt_get_result not available'); +?> +--FILE-- +<?php + /* + NOTE: no datatype tests here! This is done by + mysqli_stmt_bind_result.phpt already. Restrict + this test case to the basics. + */ + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_get_result())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_get_result($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_null($tmp = @mysqli_stmt_get_result($stmt, "foo"))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id ASC LIMIT 1")) + printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[006] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) { + printf("[007] Expecting object/mysqli_result got %s/%s, [%d] %s\n", + gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + while ($row = mysqli_fetch_assoc($res)) + var_dump($row); + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + + if (false !== ($res = mysqli_stmt_get_result($stmt))) { + printf("[008] boolean/false got %s/%s, [%d] %s\n", + gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + mysqli_stmt_execute($stmt); + if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) { + printf("[009] Expecting object/mysqli_result got %s/%s, [%d] %s\n", + gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + while ($row = mysqli_fetch_assoc($res)) + var_dump($row); + var_dump(mysqli_fetch_assoc($res)); + mysqli_free_result($res); + + mysqli_stmt_close($stmt); + + if (!($stmt = mysqli_stmt_init($link)) || + !mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id ASC LIMIT 2") || + !mysqli_stmt_execute($stmt)) + printf("[010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = $label = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label)) + printf("[011] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_fetch($stmt)) + printf("[012] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (false !== ($res = mysqli_stmt_get_result($stmt))) { + printf("[013] boolean/false got %s/%s, [%d] %s\n", + gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + mysqli_stmt_close($stmt); + + if (!($stmt = mysqli_stmt_init($link)) || + !mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id ASC LIMIT 2") || + !mysqli_stmt_execute($stmt)) + printf("[014] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) { + printf("[015] Expecting object/mysqli_result got %s/%s, [%d] %s\n", + gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + $id = $label = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label)) + printf("[016] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_fetch($stmt)) + printf("[017] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + mysqli_stmt_close($stmt); + + if (!($stmt = mysqli_stmt_init($link)) || + !mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id ASC LIMIT 2") || + !mysqli_stmt_execute($stmt)) + printf("[018] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) { + printf("[019] Expecting object/mysqli_result got %s/%s, [%d] %s\n", + gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + $id = $label = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label)) + printf("[020] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $row = mysqli_fetch_assoc($res); + if (NULL !== $id || NULL !== $label) + printf("[021] Bound variables should not have been set\n"); + mysqli_free_result($res); + + mysqli_stmt_close($stmt); + + if (!($stmt = mysqli_stmt_init($link)) || + !mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id ASC LIMIT 2") || + !mysqli_stmt_execute($stmt)) + printf("[022] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) { + printf("[023] Expecting object/mysqli_result got %s/%s, [%d] %s\n", + gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + if (!in_array($res->type, array(MYSQLI_STORE_RESULT, MYSQLI_USE_RESULT))) { + printf("[024] Unknown result set type %s\n", $res->type); + } + if ($res->type !== MYSQLI_STORE_RESULT) + printf("[025] Expecting int/%d got %s/%s", MYSQLI_STORE_RESULT, gettype($res->type), $res->type); + + mysqli_free_result($res); + mysqli_stmt_close($stmt); + mysqli_close($link); + + if (NULL !== ($res = mysqli_stmt_get_result($stmt))) { + printf("[022] Expecting NULL got %s/%s\n", + gettype($res), $res); + } + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +array(2) { + [%u|b%"id"]=> + int(1) + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +NULL +array(2) { + [%u|b%"id"]=> + int(1) + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +NULL +[017] [2014] Commands out of sync; you can't run this command now + +Warning: mysqli_stmt_get_result(): Couldn't fetch mysqli_stmt in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt new file mode 100644 index 0000000..6c476f7 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt @@ -0,0 +1,133 @@ +--TEST-- +Fetching BIT column values using the PS API +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifemb.inc'); + require_once('skipifconnectfailure.inc'); + + if (!function_exists('mysqli_stmt_get_result')) + die("skip mysqli_stmt_get_result() not available"); + + require_once('connect.inc'); + require_once('table.inc'); + if (mysqli_get_server_version($link) < 50003) + // b'001' syntax not supported before 5.0.3 + die("skip Syntax used for test not supported with MySQL Server before 5.0.3"); + if (!$IS_MYSQLND && (mysqli_get_client_version() < 50003)) + // better don't trust libmysql before 5.0.3 + die("skip Syntax used for test not supported with MySQL Server before 5.0.3"); +?> +--FILE-- +<?php + require('connect.inc'); + + function dec32bin($dec, $bits) { + + $maxval = pow(2, $bits); + $bin = ''; + for ($bitval = $maxval; $bitval >= 1; $bitval = $bitval / 2) { + if (($dec / $bitval) >= 1) { + $bin .= '1'; + $dec -= $bitval; + } else { + $bin .= '0'; + } + } + return $bin; + } + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + for ($bits = 1; $bits <= 46; $bits++) { + if (1 == $bits) + $max_value = 1; + else + $max_value = pow(2, $bits) - 1; + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test") || + !mysqli_query($link, $sql = sprintf('CREATE TABLE test(id BIGINT UNSIGNED, bit_value BIT(%d) NOT NULL, bit_null BIT(%d) DEFAULT NULL) ENGINE="%s"', $bits, $bits, $engine))) + printf("[002 - %d] [%d] %s\n",$bits, mysqli_errno($link), mysqli_error($link)); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[003 - %d] [%d] %s\n", $bits, mysqli_errno($link), mysqli_error($link)); + + $tests = 0; + $rand_max = mt_getrandmax(); + while ($tests < 10) { + + $tests++; + if (1 == $tests) + $value = 0; + else if (2 == $tests) + $value = $max_value; + else { + if ($max_value > $rand_max) { + $max_loops = floor($max_value/$rand_max); + $num_loops = mt_rand(1, $max_loops); + $value = 0; + for ($i = 0; $i < $num_loops; $i++) + $value += mt_rand(0, $rand_max); + } else { + $value = mt_rand(0, $max_value); + } + } + + $bin = ($bits < 32) ? decbin($value) : dec32bin($value, $bits); + $sql = sprintf("INSERT INTO test(id, bit_value) VALUES (%s, b'%s')", $value, $bin); + for ($i = 0; ($i < strlen($bin)) && ($bin[$i] == '0'); $i++) + ; + $bin2 = substr($bin, $i, strlen($bin)); + + if (!mysqli_stmt_prepare($stmt, $sql) || + !mysqli_stmt_execute($stmt)) + printf("[004 - %d] [%d] %s\n", $bits, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $sql = sprintf("SELECT bin(bit_value) AS _bin, id, bit_value, bit_null FROM test WHERE id = %s", $value); + if (!mysqli_stmt_prepare($stmt, $sql) || + !mysqli_stmt_execute($stmt)) + printf("[005 - %d] [%d] %s\n", $bits, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!$res = mysqli_stmt_get_result($stmt)) + printf("[006 - %d] [%d] %s\n", $bits, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[007 - %d] [%d] %s\n", $bits, mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + + if (($value != $row['id']) || (($bin != $row['_bin']) && ($bin2 != $row['_bin']))) { + debug_zval_dump($row); + printf("[008 - %d] Insert of %s in BIT(%d) column might have failed. id = %s, bin = %s (%s/%s)\n", + $bits, $value, $bits, $row['id'], $row['_bin'], $bin, $bin2); + break; + } + if ($value != $row['bit_value']) { + debug_zval_dump($row); + printf("%10s %64s\n%10s %64s\n", '_bin', $row['_bin'], 'insert', $bin); + printf("[009 - %d] Expecting %s got %s\n", $bits, $value, $row['bit_value']); + break; + } + + if (null !== $row['bit_null']) { + debug_zval_dump($row); + printf("[010 - %d] Expecting null got %s/%s\n", $bits, gettype($row['bit_value']), $row['bit_value']); + break; + } + + } + + mysqli_stmt_close($stmt); + + } + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_field_count.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_field_count.phpt new file mode 100644 index 0000000..046f904 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_get_result_field_count.phpt @@ -0,0 +1,50 @@ +--TEST-- +mysqli_stmt_get_result() - meta data, field_count() +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifemb.inc'); + require_once('skipifconnectfailure.inc'); + + if (!function_exists('mysqli_stmt_get_result')) + die('skip mysqli_stmt_get_result not available'); +?> +--FILE-- +<?php + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id ASC LIMIT 3")) + printf("[002] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[003] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) { + printf("[004] Expecting object/mysqli_result got %s/%s, [%d] %s\n", + gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + if (!is_object($res_meta = mysqli_stmt_result_metadata($stmt)) || + 'mysqli_result' != get_class($res_meta)) { + printf("[005] Expecting object/mysqli_result got %s/%s, [%d] %s\n", + gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + printf("%s %s\n", + $res_meta->field_count, + $res->field_count); + + mysqli_stmt_close($stmt); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +2 2 +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_geom.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_geom.phpt new file mode 100644 index 0000000..c86a385 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_get_result_geom.phpt @@ -0,0 +1,143 @@ +--TEST-- +mysqli_stmt_get_result - geometry / spatial types +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifemb.inc'); + require_once('skipifconnectfailure.inc'); + + if (!function_exists('mysqli_stmt_get_result')) + die("skip mysqli_stmt_get_result() not available"); + + if (!defined("MYSQLI_TYPE_GEOMETRY")) + die("skip MYSQLI_TYPE_GEOMETRY not defined"); +?> +--FILE-- +<?php + require('connect.inc'); + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + function func_mysqli_stmt_get_result_geom($link, $engine, $sql_type, $bind_value, $offset) { + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) { + printf("[%04d] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!mysqli_query($link, sprintf("CREATE TABLE test(id INT, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { + // don't bail - column type might not be supported by the server, ignore this + return false; + } + + for ($id = 1; $id < 4; $id++) { + $sql = sprintf("INSERT INTO test(id, label) VALUES (%d, %s)", $id, $bind_value); + if (!mysqli_query($link, $sql)) { + printf("[%04d] [%d] %s\n", $offset + 2 + $id, mysqli_errno($link), mysqli_error($link)); + } + } + + if (!$stmt = mysqli_stmt_init($link)) { + printf("[%04d] [%d] %s\n", $offset + 6, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test")) { + printf("[%04d] [%d] %s\n", $offset + 7, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + mysqli_stmt_close($stmt); + return false; + } + + if (!mysqli_stmt_execute($stmt)) { + printf("[%04d] [%d] %s\n", $offset + 8, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + mysqli_stmt_close($stmt); + return false; + } + if (!$res = mysqli_stmt_get_result($stmt)) { + printf("[%04d] [%d] %s\n", $offset + 9, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + mysqli_stmt_close($stmt); + return false; + } + + $result = mysqli_stmt_result_metadata($stmt); + $fields = mysqli_fetch_fields($result); + if ($fields[1]->type != MYSQLI_TYPE_GEOMETRY) { + printf("[%04d] [%d] %s wrong type %d\n", $offset + 10, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), $fields[1]->type); + } + + $num = 0; + while ($row = mysqli_fetch_assoc($res)) { + $bind_res = &$row['label']; + + if (!$stmt2 = mysqli_stmt_init($link)) { + printf("[%04d] [%d] %s\n", $offset + 11, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!mysqli_stmt_prepare($stmt2, "INSERT INTO test(id, label) VALUES (?, ?)")) { + printf("[%04d] [%d] %s\n", $offset + 12, mysqli_stmt_errno($stmt2), mysqli_stmt_error($stmt2)); + return false; + } + + $id = $row['id'] + 10; + if (!mysqli_stmt_bind_param($stmt2, "is", $id, $bind_res)) { + printf("[%04d] [%d] %s\n", $offset + 13, mysqli_stmt_errno($stmt2), mysqli_stmt_error($stmt2)); + return false; + } + + if (!mysqli_stmt_execute($stmt2)) { + printf("[%04d] [%d] %s\n", $offset + 14, mysqli_stmt_errno($stmt2), mysqli_stmt_error($stmt2)); + return false; + } + mysqli_stmt_close($stmt2); + + if (!$res_normal = mysqli_query($link, sprintf("SELECT id, label FROM test WHERE id = %d", + $row['id'] + 10))) { + printf("[%04d] [%d] %s\n", $offset + 15, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!$row_normal = mysqli_fetch_assoc($res_normal)) { + printf("[%04d] [%d] %s\n", $offset + 16, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if ($row_normal['label'] != $bind_res) { + printf("[%04d] PS and non-PS return different data.\n", $offset + 17); + return false; + } + mysqli_free_result($res_normal); + $num++; + } + + if ($num != 3) { + printf("[%04d] [%d] %s, expecting 3 results, got only %d results\n", + $offset + 18, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), $num); + mysqli_free_result($res); + mysqli_stmt_close($stmt); + return false; + } + mysqli_free_result($res); + mysqli_stmt_close($stmt); + + return true; + } + + func_mysqli_stmt_get_result_geom($link, $engine, "GEOMETRY", "GeomFromText('POINT(2 2)')", 20); + func_mysqli_stmt_get_result_geom($link, $engine, "POINT", "GeomFromText('POINT(1 1)')", 40); + func_mysqli_stmt_get_result_geom($link, $engine, "LINESTRING", "GeomFromText('LINESTRING(0 0,1 1,2 2)')", 60); + func_mysqli_stmt_get_result_geom($link, $engine, "POLYGON", "GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))')", 80); + func_mysqli_stmt_get_result_geom($link, $engine, "MULTIPOINT", "GeomFromText('MULTIPOINT(1 1, 2 2)')", 100); + func_mysqli_stmt_get_result_geom($link, $engine, "MULTILINESTRING", "GeomFromText('MULTILINESTRING((0 0,1 1,2 2),(0 0,1 1,3 3))')", 120); + func_mysqli_stmt_get_result_geom($link, $engine, "MULTIPOLYGON", "GeomFromText('MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5)),((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5)))')", 140); + func_mysqli_stmt_get_result_geom($link, $engine, "GEOMETRYCOLLECTION", "GeomFromText('GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))')", 160); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt new file mode 100644 index 0000000..8689880 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt @@ -0,0 +1,237 @@ +--TEST-- +mysqli_stmt_get_result() - meta data +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_stmt_get_result')) + die('skip mysqli_stmt_get_result not available'); +?> +--FILE-- +<?php + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id ASC LIMIT 3")) + printf("[002] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[003] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) { + printf("[004] Expecting object/mysqli_result got %s/%s, [%d] %s\n", + gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + if (!is_object($res_meta = mysqli_stmt_result_metadata($stmt)) || + 'mysqli_result' != get_class($res_meta)) { + printf("[005] Expecting object/mysqli_result got %s/%s, [%d] %s\n", + gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + var_dump(mysqli_fetch_assoc($res)); + var_dump(mysqli_fetch_assoc($res_meta)); + + mysqli_free_result($res); + mysqli_free_result($res_meta); + mysqli_stmt_close($stmt); + + // !mysqli_stmt_prepare($stmt, "SELECT id, label, id + 1 as _id, concat(label, '_') _label FROM test as _test ORDER BY id ASC LIMIT 3") || + if (!($stmt = mysqli_stmt_init($link)) || + !mysqli_stmt_prepare($stmt, "SELECT id , label, id + 1 AS _id, label AS _label, null AS _null, CONCAT(label, '_') _label_concat FROM test _test ORDER BY id ASC LIMIT 3") || + !mysqli_stmt_execute($stmt)) + printf("[006] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) { + printf("[007] Expecting object/mysqli_result got %s/%s, [%d] %s\n", + gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + if (!is_object($res_meta = mysqli_stmt_result_metadata($stmt)) || + 'mysqli_result' != get_class($res_meta)) { + printf("[008] Expecting object/mysqli_result got %s/%s, [%d] %s\n", + gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + if (($tmp1 = mysqli_num_fields($res)) !== ($tmp2 = mysqli_num_fields($res_meta))) { + printf("[009] %s/%s !== %s/%s\n", gettype($tmp1), $tmp1, gettype($tmp2), $tmp2); + } + + /* + if (($tmp1 = mysqli_field_count($link)) !== ($tmp2 = $res->field_count())) + printf("[010] %s/%s !== %s/%s\n", gettype($tmp1), $tmp1, gettype($tmp2), $tmp2); + + if (($tmp1 = $res_meta->field_count()) !== $tmp2) + printf("[011] %s/%s !== %s/%s\n", gettype($tmp1), $tmp1, gettype($tmp2), $tmp2); + */ + + if (($tmp1 = mysqli_field_tell($res)) !== ($tmp2 = $res_meta->current_field)) + printf("[012] %s/%s !== %s/%s\n", gettype($tmp1), $tmp1, gettype($tmp2), $tmp2); + + if (0 !== $tmp1) + printf("[013] Expecting int/0 got %s/%s\n", gettype($tmp1), $tmp1); + + $fields = array(); + while ($info = $res->fetch_field()) + $fields['res'][] = $info; + var_dump($info); + while ($info = $res_meta->fetch_field()) + $fields['meta'][] = $info; + var_dump($info); + $fields['all_res'] = $res->fetch_fields(); + $fields['all_meta'] = $res_meta->fetch_fields(); + + if (count($fields['res']) != count($fields['meta'])) { + printf("[014] stmt_get_result indicates %d fields, stmt_result_metadata indicates %d fields\n", + count($fields['res']), + count($fields['meta'])); + } + + foreach ($fields['res'] as $k => $info) { + printf("%s\n", $info->name); + if ($info->name !== $fields['meta'][$k]->name) + printf("[015 - %d] Expecting name %s/%s got %s/%s\n", + $k, gettype($info->name), $info->name, gettype($fields['meta'][$k]->name), $fields['meta'][$k]->name); + + if ($info->orgname !== $fields['meta'][$k]->orgname) + printf("[016 - %d] Expecting orgname %s/%s got %s/%s\n", + $k, gettype($info->orgname), $info->orgname, gettype($fields['meta'][$k]->orgname), $fields['meta'][$k]->orgname); + + if ($info->table !== $fields['meta'][$k]->table) + printf("[017 - %d] Expecting table %s/%s got %s/%s\n", + $k, gettype($info->table), $info->table, gettype($fields['meta'][$k]->table), $fields['meta'][$k]->table); + + if ($info->orgtable !== $fields['meta'][$k]->orgtable) + printf("[018 - %d] Expecting orgtable %s/%s got %s/%s\n", + $k, gettype($info->orgtable), $info->orgtable, gettype($fields['meta'][$k]->orgtable), $fields['meta'][$k]->orgtable); + + if ($info->def !== $fields['meta'][$k]->def) + printf("[019 - %d] Expecting def %s/%s got %s/%s\n", + $k, gettype($info->def), $info->def, gettype($fields['meta'][$k]->def), $fields['meta'][$k]->def); +/* + if ($info->max_length !== $fields['meta'][$k]->max_length) + printf("[020 - %d] Expecting max_length %s/%s got %s/%s\n", + $k, gettype($info->max_length), $info->max_length, gettype($fields['meta'][$k]->max_length), $fields['meta'][$k]->max_length); +*/ + if ($info->length !== $fields['meta'][$k]->length) + printf("[021 - %d] Expecting length %s/%s got %s/%s\n", + $k, gettype($info->length), $info->length, gettype($fields['meta'][$k]->length), $fields['meta'][$k]->length); + + if ($info->charsetnr !== $fields['meta'][$k]->charsetnr) + printf("[022 - %d] Expecting charsetnr %s/%s got %s/%s\n", + $k, gettype($info->charsetnr), $info->charsetnr, gettype($fields['meta'][$k]->charsetnr), $fields['meta'][$k]->charsetnr); + + if ($info->flags !== $fields['meta'][$k]->flags) + printf("[023 - %d] Expecting flags %s/%s got %s/%s\n", + $k, gettype($info->flags), $info->flags, gettype($fields['meta'][$k]->flags), $fields['meta'][$k]->flags); + + if ($info->type !== $fields['meta'][$k]->type) + printf("[024 - %d] Expecting type %s/%s got %s/%s\n", + $k, gettype($info->type), $info->type, gettype($fields['meta'][$k]->type), $fields['meta'][$k]->type); + + if ($info->decimals !== $fields['meta'][$k]->decimals) + printf("[025 - %d] Expecting decimals %s/%s got %s/%s\n", + $k, getdecimals($info->decimals), $info->decimals, getdecimals($fields['meta'][$k]->decimals), $fields['meta'][$k]->decimals); + + /* Make them equal for the check */ + $tmp = $fields['all_res'][$k]->max_length; + $fields['all_res'][$k]->max_length = $fields['all_meta'][$k]->max_length; + + if ($fields['all_res'][$k] != $fields['all_meta'][$k]) { + printf("[026 - %d] fetch_fields() seems to have returned different data, dumping\n", $k); + var_dump($fields['all_res'][$k]); + var_dump($fields['all_meta'][$k]); + } + $fields['all_res'][$k]->max_length = $tmp; + } + + $num = count($fields['res']); + for ($i = 0; $i < 100; $i++) { + $pos = mt_rand(-1, $num + 1); + if ($pos >= 0 && $pos < $num) { + if (true !== mysqli_field_seek($res, $pos)) + printf("[027] field_seek(res) failed\n"); + if (true !== $res_meta->field_seek($pos)) + printf("[028] field_seek(res__meta) failed\n"); + + $tmp1 = $res->fetch_field(); + $tmp2 = mysqli_fetch_field($res_meta); + $tmp2->max_length = $tmp1->max_length; + if ($tmp1 != $tmp2) { + printf("[029] Field info differs, dumping data\n"); + var_dump($tmp1); + var_dump($tmp2); + } + + if ($tmp1 != $fields['res'][$pos]) { + printf("[030] Field info differs, dumping data\n"); + var_dump($tmp1); + var_dump($fields['res'][$pos]); + } + + $pos++; + if ($pos !== ($tmp = mysqli_field_tell($res))) + printf("[031] Expecting %s/%s got %s/%s\n", + gettype($pos), $pos, gettype($tmp), $tmp); + + if ($pos !== ($tmp = mysqli_field_tell($res_meta))) + printf("[032] Expecting %s/%s got %s/%s\n", + gettype($pos), $pos, gettype($tmp), $tmp); + } else { + + if (false !== @mysqli_field_seek($res, $pos)) + printf("[033] field_seek(%d) did not fail\n", $pos); + if (false !== @mysqli_field_seek($res_meta, $pos)) + printf("[034] field_seek(%d) did not fail\n", $pos); + } + } + + $res->free_result(); + mysqli_free_result($res_meta); + + var_dump(mysqli_fetch_field($res)); + + mysqli_stmt_close($stmt); + + var_dump(mysqli_fetch_field($res)); + + mysqli_close($link); + + var_dump(mysqli_fetch_field($res)); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +array(2) { + [%u|b%"id"]=> + int(1) + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +NULL +bool(false) +bool(false) +id +label +_id +_label +_null +_label_concat + +Warning: mysqli_fetch_field(): Couldn't fetch mysqli_result in %s on line %d +NULL + +Warning: mysqli_fetch_field(): Couldn't fetch mysqli_result in %s on line %d +NULL + +Warning: mysqli_fetch_field(): Couldn't fetch mysqli_result in %s on line %d +NULL +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt new file mode 100644 index 0000000..afaccaf --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt @@ -0,0 +1,176 @@ +--TEST-- +mysqli_stmt_get_result() - meta data, field info +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_stmt_get_result')) + die('skip mysqli_stmt_get_result not available'); +?> +--FILE-- +<?php + require('table.inc'); + $charsets = my_get_charsets($link); + + if (!($stmt = mysqli_stmt_init($link)) || + !mysqli_stmt_prepare($stmt, "SELECT id, label, id + 1 as _id, concat(label, '_') ___label FROM test ORDER BY id ASC LIMIT 3") || + !mysqli_stmt_execute($stmt)) + printf("[001] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) { + printf("[002] Expecting object/mysqli_result got %s/%s, [%d] %s\n", + gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + if (!is_object($res_meta = mysqli_stmt_result_metadata($stmt)) || + 'mysqli_result' != get_class($res_meta)) { + printf("[003] Expecting object/mysqli_result got %s/%s, [%d] %s\n", + gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + $i = 0; + while ($field = $res->fetch_field()) { + var_dump($field); + $i++; + if (2 == $i) { + /* + Label column, result set charset. + All of the following columns are "too hot" - too server dependent + */ + if ($field->charsetnr != $charsets['results']['nr']) { + printf("[004] Expecting charset %s/%d got %d\n", + $charsets['results']['charset'], + $charsets['results']['nr'], $field->charsetnr); + } + if ($field->length != (1 * $charsets['results']['maxlen'])) { + printf("[005] Expecting length %d got %d\n", + $charsets['results']['maxlen'], + $field->max_length); + } + } + } + + mysqli_stmt_close($stmt); + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(2) "id" + [%u|b%"orgname"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"orgtable"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(0) + [%u|b%"length"]=> + int(11) + [%u|b%"charsetnr"]=> + int(63) + [%u|b%"flags"]=> + int(49155) + [%u|b%"type"]=> + int(3) + [%u|b%"decimals"]=> + int(0) +} +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(5) "label" + [%u|b%"orgname"]=> + %unicode|string%(5) "label" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"orgtable"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(%d) + [%u|b%"length"]=> + int(%d) + [%u|b%"charsetnr"]=> + int(%d) + [%u|b%"flags"]=> + int(0) + [%u|b%"type"]=> + int(254) + [%u|b%"decimals"]=> + int(0) +} +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(3) "_id" + [%u|b%"orgname"]=> + %unicode|string%(0) "" + [%u|b%"table"]=> + %unicode|string%(0) "" + [%u|b%"orgtable"]=> + %unicode|string%(0) "" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(0) "" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(0) + [%u|b%"length"]=> + int(%d) + [%u|b%"charsetnr"]=> + int(63) + [%u|b%"flags"]=> + int(32897) + [%u|b%"type"]=> + int(8) + [%u|b%"decimals"]=> + int(0) +} +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(8) "___label" + [%u|b%"orgname"]=> + %unicode|string%(0) "" + [%u|b%"table"]=> + %unicode|string%(0) "" + [%u|b%"orgtable"]=> + %unicode|string%(0) "" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(0) "" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(%d) + [%u|b%"length"]=> + int(%d) + [%u|b%"charsetnr"]=> + int(%d) + [%u|b%"flags"]=> + int(0) + [%u|b%"type"]=> + int(253) + [%u|b%"decimals"]=> + int(31) +} +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_non_select.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_non_select.phpt new file mode 100644 index 0000000..c057f7d --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_get_result_non_select.phpt @@ -0,0 +1,95 @@ +--TEST-- +mysqli_stmt_get_result() - SHOW, DESCRIBE, EXPLAIN +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_stmt_get_result')) + die('skip mysqli_stmt_get_result not available'); +?> +--FILE-- +<?php + /* + NOTE: no datatype tests here! This is done by + mysqli_stmt_bind_result.phpt already. Restrict + this test case to the basics. + */ + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (mysqli_query($link, 'PREPARE mystmt FROM "SHOW ENGINES"')) { + mysqli_query($link, 'DEALLOCATE PREPARE mystmt'); + + if (!$stmt->prepare('SHOW ENGINES') || + !$stmt->execute()) + printf("[002] [%d] %s\n", $stmt->errno, $stmt->error); + + if (!$res = $stmt->get_result()) + printf("[003] [%d] %s\n", $stmt->errno, $stmt->error); + + $engines = mysqli_fetch_all($res, MYSQLI_NUM); + if (empty($engines)) { + printf("[004] It is very unlikely that SHOW ENGINES returns no data, check manually\n"); + } else { + $found = false; + foreach ($engines as $k => $engine) + foreach ($engine as $k => $v) + if (stristr('MyISAM', $v)) { + $found = true; + break; + } + if (!$found) + printf("[005] It is very unlikely that SHOW ENGINES does not show MyISAM, check manually\n"); + } + mysqli_free_result($res); + } + + if (mysqli_query($link, 'PREPARE mystmt FROM "DESCRIBE test id"')) { + mysqli_query($link, 'DEALLOCATE PREPARE mystmt'); + + if (!$stmt->prepare('DESCRIBE test id') || + !$stmt->execute()) + printf("[006] [%d] %s\n", $stmt->errno, $stmt->error); + + if (!$res = $stmt->get_result()) + printf("[007] [%d] %s\n", $stmt->errno, $stmt->error); + + $description = mysqli_fetch_assoc($res); + if ($description['Field'] != 'id') { + printf("[008] Returned data seems wrong, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + var_dump($description); + } + mysqli_free_result($res); + } + + if (mysqli_query($link, 'PREPARE mystmt FROM "EXPLAIN SELECT id FROM test"')) { + mysqli_query($link, 'DEALLOCATE PREPARE mystmt'); + + if (!$stmt->prepare('EXPLAIN SELECT id FROM test') || + !$stmt->execute()) + printf("[009] [%d] %s\n", $stmt->errno, $stmt->error); + + if (!$res = $stmt->get_result()) + printf("[010] [%d] %s\n", $stmt->errno, $stmt->error); + + $tmp = mysqli_fetch_assoc($res); + if (empty($tmp)) + printf("[011] Empty EXPLAIN result set seems wrong, check manually, [%d] %s\n", + mysqli_errno($link), mysqli_error($link)); + mysqli_free_result($res); + } + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt new file mode 100644 index 0000000..ffb655d --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt @@ -0,0 +1,129 @@ +--TEST-- +mysqli_stmt_get_result() - seeking +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!function_exists('mysqli_stmt_get_result')) + die('skip mysqli_stmt_get_result not available'); +?> +--FILE-- +<?php + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id ASC LIMIT 3")) + printf("[002] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[003] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!is_object($res = mysqli_stmt_get_result($stmt)) || 'mysqli_result' != get_class($res)) { + printf("[004] Expecting object/mysqli_result got %s/%s, [%d] %s\n", + gettype($res), $res, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + if (3 !== $res->num_rows) + printf("[005] Expecting 3 rows, got %s/%s rows\n", gettype($res->num_rows), $res->num_rows); + + if (2 !== $res->field_count) + printf("[006] Expecting 2 fields, got %s/%s rows\n", gettype($res->field_count), $res->field_count); + + if (0 !== $res->current_field) + printf("[006] Expecting offset 0, got %s/%s rows\n", gettype($res->current_field), $res->current_field); + + for ($i = 2; $i > 0; $i--) { + if (!$res->data_seek($i)) + printf("[007] Cannot seek to position %d, [%d] %s\n", + $i, mysqli_stmt_errno($stmt), $stmt->error); + $row = $res->fetch_array(MYSQLI_BOTH); + if (($row[0] !== $row['id']) || ($row[0] !== $i + 1)) { + printf("[008] Record looks wrong, dumping data\n"); + var_dump($row); + } else { + unset($row[0]); + unset($row['id']); + } + if ($row[1] !== $row['label']) { + printf("[009] Record looks wrong, dumping data\n"); + var_dump($row); + } else { + unset($row[1]); + unset($row['label']); + } + if (!empty($row)) { + printf("[010] Not empty, dumping unexpected data\n"); + var_dump($row); + } + } + + if (false !== ($tmp = $res->data_seek(-1))) + printf("[011] Expecting boolean/false got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = $res->data_seek($res->num_rows + 1))) + printf("[012] Expecting boolean/false got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = $res->data_seek(PHP_INT_MAX + 1))) + printf("[013] Expecting boolean/false got %s/%s\n", gettype($tmp), $tmp); + + for ($i = 0; $i < 100; $i++) { + /* intentionally out of range! */ + $pos = mt_rand(-1, 4); + $tmp = mysqli_data_seek($res, $pos); + if (($pos >= 0 && $pos < 3)) { + if (true !== $tmp) + printf("[015] Expecting boolan/true got %s/%s\n", gettype($tmp), $tmp); + $row = $res->fetch_array(MYSQLI_NUM); + if ($row[0] !== $pos + 1) + printf("[016] Expecting id = %d for pos %d got %s/%s\n", + $pos + 1, $pos, gettype($row[0]), $row[0]); + } else { + if (false !== $tmp) + printf("[014] Expecting boolan/false got %s/%s\n", gettype($tmp), $tmp); + } + } + + mysqli_stmt_close($stmt); + + if (true !== ($tmp = mysqli_data_seek($res, 0))) + printf("[015] Expecting boolan/true got %s/%s\n", gettype($tmp), $tmp); + + if (!is_array($row = $res->fetch_array(MYSQLI_NUM))) + printf("[016] Expecting array got %s/%s\n", gettype($tmp), $tmp); + + mysqli_free_result($res); + + if (NULL !== ($tmp = mysqli_data_seek($res, 0))) + printf("[017] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($row = $res->fetch_array(MYSQLI_NUM))) + printf("[018] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + if (NULL !== ($tmp = mysqli_data_seek($res, 0))) + printf("[019] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($row = $res->fetch_array(MYSQLI_NUM))) + printf("[020] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- + +Warning: mysqli_data_seek(): Couldn't fetch mysqli_result in %s on line %d + +Warning: mysqli_result::fetch_array(): Couldn't fetch mysqli_result in %s on line %d + +Warning: mysqli_data_seek(): Couldn't fetch mysqli_result in %s on line %d + +Warning: mysqli_result::fetch_array(): Couldn't fetch mysqli_result in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_types.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_types.phpt new file mode 100644 index 0000000..724a32a --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_get_result_types.phpt @@ -0,0 +1,259 @@ +--TEST-- +mysqli_stmt_get_result - data types +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifemb.inc'); + require_once('skipifconnectfailure.inc'); + + if (!function_exists('mysqli_stmt_get_result')) + die("skip mysqli_stmt_get_result() not available"); +?> +--FILE-- +<?php + require('connect.inc'); + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + $hint_str_or_unicode = (version_compare(PHP_VERSION, '5.9.9', '>') == 1) ? 'unicode' : 'string'; + + function func_mysqli_stmt_get_result($link, $engine, $bind_type, $sql_type, $bind_value, $offset, $type_hint = null) { + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) { + printf("[%04d] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!mysqli_query($link, sprintf("CREATE TABLE test(id INT, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { + // don't bail - column type might not be supported by the server, ignore this + return false; + } + + if (!$stmt = mysqli_stmt_init($link)) { + printf("[%04d] [%d] %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)")) { + printf("[%04d] [%d] %s\n", $offset + 2, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + $id = null; + if (!mysqli_stmt_bind_param($stmt, "i" . $bind_type, $id, $bind_value)) { + printf("[%04d] [%d] %s\n", $offset + 3, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + mysqli_stmt_close($stmt); + return false; + } + + for ($id = 1; $id < 4; $id++) { + if (!mysqli_stmt_execute($stmt)) { + printf("[%04d] [%d] %s\n", $offset + 3 + $id, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + mysqli_stmt_close($stmt); + return false; + } + } + mysqli_stmt_close($stmt); + + $stmt = mysqli_stmt_init($link); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test")) { + printf("[%04d] [%d] %s\n", $offset + 7, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + mysqli_stmt_close($stmt); + return false; + } + + if (!mysqli_stmt_execute($stmt)) { + printf("[%04d] [%d] %s\n", $offset + 8, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + mysqli_stmt_close($stmt); + return false; + } + + $result = mysqli_stmt_result_metadata($stmt); + + if (!$res = mysqli_stmt_get_result($stmt)) { + printf("[%04d] [%d] %s\n", $offset + 9, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + mysqli_stmt_close($stmt); + return false; + } + $num = 0; + $fields = mysqli_fetch_fields($result); + + while ($row = mysqli_fetch_assoc($res)) { + $bind_res = &$row['label']; + if (!gettype($bind_res) == 'unicode') { + if ($bind_res !== $bind_value && (!$type_hint || ($type_hint !== gettype($bind_res)))) { + printf("[%04d] [%d] Expecting %s/'%s' [type hint = %s], got %s/'%s'\n", + $offset + 10, $num, + gettype($bind_value), $bind_value, $type_hint, + gettype($bind_res), $bind_res); + mysqli_free_result($res); + mysqli_stmt_close($stmt); + return false; + } + } + $num++; + } + + if ($num != 3) { + printf("[%04d] [%d] %s, expecting 3 results, got only %d results\n", + $offset + 11, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), $num); + mysqli_free_result($res); + mysqli_stmt_close($stmt); + return false; + } + + mysqli_free_result($res); + mysqli_stmt_close($stmt); + return true; + } + + + function func_mysqli_stmt_bind_make_string($len) { + + $ret = ''; + for ($i = 0; $i < $len; $i++) + $ret .= chr(mt_rand(65, 90)); + + return $ret; + } + + func_mysqli_stmt_get_result($link, $engine, "i", "TINYINT", -11, 20); + func_mysqli_stmt_get_result($link, $engine, "i", "TINYINT", NULL, 40); + func_mysqli_stmt_get_result($link, $engine, "i", "TINYINT UNSIGNED", 1, 60); + func_mysqli_stmt_get_result($link, $engine, "i", "TINYINT UNSIGNED", NULL, 80); + + func_mysqli_stmt_get_result($link, $engine, "i", "BOOL", 1, 100); + func_mysqli_stmt_get_result($link, $engine, "i", "BOOL", NULL, 120); + func_mysqli_stmt_get_result($link, $engine, "i", "BOOLEAN", 0, 140); + func_mysqli_stmt_get_result($link, $engine, "i", "BOOLEAN", NULL, 160); + + func_mysqli_stmt_get_result($link, $engine, "i", "SMALLINT", -32768, 180); + func_mysqli_stmt_get_result($link, $engine, "i", "SMALLINT", 32767, 200); + func_mysqli_stmt_get_result($link, $engine, "i", "SMALLINT", NULL, 220); + func_mysqli_stmt_get_result($link, $engine, "i", "SMALLINT UNSIGNED", 65535, 240); + func_mysqli_stmt_get_result($link, $engine, "i", "SMALLINT UNSIGNED", NULL, 260); + + func_mysqli_stmt_get_result($link, $engine, "d", "MEDIUMINT", -8388608, 280, "integer"); + func_mysqli_stmt_get_result($link, $engine, "d", "MEDIUMINT", 8388607, 300, "integer"); + func_mysqli_stmt_get_result($link, $engine, "d", "MEDIUMINT", NULL, 320); + func_mysqli_stmt_get_result($link, $engine, "d", "MEDIUMINT UNSIGNED", 16777215, 340, "integer"); + func_mysqli_stmt_get_result($link, $engine, "d", "MEDIUMINT UNSIGNED", NULL, 360); + + func_mysqli_stmt_get_result($link, $engine, "i", "INTEGER", (defined("PHP_INT_MAX")) ? max(-1 * PHP_INT_MAX + 1, -2147483648) : 1, 380); + func_mysqli_stmt_get_result($link, $engine, "i", "INTEGER", -2147483647, 400, "integer"); + func_mysqli_stmt_get_result($link, $engine, "i", "INTEGER", (defined("PHP_INT_MAX")) ? min(2147483647, PHP_INT_MAX) : 1, 420); + func_mysqli_stmt_get_result($link, $engine, "i", "INTEGER", NULL, 440); + func_mysqli_stmt_get_result($link, $engine, "i", "INTEGER UNSIGNED", (defined("PHP_INT_MAX")) ? min(4294967295, 2147483647) : 1, 460); + func_mysqli_stmt_get_result($link, $engine, "i", "INTEGER UNSIGNED", 4294967295, 480, (defined("PHP_INT_MAX") && (4294967295 > PHP_INT_MAX)) ? "string" : null); + func_mysqli_stmt_get_result($link, $engine, "i", "INTEGER UNSIGNED", NULL, 500); + + /* test is broken too: we bind "integer" but value is a float + func_mysqli_stmt_get_result($link, $engine, "i", "BIGINT", -9223372036854775808, 520); + func_mysqli_stmt_get_result($link, $engine, "i", "BIGINT UNSIGNED", 18446744073709551615, 560); + */ + func_mysqli_stmt_get_result($link, $engine, "i", "BIGINT", NULL, 540); + func_mysqli_stmt_get_result($link, $engine, "i", "BIGINT UNSIGNED", NULL, 580); + func_mysqli_stmt_get_result($link, $engine, "i", "BIGINT", -1, 1780); + func_mysqli_stmt_get_result($link, $engine, "i", "BIGINT UNSIGNED", 1, 1800); + func_mysqli_stmt_get_result($link, $engine, "i", "BIGINT", -1 * PHP_INT_MAX + 1, 1820); + func_mysqli_stmt_get_result($link, $engine, "i", "BIGINT UNSIGNED", PHP_INT_MAX, 1840); + func_mysqli_stmt_get_result($link, $engine, "s", "BIGINT UNSIGNED", "18446744073709551615", 1860); + func_mysqli_stmt_get_result($link, $engine, "s", "BIGINT", "-9223372036854775808", 1880); + + func_mysqli_stmt_get_result($link, $engine, "d", "FLOAT", -9223372036854775808 - 1.1, 600); + func_mysqli_stmt_get_result($link, $engine, "d", "FLOAT", NULL, 620); + func_mysqli_stmt_get_result($link, $engine, "d", "FLOAT UNSIGNED", 18446744073709551615 + 1.1, 640); + func_mysqli_stmt_get_result($link, $engine, "d", "FLOAT UNSIGNED ", NULL, 660); + + // Yes, we need the temporary variable. The PHP casting will fouls us otherwise. + $tmp = strval('-99999999.99'); + func_mysqli_stmt_get_result($link, $engine, "d", "DOUBLE(10,2)", $tmp, 680, "string"); + func_mysqli_stmt_get_result($link, $engine, "d", "DOUBLE(10,2)", NULL, 700); + $tmp = strval('99999999.99'); + func_mysqli_stmt_get_result($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", $tmp , 720, "string"); + func_mysqli_stmt_get_result($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", NULL, 740); + $tmp = strval('-99999999.99'); + func_mysqli_stmt_get_result($link, $engine, "d", "DECIMAL(10,2)", $tmp, 760, "string"); + func_mysqli_stmt_get_result($link, $engine, "d", "DECIMAL(10,2)", NULL, 780); + $tmp = strval('99999999.99'); + func_mysqli_stmt_get_result($link, $engine, "d", "DECIMAL(10,2)", $tmp, 800, "string"); + func_mysqli_stmt_get_result($link, $engine, "d", "DECIMAL(10,2)", NULL, 820); + + // don't care about date() strict TZ warnings... + func_mysqli_stmt_get_result($link, $engine, "s", "DATE", @date('Y-m-d'), 840); + func_mysqli_stmt_get_result($link, $engine, "s", "DATE NOT NULL", @date('Y-m-d'), 860); + func_mysqli_stmt_get_result($link, $engine, "s", "DATE", NULL, 880); + + func_mysqli_stmt_get_result($link, $engine, "s", "DATETIME", @date('Y-m-d H:i:s'), 900); + func_mysqli_stmt_get_result($link, $engine, "s", "DATETIME NOT NULL", @date('Y-m-d H:i:s'), 920); + func_mysqli_stmt_get_result($link, $engine, "s", "DATETIME", NULL, 940); + + func_mysqli_stmt_get_result($link, $engine, "s", "TIMESTAMP", @date('Y-m-d H:i:s'), 960); + + func_mysqli_stmt_get_result($link, $engine, "s", "TIME", @date('H:i:s'), 980); + func_mysqli_stmt_get_result($link, $engine, "s", "TIME NOT NULL", @date('H:i:s'), 1000); + func_mysqli_stmt_get_result($link, $engine, "s", "TIME", NULL, 1020); + + $tmp = intval(@date('Y')); + func_mysqli_stmt_get_result($link, $engine, "s", "YEAR", $tmp, 1040, "integer"); + func_mysqli_stmt_get_result($link, $engine, "s", "YEAR NOT NULL", $tmp, 1060, "integer"); + func_mysqli_stmt_get_result($link, $engine, "s", "YEAR", NULL, 1080); + + $string255 = func_mysqli_stmt_bind_make_string(255); + func_mysqli_stmt_get_result($link, $engine, "s", "CHAR(1)", "a", 1110, $hint_str_or_unicode); + func_mysqli_stmt_get_result($link, $engine, "s", "CHAR(255)", $string255, 1120, $hint_str_or_unicode); + func_mysqli_stmt_get_result($link, $engine, "s", "CHAR(1) NOT NULL", "a", 1140, $hint_str_or_unicode); + func_mysqli_stmt_get_result($link, $engine, "s", "CHAR(1)", NULL, 1160); + + $string65k = func_mysqli_stmt_bind_make_string(65535); + func_mysqli_stmt_get_result($link, $engine, "s", "VARCHAR(1)", "a", 1180, $hint_str_or_unicode); + func_mysqli_stmt_get_result($link, $engine, "s", "VARCHAR(255)", $string255, 1200, $hint_str_or_unicode); + func_mysqli_stmt_get_result($link, $engine, "s", "VARCHAR(65635)", $string65k, 1220, $hint_str_or_unicode); + func_mysqli_stmt_get_result($link, $engine, "s", "VARCHAR(1) NOT NULL", "a", 1240, $hint_str_or_unicode); + func_mysqli_stmt_get_result($link, $engine, "s", "VARCHAR(1)", NULL, 1260); + + func_mysqli_stmt_get_result($link, $engine, "s", "BINARY(1)", "a", 1280); + func_mysqli_stmt_get_result($link, $engine, "s", "BINARY(1)", chr(0), 1300); + func_mysqli_stmt_get_result($link, $engine, "s", "BINARY(1) NOT NULL", "b", 1320); + func_mysqli_stmt_get_result($link, $engine, "s", "BINARY(1)", NULL, 1340); + + func_mysqli_stmt_get_result($link, $engine, "s", "VARBINARY(1)", "a", 1360); + func_mysqli_stmt_get_result($link, $engine, "s", "VARBINARY(1)", chr(0), 1380); + func_mysqli_stmt_get_result($link, $engine, "s", "VARBINARY(1) NOT NULL", "b", 1400); + func_mysqli_stmt_get_result($link, $engine, "s", "VARBINARY(1)", NULL, 1420); + + func_mysqli_stmt_get_result($link, $engine, "s", "TINYBLOB", "a", 1440); + func_mysqli_stmt_get_result($link, $engine, "s", "TINYBLOB", chr(0), 1460); + func_mysqli_stmt_get_result($link, $engine, "s", "TINYBLOB NOT NULL", "b", 1480); + func_mysqli_stmt_get_result($link, $engine, "s", "TINYBLOB", NULL, 1500); + + func_mysqli_stmt_get_result($link, $engine, "s", "TINYTEXT", "a", 1520, $hint_str_or_unicode); + func_mysqli_stmt_get_result($link, $engine, "s", "TINYTEXT NOT NULL", "a", 1540, $hint_str_or_unicode); + func_mysqli_stmt_get_result($link, $engine, "s", "TINYTEXT", NULL, 1560, $hint_str_or_unicode); + + // Note: you cannot insert any blob values this way. But you can check the API at least partly this way + // Extra BLOB tests are in mysqli_stmt_send_long() + func_mysqli_stmt_get_result($link, $engine, "b", "BLOB", b"", 1580); + func_mysqli_stmt_get_result($link, $engine, "b", "TEXT", "", 1600, $hint_str_or_unicode); + func_mysqli_stmt_get_result($link, $engine, "b", "MEDIUMBLOB", b"", 1620); + func_mysqli_stmt_get_result($link, $engine, "b", "MEDIUMTEXT", "", 1640, $hint_str_or_unicode); + + /* Is this one related? http://bugs.php.net/bug.php?id=35759 */ + func_mysqli_stmt_get_result($link, $engine, "b", "LONGBLOB", "", 1660); + func_mysqli_stmt_get_result($link, $engine, "b", "LONGTEXT", "", 1680, $hint_str_or_unicode); + + func_mysqli_stmt_get_result($link, $engine, "s", "ENUM('a', 'b')", "a", 1700, $hint_str_or_unicode); + func_mysqli_stmt_get_result($link, $engine, "s", "ENUM('a', 'b')", NULL, 1720, $hint_str_or_unicode); + func_mysqli_stmt_get_result($link, $engine, "s", "SET('a', 'b')", "a", 1740, $hint_str_or_unicode); + func_mysqli_stmt_get_result($link, $engine, "s", "SET('a', 'b')", NULL, 1760, $hint_str_or_unicode); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt b/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt new file mode 100644 index 0000000..2b0e150 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt @@ -0,0 +1,107 @@ +--TEST-- +mysqli_stmt_get_warnings() - TODO +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +require_once("connect.inc"); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + die(sprintf("skip Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket)); +} + +if (!mysqli_query($link, "DROP TABLE IF EXISTS test") || + !mysqli_query($link, "CREATE TABLE test(id SMALLINT)")) + die(sprintf("skip [%d] %s\n", $link->errno, $link->error)); + +if (!@mysqli_query("INSERT INTO test(id) VALUES (100001)")) + die("skip Strict sql mode seems to be active. We won't get a warning to check for."); + +mysqli_query($link, "DROP TABLE IF EXISTS test"); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_get_warnings())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_get_warnings($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (NULL !== ($tmp = mysqli_stmt_get_warnings($stmt))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, "DROP TABLE IF EXISTS test") || !mysqli_stmt_execute($stmt)) + printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (false !== ($tmp = mysqli_stmt_get_warnings($stmt))) + printf("[006] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, "CREATE TABLE test(id SMALLINT, label CHAR(1))") || !mysqli_stmt_execute($stmt)) + printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (false !== ($tmp = mysqli_stmt_get_warnings($stmt))) + printf("[008] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (100000, 'a'), (100001, 'b')") || + !mysqli_stmt_execute($stmt)) + printf("[009] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!is_object($warning = mysqli_stmt_get_warnings($stmt))) + printf("[010] Expecting mysqli_warning object, got %s/%s\n", gettype($warning), $warning); + + if ('mysqli_warning' !== get_class($warning)) + printf("[011] Expecting object of type mysqli_warning got type '%s'", get_class($warning)); + + if (!method_exists($warning, 'next')) + printf("[012] Object mysqli_warning seems to lack method next()\n"); + + $i = 0; + do { + + if ('' == $warning->message) + printf("[013 - %d] Message should not be empty\n", $i); + + if ('' == $warning->sqlstate) + printf("[014 - %d] SQL State should not be empty\n", $i); + + if (0 == $warning->errno) + printf("[015 - %d] Error number should not be zero\n", $i); + + $i++; + + } while ($warning->next()); + + if (2 != $i) + printf("[016] Expected 2 warnings, got %d warnings\n", $i); + + mysqli_stmt_close($stmt); + + if (NULL !== ($tmp = mysqli_stmt_get_warnings($stmt))) + printf("[015] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_get_warnings(): invalid object or resource mysqli_stmt + in %s on line %d + +Warning: mysqli_stmt_get_warnings(): Couldn't fetch mysqli_stmt in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_init.phpt b/ext/mysqli/tests/mysqli_stmt_init.phpt new file mode 100644 index 0000000..4f09719 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_init.phpt @@ -0,0 +1,58 @@ +--TEST-- +mysqli_stmt_init() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + /* + NOTE: no datatype tests here! This is done by + mysqli_stmt_bind_result.phpt already. Restrict + this test case to the basics. + */ + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_init())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_init($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!is_object($stmt = mysqli_stmt_init($link))) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_object($stmt2 = @mysqli_stmt_init($link))) + printf("[003a] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_stmt_close($stmt); + + if (NULL !== ($tmp = mysqli_stmt_init($stmt))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + if (NULL !== ($tmp = mysqli_stmt_init($link))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_close(): invalid object or resource mysqli_stmt + in %s on line %d + +Warning: mysqli_stmt_init() expects parameter 1 to be mysqli, object given in %s on line %d + +Warning: mysqli_stmt_init(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_insert_id.phpt b/ext/mysqli/tests/mysqli_stmt_insert_id.phpt new file mode 100644 index 0000000..c7a5aff --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_insert_id.phpt @@ -0,0 +1,77 @@ +--TEST-- +mysqli_stmt_insert_id() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_insert_id())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + $stmt = @new mysqli_stmt($link); + if (!is_null($tmp = @mysqli_insert_id($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + $stmt = mysqli_stmt_init($link); + if (NULL !== ($tmp = @mysqli_stmt_insert_id($stmt))) + printf("[003] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 1") || + !mysqli_stmt_execute($stmt)) { + printf("[004] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + if (0 !== ($tmp = mysqli_stmt_insert_id($stmt))) + printf("[005] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_close($stmt); + + // no auto_increment column + $stmt = mysqli_stmt_init($link); + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (100, 'a')") || + !mysqli_stmt_execute($stmt)) { + printf("[006] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + if (0 !== ($tmp = mysqli_stmt_insert_id($stmt))) + printf("[007] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + if (mysqli_get_server_version($link) > 50000 && + (!mysqli_stmt_prepare($stmt, "ALTER TABLE test MODIFY id INT NOT NULL AUTO_INCREMENT") || + !mysqli_stmt_execute($stmt))) { + printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } else if (mysqli_get_server_version($link) < 50000){ + mysqli_query($link, "ALTER TABLE test MODIFY id INT NOT NULL AUTO_INCREMENT"); + } + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(label) VALUES ('a')") || + !mysqli_stmt_execute($stmt)) { + printf("[009] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + if (0 === ($tmp = mysqli_stmt_insert_id($stmt))) + printf("[010] Expecting int/any non zero, got %s/%s\n", gettype($tmp), $tmp); + mysqli_stmt_close($stmt); + + mysqli_close($link); + + var_dump(mysqli_stmt_insert_id($stmt)); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_insert_id(): Couldn't fetch mysqli_stmt in %s on line %d +NULL +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_num_rows.phpt b/ext/mysqli/tests/mysqli_stmt_num_rows.phpt new file mode 100644 index 0000000..a1f5e89 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_num_rows.phpt @@ -0,0 +1,118 @@ +--TEST-- +mysqli_stmt_num_rows() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_num_rows())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_num_rows($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + function func_test_mysqli_stmt_num_rows($stmt, $query, $expected, $offset) { + + if (!mysqli_stmt_prepare($stmt, $query)) { + printf("[%03d] [%d] %s\n", $offset, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if (!mysqli_stmt_execute($stmt)) { + printf("[%03d] [%d] %s\n", $offset + 1, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if (!mysqli_stmt_store_result($stmt)) { + printf("[%03d] [%d] %s\n", $offset + 2, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if ($expected !== ($tmp = mysqli_stmt_num_rows($stmt))) + printf("[%03d] Expecting %s/%d, got %s/%d\n", $offset + 3, + gettype($expected), $expected, + gettype($tmp), $tmp); + + mysqli_stmt_free_result($stmt); + + return true; + } + + func_test_mysqli_stmt_num_rows($stmt, "SELECT 1 AS a", 1, 10); + func_test_mysqli_stmt_num_rows($stmt, "SHOW VARIABLES LIKE '%nixnutz%'", 0, 20); + // Note: for statements that return no result set mysqli_num_rows() differs from mysqli_stmt_num_rows() slightly + // mysqli_num_rows() failed to fetch the result set and the PHP parameter check makes it return NULL + // mysqli_stmt_numrows() has a valid resource to work on and it will return int/0 instead. No bug, but + // slightly different behaviour... - if you really check the data types and don't rely on casting like 98% of all PHP + // users do. + func_test_mysqli_stmt_num_rows($stmt, "INSERT INTO test(id, label) VALUES (100, 'z')", 0, 30); + + if ($res = mysqli_query($link, 'SELECT COUNT(id) AS num FROM test')) { + $row = mysqli_fetch_assoc($res); + mysqli_free_result($res); + func_test_mysqli_stmt_num_rows($stmt, "SELECT id, label FROM test", (int)$row['num'], 40); + } else { + printf("[050] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + print "run_tests.php don't fool me with your 'ungreedy' expression '.+?'!\n"; + + if (!mysqli_stmt_prepare($stmt, 'SELECT id FROM test')) + printf("[051] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (mysqli_stmt_execute($stmt)) { + + $i = 0; + do { + if (0 !== ($tmp = mysqli_stmt_num_rows($stmt))) + printf("[53 - %03d] Expecting int/0, got %s/%s\n", $i, gettype($tmp), $tmp); + $i++; + } while (mysqli_stmt_fetch($stmt)); + + /* NOTE to users + Behaviour with libmysql is UNDEFINED, see http://news.php.net/php.internals/55210 + Because it is undefined it is allowed to the mysqlnd DEVELOPER to implement + any behaviour they like, including the one checked for in this test. + What the test does is cover an implementation detail of the mysqlnd library. + This implementation detail may, at any time, change without prior notice. + On the contrary, the mysqlnd way is a reasonable one and, maybe, one fine + day, after Klingons visited earh, becomes the official one. Meanwhile do + not rely on it. + */ + if ($IS_MYSQLND && (7 !== ($tmp = mysqli_stmt_num_rows($stmt)))) + printf("[54] Expecting int/7, got %s/%s\n", gettype($tmp), $tmp); + + } else { + printf("[055] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + mysqli_stmt_close($stmt); + + if (NULL !== ($tmp = mysqli_stmt_num_rows($stmt))) + printf("[056] Expecting NULL, got %s/%s\n"); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +run_tests.php don't fool me with your 'ungreedy' expression '.+?'! + +Warning: mysqli_stmt_num_rows(): Couldn't fetch mysqli_stmt in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_param_count.phpt b/ext/mysqli/tests/mysqli_stmt_param_count.phpt new file mode 100644 index 0000000..3526956 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_param_count.phpt @@ -0,0 +1,72 @@ +--TEST-- +mysqli_stmt_param_count() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_param_count())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_param_count($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (NULL !== ($tmp = mysqli_stmt_param_count($stmt))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + function func_test_mysqli_stmt_param_count($stmt, $query, $expected, $offset) { + + if (!mysqli_stmt_prepare($stmt, $query)) { + printf("[%03d] [%d] %s\n", $offset, mysqli_stmt_errno($stmt), mysqli_error($stmt)); + return false; + } + + if ($expected !== ($tmp = mysqli_stmt_param_count($stmt))) + printf("[%03d] Expecting %s/%d, got %s/%d\n", $offset + 3, + gettype($expected), $expected, + gettype($tmp), $tmp); + return true; + } + + func_test_mysqli_stmt_param_count($stmt, "SELECT 1 AS a", 0, 10); + func_test_mysqli_stmt_param_count($stmt, "INSERT INTO test(id) VALUES (?)", 1, 20); + func_test_mysqli_stmt_param_count($stmt, "INSERT INTO test(id, label) VALUES (?, ?)", 2, 30); + func_test_mysqli_stmt_param_count($stmt, "INSERT INTO test(id, label) VALUES (?, '?')", 1, 40); + + mysqli_stmt_close($stmt); + + if (NULL !== ($tmp = mysqli_stmt_param_count($stmt))) + printf("[40] Expecting NULL, got %s/%s\n"); + + mysqli_close($link); + + /* Check that the function alias exists. It's a deprecated function, + but we have not announce the removal so far, therefore we need to check for it */ + if (!is_null($tmp = @mysqli_stmt_param_count())) + printf("[041] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_param_count(): invalid object or resource mysqli_stmt + in %s on line %d + +Warning: mysqli_stmt_param_count(): Couldn't fetch mysqli_stmt in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_prepare.phpt b/ext/mysqli/tests/mysqli_stmt_prepare.phpt new file mode 100644 index 0000000..3eb576a --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_prepare.phpt @@ -0,0 +1,56 @@ +--TEST-- +mysqli_stmt_prepare() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + // Note: No SQL tests here! We can expand one of the *fetch() + // tests to a generic SQL test, if we ever need that. + // We would duplicate the SQL test cases if we have it here and in one of the + // fetch tests, because the fetch tests would have to call prepare/execute etc. + // anyway. + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_prepare())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_prepare($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (NULL !== ($tmp = @mysqli_stmt_prepare($stmt))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (false !== ($tmp = mysqli_stmt_prepare($stmt, ''))) + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_stmt_prepare($stmt, 'SELECT id FROM test'))) + printf("[006] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_stmt_close($stmt); + + if (NULL !== ($tmp = mysqli_stmt_prepare($stmt, "SELECT id FROM test"))) + printf("[007] Expecting NULL, got %s/%s\n"); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_prepare(): Couldn't fetch mysqli_stmt in %s on line %d +done! diff --git a/ext/mysqli/tests/mysqli_stmt_reset.phpt b/ext/mysqli/tests/mysqli_stmt_reset.phpt new file mode 100644 index 0000000..d731da2 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_reset.phpt @@ -0,0 +1,112 @@ +--TEST-- +mysqli_stmt_reset() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + // Note: No SQL tests here! We can expand one of the *fetch() + // tests to a generic SQL test, if we ever need that. + // We would duplicate the SQL test cases if we have it here and in one of the + // fetch tests, because the fetch tests would have to call prepare/execute etc. + // anyway. + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_reset())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_reset($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (NULL !== ($tmp = mysqli_stmt_reset($stmt))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_stmt_prepare($stmt, 'SELECT id FROM test'))) + printf("[005] Expecting boolean/true, got %s/%s, [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (true !== ($tmp = mysqli_stmt_reset($stmt))) + printf("[006] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (true !== ($tmp = mysqli_stmt_execute($stmt))) + printf("[007] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + $id = null; + if (!mysqli_stmt_bind_result($stmt, $id)) + printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_fetch($stmt)) + printf("[009] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + var_dump($id); + mysqli_stmt_close($stmt); + if (!$stmt = mysqli_stmt_init($link)) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "CREATE TABLE test(id INT NOT NULL AUTO_INCREMENT, label BLOB, PRIMARY KEY(id))")) + printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(label) VALUES (?)")) + printf("[013] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $label = null; + if (!mysqli_stmt_bind_param($stmt, "b", $label)) + printf("[014] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $label = 'abc'; + for ($i = 0; $i < 10; $i++) { + if (!mysqli_stmt_send_long_data($stmt, 0, $label)) + printf("[015 - %d] [%d] %s\n", $i, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + + if (!mysqli_stmt_reset($stmt)) + printf("[016] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_execute($stmt)) + printf("[017] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!$res = mysqli_query($link, "SELECT label FROM test")) + printf("[018] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + + if ($row['label'] != '') + printf("[020] Expecting empty string, got string/%s\n", $row['label']); + + mysqli_stmt_close($stmt); + + if (NULL !== ($tmp = mysqli_stmt_reset($stmt))) + printf("[021] Expecting NULL, got %s/%s\n"); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_reset(): invalid object or resource mysqli_stmt + in %s on line %d +int(1) + +Warning: mysqli_stmt_reset(): Couldn't fetch mysqli_stmt in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt b/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt new file mode 100644 index 0000000..a38706f --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt @@ -0,0 +1,134 @@ +--TEST-- +mysqli_stmt_result_metadata() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_result_metadata())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_result_metadata($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (NULL !== ($tmp = mysqli_stmt_result_metadata($stmt))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test")) + printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!is_object(($res = mysqli_stmt_result_metadata($stmt)))) + printf("[006] Expecting object, got %s/%s\n", gettype($tmp), $tmp); + + if (2 !== ($tmp = mysqli_num_fields($res))) + printf("[007] Expecting int/2, got %s/%s, [%d] %s\n", + gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); + + if (!is_object($field0_fetch = mysqli_fetch_field($res))) + printf("[008] Expecting object, got %s/%s, [%d] %s\n", + gettype($field0_fetch), $field0_fetch, mysqli_errno($link), mysqli_error($link)); + + if (!is_object($field0_direct = mysqli_fetch_field_direct($res, 0))) + printf("[009] Expecting object, got %s/%s, [%d] %s\n", + gettype($field0_direct), $field0_direct, mysqli_errno($link), mysqli_error($link)); + + if ($field0_fetch != $field0_direct) { + printf("[010] mysqli_fetch_field() differs from mysqli_fetch_field_direct()\n"); + var_dump($field0_fetch); + var_dump($field0_direct); + } + + var_dump($field0_fetch); + + if (!is_array($tmp = mysqli_fetch_fields($res))) + printf("[011] Expecting array, got %s/%s, [%d] %s\n", + gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); + + if (empty($tmp[0]) || empty($tmp[1]) || $tmp[0] != $field0_direct) { + printf("[012] mysqli_fetch_fields() return value is suspicious\n"); + var_dump($tmp); + } + + if (!mysqli_field_seek($res, 1)) + printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_object($field1_direct = mysqli_fetch_field_direct($res, 1))) + printf("[014] Expecting object, got %s/%s, [%d] %s\n", + gettype($field1_direct), $field1_direct, mysqli_errno($link), mysqli_error($link)); + + if ($tmp[1] != $field1_direct) { + printf("[015] mysqli_fetch_field_direct() differs from mysqli_fetch_fields()\n"); + var_dump($field1_direct); + var_dump($tmp); + } + + if (1 !== ($tmp = mysqli_field_tell($res))) + printf("[016] Expecting int/1, got %s/%s, [%d] %s\n", + gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + mysqli_stmt_close($stmt); + + if (NULL !== ($tmp = mysqli_stmt_result_metadata($stmt))) + printf("[017] Expecting NULL, got %s/%s\n"); + + /* Check that the function alias exists. It's a deprecated function, + but we have not announce the removal so far, therefore we need to check for it */ + if (!is_null($tmp = @mysqli_stmt_result_metadata())) + printf("[018] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- + +Warning: mysqli_stmt_result_metadata(): invalid object or resource mysqli_stmt + in %s on line %d +object(stdClass)#5 (13) { + [%u|b%"name"]=> + %unicode|string%(2) "id" + [%u|b%"orgname"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"orgtable"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"db"]=> + %unicode|string%(%d) "%s" + [%u|b%"catalog"]=> + %unicode|string%(%d) "%s" + [%u|b%"max_length"]=> + int(0) + [%u|b%"length"]=> + int(11) + [%u|b%"charsetnr"]=> + int(63) + [%u|b%"flags"]=> + int(49155) + [%u|b%"type"]=> + int(3) + [%u|b%"decimals"]=> + int(0) +} + +Warning: mysqli_stmt_result_metadata(): Couldn't fetch mysqli_stmt in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_result_metadata_sqltests.phpt b/ext/mysqli/tests/mysqli_stmt_result_metadata_sqltests.phpt new file mode 100644 index 0000000..a7dad1b --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_result_metadata_sqltests.phpt @@ -0,0 +1,232 @@ +--TEST-- +mysqli_stmt_result_metadata() - non SELECT statements +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +die("skip Check again when the Klingons visit earth - http://bugs.mysql.com/bug.php?id=42490"); +?> +--FILE-- +<?php + require('table.inc'); + + function testStatement($offset, $link, $sql, $expected_lib, $expected_mysqlnd, $check_mysqlnd, $compare) { + + if (!$stmt = mysqli_stmt_init($link)) { + printf("[%04d - %s] [%d] %s\n", + $offset, $sql, + mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!@mysqli_stmt_prepare($stmt, $sql)) { + /* Not all server versions will support all statements */ + /* Failing to prepare is OK */ + return true; + } + + if (empty($expected_lib) && (false !== $res)) { + printf("[%04d - %s] No metadata expected\n", + $offset + 1, $sql); + return false; + } else if (!empty($expected_lib) && (false == $res)) { + printf("[%04d - %s] Metadata expected\n", + $offset + 2, $sql); + return false; + } + if (!empty($expected_lib)) { + if (!is_object($res)) { + printf("[%04d - %s] [%d] %s\n", + $offset + 3, $sql, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + if (get_class($res) != 'mysqli_result') { + printf("[%04d - %s] Expecting object/mysqli_result got object/%s\n", + $offset + 4, $sql, get_class($res)); + return false; + } + + $meta = array( + 'num_fields' => mysqli_num_fields($res), + 'fetch_field' => mysqli_fetch_field($res), + 'fetch_field_direct0' => mysqli_fetch_field_direct($res, 0), + 'fetch_field_direct1' => @mysqli_fetch_field_direct($res, 1), + 'fetch_fields' => count(mysqli_fetch_fields($res)), + 'field_count' => $res->field_count, + 'field_seek-1' => @mysqli_field_seek($res, -1), + 'field_seek0' => mysqli_field_seek($res, 0), + 'field_tell' => mysqli_field_tell($res), + ); + if (is_object($meta['fetch_field'])) { + $meta['fetch_field']->charsetnr = 'ignore'; + $meta['fetch_field']->flags = 'ignore'; + } + if (is_object($meta['fetch_field_direct0'])) { + $meta['fetch_field_direct0']->charsetnr = 'ignore'; + $meta['fetch_field_direct0']->flags = 'ignore'; + } + if (is_object($meta['fetch_field_direct1'])) { + $meta['fetch_field_direct1']->charsetnr = 'ignore'; + $meta['fetch_field_direct1']->flags = 'ignore'; + } + mysqli_free_result($res); + + if ($meta != $expected_lib) { + printf("[%04d - %s] Metadata differes from expected values\n", + $offset + 5, $sql); + var_dump($meta); + var_dump($expected_lib); + return false; + } + } + + if (function_exists('mysqli_stmt_get_result')) { + /* mysqlnd only */ + if (!mysqli_stmt_execute($stmt)) { + printf("[%04d - %s] [%d] %s\n", + $offset + 6, $sql, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + $res = mysqli_stmt_get_result($stmt); + if (false === $res && !empty($expected_mysqlnd)) { + printf("[%04d - %s] Expecting resultset [%d] %s\n", + $offset + 7, $sql, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } else if (empty($expected_mysqlnd) && false !== $res) { + printf("[%04d - %s] Unexpected resultset [%d] %s\n", + $offset + 8, $sql, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if (!is_object($res)) { + printf("[%04d - %s] [%d] %s\n", + $offset + 9, $sql, + mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + if ('mysqli_result' != get_class($res)) { + printf("[%04d - %s] Expecting object/mysqli_result got object/%s\n", + $offset + 10, $sql, + get_class($res)); + return false; + } + + $meta_res = array( + 'num_fields' => mysqli_num_fields($res), + 'fetch_field' => mysqli_fetch_field($res), + 'fetch_field_direct0' => mysqli_fetch_field_direct($res, 0), + 'fetch_field_direct1' => @mysqli_fetch_field_direct($res, 1), + 'fetch_fields' => count(mysqli_fetch_fields($res)), + 'field_count' => mysqli_field_count($link), + 'field_seek-1' => @mysqli_field_seek($res, -1), + 'field_seek0' => mysqli_field_seek($res, 0), + 'field_tell' => mysqli_field_tell($res), + ); + if (is_object($meta_res['fetch_field'])) { + $meta_res['fetch_field']->charsetnr = 'ignore'; + $meta_res['fetch_field']->flags = 'ignore'; + } + if (is_object($meta_res['fetch_field_direct0'])) { + $meta_res['fetch_field_direct0']->charsetnr = 'ignore'; + $meta_res['fetch_field_direct0']->flags = 'ignore'; + } + if (is_object($meta_res['fetch_field_direct1'])) { + $meta_res['fetch_field_direct1']->charsetnr = 'ignore'; + $meta_res['fetch_field_direct1']->flags = 'ignore'; + } + mysqli_free_result($res); + if ($check_mysqlnd && $meta_res != $expected_mysqlnd) { + printf("[%04d - %s] Metadata differs from expected\n", + $offset + 11, $sql); + var_dump($meta_res); + var_dump($expected_mysqlnd); + } else { + if ($meta_res['field_count'] < 1) { + printf("[%04d - %s] Metadata seems wrong, no fields?\n", + $offset + 12, $sql); + var_dump($meta_res); + var_dump(mysqli_fetch_assoc($res)); + } + } + + if ($compare && $meta_res != $meta) { + printf("[%04d - %s] Metadata returned by mysqli_stmt_result_metadata() and mysqli_stmt_get_result() differ\n", + $offset + 13, $sql); + var_dump($meta_res); + var_dump($meta); + } + + } + + mysqli_stmt_close($stmt); + return true; + } + + /* Note: very weak testing, we accept almost any result */ + + testStatement(100, $link, 'ANALYZE TABLE test', array(), array(1), false, false); + testStatement(120, $link, 'OPTIMIZE TABLE test', array(), array(1), false, false); + testStatement(140, $link, 'REPAIR TABLE test', array(), array(1), false, false); + + testStatement(160, $link, 'SHOW AUTHORS', array(), array(1), false, false); + testStatement(180, $link, 'SHOW CHARACTER SET', array(), array(1), false, false); + testStatement(200, $link, 'SHOW COLLATION', array(), array(1), false, false); + testStatement(220, $link, 'SHOW CONTRIBUTORS', array(), array(1), false, false); + testStatement(240, $link, 'SHOW CREATE DATABASE ' . $db, array(), array(1), false, false); + testStatement(260, $link, 'SHOW DATABASES', array(), array(1), false, false); + testStatement(280, $link, 'SHOW ENGINE InnoDB STATUS', array(), array(1), false, false); + testStatement(300, $link, 'SHOW ENGINES', array(), array(1), false, false); + testStatement(320, $link, 'SHOW PLUGINS', array(), array(1), false, false); + testStatement(340, $link, 'SHOW PROCESSLIST', array(), array(1), false, false); + testStatement(360, $link, 'SHOW FULL PROCESSLIST', array(), array(1), false, false); + testStatement(380, $link, 'SHOW STATUS', array(), array(1), false, false); + testStatement(400, $link, 'SHOW TABLE STATUS', array(), array(1), false, false); + testStatement(420, $link, 'SHOW TABLE STATUS', array(), array(1), false, false); + testStatement(440, $link, 'SHOW TABLES', array(), array(1), false, false); + testStatement(460, $link, 'SHOW OPEN TABLES', array(), array(1), false, false); + testStatement(460, $link, 'SHOW VARIABLES', array(), array(1), false, false); + + $field0 = new stdClass(); + $field0->name = 'id'; + $field0->orgname = 'id'; + $field0->table = 'test'; + $field0->orgtable = 'test'; + $field0->def = ''; + $field0->max_length = 0; + $field0->length = 11; + $field0->charsetnr = 'ignore'; + $field0->flags = 'ignore'; + $field0->type = MYSQLI_TYPE_LONG; + $field0->decimals = 0; + $meta_lib = array( + 'num_fields' => 1, + 'fetch_field' => $field0, + 'fetch_field_direct0' => $field0, + 'fetch_field_direct1' => false, + 'fetch_fields' => 1, + 'field_count' => 1, + 'field_seek-1' => false, + 'field_seek0' => true, + 'field_tell' => 0, + ); + $meta_mysqlnd = $meta_lib; + testStatement(480, $link, 'SELECT id FROM test', $meta_lib, $meta_mysqlnd, true, true); + + testStatement(500, $link, 'CHECKSUM TABLE test', array(), array(1), false, false); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt b/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt new file mode 100644 index 0000000..7e2f860 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt @@ -0,0 +1,135 @@ +--TEST-- +mysqli_stmt_send_long_data() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_send_long_data())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_send_long_data($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (NULL !== ($tmp = @mysqli_stmt_send_long_data($stmt, ''))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, sprintf("CREATE TABLE test(id INT NOT NULL AUTO_INCREMENT, label LONGBLOB, PRIMARY KEY(id)) ENGINE = %s", $engine))) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)")) + printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = null; + $label = null; + if (!mysqli_stmt_bind_param($stmt, "ib", $id, $label)) + printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!$res = mysqli_query($link, "SHOW VARIABLES LIKE 'max_allowed_packet'")) + printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + + if (isset($row['VARIABLE_VALUE']) && !isset($row['Value'])) + // MySQL 6.0 + $row['Value'] = $row['VARIABLE_VALUE']; + + if (0 === ($max_allowed_packet = (int)$row['Value'])) + printf("[011] Cannot determine max_allowed_packet size and/or bogus max_allowed_packet setting used.\n"); + + // let's ignore upper limits for LONGBLOB (2^32) ... + // maximum packet size up to which we test is 10M + $tmp = ''; + $blob = ''; + for ($i = 0; $i < 1024; $i++) { + $tmp .= 'a'; + } + + $limit = min(floor($max_allowed_packet / 1024 / 2), 10240); + for ($i = 0; $i < $limit; $i++) + $blob .= $tmp; + /* + if (floor($max_allowed_packet / 1024) <= 10240) { + $limit = strlen($blob) - $max_allowed_packet - 1; + for ($i = 0; $i < $limit; $i++) + $blob .= 'a'; + } + */ + assert(strlen($blob) <= $max_allowed_packet); + + if (false !== ($tmp = mysqli_stmt_send_long_data($stmt, -1, $blob))) + printf("[012] Expecting boolean/false, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (false !== ($tmp = @mysqli_stmt_send_long_data($stmt, PHP_INT_MAX + 1, $blob))) + printf("[013] Expecting boolean/false, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (false !== ($tmp = mysqli_stmt_send_long_data($stmt, 999, $blob))) + printf("[014] Expecting boolean/false, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (true !== ($tmp = mysqli_stmt_send_long_data($stmt, 1, $blob))) + printf("[015] Expecting boolean/true, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = 1; + if (true !== mysqli_stmt_execute($stmt)) + printf("[016] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + mysqli_stmt_close($stmt); + + if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id")) + printf("[017] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (1 != ($tmp = mysqli_num_rows($res))) + printf("[018] Expecting 1 rows, mysqli_num_rows() reports %d rows. [%d] %s\n", + $tmp, mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + + if (empty($row['id']) || empty($row['label']) || ($row['id'] != 1)) + printf("[020] Record seems to be incomplete\n"); + + if ($blob != $row['label']) + printf("[021] Blob value has not been stored properly!\n"); + + if (NULL !== ($tmp = @mysqli_stmt_send_long_data($stmt, ''))) + printf("[022] Expecting NULL, got %s/%s\n"); + + /* Check that the function alias exists. It's a deprecated function, + but we have not announce the removal so far, therefore we need to check for it */ + if (!is_null($tmp = @mysqli_stmt_send_long_data())) + printf("[023] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_send_long_data(): Invalid parameter number in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_libmysql.phpt b/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_libmysql.phpt new file mode 100644 index 0000000..a1fc200 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_libmysql.phpt @@ -0,0 +1,98 @@ +--TEST-- +mysqli_stmt_send_long_data() - exceed packet size, libmysql - bug #26824 +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (stristr(mysqli_get_client_info(), 'mysqlnd')) + die("skip: test for libmysql"); +?> +--FILE-- +<?php + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, sprintf("CREATE TABLE test(id INT NOT NULL AUTO_INCREMENT, label LONGBLOB, PRIMARY KEY(id)) ENGINE = %s", $engine))) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)")) + printf("[004] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = null; + $label = null; + if (!mysqli_stmt_bind_param($stmt, "ib", $id, $label)) + printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!$res = mysqli_query($link, "SHOW VARIABLES LIKE 'max_allowed_packet'")) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + + if (0 === ($max_allowed_packet = (int)$row['Value'])) + printf("[008] Cannot determine max_allowed_packet size and/or bogus max_allowed_packet setting used.\n"); + + // let's ignore upper limits for LONGBLOB (2^32) ... + // maximum packet size up to which we test is 10M + $tmp = ''; + $blob = ''; + for ($i = 0; $i < 1024; $i++) { + $tmp .= 'a'; + } + + $limit = min(floor($max_allowed_packet / 1024 / 2), 10240); + for ($i = 0; $i < $limit; $i++) + $blob .= $tmp; + + assert(strlen($blob) <= $max_allowed_packet); + + if (true != ($tmp = mysqli_stmt_send_long_data($stmt, 1, $blob))) + printf("[009] Expecting boolean/true, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = 1; + if (true !== mysqli_stmt_execute($stmt)) + printf("[010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + /* + TODO - we skip this part of the test for now, because of bugs.mysql.com/26824 + if (floor($max_allowed_packet / 1024 / 2) <= 10240) { + // test with a blob smaller than 10M allows us to test + // for too long packages without wasting too much memory + $limit = $max_allowed_packet - strlen($blob) + 1; + $blob2 = $blob; + for ($i = 0; $i < $limit; $i++) + $blob2 .= 'b'; + + assert(strlen($blob2) > $max_allowed_packet); + + if (true != ($tmp = mysqli_stmt_send_long_data($stmt, 1, $blob2))) + printf("[011] Expecting boolean/false, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = 2; + if (false !== ($tmp = mysqli_stmt_execute($stmt))) + printf("[012] Expecting boolean/false, got %s/%s, [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + */ + mysqli_stmt_close($stmt); + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt b/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt new file mode 100644 index 0000000..95d2302 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt @@ -0,0 +1,103 @@ +--TEST-- +mysqli_stmt_send_long_data() - exceed packet size, mysqlnd +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); + +if (!stristr(mysqli_get_client_info(), 'mysqlnd')) + die("skip: warnings only available in mysqlnd"); +?> +--FILE-- +<?php + require('table.inc'); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, sprintf("CREATE TABLE test(id INT NOT NULL AUTO_INCREMENT, label LONGBLOB, PRIMARY KEY(id)) ENGINE = %s", $engine))) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)")) + printf("[004] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = null; + $label = null; + if (!mysqli_stmt_bind_param($stmt, "ib", $id, $label)) + printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!$res = mysqli_query($link, "SHOW VARIABLES LIKE 'max_allowed_packet'")) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!$row = mysqli_fetch_assoc($res)) + printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + + if (0 === ($max_allowed_packet = (int)$row['Value'])) + printf("[008] Cannot determine max_allowed_packet size and/or bogus max_allowed_packet setting used.\n"); + + // let's ignore upper limits for LONGBLOB (2^32) ... + // maximum packet size up to which we test is 10M + $tmp = ''; + $blob = ''; + $tmp = str_repeat('a', 1024); + + $limit = min(floor($max_allowed_packet / 1024 / 2), 10240); + $blob = str_repeat($tmp, $limit); + + assert(strlen($blob) <= $max_allowed_packet); + + if (true !== ($tmp = mysqli_stmt_send_long_data($stmt, 1, $blob))) + printf("[009] Expecting boolean/true, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = 1; + if (true !== mysqli_stmt_execute($stmt)) + printf("[010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + /* + TODO - we skip this because of the open bug http://bugs.mysql.com/bug.php?id=26824 + It would always fail. + + This should be added to the EXPECTF, if you reactivate the test +Warning: mysqli_stmt_send_long_data(): Skipped %d bytes. Last command STMT_SEND_LONG_DATA hasn't consumed all the output from the server in %s on line %d + +Warning: mysqli_stmt_send_long_data(): There was an error while sending long data. Probably max_allowed_packet_size is smaller than the data. You have to increase it or send smaller chunks of data. Answer was %d bytes long. in %s on line %d + + + + if (floor($max_allowed_packet / 1024 / 2) <= 10240) { + // test with a blob smaller than 10M allows us to test + // for too long packages without wasting too much memory + $limit = $max_allowed_packet - strlen($blob) + 1; + $blob2 = $blob; + $blob2 .= str_repeat('b', $limit); + + assert(strlen($blob2) > $max_allowed_packet); + + if (false !== ($tmp = mysqli_stmt_send_long_data($stmt, 1, $blob2))) + printf("[011] Expecting boolean/false, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + $id = 2; + if (false !== ($tmp = mysqli_stmt_execute($stmt))) + printf("[012] Expecting boolean/false, got %s/%s, [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } + */ + mysqli_stmt_close($stmt); + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_sqlstate.phpt b/ext/mysqli/tests/mysqli_stmt_sqlstate.phpt new file mode 100644 index 0000000..5ea35df --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_sqlstate.phpt @@ -0,0 +1,63 @@ +--TEST-- +mysqli_stmt_sqlstate() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_sqlstate())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_sqlstate($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!is_null($tmp = @mysqli_stmt_sqlstate($link, ''))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (NULL !== ($tmp = mysqli_stmt_sqlstate($stmt))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, "SELECT id FROM test")) + printf("[006] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if ('00000' !== ($tmp = mysqli_stmt_sqlstate($stmt))) + printf("[007] Expecting string/00000, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (mysqli_stmt_prepare($stmt, "SELECT believe_me FROM i_dont_belive_that_this_table_exists")) + printf("[008] Should fail! [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if ('' === ($tmp = mysqli_stmt_sqlstate($stmt))) + printf("[009] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + mysqli_stmt_close($stmt); + + if (NULL !== ($tmp = mysqli_stmt_sqlstate($stmt))) + printf("[010] Expecting NULL, got %s/%s\n"); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_stmt_sqlstate(): invalid object or resource mysqli_stmt + in %s on line %d + +Warning: mysqli_stmt_sqlstate(): Couldn't fetch mysqli_stmt in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_store_result.phpt b/ext/mysqli/tests/mysqli_stmt_store_result.phpt new file mode 100644 index 0000000..a6411ca --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_store_result.phpt @@ -0,0 +1,90 @@ +--TEST-- +mysqli_stmt_store_result() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_stmt_store_result())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_stmt_store_result($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!is_null($tmp = @mysqli_stmt_store_result(new mysqli_stmt()))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + // stmt object status test + if (NULL !== ($tmp = @mysqli_stmt_store_result($stmt))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (100, 'z')") || + !mysqli_stmt_execute($stmt)) + printf("[006] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (true !== ($tmp = @mysqli_stmt_store_result($stmt))) + printf("[007] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test ORDER BY id') || + !mysqli_stmt_execute($stmt)) + printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!$link_buf = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[009] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (!$stmt_buf = mysqli_stmt_init($link_buf)) + printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_stmt_prepare($stmt_buf, "SELECT id, label FROM test ORDER BY id") || + !mysqli_stmt_execute($stmt_buf)) + printf("[011] [%d] %s\n", mysqli_stmt_errno($stmt_buf), mysqli_stmt_error($stmt_buf)); + + $id = $label = $id_buf = $label_buf = null; + if (!mysqli_stmt_bind_result($stmt, $id, $label)) + printf("[012] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + + if (!mysqli_stmt_bind_result($stmt_buf, $id_buf, $label_buf)) + printf("[013] [%d] %s\n", mysqli_stmt_errno($stmt_buf), mysqli_stmt_error($stmt_buf)); + + while (mysqli_stmt_fetch($stmt)) { + if (!mysqli_stmt_fetch($stmt_buf)) { + printf("[014] Unbuffered statement indicates more rows than buffered, [%d] %s\n", + mysqli_stmt_errno($stmt_buf), mysqli_stmt_error($stmt_buf)); + } + if ($id !== $id_buf) + printf("[015] unbuffered '%s'/%s, buffered '%s'/%s\n", + $id, gettype($id), $id_buf, gettype($id_buf)); + if ($label !== $label_buf) + printf("[016] unbuffered '%s'/%s, buffered '%s'/%s\n", + $label, gettype($label), $label_buf, gettype($label_buf)); + } + + mysqli_stmt_close($stmt); + mysqli_stmt_close($stmt_buf); + + if (NULL !== ($tmp = @mysqli_stmt_store_result($stmt))) + printf("[017] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + mysqli_close($link_buf); + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_unclonable.phpt b/ext/mysqli/tests/mysqli_stmt_unclonable.phpt new file mode 100644 index 0000000..57d8d6d --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_unclonable.phpt @@ -0,0 +1,25 @@ +--TEST-- +Trying to clone mysqli_stmt object +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!$stmt = mysqli_stmt_init($link)) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + /* no, still bails out */ + $stmt_clone = clone $stmt; + print "done!"; +?> +--EXPECTF-- +Fatal error: Trying to clone an uncloneable object of class mysqli_stmt in %s on line %d
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_store_result.phpt b/ext/mysqli/tests/mysqli_store_result.phpt new file mode 100644 index 0000000..c61c124 --- /dev/null +++ b/ext/mysqli/tests/mysqli_store_result.phpt @@ -0,0 +1,64 @@ +--TEST-- +mysqli_store_result() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_store_result())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_store_result($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id")) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_object($res = mysqli_store_result($link))) + printf("[004] Expecting object, got %s/%s. [%d] %s\n", + gettype($res), $res, mysqli_errno($link), mysqli_error($link)); + + if (true !== ($tmp = mysqli_data_seek($res, 2))) + printf("[005] Expecting boolean/true, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + + if (!mysqli_query($link, "DELETE FROM test")) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (false !== ($res = mysqli_store_result($link))) + printf("[007] Expecting boolean/false, got %s/%s. [%d] %s\n", + gettype($res), $res, mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id")) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (false !== ($tmp = mysqli_data_seek($res, 1))) + printf("[009] Expecting boolean/false, got %s/%s\n", + gettype($tmp), $tmp); + + mysqli_close($link); + + if (NULL !== ($tmp = mysqli_store_result($link))) + printf("[010] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_store_result(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_thread_id.phpt b/ext/mysqli/tests/mysqli_thread_id.phpt new file mode 100644 index 0000000..3a7e1ae --- /dev/null +++ b/ext/mysqli/tests/mysqli_thread_id.phpt @@ -0,0 +1,44 @@ +--TEST-- +mysqli_thread_id() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_thread_id())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_thread_id($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!is_int($tmp = mysqli_thread_id($link)) || (0 === $tmp)) + printf("[003] Expecting int/any but zero, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); + + // should work if the thread id is correct + mysqli_kill($link, mysqli_thread_id($link)); + + mysqli_close($link); + + if (NULL !== ($tmp = mysqli_thread_id($link))) + printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_thread_id(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_thread_safe.phpt b/ext/mysqli/tests/mysqli_thread_safe.phpt new file mode 100644 index 0000000..0777c2a --- /dev/null +++ b/ext/mysqli/tests/mysqli_thread_safe.phpt @@ -0,0 +1,16 @@ +--TEST-- +mysqli_thread_safe() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +?> +--FILE-- +<?php + if (!is_bool($tmp = mysqli_thread_safe())) + printf("[001] Expecting boolean/any, got %s/%s.\n", gettype($tmp), $tmp); + + print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_unclonable.phpt b/ext/mysqli/tests/mysqli_unclonable.phpt new file mode 100644 index 0000000..e332b9f --- /dev/null +++ b/ext/mysqli/tests/mysqli_unclonable.phpt @@ -0,0 +1,23 @@ +--TEST-- +Trying to clone mysqli object +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + $link_clone = clone $link; + mysqli_close($link); + + print "done!"; +?> +--EXPECTF-- +Fatal error: Trying to clone an uncloneable object of class mysqli in %s on line %d
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_use_result.phpt b/ext/mysqli/tests/mysqli_use_result.phpt new file mode 100644 index 0000000..25d1692 --- /dev/null +++ b/ext/mysqli/tests/mysqli_use_result.phpt @@ -0,0 +1,66 @@ +--TEST-- +mysqli_use_result() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_use_result())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_use_result($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id")) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_object($res = mysqli_use_result($link))) + printf("[004] Expecting object, got %s/%s. [%d] %s\n", + gettype($res), $res, mysqli_errno($link), mysqli_error($link)); + + if (false !== ($tmp = mysqli_data_seek($res, 2))) + printf("[005] Expecting boolean/true, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); + + mysqli_free_result($res); + + if (!mysqli_query($link, "DELETE FROM test")) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (false !== ($res = mysqli_use_result($link))) + printf("[007] Expecting boolean/false, got %s/%s. [%d] %s\n", + gettype($res), $res, mysqli_errno($link), mysqli_error($link)); + + if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id")) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (false !== ($tmp = mysqli_data_seek($res, 1))) + printf("[009] Expecting boolean/false, got %s/%s\n", + gettype($tmp), $tmp); + + mysqli_close($link); + + if (NULL !== ($tmp = mysqli_use_result($link))) + printf("[010] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_data_seek(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d + +Warning: mysqli_use_result(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_warning_count.phpt b/ext/mysqli/tests/mysqli_warning_count.phpt new file mode 100644 index 0000000..cff9c02 --- /dev/null +++ b/ext/mysqli/tests/mysqli_warning_count.phpt @@ -0,0 +1,52 @@ +--TEST-- +mysqli_warning_count() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + + $tmp = NULL; + $link = NULL; + + if (!is_null($tmp = @mysqli_warning_count())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!is_null($tmp = @mysqli_warning_count($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + if (NULL !== ($tmp = @mysqli_warning_count($link, "too_many"))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (!$res = mysqli_query($link, "SELECT id, label FROM test")) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (0 !== ($tmp = mysqli_warning_count($link))) + printf("[005] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS this_table_does_not_exist")) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (1 !== ($tmp = mysqli_warning_count($link))) + printf("[007] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + + mysqli_close($link); + + if (NULL !== ($tmp = mysqli_warning_count($link))) + printf("[010] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysqli_warning_count(): Couldn't fetch mysqli in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_warning_unclonable.phpt b/ext/mysqli/tests/mysqli_warning_unclonable.phpt new file mode 100644 index 0000000..d3ae47d --- /dev/null +++ b/ext/mysqli/tests/mysqli_warning_unclonable.phpt @@ -0,0 +1,41 @@ +--TEST-- +Trying to clone mysqli_warning object +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); +if (!$TEST_EXPERIMENTAL) + die("skip - experimental (= unsupported) feature"); +?> +--FILE-- +<?php + require_once("connect.inc"); + + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) + printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "CREATE TABLE test (id SMALLINT)")) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, "INSERT INTO test (id) VALUES (1000000)")) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!is_object($warning = mysqli_get_warnings($link)) || 'mysqli_warning' != get_class($warning)) { + printf("[005] Expecting object/mysqli_warning, got %s/%s\n", gettype($tmp), (is_object($tmp) ? var_dump($tmp, true) : $tmp)); + } + + $warning_clone = clone $warning; + print "done!"; +?> +--CLEAN-- +<?php + require_once("clean_table.inc"); +?> +--EXPECTF-- +Fatal error: Trying to clone an uncloneable object of class mysqli_warning in %s on line %d
\ No newline at end of file diff --git a/ext/mysqli/tests/reflection_tools.inc b/ext/mysqli/tests/reflection_tools.inc new file mode 100644 index 0000000..c8338bf --- /dev/null +++ b/ext/mysqli/tests/reflection_tools.inc @@ -0,0 +1,121 @@ +<?php + function inspectClass($class) { + + /* not used: public ReflectionClass[] getInterfaces() */ + + printf("\nInspecting class '%s'\n", $class->getName()); + printf("isInternal: %s\n", ($class->isInternal()) ? 'yes' : 'no'); + printf("isUserDefined: %s\n", ($class->isUserDefined()) ? 'yes' : 'no'); + printf("isInstantiable: %s\n", ($class->isInstantiable()) ? 'yes' : 'no'); + printf("isInterface: %s\n", ($class->isInterface()) ? 'yes' : 'no'); + printf("isAbstract: %s\n", ($class->isAbstract()) ? 'yes' : 'no'); + printf("isFinal: %s\n", ($class->isFinal()) ? 'yes' : 'no'); + printf("isIteratable: %s\n", ($class->isIterateable()) ? 'yes' : 'no'); + printf("Modifiers: '%d'\n", $class->getModifiers()); + printf("Parent Class: '%s'\n", $class->getParentClass()); + printf("Extension: '%s'\n", $class->getExtensionName()); + + if ($method = $class->getConstructor()) + inspectMethod($method); + + if ($methods = $class->getMethods()) { + $tmp = array(); + foreach ($methods as $method) + $tmp[$method->getName()] = $method; + + ksort($tmp, SORT_STRING); + foreach ($tmp as $method) + inspectMethod($method); + } + + if ($properties = $class->getProperties()) { + $tmp = array(); + foreach ($properties as $prop) + $tmp[$prop->getName()] = $prop; + ksort($tmp, SORT_STRING); + foreach ($tmp as $prop) + inspectProperty($prop); + } + + + if ($properties = $class->getDefaultProperties()) { + ksort($properties, SORT_STRING); + foreach ($properties as $name => $v) + printf("Default property '%s'\n", $name); + } + + if ($properties = $class->getStaticProperties()) { + ksort($properties, SORT_STRING); + foreach ($properties as $name => $v) + printf("Static property '%s'\n", $name); + } + + if ($constants = $class->getConstants()) { + ksort($constants, SORT_STRING); + foreach ($constant as $name => $value) + printf("Constant '%s' = '%s'\n", $name, $value); + } + + } + + function inspectProperty(&$prop) { + + printf("\nInspecting property '%s'\n", $prop->getName()); + printf("isPublic: %s\n", ($prop->isPublic()) ? 'yes' : 'no'); + printf("isPrivate: %s\n", ($prop->isPrivate()) ? 'yes' : 'no'); + printf("isProtected: %s\n", ($prop->isProtected()) ? 'yes' : 'no'); + printf("isStatic: %s\n", ($prop->isStatic()) ? 'yes' : 'no'); + printf("isDefault: %s\n", ($prop->isDefault()) ? 'yes' : 'no'); + printf("Modifiers: %d\n", $prop->getModifiers()); + // printf("Value\n"); var_export($prop->getValue()); + + } + + function inspectMethod(&$method) { + + printf("\nInspecting method '%s'\n", $method->getName()); + printf("isFinal: %s\n", ($method->isFinal()) ? 'yes' : 'no'); + printf("isAbstract: %s\n", ($method->isAbstract()) ? 'yes' : 'no'); + printf("isPublic: %s\n", ($method->isPublic()) ? 'yes' : 'no'); + printf("isPrivate: %s\n", ($method->isPrivate()) ? 'yes' : 'no'); + printf("isProtected: %s\n", ($method->isProtected()) ? 'yes' : 'no'); + printf("isStatic: %s\n", ($method->isStatic()) ? 'yes' : 'no'); + printf("isConstructor: %s\n", ($method->isConstructor()) ? 'yes' : 'no'); + printf("isDestructor: %s\n", ($method->isDestructor()) ? 'yes' : 'no'); + printf("isInternal: %s\n", ($method->isInternal()) ? 'yes' : 'no'); + printf("isUserDefined: %s\n", ($method->isUserDefined()) ? 'yes' : 'no'); + printf("returnsReference: %s\n", ($method->returnsReference()) ? 'yes' : 'no'); + printf("Modifiers: %d\n", $method->getModifiers()); + printf("Number of Parameters: %d\n", $method->getNumberOfParameters()); + printf("Number of Required Parameters: %d\n", $method->getNumberOfRequiredParameters()); + + if ($params = $method->getParameters()) { + $tmp = array(); + foreach ($params as $k => $param) + $tmp[$param->getName()] = $param; + +// ksort($tmp, SORT_STRING); + foreach ($tmp as $param) + inspectParameter($method, $param); + } + + if ($static = $method->getStaticVariables()) { + sort($static, SORT_STRING); + printf("Static variables: %s\n", implode('/', $static)); + } + + } + + function inspectParameter(&$method, &$param) { + + printf("\nInspecting parameter '%s' of method '%s'\n", + $param->getName(), $method->getName()); + printf("isArray: %s\n", ($param->isArray()) ? 'yes': 'no'); + printf("allowsNull: %s\n", ($param->allowsNull()) ? 'yes' : 'no'); + printf("isPassedByReference: %s\n", ($param->isPassedByReference()) ? 'yes' : 'no'); + printf("isOptional: %s\n", ($param->isOptional()) ? 'yes' : 'no'); + printf("isDefaultValueAvailable: %s\n", ($param->isDefaultValueAvailable()) ? 'yes' : 'no'); + // printf("getDefaultValue: %s\n", ($param->getDefaultValue()) ? 'yes' : 'no'); + + } +?>
\ No newline at end of file diff --git a/ext/mysqli/tests/skipif.inc b/ext/mysqli/tests/skipif.inc new file mode 100644 index 0000000..a7581fb --- /dev/null +++ b/ext/mysqli/tests/skipif.inc @@ -0,0 +1,5 @@ +<?php +if (!extension_loaded('mysqli')){ + die('skip mysqli extension not available'); +} +?>
\ No newline at end of file diff --git a/ext/mysqli/tests/skipifconnectfailure.inc b/ext/mysqli/tests/skipifconnectfailure.inc new file mode 100644 index 0000000..32a9763 --- /dev/null +++ b/ext/mysqli/tests/skipifconnectfailure.inc @@ -0,0 +1,10 @@ +<?php +require_once('connect.inc'); +if ($skip_on_connect_failure) { + include_once('connect.inc'); + $link = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); + if (!is_object($link)) + die(sprintf("skip Can't connect to MySQL Server - [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); + mysqli_close($link); +} +?> diff --git a/ext/mysqli/tests/skipifemb.inc b/ext/mysqli/tests/skipifemb.inc new file mode 100644 index 0000000..254a4cc --- /dev/null +++ b/ext/mysqli/tests/skipifemb.inc @@ -0,0 +1,5 @@ +<?php + $driver = new mysqli_driver(); + if ($driver->embedded) + die("skip test doesn't run with embedded server"); +?>
\ No newline at end of file diff --git a/ext/mysqli/tests/skipifnotemb.inc b/ext/mysqli/tests/skipifnotemb.inc new file mode 100644 index 0000000..d73d185 --- /dev/null +++ b/ext/mysqli/tests/skipifnotemb.inc @@ -0,0 +1,5 @@ +<?php + $driver = new mysqli_driver(); + if (!$driver->embedded) + die("skip test for with embedded server only"); +?>
\ No newline at end of file diff --git a/ext/mysqli/tests/skipifunicode.inc b/ext/mysqli/tests/skipifunicode.inc new file mode 100644 index 0000000..da4dd8e --- /dev/null +++ b/ext/mysqli/tests/skipifunicode.inc @@ -0,0 +1,5 @@ +<?php +if (version_compare(PHP_VERSION, '5.9.9', '>') == 1) { + die('skip Not functional with PHP 6 (fomerly PHP 6 && unicode.semantics=On)'); +} +?> diff --git a/ext/mysqli/tests/table.inc b/ext/mysqli/tests/table.inc new file mode 100644 index 0000000..aa1207a --- /dev/null +++ b/ext/mysqli/tests/table.inc @@ -0,0 +1,23 @@ +<?PHP +require_once('connect.inc'); + +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + exit(1); +} + +if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { + printf("Failed to drop old test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + exit(1); +} + +if (!mysqli_query($link, 'CREATE TABLE test(id INT, label CHAR(1), PRIMARY KEY(id)) ENGINE=' . $engine)) { + printf("Failed to create test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + exit(1); +} + +if (!mysqli_query($link, "INSERT INTO test(id, label) VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'), (6, 'f')")) { + printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link)); +} +?>
\ No newline at end of file |