mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
- Add mysqlnd support for PDO_mysql, fixes at least bug#41997,#42499,
pecl#12794, pecl#12401 # Running the tests: # (Note: Doesn't work currnetly on HEAD, see: # http://news.php.net/php.qa/64378) # # PDO_MYSQL_TEST_DSN - DSN # For example: mysql:dbname=test;host=localhost;port=3306 # # PDO_MYSQL_TEST_HOST - database host # PDO_MYSQL_TEST_DB - database (schema) name # PDO_MYSQL_TEST_SOCKET - database server socket # PDO_MYSQL_TEST_ENGINE - storage engine to use # PDO_MYSQL_TEST_USER - database user # PDO_MYSQL_TEST_PASS - database user password # PDO_MYSQL_TEST_CHARSET - database charset # # NOTE: if any of PDO_MYSQL_TEST_[HOST|DB|SOCKET|ENGINE|CHARSET] is # part of PDO_MYSQL_TEST_DSN, the values must match. That is, for example, # for PDO_MYSQL_TEST_DSN = mysql:dbname=test you MUST set PDO_MYSQL_TEST_DB=test.
This commit is contained in:
parent
0df974b7a5
commit
ae1cd8e253
105 changed files with 10872 additions and 458 deletions
|
@ -538,6 +538,20 @@ static inline void fetch_value(pdo_stmt_t *stmt, zval *dest, int colno, int *typ
|
|||
stmt->methods->get_col(stmt, colno, &value, &value_len, &caller_frees TSRMLS_CC);
|
||||
|
||||
switch (type) {
|
||||
case PDO_PARAM_ZVAL:
|
||||
if (value && value_len == sizeof(zval)) {
|
||||
int need_copy = (new_type != PDO_PARAM_ZVAL || stmt->dbh->stringify) ? 1 : 0;
|
||||
zval *zv = *(zval**)value;
|
||||
ZVAL_ZVAL(dest, zv, need_copy, 1);
|
||||
} else {
|
||||
ZVAL_NULL(dest);
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(dest) == IS_NULL) {
|
||||
type = new_type;
|
||||
}
|
||||
break;
|
||||
|
||||
case PDO_PARAM_INT:
|
||||
if (value && value_len == sizeof(long)) {
|
||||
ZVAL_LONG(dest, *(long*)value);
|
||||
|
@ -1879,7 +1893,10 @@ static PHP_METHOD(PDOStatement, getColumnMeta)
|
|||
add_assoc_string(return_value, "name", col->name, 1);
|
||||
add_assoc_long(return_value, "len", col->maxlen); /* FIXME: unsigned ? */
|
||||
add_assoc_long(return_value, "precision", col->precision);
|
||||
add_assoc_long(return_value, "pdo_type", col->param_type);
|
||||
if (col->param_type != PDO_PARAM_ZVAL) {
|
||||
/* if param_type is PDO_PARAM_ZVAL the driver has to provide correct data */
|
||||
add_assoc_long(return_value, "pdo_type", col->param_type);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64 TSRMLS_DC);
|
|||
# define FALSE 0
|
||||
#endif
|
||||
|
||||
#define PDO_DRIVER_API 20061209
|
||||
#define PDO_DRIVER_API 20080721
|
||||
|
||||
enum pdo_param_type {
|
||||
PDO_PARAM_NULL,
|
||||
|
@ -68,7 +68,12 @@ enum pdo_param_type {
|
|||
PDO_PARAM_STMT, /* hierarchical result set */
|
||||
|
||||
/* get_col ptr should point to a zend_bool */
|
||||
PDO_PARAM_BOOL
|
||||
PDO_PARAM_BOOL,
|
||||
|
||||
/* get_col ptr should point to a zval*
|
||||
and the driver is responsible for adding correct type information to get_column_meta()
|
||||
*/
|
||||
PDO_PARAM_ZVAL
|
||||
};
|
||||
|
||||
/* magic flag to denote a parameter as being input/output */
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
mySQL driver for PDO
|
||||
George Schlossnagle, Wez Furlong, Ilia Alshanetsky
|
||||
|
||||
MySQL driver for PDO
|
||||
George Schlossnagle, Wez Furlong, Ilia Alshanetsky, Johannes Schlueter
|
||||
|
||||
|
|
|
@ -2,68 +2,143 @@ dnl
|
|||
dnl $Id$
|
||||
dnl
|
||||
|
||||
if test "$PHP_PDO" != "no"; then
|
||||
|
||||
AC_DEFUN([PDO_MYSQL_LIB_CHK], [
|
||||
str="$PDO_MYSQL_DIR/$1/libmysqlclient.*"
|
||||
for j in `echo $str`; do
|
||||
if test -r $j; then
|
||||
PDO_MYSQL_LIB_DIR=$MYSQL_DIR/$1
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
])
|
||||
|
||||
dnl TODO Rename when moving to pdo_mysql
|
||||
PHP_ARG_WITH(pdo-mysql, for MySQL support for PDO,
|
||||
[ --with-pdo-mysql[=DIR] PDO: MySQL support. DIR is the MySQL base directory])
|
||||
[ --with-pdo-mysql[=DIR] PDO: MySQL support. DIR is the MySQL base directoy
|
||||
If mysqlnd is passed as DIR, the MySQL native
|
||||
native driver will be used [/usr/local]])
|
||||
|
||||
if test -z "$PHP_ZLIB_DIR"; then
|
||||
PHP_ARG_WITH(zlib-dir, for the location of libz,
|
||||
[ --with-zlib-dir[=DIR] PDO_MySQL: Set the path to libz install prefix], no, no)
|
||||
fi
|
||||
|
||||
if test "$PHP_PDO_MYSQL" != "no"; then
|
||||
AC_DEFINE(HAVE_MYSQL, 1, [Whether you have MySQL])
|
||||
PHP_MYSQLND_ENABLED=yes
|
||||
|
||||
for i in $PHP_PDO_MYSQL /usr/local /usr ; do
|
||||
PDO_MYSQL_DIR=$i
|
||||
PDO_MYSQL_CONFIG=$PDO_MYSQL_DIR/bin/mysql_config
|
||||
if test -r $i/include/mysql; then
|
||||
PDO_MYSQL_INC_DIR=$i/include/mysql
|
||||
else
|
||||
PDO_MYSQL_INC_DIR=$i/include
|
||||
fi
|
||||
if test -r $i/lib/mysql; then
|
||||
PDO_MYSQL_LIB_DIR=$i/lib/mysql
|
||||
else
|
||||
PDO_MYSQL_LIB_DIR=$i/lib
|
||||
fi
|
||||
if test -x $PDO_MYSQL_CONFIG; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
AC_DEFUN([PDO_MYSQL_LIB_CHK], [
|
||||
str="$PDO_MYSQL_DIR/$1/libmysqlclient*"
|
||||
for j in `echo $str`; do
|
||||
if test -r $j; then
|
||||
PDO_MYSQL_LIB_DIR=$PDO_MYSQL_DIR/$1
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
])
|
||||
|
||||
if test -z "$PDO_MYSQL_DIR"; then
|
||||
AC_MSG_ERROR([Cannot find MySQL header files under $PHP_MYSQL.
|
||||
Note that the MySQL client library is not bundled anymore!])
|
||||
fi
|
||||
|
||||
if test -x $PDO_MYSQL_CONFIG; then
|
||||
PDO_MYSQL_SOCKET=`$PDO_MYSQL_CONFIG --socket`
|
||||
fi
|
||||
|
||||
if test "$PHP_MYSQL_SOCK" != "no" && test "$PHP_MYSQL_SOCK" != "yes"; then
|
||||
AC_DEFINE_UNQUOTED(PDO_MYSQL_UNIX_ADDR, "$PHP_MYSQL_SOCK", [ ])
|
||||
if test "$PHP_PDO_MYSQL" = "mysqlnd"; then
|
||||
dnl enables build of mysqnd library
|
||||
PHP_MYSQL_ENABLED=yes
|
||||
AC_DEFINE([PDO_USE_MYSQLND], 1, [Whether pdo_mysql uses mysqlnd])
|
||||
else
|
||||
AC_DEFINE(HAVE_MYSQL, 1, [Whether you have MySQL])
|
||||
AC_MSG_CHECKING([for mysql_config])
|
||||
|
||||
if test -f $PHP_PDO_MYSQL && test -x $PHP_PDO_MYSQL ; then
|
||||
PDO_MYSQL_CONFIG=$PHP_PDO_MYSQL
|
||||
elif test "$PHP_PDO_MYSQL" != "yes"; then
|
||||
if test -d "$PHP_PDO_MYSQL" ; then
|
||||
if test -x "$PHP_PDO_MYSQL/bin/mysql_config" ; then
|
||||
PDO_MYSQL_CONFIG="$PHP_PDO_MYSQL/bin/mysql_config"
|
||||
else
|
||||
PDO_MYSQL_DIR="$PHP_PDO_MYSQL"
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([$PHP_PDO_MYSQL is not a directory])
|
||||
AC_MSG_ERROR([can not find mysql under the "$PHP_PDO_MYSQL" that you specified])
|
||||
fi
|
||||
else
|
||||
for i in /usr/local /usr ; do
|
||||
if test -x "$i/bin/mysql_config" ; then
|
||||
PDO_MYSQL_CONFIG="$i/bin/mysql_config"
|
||||
break;
|
||||
fi
|
||||
if test -r $i/include/mysql/mysql.h || test -r $i/include/mysql.h ; then
|
||||
PDO_MYSQL_DIR="$i"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if test -n "$PDO_MYSQL_CONFIG" && test -x "$PDO_MYSQL_CONFIG" ; then
|
||||
AC_MSG_RESULT($PDO_MYSQL_CONFIG)
|
||||
if test "x$SED" = "x"; then
|
||||
AC_PATH_PROG(SED, sed)
|
||||
fi
|
||||
|
||||
if test "$enable_maintainer_zts" = "yes"; then
|
||||
PDO_MYSQL_LIBNAME=mysqlclient_r
|
||||
PDO_MYSQL_LIBS=`$PDO_MYSQL_CONFIG --libs_r | $SED -e "s/'//g"`
|
||||
else
|
||||
PDO_MYSQL_LIBNAME=mysqlclient
|
||||
PDO_MYSQL_LIBS=`$PDO_MYSQL_CONFIG --libs | $SED -e "s/'//g"`
|
||||
fi
|
||||
PDO_MYSQL_INCLUDE=`$PDO_MYSQL_CONFIG --cflags | $SED -e "s/'//g"`
|
||||
PDO_MYSQL_SOCKET=`$PDO_MYSQL_CONFIG --socket`
|
||||
elif test -z "$PDO_MYSQL_DIR"; then
|
||||
AC_MSG_RESULT([not found])
|
||||
AC_MSG_ERROR([Cannot find MySQL header files under $PDO_MYSQL_DIR])
|
||||
else
|
||||
AC_MSG_RESULT([not found])
|
||||
AC_MSG_CHECKING([for mysql install under $PDO_MYSQL_DIR])
|
||||
if test -r $PDO_MYSQL_DIR/include/mysql; then
|
||||
PDO_MYSQL_INC_DIR=$PDO_MYSQL_DIR/include/mysql
|
||||
else
|
||||
PDO_MYSQL_INC_DIR=$PDO_MYSQL_DIR/include
|
||||
fi
|
||||
if test -r $PDO_MYSQL_DIR/$PHP_LIBDIR/mysql; then
|
||||
PDO_MYSQL_LIB_DIR=$PDO_MYSQL_DIR/$PHP_LIBDIR/mysql
|
||||
else
|
||||
PDO_MYSQL_LIB_DIR=$PDO_MYSQL_DIR/$PHP_LIBDIR
|
||||
fi
|
||||
|
||||
if test -r "$PDO_MYSQL_LIB_DIR"; then
|
||||
AC_MSG_RESULT([libs under $PDO_MYSQL_LIB_DIR; seems promising])
|
||||
else
|
||||
AC_MSG_RESULT([can not find it])
|
||||
AC_MSG_ERROR([Unable to find your mysql installation])
|
||||
fi
|
||||
|
||||
PHP_ADD_INCLUDE($PDO_MYSQL_INC_DIR)
|
||||
PDO_MYSQL_INCLUDE=-I$PDO_MYSQL_INC_DIR
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(PDO_MYSQL_UNIX_ADDR, "$PDO_MYSQL_SOCKET", [ ])
|
||||
fi
|
||||
|
||||
PHP_ADD_LIBRARY_WITH_PATH(mysqlclient, $PDO_MYSQL_LIB_DIR, PDO_MYSQL_SHARED_LIBADD)
|
||||
PHP_ADD_INCLUDE($PDO_MYSQL_INC_DIR)
|
||||
if test -x $PDO_MYSQL_CONFIG; then
|
||||
PDO_MYSQL_LIBS=`$PDO_MYSQL_CONFIG --libs`
|
||||
PHP_SUBST_OLD(PDO_MYSQL_LIBS)
|
||||
fi
|
||||
PHP_CHECK_LIBRARY($PDO_MYSQL_LIBNAME, mysql_query,
|
||||
[
|
||||
PHP_EVAL_INCLINE($PDO_MYSQL_INCLUDE)
|
||||
PHP_EVAL_LIBLINE($PDO_MYSQL_LIBS, PDO_MYSQL_SHARED_LIBADD)
|
||||
],[
|
||||
if test "$PHP_ZLIB_DIR" != "no"; then
|
||||
PHP_ADD_LIBRARY_WITH_PATH(z, $PHP_ZLIB_DIR, PDO_MYSQL_SHARED_LIBADD)
|
||||
PHP_CHECK_LIBRARY($PDO_MYSQL_LIBNAME, mysql_query, [], [
|
||||
AC_MSG_ERROR([PDO_MYSQL configure failed. Please check config.log for more information.])
|
||||
], [
|
||||
-L$PHP_ZLIB_DIR/$PHP_LIBDIR -L$PDO_MYSQL_LIB_DIR
|
||||
])
|
||||
PDO_MYSQL_LIBS="$PDO_MYSQL_LIBS -L$PHP_ZLIB_DIR/$PHP_LIBDIR -lz"
|
||||
else
|
||||
PHP_ADD_LIBRARY(z,, PDO_MYSQL_SHARED_LIBADD)
|
||||
PHP_CHECK_LIBRARY($PDO_MYSQL_LIBNAME, mysql_query, [], [
|
||||
AC_MSG_ERROR([Try adding --with-zlib-dir=<DIR>. Please check config.log for more information.])
|
||||
], [
|
||||
-L$PDO_MYSQL_LIB_DIR
|
||||
])
|
||||
PDO_MYSQL_LIBS="$PDO_MYSQL_LIBS -lz"
|
||||
fi
|
||||
|
||||
_SAVE_LDFLAGS=$LDFLAGS
|
||||
LDFLAGS="$LDFLAGS $PDO_MYSQL_LIBS"
|
||||
AC_CHECK_FUNCS([mysql_commit mysql_stmt_prepare mysql_next_result mysql_sqlstate])
|
||||
LDFLAGS=$_SAVE_LDFLAGS
|
||||
PHP_EVAL_INCLINE($PDO_MYSQL_INCLUDE)
|
||||
PHP_EVAL_LIBLINE($PDO_MYSQL_LIBS, PDO_MYSQL_SHARED_LIBADD)
|
||||
],[
|
||||
$PDO_MYSQL_LIBS
|
||||
])
|
||||
|
||||
_SAVE_LIBS=$LIBS
|
||||
LIBS="$LIBS $PDO_MYSQL_LIBS"
|
||||
AC_CHECK_FUNCS([mysql_commit mysql_stmt_prepare mysql_next_result mysql_sqlstate])
|
||||
LIBS=$_SAVE_LIBS
|
||||
fi
|
||||
|
||||
ifdef([PHP_CHECK_PDO_INCLUDES],
|
||||
[
|
||||
|
@ -82,18 +157,19 @@ Note that the MySQL client library is not bundled anymore!])
|
|||
AC_MSG_RESULT($pdo_inc_path)
|
||||
])
|
||||
|
||||
PHP_NEW_EXTENSION(pdo_mysql, pdo_mysql.c mysql_driver.c mysql_statement.c, $ext_shared,,-I$pdo_inc_path)
|
||||
|
||||
dnl fix after renaming to pdo_mysql
|
||||
PHP_NEW_EXTENSION(pdo_mysql, pdo_mysql.c mysql_driver.c mysql_statement.c, $ext_shared,,-I$pdo_inc_path -I)
|
||||
ifdef([PHP_ADD_EXTENSION_DEP],
|
||||
[
|
||||
PHP_ADD_EXTENSION_DEP(pdo_mysql, pdo)
|
||||
PHP_ADD_EXTENSION_DEP(pdo_mysql, pdo)
|
||||
if test "$PHP_MYSQL" = "mysqlnd"; then
|
||||
PHP_ADD_EXTENSION_DEP(pdo_mysql, mysqlnd)
|
||||
fi
|
||||
])
|
||||
PDO_MYSQL_MODULE_TYPE=external
|
||||
PDO_MYSQL_INCLUDE=-I$PDO_MYSQL_INC_DIR
|
||||
|
||||
PHP_SUBST(PDO_MYSQL_SHARED_LIBADD)
|
||||
|
||||
PHP_SUBST_OLD(PDO_MYSQL_MODULE_TYPE)
|
||||
PHP_SUBST_OLD(PDO_MYSQL_LIBS)
|
||||
PHP_SUBST_OLD(PDO_MYSQL_INCLUDE)
|
||||
fi
|
||||
|
||||
fi
|
||||
dnl vim: se ts=2 sw=2 et:
|
||||
|
|
|
@ -4,11 +4,17 @@
|
|||
ARG_WITH("pdo-mysql", "MySQL support for PDO", "no");
|
||||
|
||||
if (PHP_PDO_MYSQL != "no") {
|
||||
if (CHECK_LIB("libmysql.lib", "pdo_mysql", PHP_PDO_MYSQL) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("mysql.h", "CFLAGS_PDO_MYSQL", PHP_PHP_BUILD + "\\include\\mysql;" + PHP_PDO_MYSQL)) {
|
||||
if (PHP_PDO_MYSQL == "yes" || PHP_PDO_MYSQL == "mysqlnd") {
|
||||
AC_DEFINE('PDO_USE_MYSQLND', 1, 'Using MySQL native driver');
|
||||
STDOUT.WriteLine("INFO: mysqlnd build");
|
||||
EXTENSION("pdo_mysql", "pdo_mysql.c mysql_driver.c mysql_statement.c");
|
||||
ADD_EXTENSION_DEP('pdo_mysql', 'pdo');
|
||||
} else {
|
||||
WARNING("pdo_mysql not enabled; libraries and headers not found");
|
||||
if (CHECK_LIB("libmysql.lib", "pdo_mysql", PHP_PDO_MYSQL) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("mysql.h", "CFLAGS_PDO_MYSQL", PHP_PHP_BUILD + "\\include\\mysql;" + PHP_PDO_MYSQL)) {
|
||||
EXTENSION("pdo_mysql", "pdo_mysql.c mysql_driver.c mysql_statement.c");
|
||||
} else {
|
||||
WARNING("pdo_mysql not enabled; libraries and headers not found");
|
||||
}
|
||||
}
|
||||
ADD_EXTENSION_DEP('pdo_mysql', 'pdo');
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
+----------------------------------------------------------------------+
|
||||
| Author: George Schlossnagle <george@omniti.com> |
|
||||
| Wez Furlong <wez@php.net> |
|
||||
| Johannes Schlueter <johannes@mysql.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
@ -30,18 +31,29 @@
|
|||
#include "pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_mysql.h"
|
||||
#include "php_pdo_mysql_int.h"
|
||||
#ifndef PDO_USE_MYSQLND
|
||||
#include <mysqld_error.h>
|
||||
#endif
|
||||
#include "zend_exceptions.h"
|
||||
|
||||
#if PDO_USE_MYSQLND
|
||||
# define pdo_mysql_init(persistent) mysqlnd_init(persistent)
|
||||
#else
|
||||
# define pdo_mysql_init(persistent) mysql_init(NULL)
|
||||
#endif
|
||||
|
||||
const char *pdo_mysql_get_sqlstate(unsigned int my_errno) {
|
||||
#if !HAVE_MYSQL_SQLSTATE && !PDO_USE_MYSQLND
|
||||
static const char *pdo_mysql_get_sqlstate(unsigned int my_errno) { /* {{{ */
|
||||
switch (my_errno) {
|
||||
/* import auto-generated case: code */
|
||||
#include "php_pdo_mysql_sqlstate.h"
|
||||
default: return "HY000";
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
|
||||
/* {{{ _pdo_mysql_error */
|
||||
int _pdo_mysql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *file, int line TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||
|
@ -49,6 +61,8 @@ int _pdo_mysql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *file, int lin
|
|||
pdo_mysql_error_info *einfo;
|
||||
pdo_mysql_stmt *S = NULL;
|
||||
|
||||
PDO_DBG_ENTER("_pdo_mysql_error");
|
||||
PDO_DBG_INF_FMT("file=%s line=%d", file, line);
|
||||
if (stmt) {
|
||||
S = (pdo_mysql_stmt*)stmt->driver_data;
|
||||
pdo_err = &stmt->error_code;
|
||||
|
@ -58,7 +72,16 @@ int _pdo_mysql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *file, int lin
|
|||
einfo = &H->einfo;
|
||||
}
|
||||
|
||||
einfo->errcode = mysql_errno(H->server);
|
||||
#if HAVE_MYSQL_STMT_PREPARE || PDO_USE_MYSQLND
|
||||
if (S && S->stmt) {
|
||||
einfo->errcode = mysql_stmt_errno(S->stmt);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
einfo->errcode = mysql_errno(H->server);
|
||||
}
|
||||
|
||||
einfo->file = file;
|
||||
einfo->line = line;
|
||||
|
||||
|
@ -68,23 +91,29 @@ int _pdo_mysql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *file, int lin
|
|||
}
|
||||
|
||||
if (einfo->errcode) {
|
||||
if (2014 != einfo->errcode) {
|
||||
einfo->errmsg = pestrdup(mysql_error(H->server), dbh->is_persistent);
|
||||
} else {
|
||||
if (einfo->errcode == 2014) {
|
||||
einfo->errmsg = pestrdup(
|
||||
"Cannot execute queries while other unbuffered queries are active. "
|
||||
"Consider using PDOStatement::fetchAll(). Alternatively, if your code "
|
||||
"is only ever going to run against mysql, you may enable query "
|
||||
"buffering by setting the PDO_MYSQL_ATTR_USE_BUFFERED_QUERY attribute.",
|
||||
"buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.",
|
||||
dbh->is_persistent);
|
||||
} else if (einfo->errcode == 2057) {
|
||||
einfo->errmsg = pestrdup(
|
||||
"A stored procedure returning result sets of different size was called. "
|
||||
"This is not supported by libmysql",
|
||||
dbh->is_persistent);
|
||||
|
||||
} else {
|
||||
einfo->errmsg = pestrdup(mysql_error(H->server), dbh->is_persistent);
|
||||
}
|
||||
} else { /* no error */
|
||||
strcpy(*pdo_err, PDO_ERR_NONE);
|
||||
return 0;
|
||||
PDO_DBG_RETURN(0);
|
||||
}
|
||||
|
||||
#if HAVE_MYSQL_SQLSTATE
|
||||
# if HAVE_MYSQL_STMT_PREPARE
|
||||
#if HAVE_MYSQL_SQLSTATE || PDO_USE_MYSQLND
|
||||
# if HAVE_MYSQL_STMT_PREPARE || PDO_USE_MYSQLND
|
||||
if (S && S->stmt) {
|
||||
strcpy(*pdo_err, mysql_stmt_sqlstate(S->stmt));
|
||||
} else
|
||||
|
@ -97,25 +126,23 @@ int _pdo_mysql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *file, int lin
|
|||
#endif
|
||||
|
||||
if (!dbh->methods) {
|
||||
#if PHP_VERSION_ID > 50200
|
||||
PDO_DBG_INF("Throwing exception");
|
||||
zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "SQLSTATE[%s] [%d] %s",
|
||||
*pdo_err, einfo->errcode, einfo->errmsg);
|
||||
#else
|
||||
zend_throw_exception_ex(php_pdo_get_exception(TSRMLS_C), 0 TSRMLS_CC, "SQLSTATE[%s] [%d] %s",
|
||||
*pdo_err, einfo->errcode, einfo->errmsg);
|
||||
#endif
|
||||
}
|
||||
/* printf("** [%s:%d] %s %s\n", file, line, *pdo_err, einfo->errmsg); */
|
||||
|
||||
return einfo->errcode;
|
||||
PDO_DBG_RETURN(einfo->errcode);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ pdo_mysql_fetch_error_func */
|
||||
static int pdo_mysql_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC)
|
||||
{
|
||||
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||
pdo_mysql_error_info *einfo = &H->einfo;
|
||||
|
||||
PDO_DBG_ENTER("pdo_mysql_fetch_error_func");
|
||||
PDO_DBG_INF_FMT("dbh=%p stmt=%p", dbh, stmt);
|
||||
if (stmt) {
|
||||
pdo_mysql_stmt *S = (pdo_mysql_stmt*)stmt->driver_data;
|
||||
einfo = &S->einfo;
|
||||
|
@ -128,13 +155,17 @@ static int pdo_mysql_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *in
|
|||
add_next_index_string(info, einfo->errmsg, 1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
PDO_DBG_RETURN(1);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mysql_handle_closer */
|
||||
static int mysql_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||
|
||||
PDO_DBG_ENTER("mysql_handle_closer");
|
||||
PDO_DBG_INF_FMT("dbh=%p", dbh);
|
||||
if (H) {
|
||||
if (H->server) {
|
||||
mysql_close(H->server);
|
||||
|
@ -147,20 +178,26 @@ static int mysql_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
|
|||
pefree(H, dbh->is_persistent);
|
||||
dbh->driver_data = NULL;
|
||||
}
|
||||
return 0;
|
||||
PDO_DBG_RETURN(0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mysql_handle_preparer */
|
||||
static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC)
|
||||
{
|
||||
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||
pdo_mysql_stmt *S = ecalloc(1, sizeof(pdo_mysql_stmt));
|
||||
#if HAVE_MYSQL_STMT_PREPARE
|
||||
#if HAVE_MYSQL_STMT_PREPARE || PDO_USE_MYSQLND
|
||||
char *nsql = NULL;
|
||||
int nsql_len = 0;
|
||||
int ret;
|
||||
int server_version;
|
||||
#endif
|
||||
|
||||
PDO_DBG_ENTER("mysql_handle_preparer");
|
||||
PDO_DBG_INF_FMT("dbh=%p", dbh);
|
||||
PDO_DBG_INF_FMT("sql=%.*s", sql_len, sql);
|
||||
|
||||
S->H = H;
|
||||
stmt->driver_data = S;
|
||||
stmt->methods = &mysql_stmt_methods;
|
||||
|
@ -169,11 +206,11 @@ static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
|
|||
goto end;
|
||||
}
|
||||
|
||||
/* TODO: add runtime check to determine if the server we are talking to supports
|
||||
* prepared statements; if it doesn't, we should set stmt->supports_placeholders
|
||||
* to PDO_PLACEHOLDER_NONE, and have the rest of the code look at S->stmt to
|
||||
* determine if we're using real prepared statements or the PDO emulated version */
|
||||
#if HAVE_MYSQL_STMT_PREPARE
|
||||
#if HAVE_MYSQL_STMT_PREPARE || PDO_USE_MYSQLND
|
||||
server_version = mysql_get_server_version(H->server);
|
||||
if (server_version < 40100) {
|
||||
goto fallback;
|
||||
}
|
||||
stmt->supports_placeholders = PDO_PLACEHOLDER_POSITIONAL;
|
||||
ret = pdo_parse_params(stmt, (char*)sql, sql_len, &nsql, &nsql_len TSRMLS_CC);
|
||||
|
||||
|
@ -184,7 +221,7 @@ static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
|
|||
} else if (ret == -1) {
|
||||
/* failed to parse */
|
||||
strcpy(dbh->error_code, stmt->error_code);
|
||||
return 0;
|
||||
PDO_DBG_RETURN(0);
|
||||
}
|
||||
|
||||
if (!(S->stmt = mysql_stmt_init(H->server))) {
|
||||
|
@ -192,7 +229,7 @@ static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
|
|||
if (nsql) {
|
||||
efree(nsql);
|
||||
}
|
||||
return 0;
|
||||
PDO_DBG_RETURN(0);
|
||||
}
|
||||
|
||||
if (mysql_stmt_prepare(S->stmt, sql, sql_len)) {
|
||||
|
@ -208,7 +245,7 @@ static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
|
|||
if (nsql) {
|
||||
efree(nsql);
|
||||
}
|
||||
return 0;
|
||||
PDO_DBG_RETURN(0);
|
||||
}
|
||||
if (nsql) {
|
||||
efree(nsql);
|
||||
|
@ -217,114 +254,199 @@ static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
|
|||
S->num_params = mysql_stmt_param_count(S->stmt);
|
||||
|
||||
if (S->num_params) {
|
||||
S->params_given = 0;
|
||||
#if PDO_USE_MYSQLND
|
||||
S->params = NULL;
|
||||
#else
|
||||
S->params = ecalloc(S->num_params, sizeof(MYSQL_BIND));
|
||||
S->in_null = ecalloc(S->num_params, sizeof(my_bool));
|
||||
S->in_length = ecalloc(S->num_params, sizeof(unsigned long));
|
||||
#endif
|
||||
}
|
||||
|
||||
dbh->alloc_own_columns = 1;
|
||||
|
||||
S->max_length = pdo_attr_lval(driver_options, PDO_ATTR_MAX_COLUMN_LEN, 0 TSRMLS_CC);
|
||||
|
||||
return 1;
|
||||
PDO_DBG_RETURN(1);
|
||||
|
||||
fallback:
|
||||
#endif
|
||||
end:
|
||||
stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
|
||||
|
||||
return 1;
|
||||
PDO_DBG_RETURN(1);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mysql_handle_doer */
|
||||
static long mysql_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
|
||||
{
|
||||
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||
PDO_DBG_ENTER("mysql_handle_doer");
|
||||
PDO_DBG_INF_FMT("dbh=%p", dbh);
|
||||
PDO_DBG_INF_FMT("sql=%.*s", sql_len, sql);
|
||||
|
||||
if (mysql_real_query(H->server, sql, sql_len)) {
|
||||
pdo_mysql_error(dbh);
|
||||
return -1;
|
||||
PDO_DBG_RETURN(-1);
|
||||
} else {
|
||||
my_ulonglong c = mysql_affected_rows(H->server);
|
||||
if (c == (my_ulonglong) -1) {
|
||||
pdo_mysql_error(dbh);
|
||||
return (H->einfo.errcode ? -1 : 0);
|
||||
PDO_DBG_RETURN(H->einfo.errcode ? -1 : 0);
|
||||
} else {
|
||||
return c;
|
||||
|
||||
#if HAVE_MYSQL_NEXT_RESULT || PDO_USE_MYSQLND
|
||||
/* MULTI_QUERY support - eat up all unfetched result sets */
|
||||
MYSQL_RES* result;
|
||||
while (mysql_more_results(H->server)) {
|
||||
if (mysql_next_result(H->server)) {
|
||||
PDO_DBG_RETURN(1);
|
||||
}
|
||||
result = mysql_store_result(H->server);
|
||||
if (result) {
|
||||
mysql_free_result(result);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
PDO_DBG_RETURN((int)c);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ pdo_mysql_last_insert_id */
|
||||
static char *pdo_mysql_last_insert_id(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC)
|
||||
{
|
||||
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||
char *id = php_pdo_int64_to_str(mysql_insert_id(H->server) TSRMLS_CC);
|
||||
PDO_DBG_ENTER("pdo_mysql_last_insert_id");
|
||||
*len = strlen(id);
|
||||
return id;
|
||||
PDO_DBG_RETURN(id);
|
||||
}
|
||||
|
||||
/* {{{ mysql_handle_quoter */
|
||||
static int mysql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype TSRMLS_DC)
|
||||
{
|
||||
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||
PDO_DBG_ENTER("mysql_handle_quoter");
|
||||
PDO_DBG_INF_FMT("dbh=%p", dbh);
|
||||
PDO_DBG_INF_FMT("unquoted=%.*s", unquotedlen, unquoted);
|
||||
*quoted = safe_emalloc(2, unquotedlen, 3);
|
||||
*quotedlen = mysql_real_escape_string(H->server, *quoted + 1, unquoted, unquotedlen);
|
||||
(*quoted)[0] =(*quoted)[++*quotedlen] = '\'';
|
||||
(*quoted)[++*quotedlen] = '\0';
|
||||
return 1;
|
||||
PDO_DBG_INF_FMT("quoted=%.*s", *quotedlen, *quoted);
|
||||
PDO_DBG_RETURN(1);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mysql_handle_begin */
|
||||
static int mysql_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
return 0 <= mysql_handle_doer(dbh, ZEND_STRL("START TRANSACTION") TSRMLS_CC);
|
||||
PDO_DBG_ENTER("mysql_handle_quoter");
|
||||
PDO_DBG_INF_FMT("dbh=%p", dbh);
|
||||
PDO_DBG_RETURN(0 <= mysql_handle_doer(dbh, ZEND_STRL("START TRANSACTION") TSRMLS_CC));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mysql_handle_commit */
|
||||
static int mysql_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
return 0 <= mysql_handle_doer(dbh, ZEND_STRL("COMMIT") TSRMLS_CC);
|
||||
PDO_DBG_ENTER("mysql_handle_commit");
|
||||
PDO_DBG_INF_FMT("dbh=%p", dbh);
|
||||
#if MYSQL_VERSION_ID >= 40100 || defined(PDO_USE_MYSQLND)
|
||||
PDO_DBG_RETURN(0 <= mysql_commit(((pdo_mysql_db_handle *)dbh->driver_data)->server));
|
||||
#else
|
||||
PDO_DBG_RETURN(0 <= mysql_handle_doer(dbh, ZEND_STRL("COMMIT") TSRMLS_CC));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* {{{ mysql_handle_rollback */
|
||||
static int mysql_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
return 0 <= mysql_handle_doer(dbh, ZEND_STRL("ROLLBACK") TSRMLS_CC);
|
||||
PDO_DBG_ENTER("mysql_handle_rollback");
|
||||
PDO_DBG_INF_FMT("dbh=%p", dbh);
|
||||
#if MYSQL_VERSION_ID >= 40100 || defined(PDO_USE_MYSQLND)
|
||||
PDO_DBG_RETURN(0 <= mysql_rollback(((pdo_mysql_db_handle *)dbh->driver_data)->server));
|
||||
#else
|
||||
PDO_DBG_RETURN(0 <= mysql_handle_doer(dbh, ZEND_STRL("ROLLBACK") TSRMLS_CC));
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int mysql_handle_autocommit(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
/* {{{ mysql_handle_autocommit */
|
||||
static inline int mysql_handle_autocommit(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
PDO_DBG_ENTER("mysql_handle_autocommit");
|
||||
PDO_DBG_INF_FMT("dbh=%p", dbh);
|
||||
PDO_DBG_INF_FMT("dbh->autocommit=%d", dbh->auto_commit);
|
||||
#if MYSQL_VERSION_ID >= 40100 || defined(PDO_USE_MYSQLND)
|
||||
PDO_DBG_RETURN(0 <= mysql_autocommit(((pdo_mysql_db_handle *)dbh->driver_data)->server, dbh->auto_commit));
|
||||
#else
|
||||
if (dbh->auto_commit) {
|
||||
return 0 <= mysql_handle_doer(dbh, ZEND_STRL("SET AUTOCOMMIT=1") TSRMLS_CC);
|
||||
PDO_DBG_RETURN(0 <= mysql_handle_doer(dbh, ZEND_STRL("SET AUTOCOMMIT=1") TSRMLS_CC));
|
||||
} else {
|
||||
return 0 <= mysql_handle_doer(dbh, ZEND_STRL("SET AUTOCOMMIT=0") TSRMLS_CC);
|
||||
PDO_DBG_RETURN(0 <= mysql_handle_doer(dbh, ZEND_STRL("SET AUTOCOMMIT=0") TSRMLS_CC));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ pdo_mysql_set_attribute */
|
||||
static int pdo_mysql_set_attribute(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)
|
||||
{
|
||||
PDO_DBG_ENTER("pdo_mysql_set_attribute");
|
||||
PDO_DBG_INF_FMT("dbh=%p", dbh);
|
||||
PDO_DBG_INF_FMT("attr=%l", attr);
|
||||
switch (attr) {
|
||||
case PDO_ATTR_AUTOCOMMIT:
|
||||
|
||||
convert_to_boolean(val);
|
||||
case PDO_ATTR_AUTOCOMMIT:
|
||||
convert_to_boolean(val);
|
||||
|
||||
/* ignore if the new value equals the old one */
|
||||
if (dbh->auto_commit ^ Z_BVAL_P(val)) {
|
||||
dbh->auto_commit = Z_BVAL_P(val);
|
||||
mysql_handle_autocommit(dbh TSRMLS_CC);
|
||||
}
|
||||
return 1;
|
||||
/* ignore if the new value equals the old one */
|
||||
if (dbh->auto_commit ^ Z_BVAL_P(val)) {
|
||||
dbh->auto_commit = Z_BVAL_P(val);
|
||||
mysql_handle_autocommit(dbh TSRMLS_CC);
|
||||
}
|
||||
PDO_DBG_RETURN(1);
|
||||
|
||||
case PDO_MYSQL_ATTR_USE_BUFFERED_QUERY:
|
||||
((pdo_mysql_db_handle *)dbh->driver_data)->buffered = Z_BVAL_P(val);
|
||||
return 1;
|
||||
case PDO_MYSQL_ATTR_DIRECT_QUERY:
|
||||
((pdo_mysql_db_handle *)dbh->driver_data)->emulate_prepare = Z_BVAL_P(val);
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
case PDO_MYSQL_ATTR_USE_BUFFERED_QUERY:
|
||||
((pdo_mysql_db_handle *)dbh->driver_data)->buffered = Z_BVAL_P(val);
|
||||
PDO_DBG_RETURN(1);
|
||||
case PDO_MYSQL_ATTR_DIRECT_QUERY:
|
||||
case PDO_ATTR_EMULATE_PREPARES:
|
||||
((pdo_mysql_db_handle *)dbh->driver_data)->emulate_prepare = Z_BVAL_P(val);
|
||||
PDO_DBG_RETURN(1);
|
||||
case PDO_ATTR_FETCH_TABLE_NAMES:
|
||||
((pdo_mysql_db_handle *)dbh->driver_data)->fetch_table_names = Z_BVAL_P(val);
|
||||
PDO_DBG_RETURN(1);
|
||||
#ifndef PDO_USE_MYSQLND
|
||||
case PDO_MYSQL_ATTR_MAX_BUFFER_SIZE:
|
||||
if (Z_LVAL_P(val) < 0) {
|
||||
// TODO - Johannes, can we throw a warning here?
|
||||
((pdo_mysql_db_handle *)dbh->driver_data)->max_buffer_size = 1024*1024;
|
||||
PDO_DBG_INF_FMT("Adjusting invalid buffer size to =%l", ((pdo_mysql_db_handle *)dbh->driver_data)->max_buffer_size);
|
||||
} else {
|
||||
((pdo_mysql_db_handle *)dbh->driver_data)->max_buffer_size = Z_LVAL_P(val);
|
||||
}
|
||||
PDO_DBG_RETURN(1);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
PDO_DBG_RETURN(0);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ pdo_mysql_get_attribute */
|
||||
static int pdo_mysql_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value TSRMLS_DC)
|
||||
{
|
||||
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||
|
||||
PDO_DBG_ENTER("pdo_mysql_get_attribute");
|
||||
PDO_DBG_INF_FMT("dbh=%p", dbh);
|
||||
PDO_DBG_INF_FMT("attr=%l", attr);
|
||||
switch (attr) {
|
||||
case PDO_ATTR_CLIENT_VERSION:
|
||||
ZVAL_STRING(return_value, (char *)mysql_get_client_info(), 1);
|
||||
|
@ -337,42 +459,50 @@ static int pdo_mysql_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value
|
|||
case PDO_ATTR_CONNECTION_STATUS:
|
||||
ZVAL_STRING(return_value, (char *)mysql_get_host_info(H->server), 1);
|
||||
break;
|
||||
|
||||
case PDO_ATTR_SERVER_INFO: {
|
||||
char *tmp;
|
||||
#if PDO_USE_MYSQLND
|
||||
int tmp_len;
|
||||
|
||||
if (mysqlnd_stat(H->server, &tmp, &tmp_len) == PASS) {
|
||||
ZVAL_STRINGL(return_value, tmp, tmp_len, 0);
|
||||
#else
|
||||
if ((tmp = (char *)mysql_stat(H->server))) {
|
||||
ZVAL_STRING(return_value, tmp, 1);
|
||||
#endif
|
||||
} else {
|
||||
pdo_mysql_error(dbh);
|
||||
return -1;
|
||||
PDO_DBG_RETURN(-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PDO_ATTR_AUTOCOMMIT:
|
||||
ZVAL_LONG(return_value, dbh->auto_commit);
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case PDO_MYSQL_ATTR_USE_BUFFERED_QUERY:
|
||||
ZVAL_LONG(return_value, H->buffered);
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case PDO_MYSQL_ATTR_DIRECT_QUERY:
|
||||
ZVAL_LONG(return_value, H->emulate_prepare);
|
||||
return 1;
|
||||
break;
|
||||
|
||||
#ifndef PDO_USE_MYSQLND
|
||||
case PDO_MYSQL_ATTR_MAX_BUFFER_SIZE:
|
||||
ZVAL_LONG(return_value, H->max_buffer_size);
|
||||
return 1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return 0;
|
||||
PDO_DBG_RETURN(0);
|
||||
}
|
||||
|
||||
return 1;
|
||||
PDO_DBG_RETURN(1);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ pdo_mysql_check_liveness */
|
||||
static int pdo_mysql_check_liveness(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||
|
@ -381,27 +511,31 @@ static int pdo_mysql_check_liveness(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
|
|||
unsigned int my_errno;
|
||||
#endif
|
||||
|
||||
PDO_DBG_ENTER("pdo_mysql_check_liveness");
|
||||
PDO_DBG_INF_FMT("dbh=%p", dbh);
|
||||
|
||||
#if MYSQL_VERSION_ID > 32230
|
||||
if (mysql_ping(H->server)) {
|
||||
return FAILURE;
|
||||
PDO_DBG_RETURN(FAILURE);
|
||||
}
|
||||
#else /* no mysql_ping() */
|
||||
handler=signal(SIGPIPE, SIG_IGN);
|
||||
handler = signal(SIGPIPE, SIG_IGN);
|
||||
mysql_stat(H->server);
|
||||
switch (mysql_errno(H->server)) {
|
||||
case CR_SERVER_GONE_ERROR:
|
||||
/* case CR_SERVER_LOST: I'm not sure this means the same as "gone" for us */
|
||||
case CR_SERVER_LOST:
|
||||
signal(SIGPIPE, handler);
|
||||
return FAILURE;
|
||||
PDO_DBG_RETURN(FAILURE);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
signal(SIGPIPE, handler);
|
||||
#endif /* end mysql_ping() */
|
||||
return SUCCESS;
|
||||
PDO_DBG_RETURN(SUCCESS);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mysql_methods */
|
||||
static struct pdo_dbh_methods mysql_methods = {
|
||||
mysql_handle_closer,
|
||||
mysql_handle_preparer,
|
||||
|
@ -416,8 +550,17 @@ static struct pdo_dbh_methods mysql_methods = {
|
|||
pdo_mysql_get_attribute,
|
||||
pdo_mysql_check_liveness
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifndef PDO_MYSQL_UNIX_ADDR
|
||||
# ifdef PHP_WIN32
|
||||
# define MYSQL_UNIX_ADDR "MySQL"
|
||||
# else
|
||||
# define MYSQL_UNIX_ADDR PDO_MYSQL_G(default_socket)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* {{{ pdo_mysql_handle_factory */
|
||||
static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_mysql_db_handle *H;
|
||||
|
@ -430,7 +573,7 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
|
|||
{ "dbname", "", 0 },
|
||||
{ "host", "localhost", 0 },
|
||||
{ "port", "3306", 0 },
|
||||
{ "unix_socket", PDO_MYSQL_UNIX_ADDR, 0 },
|
||||
{ "unix_socket", MYSQL_UNIX_ADDR, 0 },
|
||||
};
|
||||
int connect_opts = 0
|
||||
#ifdef CLIENT_MULTI_RESULTS
|
||||
|
@ -441,48 +584,85 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
|
|||
#endif
|
||||
;
|
||||
|
||||
#if PDO_USE_MYSQLND
|
||||
int dbname_len = 0;
|
||||
int password_len = 0;
|
||||
#endif
|
||||
PDO_DBG_ENTER("pdo_mysql_handle_factory");
|
||||
PDO_DBG_INF_FMT("dbh=%p", dbh);
|
||||
#ifdef CLIENT_MULTI_RESULTS
|
||||
PDO_DBG_INF("multi results");
|
||||
#endif
|
||||
|
||||
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 5);
|
||||
|
||||
H = pecalloc(1, sizeof(pdo_mysql_db_handle), dbh->is_persistent);
|
||||
|
||||
|
||||
H->einfo.errcode = 0;
|
||||
H->einfo.errmsg = NULL;
|
||||
|
||||
/* allocate an environment */
|
||||
|
||||
|
||||
/* handle for the server */
|
||||
if (!(H->server = mysql_init(NULL))) {
|
||||
if (!(H->server = pdo_mysql_init(dbh->is_persistent))) {
|
||||
pdo_mysql_error(dbh);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
dbh->driver_data = H;
|
||||
H->max_buffer_size = 1024 * 1024;
|
||||
|
||||
#ifndef PDO_USE_MYSQLND
|
||||
H->max_buffer_size = 1024*1024;
|
||||
#endif
|
||||
|
||||
H->buffered = H->emulate_prepare = 1;
|
||||
|
||||
/* handle MySQL options */
|
||||
if (driver_options) {
|
||||
long connect_timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, 30 TSRMLS_CC);
|
||||
long local_infile = pdo_attr_lval(driver_options, PDO_MYSQL_ATTR_LOCAL_INFILE, 0 TSRMLS_CC);
|
||||
#ifndef PDO_USE_MYSQLND
|
||||
char *init_cmd = NULL, *default_file = NULL, *default_group = NULL;
|
||||
|
||||
#endif
|
||||
H->buffered = pdo_attr_lval(driver_options, PDO_MYSQL_ATTR_USE_BUFFERED_QUERY, 1 TSRMLS_CC);
|
||||
H->emulate_prepare = pdo_attr_lval(driver_options, PDO_MYSQL_ATTR_DIRECT_QUERY, 1 TSRMLS_CC);
|
||||
H->max_buffer_size = pdo_attr_lval(driver_options, PDO_MYSQL_ATTR_MAX_BUFFER_SIZE, H->max_buffer_size TSRMLS_CC);
|
||||
|
||||
if (PG(open_basedir) && PG(open_basedir)[0] != '\0') {
|
||||
local_infile = 0;
|
||||
}
|
||||
H->emulate_prepare = pdo_attr_lval(driver_options,
|
||||
PDO_MYSQL_ATTR_DIRECT_QUERY, H->emulate_prepare TSRMLS_CC);
|
||||
H->emulate_prepare = pdo_attr_lval(driver_options,
|
||||
PDO_ATTR_EMULATE_PREPARES, H->emulate_prepare TSRMLS_CC);
|
||||
|
||||
#ifndef PDO_USE_MYSQLND
|
||||
H->max_buffer_size = pdo_attr_lval(driver_options, PDO_MYSQL_ATTR_MAX_BUFFER_SIZE, H->max_buffer_size TSRMLS_CC);
|
||||
#endif
|
||||
|
||||
if (mysql_options(H->server, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout)) {
|
||||
pdo_mysql_error(dbh);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
#if PHP_MAJOR_VERSION < 6
|
||||
if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode))
|
||||
#else
|
||||
if (PG(open_basedir) && PG(open_basedir)[0] != '\0')
|
||||
#endif
|
||||
{
|
||||
local_infile = 0;
|
||||
}
|
||||
|
||||
if (mysql_options(H->server, MYSQL_OPT_LOCAL_INFILE, (const char *)&local_infile)) {
|
||||
pdo_mysql_error(dbh);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#ifdef MYSQL_OPT_RECONNECT
|
||||
/* since 5.0.3, the default for this option is 0 if not specified.
|
||||
* we want the old behaviour */
|
||||
{
|
||||
long reconnect = 1;
|
||||
mysql_options(H->server, MYSQL_OPT_RECONNECT, (const char*)&reconnect);
|
||||
}
|
||||
#endif
|
||||
#ifndef PDO_USE_MYSQLND
|
||||
init_cmd = pdo_attr_strval(driver_options, PDO_MYSQL_ATTR_INIT_COMMAND, NULL TSRMLS_CC);
|
||||
if (init_cmd) {
|
||||
if (mysql_options(H->server, MYSQL_INIT_COMMAND, (const char *)init_cmd)) {
|
||||
|
@ -512,6 +692,7 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
|
|||
}
|
||||
efree(default_group);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
dbname = vars[1].optval;
|
||||
|
@ -522,7 +703,22 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
|
|||
if (vars[2].optval && !strcmp("localhost", vars[2].optval)) {
|
||||
unix_socket = vars[4].optval;
|
||||
}
|
||||
|
||||
/* TODO: - Check zval cache + ZTS */
|
||||
#ifdef PDO_USE_MYSQLND
|
||||
if (dbname) {
|
||||
dbname_len = strlen(dbname);
|
||||
}
|
||||
|
||||
if (dbh->password) {
|
||||
password_len = strlen(dbh->password);
|
||||
}
|
||||
|
||||
if (mysqlnd_connect(H->server, host, dbh->username, dbh->password, password_len, dbname, dbname_len,
|
||||
port, unix_socket, connect_opts, PDO_MYSQL_G(mysqlnd_thd_zval_cache) TSRMLS_CC) == NULL) {
|
||||
#else
|
||||
if (mysql_real_connect(H->server, host, dbh->username, dbh->password, dbname, port, unix_socket, connect_opts) == NULL) {
|
||||
#endif
|
||||
pdo_mysql_error(dbh);
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -548,7 +744,7 @@ cleanup:
|
|||
|
||||
dbh->methods = &mysql_methods;
|
||||
|
||||
return ret;
|
||||
PDO_DBG_RETURN(ret);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -13,6 +13,7 @@
|
|||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: George Schlossnagle <george@omniti.com> |
|
||||
| Johannes Schlueter <johannes@mysql.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
@ -30,16 +31,185 @@
|
|||
#include "php_pdo_mysql.h"
|
||||
#include "php_pdo_mysql_int.h"
|
||||
|
||||
#ifdef COMPILE_DL_PDO_MYSQL
|
||||
ZEND_GET_MODULE(pdo_mysql)
|
||||
#endif
|
||||
|
||||
#if PDO_USE_MYSQLND
|
||||
ZEND_DECLARE_MODULE_GLOBALS(pdo_mysql);
|
||||
|
||||
#ifndef PHP_WIN32
|
||||
# ifndef PDO_MYSQL_UNIX_ADDR
|
||||
# define PDO_MYSQL_UNIX_ADDR "/tmp/mysql.sock"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* {{{ PHP_INI_BEGIN
|
||||
*/
|
||||
PHP_INI_BEGIN()
|
||||
#ifndef PHP_WIN32
|
||||
STD_PHP_INI_ENTRY("pdo_mysql.default_socket", PDO_MYSQL_UNIX_ADDR, PHP_INI_SYSTEM, OnUpdateString, default_socket, zend_pdo_mysql_globals, pdo_mysql_globals)
|
||||
#endif
|
||||
#if PDO_DBG_ENABLED
|
||||
STD_PHP_INI_ENTRY("pdo_mysql.debug", NULL, PHP_INI_SYSTEM, OnUpdateString, debug, zend_pdo_mysql_globals, pdo_mysql_globals)
|
||||
#endif
|
||||
STD_PHP_INI_ENTRY("pdo_mysql.cache_size", "2000", PHP_INI_SYSTEM, OnUpdateLong, cache_size, zend_pdo_mysql_globals, pdo_mysql_globals)
|
||||
PHP_INI_END()
|
||||
/* }}} */
|
||||
#endif
|
||||
|
||||
/* true global environment */
|
||||
#ifdef PDO_USE_MYSQLND
|
||||
static MYSQLND_ZVAL_PCACHE *mysql_mysqlnd_zval_cache;
|
||||
#endif
|
||||
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION
|
||||
*/
|
||||
static PHP_MINIT_FUNCTION(pdo_mysql)
|
||||
{
|
||||
#if PDO_USE_MYSQLND
|
||||
REGISTER_INI_ENTRIES();
|
||||
#endif
|
||||
|
||||
REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_USE_BUFFERED_QUERY", (long)PDO_MYSQL_ATTR_USE_BUFFERED_QUERY);
|
||||
REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_LOCAL_INFILE", (long)PDO_MYSQL_ATTR_LOCAL_INFILE);
|
||||
#ifndef PDO_USE_MYSQLND
|
||||
REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_MAX_BUFFER_SIZE", (long)PDO_MYSQL_ATTR_MAX_BUFFER_SIZE);
|
||||
REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_INIT_COMMAND", (long)PDO_MYSQL_ATTR_INIT_COMMAND);
|
||||
REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_READ_DEFAULT_FILE", (long)PDO_MYSQL_ATTR_READ_DEFAULT_FILE);
|
||||
REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_READ_DEFAULT_GROUP", (long)PDO_MYSQL_ATTR_READ_DEFAULT_GROUP);
|
||||
#endif
|
||||
REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_DIRECT_QUERY", (long)PDO_MYSQL_ATTR_DIRECT_QUERY);
|
||||
|
||||
#ifdef PDO_USE_MYSQLND
|
||||
mysql_mysqlnd_zval_cache = mysqlnd_palloc_init_cache(PDO_MYSQL_G(cache_size));
|
||||
#endif
|
||||
|
||||
return php_pdo_register_driver(&pdo_mysql_driver);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION
|
||||
*/
|
||||
static PHP_MSHUTDOWN_FUNCTION(pdo_mysql)
|
||||
{
|
||||
php_pdo_unregister_driver(&pdo_mysql_driver);
|
||||
#if PDO_USE_MYSQLND
|
||||
UNREGISTER_INI_ENTRIES();
|
||||
#endif
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
static PHP_MINFO_FUNCTION(pdo_mysql)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
#ifdef PDO_USE_MYSQLND
|
||||
php_info_print_table_header(2, "PDO Driver for MySQL, mysql native driver version", mysql_get_client_info());
|
||||
|
||||
{
|
||||
zval values;
|
||||
|
||||
php_info_print_table_header(2, "Persistent cache", mysql_mysqlnd_zval_cache? "enabled":"disabled");
|
||||
|
||||
if (mysql_mysqlnd_zval_cache) {
|
||||
/* Now report cache status */
|
||||
mysqlnd_palloc_stats(mysql_mysqlnd_zval_cache, &values);
|
||||
mysqlnd_minfo_print_hash(&values);
|
||||
zval_dtor(&values);
|
||||
}
|
||||
}
|
||||
#else
|
||||
php_info_print_table_header(2, "PDO Driver for MySQL, client library version", mysql_get_client_info());
|
||||
#endif
|
||||
php_info_print_table_end();
|
||||
|
||||
#ifdef PDO_USE_MYSQLND
|
||||
DISPLAY_INI_ENTRIES();
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
#if PDO_USE_MYSQLND
|
||||
/* {{{ PHP_RINIT_FUNCTION
|
||||
*/
|
||||
static PHP_RINIT_FUNCTION(pdo_mysql)
|
||||
{
|
||||
PDO_MYSQL_G(mysqlnd_thd_zval_cache) = mysqlnd_palloc_rinit(mysql_mysqlnd_zval_cache);
|
||||
|
||||
#if PDO_DBG_ENABLED
|
||||
if (PDO_MYSQL_G(debug)) {
|
||||
MYSQLND_DEBUG *dbg = mysqlnd_debug_init(TSRMLS_C);
|
||||
if (!dbg) {
|
||||
return FAILURE;
|
||||
}
|
||||
dbg->m->set_mode(dbg, PDO_MYSQL_G(debug));
|
||||
PDO_MYSQL_G(dbg) = dbg;
|
||||
}
|
||||
#endif
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ PHP_RSHUTDOWN_FUNCTION
|
||||
*/
|
||||
static PHP_RSHUTDOWN_FUNCTION(pdo_mysql)
|
||||
{
|
||||
mysqlnd_palloc_rshutdown(PDO_MYSQL_G(mysqlnd_thd_zval_cache));
|
||||
|
||||
#if PDO_DBG_ENABLED
|
||||
MYSQLND_DEBUG *dbg = PDO_MYSQL_G(dbg);
|
||||
PDO_DBG_ENTER("RSHUTDOWN");
|
||||
if (dbg) {
|
||||
dbg->m->close(dbg);
|
||||
dbg->m->free_handle(dbg);
|
||||
PDO_MYSQL_G(dbg) = NULL;
|
||||
}
|
||||
#endif
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ PHP_GINIT_FUNCTION
|
||||
*/
|
||||
static PHP_GINIT_FUNCTION(pdo_mysql)
|
||||
{
|
||||
pdo_mysql_globals->mysqlnd_thd_zval_cache = NULL; /* zval cache */
|
||||
pdo_mysql_globals->cache_size = 0;
|
||||
#ifndef PHP_WIN32
|
||||
pdo_mysql_globals->default_socket = NULL;
|
||||
#endif
|
||||
#if PDO_DBG_ENABLED
|
||||
pdo_mysql_globals->debug = NULL; /* The actual string */
|
||||
pdo_mysql_globals->dbg = NULL; /* The DBG object*/
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
|
||||
|
||||
/* {{{ pdo_mysql_functions[] */
|
||||
const zend_function_entry pdo_mysql_functions[] = {
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ pdo_mysql_functions[] */
|
||||
/* {{{ pdo_mysql_deps[] */
|
||||
#if ZEND_MODULE_API_NO >= 20050922
|
||||
static const zend_module_dep pdo_mysql_deps[] = {
|
||||
ZEND_MOD_REQUIRED("pdo")
|
||||
#ifdef PDO_USE_MYSQLND
|
||||
ZEND_MOD_REQUIRED("mysqlnd")
|
||||
#endif
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
#endif
|
||||
|
@ -47,65 +217,33 @@ static const zend_module_dep pdo_mysql_deps[] = {
|
|||
|
||||
/* {{{ pdo_mysql_module_entry */
|
||||
zend_module_entry pdo_mysql_module_entry = {
|
||||
#if ZEND_MODULE_API_NO >= 20050922
|
||||
STANDARD_MODULE_HEADER_EX, NULL,
|
||||
pdo_mysql_deps,
|
||||
#else
|
||||
STANDARD_MODULE_HEADER,
|
||||
#endif
|
||||
"pdo_mysql",
|
||||
pdo_mysql_functions,
|
||||
PHP_MINIT(pdo_mysql),
|
||||
PHP_MSHUTDOWN(pdo_mysql),
|
||||
#if PDO_USE_MYSQLND
|
||||
PHP_RINIT(pdo_mysql),
|
||||
PHP_RSHUTDOWN(pdo_mysql),
|
||||
#else
|
||||
NULL,
|
||||
NULL,
|
||||
#endif
|
||||
PHP_MINFO(pdo_mysql),
|
||||
"0.9",
|
||||
"1.0.2",
|
||||
#if PDO_USE_MYSQLND
|
||||
PHP_MODULE_GLOBALS(pdo_mysql),
|
||||
PHP_GINIT(pdo_mysql),
|
||||
NULL,
|
||||
NULL,
|
||||
STANDARD_MODULE_PROPERTIES_EX
|
||||
#else
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
#endif
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_PDO_MYSQL
|
||||
ZEND_GET_MODULE(pdo_mysql)
|
||||
#endif
|
||||
|
||||
/* true global environment */
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION
|
||||
*/
|
||||
PHP_MINIT_FUNCTION(pdo_mysql)
|
||||
{
|
||||
REGISTER_PDO_CONST_LONG("MYSQL_ATTR_USE_BUFFERED_QUERY", (long)PDO_MYSQL_ATTR_USE_BUFFERED_QUERY);
|
||||
REGISTER_PDO_CONST_LONG("MYSQL_ATTR_LOCAL_INFILE", (long)PDO_MYSQL_ATTR_LOCAL_INFILE);
|
||||
REGISTER_PDO_CONST_LONG("MYSQL_ATTR_INIT_COMMAND", (long)PDO_MYSQL_ATTR_INIT_COMMAND);
|
||||
REGISTER_PDO_CONST_LONG("MYSQL_ATTR_READ_DEFAULT_FILE", (long)PDO_MYSQL_ATTR_READ_DEFAULT_FILE);
|
||||
REGISTER_PDO_CONST_LONG("MYSQL_ATTR_READ_DEFAULT_GROUP", (long)PDO_MYSQL_ATTR_READ_DEFAULT_GROUP);
|
||||
REGISTER_PDO_CONST_LONG("MYSQL_ATTR_MAX_BUFFER_SIZE", (long)PDO_MYSQL_ATTR_MAX_BUFFER_SIZE);
|
||||
REGISTER_PDO_CONST_LONG("MYSQL_ATTR_DIRECT_QUERY", (long)PDO_MYSQL_ATTR_DIRECT_QUERY);
|
||||
|
||||
return php_pdo_register_driver(&pdo_mysql_driver);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo_mysql)
|
||||
{
|
||||
php_pdo_unregister_driver(&pdo_mysql_driver);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
PHP_MINFO_FUNCTION(pdo_mysql)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "PDO Driver for MySQL, client library version", mysql_get_client_info());
|
||||
php_info_print_table_row(2, "MYSQL_SOCKET", PDO_MYSQL_UNIX_ADDR);
|
||||
php_info_print_table_end();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
|
|
|
@ -24,15 +24,16 @@
|
|||
extern zend_module_entry pdo_mysql_module_entry;
|
||||
#define phpext_pdo_mysql_ptr &pdo_mysql_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_PDO_MYSQL_API __declspec(dllexport)
|
||||
#else
|
||||
#define PHP_PDO_MYSQL_API
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
PHP_MINIT_FUNCTION(pdo_mysql);
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo_mysql);
|
||||
PHP_RINIT_FUNCTION(pdo_mysql);
|
||||
PHP_RSHUTDOWN_FUNCTION(pdo_mysql);
|
||||
PHP_MINFO_FUNCTION(pdo_mysql);
|
||||
|
||||
#endif /* PHP_PDO_MYSQL_H */
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
+----------------------------------------------------------------------+
|
||||
| Author: George Schlossnagle <george@omniti.com> |
|
||||
| Wez Furlong <wez@php.net> |
|
||||
| Johannes Schlueter <johannes@mysql.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
@ -22,7 +23,66 @@
|
|||
#ifndef PHP_PDO_MYSQL_INT_H
|
||||
#define PHP_PDO_MYSQL_INT_H
|
||||
|
||||
#include <mysql.h>
|
||||
#if defined(PDO_USE_MYSQLND)
|
||||
# include "ext/mysqlnd/mysqlnd.h"
|
||||
# include "ext/mysql/mysql_mysqlnd.h"
|
||||
# include "ext/mysqlnd/mysqlnd_libmysql_compat.h"
|
||||
# define PDO_MYSQL_PARAM_BIND MYSQLND_PARAM_BIND
|
||||
#else
|
||||
# include <mysql.h>
|
||||
# define PDO_MYSQL_PARAM_BIND MYSQL_BIND
|
||||
#endif
|
||||
|
||||
#if defined(PDO_USE_MYSQLND) && PHP_DEBUG && !defined(PHP_WIN32)
|
||||
#define PDO_DBG_ENABLED 1
|
||||
|
||||
#define PDO_DBG_INF(msg) do { if (dbg_skip_trace == FALSE) PDO_MYSQL_G(dbg)->m->log(PDO_MYSQL_G(dbg), __LINE__, __FILE__, -1, "info : ", (msg)); } while (0)
|
||||
#define PDO_DBG_ERR(msg) do { if (dbg_skip_trace == FALSE) PDO_MYSQL_G(dbg)->m->log(PDO_MYSQL_G(dbg), __LINE__, __FILE__, -1, "error: ", (msg)); } while (0)
|
||||
#define PDO_DBG_INF_FMT(...) do { if (dbg_skip_trace == FALSE) PDO_MYSQL_G(dbg)->m->log_va(PDO_MYSQL_G(dbg), __LINE__, __FILE__, -1, "info : ", __VA_ARGS__); } while (0)
|
||||
#define PDO_DBG_ERR_FMT(...) do { if (dbg_skip_trace == FALSE) PDO_MYSQL_G(dbg)->m->log_va(PDO_MYSQL_G(dbg), __LINE__, __FILE__, -1, "error: ", __VA_ARGS__); } while (0)
|
||||
#define PDO_DBG_ENTER(func_name) zend_bool dbg_skip_trace = TRUE; if (PDO_MYSQL_G(dbg)) dbg_skip_trace = !PDO_MYSQL_G(dbg)->m->func_enter(PDO_MYSQL_G(dbg), __LINE__, __FILE__, func_name, strlen(func_name));
|
||||
#define PDO_DBG_RETURN(value) do { if (PDO_MYSQL_G(dbg)) PDO_MYSQL_G(dbg)->m->func_leave(PDO_MYSQL_G(dbg), __LINE__, __FILE__); return (value); } while (0)
|
||||
#define PDO_DBG_VOID_RETURN do { if (PDO_MYSQL_G(dbg)) PDO_MYSQL_G(dbg)->m->func_leave(PDO_MYSQL_G(dbg), __LINE__, __FILE__); return; } while (0)
|
||||
|
||||
#else
|
||||
#define PDO_DBG_ENABLED 0
|
||||
|
||||
static inline void PDO_DBG_INF(char *msg) {}
|
||||
static inline void PDO_DBG_ERR(char *msg) {}
|
||||
static inline void PDO_DBG_INF_FMT(char *format, ...) {}
|
||||
static inline void PDO_DBG_ERR_FMT(char *format, ...) {}
|
||||
static inline void PDO_DBG_ENTER(char *func_name) {}
|
||||
#define PDO_DBG_RETURN(value) return (value)
|
||||
#define PDO_DBG_VOID_RETURN return;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(PDO_USE_MYSQLND)
|
||||
#include "ext/mysqlnd/mysqlnd_debug.h"
|
||||
#endif
|
||||
|
||||
#ifdef PDO_USE_MYSQLND
|
||||
ZEND_BEGIN_MODULE_GLOBALS(pdo_mysql)
|
||||
MYSQLND_THD_ZVAL_PCACHE *mysqlnd_thd_zval_cache;
|
||||
long cache_size;
|
||||
#ifndef PHP_WIN32
|
||||
char *default_socket;
|
||||
#endif
|
||||
#if PDO_DBG_ENABLED
|
||||
char *debug; /* The actual string */
|
||||
MYSQLND_DEBUG *dbg; /* The DBG object */
|
||||
#endif
|
||||
ZEND_END_MODULE_GLOBALS(pdo_mysql)
|
||||
|
||||
ZEND_EXTERN_MODULE_GLOBALS(pdo_mysql);
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#define PDO_MYSQL_G(v) TSRMG(pdo_mysql_globals_id, zend_pdo_mysql_globals *, v)
|
||||
#else
|
||||
#define PDO_MYSQL_G(v) (pdo_mysql_globals.v)
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
const char *file;
|
||||
|
@ -38,8 +98,11 @@ typedef struct {
|
|||
unsigned attached:1;
|
||||
unsigned buffered:1;
|
||||
unsigned emulate_prepare:1;
|
||||
unsigned _reserved:31;
|
||||
unsigned fetch_table_names:1;
|
||||
unsigned _reserved:31;
|
||||
#if !PDO_USE_MYSQLND
|
||||
unsigned long max_buffer_size;
|
||||
#endif
|
||||
|
||||
pdo_mysql_error_info einfo;
|
||||
} pdo_mysql_db_handle;
|
||||
|
@ -51,22 +114,31 @@ typedef struct {
|
|||
typedef struct {
|
||||
pdo_mysql_db_handle *H;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_FIELD *fields;
|
||||
const MYSQL_FIELD *fields;
|
||||
MYSQL_ROW current_data;
|
||||
#if PDO_USE_MYSQLND
|
||||
unsigned long *current_lengths;
|
||||
#else
|
||||
long *current_lengths;
|
||||
#endif
|
||||
pdo_mysql_error_info einfo;
|
||||
#if HAVE_MYSQL_STMT_PREPARE
|
||||
MYSQL_STMT *stmt;
|
||||
|
||||
#if HAVE_MYSQL_STMT_PREPARE || PDO_USE_MYSQLND
|
||||
#if PDO_USE_MYSQLND
|
||||
MYSQLND_STMT *stmt;
|
||||
#else
|
||||
MYSQL_STMT *stmt;
|
||||
#endif
|
||||
int num_params;
|
||||
MYSQL_BIND *params;
|
||||
PDO_MYSQL_PARAM_BIND *params;
|
||||
#ifndef PDO_USE_MYSQLND
|
||||
my_bool *in_null;
|
||||
unsigned long *in_length;
|
||||
|
||||
MYSQL_BIND *bound_result;
|
||||
unsigned long *in_length;
|
||||
#endif
|
||||
PDO_MYSQL_PARAM_BIND *bound_result;
|
||||
my_bool *out_null;
|
||||
unsigned long *out_length;
|
||||
unsigned max_length:1;
|
||||
unsigned long *out_length;
|
||||
unsigned int params_given;
|
||||
unsigned max_length:1;
|
||||
#endif
|
||||
} pdo_mysql_stmt;
|
||||
|
||||
|
@ -81,19 +153,13 @@ extern struct pdo_stmt_methods mysql_stmt_methods;
|
|||
enum {
|
||||
PDO_MYSQL_ATTR_USE_BUFFERED_QUERY = PDO_ATTR_DRIVER_SPECIFIC,
|
||||
PDO_MYSQL_ATTR_LOCAL_INFILE,
|
||||
#ifndef PDO_USE_MYSQLND
|
||||
PDO_MYSQL_ATTR_INIT_COMMAND,
|
||||
PDO_MYSQL_ATTR_READ_DEFAULT_FILE,
|
||||
PDO_MYSQL_ATTR_READ_DEFAULT_GROUP,
|
||||
PDO_MYSQL_ATTR_MAX_BUFFER_SIZE,
|
||||
#endif
|
||||
PDO_MYSQL_ATTR_DIRECT_QUERY,
|
||||
};
|
||||
|
||||
#ifndef PDO_MYSQL_UNIX_ADDR
|
||||
# ifdef PHP_WIN32
|
||||
# define PDO_MYSQL_UNIX_ADDR "MySQL"
|
||||
# else
|
||||
# define PDO_MYSQL_UNIX_ADDR "/tmp/mysql.sock"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
16
ext/pdo_mysql/tests/README
Normal file
16
ext/pdo_mysql/tests/README
Normal file
|
@ -0,0 +1,16 @@
|
|||
You must set the following environment variables to run the tests:
|
||||
|
||||
PDO_MYSQL_TEST_DSN - DSN
|
||||
For example: mysql:dbname=test;host=localhost;port=3306
|
||||
|
||||
PDO_MYSQL_TEST_HOST - database host
|
||||
PDO_MYSQL_TEST_DB - database (schema) name
|
||||
PDO_MYSQL_TEST_SOCKET - database server socket
|
||||
PDO_MYSQL_TEST_ENGINE - storage engine to use
|
||||
PDO_MYSQL_TEST_USER - database user
|
||||
PDO_MYSQL_TEST_PASS - database user password
|
||||
PDO_MYSQL_TEST_CHARSET - database charset
|
||||
|
||||
NOTE: if any of PDO_MYSQL_TEST_[HOST|DB|SOCKET|ENGINE|CHARSET] is
|
||||
part of PDO_MYSQL_TEST_DSN, the values must match. That is, for example,
|
||||
for PDO_MYSQL_TEST_DSN = mysql:dbname=test you MUST set PDO_MYSQL_TEST_DB=test.
|
|
@ -3,16 +3,15 @@ PDO MySQL Bug #33689 (query() execute() and fetch() return false on valid select
|
|||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
|
||||
require 'ext/pdo_mysql/tests/config.inc';
|
||||
require 'ext/pdo/tests/pdo_test.inc';
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--INI--
|
||||
precision=14
|
||||
--FILE--
|
||||
<?php
|
||||
require 'ext/pdo/tests/pdo_test.inc';
|
||||
$db = PDOTest::test_factory('ext/pdo_mysql/tests/common.phpt');
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||
|
||||
$db->exec('CREATE TABLE test (bar INT NOT NULL)');
|
||||
$db->exec('INSERT INTO test VALUES(1)');
|
||||
|
@ -25,12 +24,20 @@ foreach ($db->query('SELECT * from test') as $row) {
|
|||
$stmt = $db->prepare('SELECT * from test');
|
||||
print_r($stmt->getColumnMeta(0));
|
||||
$stmt->execute();
|
||||
print_r($stmt->getColumnMeta(0));
|
||||
$tmp = $stmt->getColumnMeta(0);
|
||||
|
||||
// libmysql and mysqlnd will show the pdo_type entry at a different position in the hash
|
||||
if (!isset($tmp['pdo_type']) || (isset($tmp['pdo_type']) && $tmp['pdo_type'] != 2))
|
||||
printf("Expecting pdo_type = 2 got %s\n", $tmp['pdo_type']);
|
||||
else
|
||||
unset($tmp['pdo_type']);
|
||||
|
||||
print_r($tmp);
|
||||
?>
|
||||
--EXPECTF--
|
||||
object(PDOStatement)#%d (1) {
|
||||
[u"queryString"]=>
|
||||
unicode(18) "SELECT * from test"
|
||||
["queryString"]=>
|
||||
string(18) "SELECT * from test"
|
||||
}
|
||||
Array
|
||||
(
|
||||
|
@ -49,5 +56,4 @@ Array
|
|||
[name] => bar
|
||||
[len] => 11
|
||||
[precision] => 0
|
||||
[pdo_type] => 2
|
||||
)
|
||||
|
|
|
@ -5,7 +5,6 @@ PDO MySQL Bug #37445 (Premature stmt object destruction)
|
|||
if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
|
@ -17,5 +16,6 @@ $db->setAttribute(PDO :: ATTR_EMULATE_PREPARES, true);
|
|||
$stmt = $db->prepare("SELECT 1");
|
||||
$stmt->bindParam(':a', 'b');
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot pass parameter 2 by reference in %s/bug_37445.php on line %d
|
||||
Fatal error: Cannot pass parameter 2 by reference in %sbug_37445.php on line %d
|
||||
|
|
Binary file not shown.
96
ext/pdo_mysql/tests/bug_39858.phpt
Normal file
96
ext/pdo_mysql/tests/bug_39858.phpt
Normal file
|
@ -0,0 +1,96 @@
|
|||
--TEST--
|
||||
Bug #39858 (http://bugs.php.net/bug.php?id=39858)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
$row = $db->query('SELECT VERSION() as _version')->fetch(PDO::FETCH_ASSOC);
|
||||
$matches = array();
|
||||
if (!preg_match('/^(\d+)\.(\d+)\.(\d+)/ismU', $row['_version'], $matches))
|
||||
die(sprintf("skip Cannot determine MySQL Server version\n"));
|
||||
|
||||
$version = $matches[0] * 10000 + $matches[1] * 100 + $matches[2];
|
||||
if ($version < 50000)
|
||||
die(sprintf("skip Need MySQL Server 5.0.0+, found %d.%02d.%02d (%d)\n",
|
||||
$matches[0], $matches[1], $matches[2], $version));
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
|
||||
|
||||
function bug_39858($db) {
|
||||
|
||||
$db->exec("DROP PROCEDURE IF EXISTS p");
|
||||
$db->exec("
|
||||
CREATE PROCEDURE p()
|
||||
NOT DETERMINISTIC
|
||||
CONTAINS SQL
|
||||
SQL SECURITY DEFINER
|
||||
COMMENT ''
|
||||
BEGIN
|
||||
SELECT 2 * 2;
|
||||
END;");
|
||||
|
||||
$stmt = $db->prepare("CALL p()");
|
||||
$stmt->execute();
|
||||
do {
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
} while ($stmt->nextRowset());
|
||||
|
||||
$stmt = $db->prepare("CALL p()");
|
||||
$stmt->execute();
|
||||
do {
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
} while ($stmt->nextRowset());
|
||||
$stmt->closeCursor();
|
||||
|
||||
}
|
||||
|
||||
printf("Emulated Prepared Statements...\n");
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
|
||||
bug_39858($db);
|
||||
|
||||
printf("Native Prepared Statements...\n");
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
|
||||
bug_39858($db);
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Emulated Prepared Statements...
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["2 * 2"]=>
|
||||
string(1) "4"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["2 * 2"]=>
|
||||
string(1) "4"
|
||||
}
|
||||
}
|
||||
Native Prepared Statements...
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["2 * 2"]=>
|
||||
string(1) "4"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["2 * 2"]=>
|
||||
string(1) "4"
|
||||
}
|
||||
}
|
||||
done!
|
44
ext/pdo_mysql/tests/bug_41125.phpt
Normal file
44
ext/pdo_mysql/tests/bug_41125.phpt
Normal file
|
@ -0,0 +1,44 @@
|
|||
--TEST--
|
||||
Bug #41125 (http://bugs.php.net/bug.php?id=41125)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
|
||||
$db = MySQLPDOTest::factory();
|
||||
$row = $db->query('SELECT VERSION() as _version')->fetch(PDO::FETCH_ASSOC);
|
||||
$matches = array();
|
||||
if (!preg_match('/^(\d+)\.(\d+)\.(\d+)/ismU', $row['_version'], $matches))
|
||||
die(sprintf("skip Cannot determine MySQL Server version\n"));
|
||||
|
||||
$version = $matches[0] * 10000 + $matches[1] * 100 + $matches[2];
|
||||
die("skip $version");
|
||||
if ($version < 40100)
|
||||
die(sprintf("skip Need MySQL Server 5.0.0+, found %d.%02d.%02d (%d)\n",
|
||||
$matches[0], $matches[1], $matches[2], $version));
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
// And now allow the evil to do his work
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
|
||||
$sql = "CREATE TABLE IF NOT EXISTS test(id INT); INSERT INTO test(id) VALUES (1); SELECT * FROM test; INSERT INTO test(id) VALUES (2); SELECT * FROM test;";
|
||||
// NOTE: This will fail, it is OK to fail - you must not mix DML/DDL and SELECT
|
||||
// The PDO API does not support multiple queries properly!
|
||||
// Read http://blog.ulf-wendel.de/?p=192
|
||||
// Compare MySQL C-API documentation
|
||||
$stmt = $db->query($sql);
|
||||
do {
|
||||
var_dump($stmt->fetchAll());
|
||||
} while ($stmt->nextRowset());
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: PDOStatement::fetchAll(): SQLSTATE[HY000]: General error in %s on line %d
|
||||
array(0) {
|
||||
}
|
||||
done!
|
37
ext/pdo_mysql/tests/bug_41698.phpt
Normal file
37
ext/pdo_mysql/tests/bug_41698.phpt
Normal file
|
@ -0,0 +1,37 @@
|
|||
--TEST--
|
||||
PDO MySQL Bug #41698 (float parameters truncated to integer in prepared statements)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||
|
||||
setlocale(LC_ALL, "de","de_DE","de_DE.ISO8859-1","de_DE.ISO_8859-1","de_DE.UTF-8");
|
||||
|
||||
$db->exec('CREATE TABLE test(floatval DECIMAL(8,6))');
|
||||
$db->exec('INSERT INTO test VALUES(2.34)');
|
||||
$value=4.56;
|
||||
$stmt = $db->prepare('INSERT INTO test VALUES(?)');
|
||||
$stmt->execute(array($value));
|
||||
var_dump($db->query('SELECT * from test')->fetchAll(PDO::FETCH_ASSOC));
|
||||
?>
|
||||
--EXPECT--
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["floatval"]=>
|
||||
string(8) "2.340000"
|
||||
}
|
||||
[1]=>
|
||||
array(1) {
|
||||
["floatval"]=>
|
||||
string(8) "4.560000"
|
||||
}
|
||||
}
|
64
ext/pdo_mysql/tests/bug_41997.phpt
Normal file
64
ext/pdo_mysql/tests/bug_41997.phpt
Normal file
|
@ -0,0 +1,64 @@
|
|||
--TEST--
|
||||
PDO MySQL Bug #41997 (stored procedure call returning single rowset blocks future queries)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
|
||||
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||
$row = $db->query('SELECT VERSION() as _version')->fetch(PDO::FETCH_ASSOC);
|
||||
$matches = array();
|
||||
if (!preg_match('/^(\d+)\.(\d+)\.(\d+)/ismU', $row['_version'], $matches))
|
||||
die(sprintf("skip Cannot determine MySQL Server version\n"));
|
||||
|
||||
$version = $matches[0] * 10000 + $matches[1] * 100 + $matches[2];
|
||||
if ($version < 50000)
|
||||
die(sprintf("skip Need MySQL Server 5.0.0+, found %d.%02d.%02d (%d)\n",
|
||||
$matches[0], $matches[1], $matches[2], $version));
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||
|
||||
$db->exec('DROP PROCEDURE IF EXISTS p');
|
||||
$db->exec('CREATE PROCEDURE p() BEGIN SELECT 1 AS "one"; END');
|
||||
|
||||
$stmt = $db->query("CALL p()");
|
||||
do {
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
} while ($stmt->nextRowset());
|
||||
var_dump($stmt->errorInfo());
|
||||
|
||||
$stmt = $db->query('SELECT 2 AS "two"');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
var_dump($stmt->errorInfo());
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECT--
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["one"]=>
|
||||
string(1) "1"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(5) "00000"
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["two"]=>
|
||||
string(1) "2"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(5) "00000"
|
||||
}
|
||||
done!
|
80
ext/pdo_mysql/tests/bug_42499.phpt
Normal file
80
ext/pdo_mysql/tests/bug_42499.phpt
Normal file
|
@ -0,0 +1,80 @@
|
|||
--TEST--
|
||||
PDO MySQL Bug #42499 (http://bugs.php.net/bug.php?id=42499)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
|
||||
MySQLPDOTest::skip();
|
||||
|
||||
$db = MySQLPDOTest::factory();
|
||||
$stmt = $db->query('SELECT VERSION() as _version');
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$matches = array();
|
||||
if (!preg_match('/^(\d+)\.(\d+)\.(\d+)/ismU', $row['_version'], $matches))
|
||||
die(sprintf("skip Cannot determine MySQL Server version\n"));
|
||||
|
||||
$version = $matches[0] * 10000 + $matches[1] * 100 + $matches[2];
|
||||
if ($version < 41000)
|
||||
die(sprintf("skip Need MySQL Server 4.1.0+, found %d.%02d.%02d (%d)\n",
|
||||
$matches[0], $matches[1], $matches[2], $version));
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
function bug_42499($db) {
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$db->exec('CREATE TABLE test(id CHAR(1)); INSERT INTO test(id) VALUES ("a")');
|
||||
|
||||
$stmt = $db->query('SELECT id AS _id FROM test');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
// You must not use exec() to run statements that create a result set!
|
||||
$db->exec('SELECT id FROM test');
|
||||
// This will bail at you because you have not fetched the SELECT results: this is not a bug!
|
||||
$db->exec('INSERT INTO test(id) VALUES ("b")');
|
||||
|
||||
}
|
||||
|
||||
print "Emulated Prepared Statements...\n";
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1);
|
||||
bug_42499($db);
|
||||
|
||||
print "Native Prepared Statements...\n";
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1);
|
||||
bug_42499($db);
|
||||
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Emulated Prepared Statements...
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["_id"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
}
|
||||
|
||||
Warning: PDO::exec(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d
|
||||
Native Prepared Statements...
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["_id"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
}
|
||||
|
||||
Warning: PDO::exec(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d
|
||||
done!
|
20
ext/pdo_mysql/tests/bug_43371.phpt
Normal file
20
ext/pdo_mysql/tests/bug_43371.phpt
Normal file
|
@ -0,0 +1,20 @@
|
|||
--TEST--
|
||||
Bug #43371 (http://bugs.php.net/bug.php?id=43371)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
|
||||
$dsn = MySQLPDOTest::getDSN();
|
||||
$db = new PDO($dsn, PDO_MYSQL_TEST_USER, PDO_MYSQL_TEST_PASS, array(PDO::ATTR_PERSISTENT => true));
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECT--
|
||||
done!
|
104
ext/pdo_mysql/tests/bug_44454.phpt
Normal file
104
ext/pdo_mysql/tests/bug_44454.phpt
Normal file
|
@ -0,0 +1,104 @@
|
|||
--TEST--
|
||||
Bug #44454 (http://bugs.php.net/bug.php?id=44454)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||
|
||||
function bug_44454($db) {
|
||||
|
||||
try {
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$db->exec('CREATE TABLE test(a INT, b INT, UNIQUE KEY idx_ab (a, b))');
|
||||
$db->exec('INSERT INTO test(a, b) VALUES (1, 1)');
|
||||
|
||||
$stmt = $db->query('SELECT a, b FROM test');
|
||||
printf("... SELECT has returned %d row...\n", $stmt->rowCount());
|
||||
while ($row = $stmt->fetch()) {
|
||||
try {
|
||||
printf("... INSERT should fail...\n");
|
||||
$db->exec('INSERT INTO test(a, b) VALUES (1, 1)');
|
||||
} catch (Exception $e) {
|
||||
printf("... STMT - %s\n", var_export($stmt->errorCode(), true));
|
||||
printf("... PDO - %s\n", var_export($db->errorInfo(), true));
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
printf("... While error %s\n", $e->getMessage()); ;
|
||||
}
|
||||
|
||||
$stmt = $db->query('SELECT a, b FROM test');
|
||||
printf("... SELECT has returned %d row...\n", $stmt->rowCount());
|
||||
foreach ($stmt as $row) {
|
||||
try {
|
||||
printf("... INSERT should fail...\n");
|
||||
$db->exec('INSERT INTO test(a, b) VALUES (1, 1)');
|
||||
} catch (Exception $e) {
|
||||
printf("... STMT - %s\n", var_export($stmt->errorCode(), true));
|
||||
printf("... PDO - %s\n", var_export($db->errorInfo(), true));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
print "Native Prepared Statements\n";
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
|
||||
bug_44454($db);
|
||||
|
||||
print "\nEmulated Prepared Statements\n";
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
|
||||
bug_44454($db);
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--XFAIL--
|
||||
For some reason the exception gets thrown at the wrong place
|
||||
--EXPECT--
|
||||
Native Prepared Statements
|
||||
... SELECT has returned 1 row...
|
||||
... INSERT should fail...
|
||||
... STMT - '00000'
|
||||
... PDO - array (
|
||||
0 => '23000',
|
||||
1 => 1062,
|
||||
2 => 'Duplicate entry \'1-1\' for key 1',
|
||||
)
|
||||
... SELECT has returned 1 row...
|
||||
... INSERT should fail...
|
||||
... STMT - '00000'
|
||||
... PDO - array (
|
||||
0 => '23000',
|
||||
1 => 1062,
|
||||
2 => 'Duplicate entry \'1-1\' for key 1',
|
||||
)
|
||||
|
||||
Emulated Prepared Statements
|
||||
... SELECT has returned 1 row...
|
||||
... INSERT should fail...
|
||||
... STMT - '00000'
|
||||
... PDO - array (
|
||||
0 => '23000',
|
||||
1 => 1062,
|
||||
2 => 'Duplicate entry \'1-1\' for key 1',
|
||||
)
|
||||
... SELECT has returned 1 row...
|
||||
... INSERT should fail...
|
||||
... STMT - '00000'
|
||||
... PDO - array (
|
||||
0 => '23000',
|
||||
1 => 1062,
|
||||
2 => 'Duplicate entry \'1-1\' for key 1',
|
||||
)
|
||||
done!
|
92
ext/pdo_mysql/tests/bug_44707.phpt
Normal file
92
ext/pdo_mysql/tests/bug_44707.phpt
Normal file
|
@ -0,0 +1,92 @@
|
|||
--TEST--
|
||||
Bug #44707 (http://bugs.php.net/bug.php?id=44707) = ! driver bug
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
|
||||
MySQLPDOTest::skip();
|
||||
|
||||
$db = MySQLPDOTest::factory();
|
||||
$stmt = $db->query('SELECT VERSION() as _version');
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$matches = array();
|
||||
if (!preg_match('/^(\d+)\.(\d+)\.(\d+)/ismU', $row['_version'], $matches))
|
||||
die(sprintf("skip Cannot determine MySQL Server version\n"));
|
||||
|
||||
$version = $matches[0] * 10000 + $matches[1] * 100 + $matches[2];
|
||||
if ($version < 41000)
|
||||
die(sprintf("skip Will work different with MySQL Server < 4.1.0, found %d.%02d.%02d (%d)\n",
|
||||
$matches[0], $matches[1], $matches[2], $version));
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||
|
||||
function bug_44707($db) {
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$db->exec('CREATE TABLE test(id INT, mybool TINYINT)');
|
||||
|
||||
$id = 1;
|
||||
$mybool = false;
|
||||
var_dump($mybool);
|
||||
|
||||
$stmt = $db->prepare('INSERT INTO test(id, mybool) VALUES (?, ?)');
|
||||
$stmt->bindParam(1, $id);
|
||||
// From MySQL 4.1 on boolean and TINYINT don't match! INSERT will fail.
|
||||
// Versions prior to 4.1 have a weak test and will accept this.
|
||||
$stmt->bindParam(2, $mybool, PDO::PARAM_BOOL);
|
||||
var_dump($mybool);
|
||||
|
||||
$stmt->execute();
|
||||
var_dump($mybool);
|
||||
|
||||
$stmt = $db->query('SELECT * FROM test');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
$stmt = $db->prepare('INSERT INTO test(id, mybool) VALUES (?, ?)');
|
||||
$stmt->bindParam(1, $id);
|
||||
// INT and integer work well together
|
||||
$stmt->bindParam(2, $mybool, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
$stmt = $db->query('SELECT * FROM test');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// This is beyond the control of the driver... - the driver never gets in touch with bound values
|
||||
print "Emulated Prepared Statements\n";
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
|
||||
bug_44707($db);
|
||||
*/
|
||||
|
||||
print "Native Prepared Statements\n";
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
|
||||
bug_44707($db);
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECT--
|
||||
Native Prepared Statements
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
array(0) {
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["mybool"]=>
|
||||
string(1) "0"
|
||||
}
|
||||
}
|
||||
done!
|
50
ext/pdo_mysql/tests/bug_45120.phpt
Normal file
50
ext/pdo_mysql/tests/bug_45120.phpt
Normal file
|
@ -0,0 +1,50 @@
|
|||
--TEST--
|
||||
Bug #45120 (http://bugs.php.net/bug.php?id=45120)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||
|
||||
function bug_45120($db) {
|
||||
|
||||
$stmt = $db->prepare("SELECT 1 AS 'one'");
|
||||
if (true !== $stmt->execute())
|
||||
printf("[001] Execute has failed: %s\n", var_export($stmt->errorInfo(), true));
|
||||
|
||||
$res = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($res['one'] != 1)
|
||||
printf("[002] Wrong results: %s\n", var_export($res, true));
|
||||
|
||||
if (true !== $stmt->execute())
|
||||
printf("[003] Execute has failed: %s\n", var_export($stmt->errorInfo(), true));
|
||||
|
||||
$res = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($res['one'] != 1)
|
||||
printf("[004] Wrong results: %s\n", var_export($res, true));
|
||||
|
||||
}
|
||||
|
||||
print "Emulated Prepared Statements\n";
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
|
||||
bug_45120($db);
|
||||
|
||||
print "Native Prepared Statements\n";
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
|
||||
bug_45120($db);
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--XFAIL--
|
||||
This is an open PDO bug. It is not a PDO_MYSQL bug
|
||||
--EXPECT--
|
||||
Emulated Prepared Statements
|
||||
Native Prepared Statements
|
||||
done!
|
62
ext/pdo_mysql/tests/bug_pecl_12925.phpt
Normal file
62
ext/pdo_mysql/tests/bug_pecl_12925.phpt
Normal file
|
@ -0,0 +1,62 @@
|
|||
--TEST--
|
||||
PDO MySQL PECL bug #1295 (http://pecl.php.net/bugs/bug.php?id=12925)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
function bug_pecl_1295($db) {
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$db->exec('CREATE TABLE test(id CHAR(1))');
|
||||
$db->exec('INSERT INTO test(id) VALUES ("a")');
|
||||
$stmt = $db->prepare('UPDATE test SET id = "b"');
|
||||
$stmt->execute();
|
||||
$stmt = $db->prepare('UPDATE test SET id = "c"');
|
||||
$stmt->execute();
|
||||
$stmt = $db->prepare('SELECT id FROM test');
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
$stmt->closeCursor();
|
||||
|
||||
}
|
||||
|
||||
printf("Emulated...\n");
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
|
||||
bug_pecl_1295($db);
|
||||
|
||||
printf("Native...\n");
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
|
||||
bug_pecl_1295($db);
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECT--
|
||||
Emulated...
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(1) "c"
|
||||
}
|
||||
}
|
||||
Native...
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(1) "c"
|
||||
}
|
||||
}
|
||||
done!
|
87
ext/pdo_mysql/tests/bug_pecl_7976.phpt
Normal file
87
ext/pdo_mysql/tests/bug_pecl_7976.phpt
Normal file
|
@ -0,0 +1,87 @@
|
|||
--TEST--
|
||||
PDO MySQL Bug #42499 (http://bugs.php.net/bug.php?id=42499)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
$row = $db->query('SELECT VERSION() as _version')->fetch(PDO::FETCH_ASSOC);
|
||||
$matches = array();
|
||||
if (!preg_match('/^(\d+)\.(\d+)\.(\d+)/ismU', $row['_version'], $matches))
|
||||
die(sprintf("skip Cannot determine MySQL Server version\n"));
|
||||
|
||||
$version = $matches[0] * 10000 + $matches[1] * 100 + $matches[2];
|
||||
if ($version < 50000)
|
||||
die(sprintf("skip Need MySQL Server 5.0.0+, found %d.%02d.%02d (%d)\n",
|
||||
$matches[0], $matches[1], $matches[2], $version));
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
function bug_pecl_7976($db) {
|
||||
|
||||
$db->exec('DROP PROCEDURE IF EXISTS p');
|
||||
$db->exec('CREATE PROCEDURE p() BEGIN SELECT "1" AS _one; END;');
|
||||
|
||||
$stmt = $db->query('CALL p()');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
$stmt->closeCursor();
|
||||
|
||||
$stmt = $db->query('CALL p()');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
$stmt->closeCursor();
|
||||
|
||||
}
|
||||
|
||||
printf("Emulated...\n");
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
|
||||
bug_pecl_7976($db);
|
||||
|
||||
printf("Native...\n");
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
|
||||
bug_pecl_7976($db);
|
||||
|
||||
$db->exec('DROP PROCEDURE IF EXISTS p');
|
||||
print "done!";
|
||||
?>
|
||||
--XFAIL--
|
||||
Works with mysqlnd. It is not supported by libmysql. For libmysql is good enough to see no crash.
|
||||
--EXPECT--
|
||||
Emulated...
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["_one"]=>
|
||||
string(1) "1"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["_one"]=>
|
||||
string(1) "1"
|
||||
}
|
||||
}
|
||||
Native...
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["_one"]=>
|
||||
string(1) "1"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["_one"]=>
|
||||
string(1) "1"
|
||||
}
|
||||
}
|
||||
done!
|
|
@ -1,19 +1,52 @@
|
|||
<?php
|
||||
/* Overrule global settings, if need be */
|
||||
|
||||
if (false !== getenv('PDO_MYSQL_TEST_DSN')) {
|
||||
# user set them from their shell
|
||||
$config['ENV']['PDOTEST_DSN'] = getenv('PDO_MYSQL_TEST_DSN');
|
||||
$config['ENV']['PDOTEST_USER'] = getenv('PDO_MYSQL_TEST_USER');
|
||||
$config['ENV']['PDOTEST_PASS'] = getenv('PDO_MYSQL_TEST_PASS');
|
||||
if (false !== getenv('PDO_MYSQL_TEST_ATTR')) {
|
||||
$config['ENV']['PDOTEST_ATTR'] = getenv('PDO_MYSQL_TEST_ATTR');
|
||||
}
|
||||
# user set them from their shell
|
||||
$config['ENV']['PDOTEST_DSN'] = getenv('PDO_MYSQL_TEST_DSN');
|
||||
$config['ENV']['PDOTEST_USER'] = getenv('PDO_MYSQL_TEST_USER');
|
||||
$config['ENV']['PDOTEST_PASS'] = getenv('PDO_MYSQL_TEST_PASS');
|
||||
if (false !== getenv('PDO_MYSQL_TEST_ATTR')) {
|
||||
$config['ENV']['PDOTEST_ATTR'] = getenv('PDO_MYSQL_TEST_ATTR');
|
||||
}
|
||||
} else {
|
||||
$config['ENV']['PDOTEST_DSN'] = 'mysql:host=localhost;dbname=test';
|
||||
$config['ENV']['PDOTEST_USER'] = 'root';
|
||||
$config['ENV']['PDOTEST_PASS'] = '';
|
||||
$config['ENV']['PDOTEST_DSN'] = 'mysql:host=localhost;dbname=test';
|
||||
$config['ENV']['PDOTEST_USER'] = 'root';
|
||||
$config['ENV']['PDOTEST_PASS'] = '';
|
||||
}
|
||||
|
||||
foreach ($config['ENV'] as $k => $v) {
|
||||
putenv("$k=$v");
|
||||
}
|
||||
|
||||
/* MySQL specific settings */
|
||||
define('PDO_MYSQL_TEST_ENGINE', (false !== getenv('PDO_MYSQL_TEST_ENGINE')) ? getenv('PDO_MYSQL_TEST_ENGINE') : 'MyISAM');
|
||||
define('PDO_MYSQL_TEST_HOST', (false !== getenv('PDO_MYSQL_TEST_HOST')) ? getenv('PDO_MYSQL_TEST_HOST') : 'localhost');
|
||||
define('PDO_MYSQL_TEST_PORT', (false !== getenv('PDO_MYSQL_TEST_PORT')) ? getenv('PDO_MYSQL_TEST_PORT') : NULL);
|
||||
define('PDO_MYSQL_TEST_DB', (false !== getenv('PDO_MYSQL_TEST_DB')) ? getenv('PDO_MYSQL_TEST_DB') : 'test');
|
||||
define('PDO_MYSQL_TEST_SOCKET', (false !== getenv('PDO_MYSQL_TEST_SOCKET')) ? getenv('PDO_MYSQL_TEST_SOCKET') : NULL);
|
||||
define('PDO_MYSQL_TEST_DSN', (false !== getenv('PDO_MYSQL_TEST_DSN')) ? getenv('PDO_MYSQL_TEST_DSN') : $config['ENV']['PDOTEST_DSN']);
|
||||
define('PDO_MYSQL_TEST_USER', (false !== getenv('PDO_MYSQL_TEST_USER')) ? getenv('PDO_MYSQL_TEST_USER') : $config['ENV']['PDOTEST_USER']);
|
||||
define('PDO_MYSQL_TEST_PASS', (false !== getenv('PDO_MYSQL_TEST_PASS')) ? getenv('PDO_MYSQL_TEST_PASS') : $config['ENV']['PDOTEST_PASS']);
|
||||
define('PDO_MYSQL_TEST_CHARSET', (false !== getenv('PDO_MYSQL_TEST_CHARSET')) ? getenv('PDO_MYSQL_TEST_CHARSET') : NULL);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -4,7 +4,7 @@ PDO MySQL auto_increment / last insert id
|
|||
<?php
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
|
@ -32,4 +32,4 @@ PDOStatement Object
|
|||
(
|
||||
[queryString] => INSERT INTO test (num) VALUES (451)
|
||||
)
|
||||
24
|
||||
24
|
||||
|
|
162
ext/pdo_mysql/tests/mysql_pdo_test.inc
Normal file
162
ext/pdo_mysql/tests/mysql_pdo_test.inc
Normal file
|
@ -0,0 +1,162 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'config.inc');
|
||||
require_once(dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc');
|
||||
|
||||
class MySQLPDOTest extends PDOTest {
|
||||
|
||||
static function factory($classname = 'PDO', $drop_test_tables = false, $myattr = null) {
|
||||
|
||||
$dsn = self::getDSN();
|
||||
$user = PDO_MYSQL_TEST_USER;
|
||||
$pass = PDO_MYSQL_TEST_PASS;
|
||||
$attr = getenv('PDOTEST_ATTR');
|
||||
|
||||
if (is_string($attr) && strlen($attr)) {
|
||||
$attr = unserialize($attr);
|
||||
} else {
|
||||
$attr = null;
|
||||
}
|
||||
if ($user === false)
|
||||
$user = NULL;
|
||||
if ($pass === false)
|
||||
$pass = NULL;
|
||||
|
||||
$db = new $classname($dsn, $user, $pass, $attr);
|
||||
if (!$db) {
|
||||
die("Could not create PDO object (DSN=$dsn, user=$user)\n");
|
||||
}
|
||||
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
|
||||
$db->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
|
||||
|
||||
return $db;
|
||||
}
|
||||
|
||||
static function createTestTable($db, $engine = null) {
|
||||
if (!$engine)
|
||||
$engine = PDO_MYSQL_TEST_ENGINE;
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$db->exec('CREATE TABLE test(id INT, label CHAR(1), PRIMARY KEY(id)) ENGINE=' . $engine);
|
||||
$db->exec('INSERT INTO test(id, label) VALUES (1, "a"), (2, "b"), (3, "c"), (4, "d"), (5, "e"), (6, "f")');
|
||||
}
|
||||
|
||||
static function getTableEngine() {
|
||||
return PDO_MYSQL_TEST_ENGINE;
|
||||
}
|
||||
|
||||
|
||||
static function getDSN($new_options = null, $addition = '') {
|
||||
if (!$new_options)
|
||||
return PDO_MYSQL_TEST_DSN . $addition;
|
||||
|
||||
$old_options = array();
|
||||
$dsn = substr(PDO_MYSQL_TEST_DSN,
|
||||
strpos(PDO_MYSQL_TEST_DSN, ':') + 1,
|
||||
strlen(PDO_MYSQL_TEST_DSN));
|
||||
|
||||
// no real parser - any excotic setting can fool us
|
||||
$parts = explode(';', $dsn);
|
||||
foreach ($parts as $k => $v) {
|
||||
$tmp = explode('=', $v);
|
||||
if (count($tmp) == 2)
|
||||
$old_options[$tmp[0]] = $tmp[1];
|
||||
}
|
||||
|
||||
$options = $old_options;
|
||||
foreach ($new_options as $k => $v)
|
||||
$options[$k] = $v;
|
||||
|
||||
$dsn = 'mysql:';
|
||||
foreach ($options as $k => $v)
|
||||
$dsn .= sprintf('%s=%s;', $k, $v);
|
||||
|
||||
if ($addition)
|
||||
$dsn .= $addition;
|
||||
else
|
||||
$dsn = substr($dsn, 0, strlen($dsn) -1);
|
||||
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
static function getClientVersion($db) {
|
||||
return self::extractVersion($db->getAttribute(PDO::ATTR_CLIENT_VERSION));
|
||||
}
|
||||
|
||||
static function getServerVersion($db) {
|
||||
return self::extractVersion($db->getAttribute(PDO::ATTR_SERVER_VERSION));
|
||||
}
|
||||
|
||||
static function extractVersion($version_string) {
|
||||
/*
|
||||
TODO:
|
||||
We're a bit in trouble: PDO_MYSQL returns version strings.
|
||||
That's wrong according to the manual. According to the manual
|
||||
integers should be returned. However, this code needs to work
|
||||
with stinky PDO_MYSQL and hopefully better PDO_MYSQLND.
|
||||
*/
|
||||
|
||||
// already an int value?
|
||||
if (is_int($version_string))
|
||||
return $version_string;
|
||||
|
||||
// string but int value?
|
||||
$tmp = (int)$version_string;
|
||||
if (((string)$tmp) === $version_string)
|
||||
return $tmp;
|
||||
|
||||
// stinky string which we need to parse
|
||||
$parts = explode('.', $version_string);
|
||||
if (count($parts) != 3)
|
||||
return -1;
|
||||
|
||||
$version = (int)$parts[0] * 10000;
|
||||
$version+= (int)$parts[1] * 100;
|
||||
$version+= (int)$parts[2];
|
||||
|
||||
return $version;
|
||||
}
|
||||
|
||||
static function getTempDir() {
|
||||
|
||||
if (!function_exists('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;
|
||||
} else {
|
||||
return sys_get_temp_dir();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static function detect_transactional_mysql_engine($db) {
|
||||
foreach ($db->query("show variables like 'have%'") as $row) {
|
||||
if ($row[1] == 'YES' && ($row[0] == 'have_innodb' || $row[0] == 'have_bdb')) {
|
||||
return str_replace("have_", "", $row[0]);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static function isPDOMySQLnd() {
|
||||
ob_start();
|
||||
phpinfo();
|
||||
$tmp = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return (true == stristr($tmp, 'PDO Driver for MySQL, mysql native driver version'));
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
303
ext/pdo_mysql/tests/pdo_mysql___construct.phpt
Normal file
303
ext/pdo_mysql/tests/pdo_mysql___construct.phpt
Normal file
|
@ -0,0 +1,303 @@
|
|||
--TEST--
|
||||
MySQL PDO->__construct() - Generic + DSN
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
|
||||
function tryandcatch($offset, $code) {
|
||||
|
||||
try {
|
||||
eval($code);
|
||||
assert(sprintf("[%03d] Should have failed\n", $offset) != '');
|
||||
} catch (PDOException $e) {
|
||||
return sprintf("[%03d] %s, [%s] %s\n",
|
||||
$offset,
|
||||
$e->getMessage(),
|
||||
(isset($db) && is_object($db)) ? $db->errorCode() : 'n/a',
|
||||
(isset($db) && is_object($db)) ? implode(' ', $db->errorInfo()) : 'n/a');
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
if (NULL !== ($db = @new PDO()))
|
||||
printf("[001] Too few parameters\n");
|
||||
|
||||
print tryandcatch(2, '$db = new PDO(chr(0));');
|
||||
print tryandcatch(3, '$db = new PDO("a" . chr(0) . "b");');
|
||||
print tryandcatch(4, '$db = new PDO("MYSQL");');
|
||||
print tryandcatch(5, '$db = new PDO("mysql");');
|
||||
print tryandcatch(6, '$db = new PDO("mysql ");');
|
||||
print tryandcatch(7, '$db = new PDO("fantasyandfriends :");');
|
||||
|
||||
$dsn = PDO_MYSQL_TEST_DSN;
|
||||
// MySQL Server might accept anonymous connections, don't
|
||||
// print anything
|
||||
tryandcatch(8, '$db = new PDO("' . $dsn . '");');
|
||||
|
||||
$user = 'dontcreatesuchauser';
|
||||
$pass = 'withthispassword';
|
||||
print tryandcatch(9, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");');
|
||||
|
||||
// should fail
|
||||
$dsn = 'mysql:';
|
||||
print tryandcatch(10, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");');
|
||||
|
||||
$dsn = PDO_MYSQL_TEST_DSN;
|
||||
$user = PDO_MYSQL_TEST_USER;
|
||||
$pass = PDO_MYSQL_TEST_PASS;
|
||||
// should work...
|
||||
$db = new PDO($dsn, $user, $pass);
|
||||
|
||||
$dsn = 'mysql:invalid=foo';
|
||||
print tryandcatch(11, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");');
|
||||
|
||||
$dsn = 'mysql:' . str_repeat('howmuch=canpdoeat;', 1000);
|
||||
print tryandcatch(12, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");');
|
||||
|
||||
$dsn = 'mysql:' . str_repeat('abcdefghij', 1024 * 10) . '=somevalue';
|
||||
print tryandcatch(13, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");');
|
||||
|
||||
if (PDO_MYSQL_TEST_HOST) {
|
||||
$host = PDO_MYSQL_TEST_HOST;
|
||||
$invalid_host = $host . 'invalid';
|
||||
|
||||
// last host specification should be the one used
|
||||
$dsn = MySQLPDOTest::getDSN(array('host' => $host), 'host=' . $invalid_host);
|
||||
try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) {
|
||||
$tmp = $e->getMessage();
|
||||
if (!stristr($tmp, 'HY000') && !stristr($tmp, '2005') && !stristr($tmp, '2002'))
|
||||
printf("[014] Cannot find proper error codes: %s\n", $tmp);
|
||||
}
|
||||
|
||||
$dsn = MySQLPDOTest::getDSN(array('host' => $invalid_host), 'host=' . $host);
|
||||
try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) {
|
||||
printf("[015] DSN=%s, %s\n", $dsn, $e->getMessage());
|
||||
}
|
||||
|
||||
$invalid_host = '-' . chr(0);
|
||||
|
||||
$dsn = MySQLPDOTest::getDSN(array('host' => $invalid_host));
|
||||
try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) {
|
||||
$tmp = $e->getMessage();
|
||||
if (!stristr($tmp, 'HY000') && !stristr($tmp, '2005') && !stristr($tmp, '2002'))
|
||||
printf("[016] Cannot find proper error codes: %s\n", $tmp);
|
||||
}
|
||||
|
||||
// parsing should not get confused by chr(0)
|
||||
$dsn = MySQLPDOTest::getDSN(array('host' => $invalid_host), 'host=' . $host);
|
||||
try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) {
|
||||
printf("[017] DSN=%s, %s\n", $dsn, $e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// what about long values for a valid option ...
|
||||
$dsn = MySQLPDOTest::getDSN(array('host' => str_repeat('0123456789', 1024 * 100)));
|
||||
try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) {
|
||||
$tmp = $e->getMessage();
|
||||
if (!stristr($tmp, 'HY000') && !stristr($tmp, '2005') && !stristr($tmp, '2002'))
|
||||
printf("[018] Cannot find proper error codes: %s\n", $tmp);
|
||||
}
|
||||
|
||||
if (PDO_MYSQL_TEST_PORT && (PDO_MYSQL_TEST_SOCKET == '')) {
|
||||
// Playing with the port makes only sense if no socket gets used
|
||||
|
||||
$port = PDO_MYSQL_TEST_PORT;
|
||||
// let's hope we don't hit a MySQL running on that port...
|
||||
$invalid_port = $port * 2;
|
||||
|
||||
$dsn = MySQLPDOTest::getDSN(array('port' => $port), 'port=' . $invalid_port);
|
||||
try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) {
|
||||
$tmp = $e->getMessage();
|
||||
if (!stristr($tmp, 'HY000') && !stristr($tmp, '2005'))
|
||||
printf("[019] Cannot find proper error codes: %s\n", $tmp);
|
||||
}
|
||||
|
||||
$dsn = MySQLPDOTest::getDSN(array('port' => $invalid_port), 'port=' . $port);
|
||||
try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) {
|
||||
printf("[020] DSN=%s, %s\n", $dsn, $e->getMessage());
|
||||
}
|
||||
|
||||
$invalid_port = 'abc';
|
||||
$dsn = MySQLPDOTest::getDSN(array('port' => $port), 'port=' . $invalid_port);
|
||||
try {
|
||||
$db = @new PDO($dsn, $user, $pass);
|
||||
// atoi('abc') = 0, 0 -> fallback to default 3306 -> may or may not fail!
|
||||
} catch (PDOException $e) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (PDO_MYSQL_TEST_DB) {
|
||||
$db = PDO_MYSQL_TEST_DB;
|
||||
$invalid_db = 'letshopeitdoesnotexist';
|
||||
|
||||
$dsn = MySQLPDOTest::getDSN(array('dbname' => $db), 'dbname=' . $invalid_db);
|
||||
try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) {
|
||||
$tmp = $e->getMessage();
|
||||
if (!stristr($tmp, '42000') && !stristr($tmp, '1049'))
|
||||
printf("[022] Cannot find proper error codes: %s\n", $tmp);
|
||||
}
|
||||
|
||||
$dsn = MySQLPDOTest::getDSN(array('dbname' => $invalid_db), 'dbname=' . $db);
|
||||
try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) {
|
||||
printf("[023] DSN=%s, %s\n", $dsn, $e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (PDO_MYSQL_TEST_SOCKET && (stristr(PDO_MYSQL_TEST_DSN, PDO_MYSQL_TEST_SOCKET) !== false)) {
|
||||
$socket = PDO_MYSQL_TEST_SOCKET;
|
||||
$invalid_socket = '/lets/hope/it/does/not/exist';
|
||||
|
||||
$dsn = MySQLPDOTest::getDSN(array('unix_socket' => $socket), 'unix_socket=' . $invalid_socket);
|
||||
try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) {
|
||||
$tmp = $e->getMessage();
|
||||
if (!stristr($tmp, 'HY000') && !stristr($tmp, '2002'))
|
||||
printf("[024] Cannot find proper error codes: %s\n", $tmp);
|
||||
}
|
||||
|
||||
$dsn = MySQLPDOTest::getDSN(array('unix_socket' => $invalid_socket), 'unix_socket=' . $socket);
|
||||
try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) {
|
||||
printf("[025] DSN=%s, %s\n", $dsn, $e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$have_charset_support = false;
|
||||
$dsn = MySQLPDOTest::getDSN();
|
||||
try {
|
||||
$db = new PDO($dsn, $user, $pass);
|
||||
$stmt = $db->query('SELECT VERSION() as _version');
|
||||
$version = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$tmp = explode('.', $version['_version']);
|
||||
if ((count($tmp) == 3) &&
|
||||
(($tmp[0] >= 4 && $tmp[1] >= 1) || ($tmp[0] >= 5))) {
|
||||
// MySQL Server 4.1 - charset support available
|
||||
$have_charset_support = true;
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[026] DSN=%s, %s\n", $dsn, $e->getMessage());
|
||||
}
|
||||
|
||||
if (PDO_MYSQL_TEST_CHARSET) {
|
||||
$charset = PDO_MYSQL_TEST_CHARSET;
|
||||
$invalid_charset = 'invalid';
|
||||
|
||||
if ($have_charset_support) {
|
||||
$dsn = MySQLPDOTest::getDSN();
|
||||
$db = new PDO($dsn, $user, $pass);
|
||||
$stmt = $db->query(sprintf('SHOW CHARACTER SET LIKE "%s"', $charset));
|
||||
$tmp = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$have_charset = (empty($tmp)) ? false : true;
|
||||
|
||||
if ($have_charset) {
|
||||
$dsn = MySQLPDOTest::getDSN(array('charset' => $charset), 'charset=' . $invalid_charset);
|
||||
try {
|
||||
$db = @new PDO($dsn, $user, $pass);
|
||||
/* NOTE: MySQL does a fallback to the charset suggested during the handshake - no error - no bug! */
|
||||
assert(false);
|
||||
printf("%s\n", $dsn);
|
||||
} catch (PDOException $e) {
|
||||
$tmp = $e->getMessage();
|
||||
/* TODO: add proper codes */
|
||||
if (!stristr($tmp, 'sqlstatecode') || !stristr($tmp, 'mysqlinternalerrcode'))
|
||||
printf("[027] TODO - Cannot find proper error codes: %s\n", $tmp);
|
||||
}
|
||||
|
||||
$dsn = MySQLPDOTest::getDSN(array('charset' => $invalid_charset), 'charset=' . $charset);
|
||||
try {
|
||||
$db = @new PDO($dsn, $user, $pass);
|
||||
/* Strictly speaking we should test more: character_set_client, character_set_results, and character_set_connection */
|
||||
$stmt = $db->query('SELECT @@character_set_connection AS _charset');
|
||||
$tmp = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($tmp['_charset'] != $charset)
|
||||
printf("[028] Character sets has not been set, @@character_set_connection reports '%s', expecting '%s'",
|
||||
$tmp['_charset'], $charset);
|
||||
} catch (PDOException $e) {
|
||||
printf("[029] DSN=%s, %s\n", $dsn, $e->getMessage());
|
||||
}
|
||||
} else {
|
||||
printf("[030] You're trying to run the tests with charset '%s' which seems not supported by the server!", $charset);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($have_charset_support) {
|
||||
// In case the PDO_MYSQL_TEST_CHARSET interferes with any defaults
|
||||
// we do another test to verify that the charset has been set.
|
||||
$dsn = MySQLPDOTest::getDSN();
|
||||
$db = new PDO($dsn, $user, $pass);
|
||||
$stmt = $db->query('SHOW CHARACTER SET LIKE "latin1"');
|
||||
$tmp = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$have_latin1 =(empty($tmp)) ? false : true;
|
||||
$stmt = $db->query('SHOW CHARACTER SET LIKE "latin2"');
|
||||
$tmp = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$have_latin2 =(empty($tmp)) ? false : true;
|
||||
|
||||
if ($have_latin1 && $have_latin2) {
|
||||
// very likely we do have both of them...
|
||||
try {
|
||||
$dsn = MySQLPDOTest::getDSN(array('charset' => 'latin1'));
|
||||
$db = new PDO($dsn, $user, $pass);
|
||||
$stmt = $db->query('SELECT @@character_set_connection AS _charset');
|
||||
$tmp = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($tmp['_charset'] != 'latin1')
|
||||
printf("[031] DSN = %s, Character sets has not been set, @@character_set_connection reports '%s', expecting '%s'",
|
||||
$dsn, $tmp['_charset'], 'latin1');
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[032] %s\n", $e->getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
$dsn = MySQLPDOTest::getDSN(array('charset' => 'latin2'));
|
||||
$db = new PDO($dsn, $user, $pass);
|
||||
$stmt = $db->query('SELECT @@character_set_connection AS _charset');
|
||||
$tmp = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($tmp['_charset'] != 'latin2')
|
||||
printf("[033] DSN = %s, character sets has not been set, @@character_set_connection reports '%s', expecting '%s'",
|
||||
$dsn, $tmp['_charset'], 'latin2');
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[034] %s\n", $e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s, [%s] %s\n",
|
||||
$e->getMessage(),
|
||||
(is_object($db)) ? $db->errorCode() : 'n/a',
|
||||
(is_object($db)) ? implode(' ', $db->errorInfo()) : 'n/a');
|
||||
}
|
||||
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
[002] invalid data source name, [n/a] n/a
|
||||
[003] invalid data source name, [n/a] n/a
|
||||
[004] invalid data source name, [n/a] n/a
|
||||
[005] invalid data source name, [n/a] n/a
|
||||
[006] invalid data source name, [n/a] n/a
|
||||
[007] could not find driver, [n/a] n/a
|
||||
[009] SQLSTATE[28000] [1045] Access denied for user 'dont%s'@'%s' (using password: YES), [n/a] n/a
|
||||
[010] SQLSTATE[28000] [1045] Access denied for user 'dont%s'@'%s' (using password: YES), [n/a] n/a
|
||||
[017] DSN=%s, SQLSTATE[%s] [%d] %s
|
||||
|
||||
Warning: assert(): Assertion failed in %s on line %d
|
||||
mysql:%s
|
||||
[033] DSN = mysql:%s, character sets has not been set, @@character_set_connection reports 'latin1', expecting 'latin2'done!
|
56
ext/pdo_mysql/tests/pdo_mysql___construct_ini.phpt
Normal file
56
ext/pdo_mysql/tests/pdo_mysql___construct_ini.phpt
Normal file
|
@ -0,0 +1,56 @@
|
|||
--TEST--
|
||||
MySQL PDO->__construct() - URI
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
/* TODO - fix this limitation */
|
||||
if (getenv('PDO_MYSQL_TEST_DSN') !== "mysql:dbname=phptest;unix_socket=/tmp/mysql.sock")
|
||||
die("skip Fix test to run in other environments as well!");
|
||||
|
||||
?>
|
||||
--INI--
|
||||
pdo.dsn.mysql="mysql:dbname=phptest;socket=/tmp/mysql.sock"
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
|
||||
$found = false;
|
||||
$values = ini_get_all();
|
||||
foreach ($values as $name => $dsn)
|
||||
if ('pdo.dsn.mysql' == $name) {
|
||||
printf("pdo.dsn.mysql=%s\n", $dsn);
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
$dsn = ini_get('pdo.dsn.mysql');
|
||||
$found = ($dsn !== false);
|
||||
}
|
||||
|
||||
if (!$found)
|
||||
printf("pdo.dsn.mysql cannot be accessed through ini_get_all()/ini_get()\n");
|
||||
|
||||
if (MySQLPDOTest::getDSN() == $dsn) {
|
||||
// we are lucky, we can run the test
|
||||
try {
|
||||
|
||||
$user = PDO_MYSQL_TEST_USER;
|
||||
$pass = PDO_MYSQL_TEST_PASS;
|
||||
$db = new PDO('mysql', $user, $pass);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s, [%s] %s\n",
|
||||
$e->getMessage(),
|
||||
(is_object($db)) ? $db->errorCode() : 'n/a',
|
||||
(is_object($db)) ? implode(' ', $db->errorInfo()) : 'n/a');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
pdo.dsn.mysql cannot be accessed through ini_get_all()/ini_get()
|
||||
done!
|
170
ext/pdo_mysql/tests/pdo_mysql___construct_options.phpt
Normal file
170
ext/pdo_mysql/tests/pdo_mysql___construct_options.phpt
Normal file
|
@ -0,0 +1,170 @@
|
|||
--TEST--
|
||||
MySQL PDO->__construct(), options
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
|
||||
function set_option_and_check($offset, $option, $value, $option_desc) {
|
||||
|
||||
$dsn = MySQLPDOTest::getDSN();
|
||||
$user = PDO_MYSQL_TEST_USER;
|
||||
$pass = PDO_MYSQL_TEST_PASS;
|
||||
|
||||
try {
|
||||
$db = new PDO($dsn, $user, $pass, array($option => $value));
|
||||
if (!is_object($db) || ($value !== ($tmp = @$db->getAttribute($option))))
|
||||
printf("[%03d] Execting '%s'/%s got '%s'/%s' for options '%s'\n",
|
||||
$offset,
|
||||
$value, gettype($value),
|
||||
$tmp, gettype($tmp),
|
||||
$option_desc);
|
||||
} catch (PDOException $e) {
|
||||
printf("[%03d] %s\n", $offset, $e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
$dsn = MySQLPDOTest::getDSN();
|
||||
$user = PDO_MYSQL_TEST_USER;
|
||||
$pass = PDO_MYSQL_TEST_PASS;
|
||||
|
||||
$valid_options = array(
|
||||
/* pdo_dbh.c */
|
||||
PDO::ATTR_PERSISTENT => 'PDO::ATTR_PERSISTENT',
|
||||
PDO::ATTR_AUTOCOMMIT => 'PDO::ATTR_AUTOCOMMIT',
|
||||
/* mysql_driver.c */
|
||||
/* TODO Possible bug PDO::ATTR_TIMEOUT != MYSQLI_OPT_CONNECT_TIMEOUT*/
|
||||
PDO::ATTR_TIMEOUT => 'PDO::ATTR_TIMEOUT',
|
||||
PDO::ATTR_EMULATE_PREPARES => 'PDO::ATTR_EMULATE_PREPARES',
|
||||
|
||||
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => 'PDO::MYSQL_ATTR_USE_BUFFERED_QUERY',
|
||||
PDO::MYSQL_ATTR_LOCAL_INFILE => 'PDO::MYSQL_ATTR_LOCAL_INFILE',
|
||||
PDO::MYSQL_ATTR_DIRECT_QUERY => 'PDO::MYSQL_ATTR_DIRECT_QUERY',
|
||||
);
|
||||
|
||||
$defaults = array(
|
||||
PDO::ATTR_PERSISTENT => false,
|
||||
PDO::ATTR_AUTOCOMMIT => 1,
|
||||
/* TODO - why is this a valid option if getAttribute() does not support it?! */
|
||||
PDO::ATTR_TIMEOUT => false,
|
||||
PDO::ATTR_EMULATE_PREPARES => 1,
|
||||
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => 1,
|
||||
/* TODO getAttribute() does not handle it */
|
||||
PDO::MYSQL_ATTR_LOCAL_INFILE => false,
|
||||
/* TODO getAttribute() does not handle it */
|
||||
PDO::MYSQL_ATTR_DIRECT_QUERY => 1,
|
||||
);
|
||||
|
||||
if (NULL !== ($db = @new PDO($dsn, $user, $pass, 'wrong type')))
|
||||
printf("[001] Expecting NULL got %s/%s\n", gettype($db), $db);
|
||||
|
||||
if (!is_object($db = new PDO($dsn, $user, $pass, array())))
|
||||
printf("[002] Expecting object got %s/%s¸\n", gettype($db), $db);
|
||||
|
||||
do {
|
||||
$invalid = mt_rand(-1000, 1000);
|
||||
} while (isset($valid_options[$invalid]));
|
||||
if (is_object($db = new PDO($dsn, $user, $pass, array($invalid => true))))
|
||||
printf("[003] [TODO][CHANGEREQUEST] Please, lets not ignore invalid options and bail out!\n");
|
||||
|
||||
$db = new PDO($dsn, $user, $pass);
|
||||
foreach ($valid_options as $option => $name) {
|
||||
/* TODO getAttribute() is pretty poor in supporting the options, suppress errors */
|
||||
$tmp = @$db->getAttribute($option);
|
||||
if ($tmp !== $defaults[$option])
|
||||
printf("[003a] Expecting default value for '%s' of '%s'/%s, getAttribute() reports setting '%s'/%s\n",
|
||||
$name, $defaults[$option], gettype($defaults[$option]),
|
||||
$tmp, gettype($tmp));
|
||||
}
|
||||
|
||||
$db = new PDO($dsn, $user, $pass, array(PDO::ATTR_AUTOCOMMIT => true));
|
||||
if (!is_object($db) || !$db->getAttribute(PDO::ATTR_AUTOCOMMIT))
|
||||
printf("[004] Autocommit should be on\n");
|
||||
|
||||
$db = new PDO($dsn, $user, $pass, array(PDO::ATTR_AUTOCOMMIT => false));
|
||||
if (!is_object($db) || $db->getAttribute(PDO::ATTR_AUTOCOMMIT))
|
||||
printf("[005] Autocommit should be off\n");
|
||||
|
||||
/* TODO: no way to check ATTR_TIMEOUT settings */
|
||||
if (!is_object($db = new PDO($dsn, $user, $pass, array(PDO::ATTR_TIMEOUT => 10))))
|
||||
printf("[006] ATTR_TIMEOUT should be accepted\n");
|
||||
|
||||
if (!is_object($db = new PDO($dsn, $user, $pass, array(PDO::ATTR_TIMEOUT => PHP_INT_MAX))))
|
||||
printf("[007] ATTR_TIMEOUT should be accepted\n");
|
||||
|
||||
if (!is_object($db = new PDO($dsn, $user, $pass, array(PDO::ATTR_TIMEOUT => -PHP_INT_MAX))))
|
||||
printf("[008] ATTR_TIMEOUT should be accepted\n");
|
||||
|
||||
/* TODO: Its ugly that PDO::ATTR_EMULATE_PREPARES == PDO::MYSQL_ATTR_DIRECT_QUERY */
|
||||
$db = new PDO($dsn, $user, $pass, array(PDO::ATTR_EMULATE_PREPARES => true));
|
||||
if (!is_object($db))
|
||||
printf("[009] ATTR_EMULATE_PREPARES should be accepted and on\n");
|
||||
if (!$db->getAttribute(PDO::ATTR_EMULATE_PREPARES))
|
||||
printf("[010] [TODO][CHANGEREQUEST] ATTR_EMULATE_PREPARES should be on\n");
|
||||
if (!$db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[011] As PDO::MYSQL_ATTR_DIRECT_QUERY == PDO::ATTR_EMULATE_PREPARES
|
||||
and PDO::ATTR_EMULATE_PREPARES overrules the other, PDO::MYSQL_ATTR_DIRECT_QUERY should be on\n");
|
||||
|
||||
$db = new PDO($dsn, $user, $pass, array(PDO::ATTR_EMULATE_PREPARES => false));
|
||||
if (!is_object($db))
|
||||
printf("[012] ATTR_EMULATE_PREPARES should be accepted and on\n");
|
||||
if ($db->getAttribute(PDO::ATTR_EMULATE_PREPARES))
|
||||
printf("[013] [TODO][CHANGEREQUEST] ATTR_EMULATE_PREPARES should be off\n");
|
||||
if ($db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[014] As PDO::MYSQL_ATTR_DIRECT_QUERY == PDO::ATTR_EMULATE_PREPARES
|
||||
and PDO::ATTR_EMULATE_PREPARES overrules the other, PDO::MYSQL_ATTR_DIRECT_QUERY should be off\n");
|
||||
|
||||
// PDO::ATTR_EMULATE_PREPARES overrules PDO::MYSQL_ATTR_DIRECT_QUERY
|
||||
// TODO: is it clever that a generic setting overrules a specific setting?
|
||||
$db = new PDO($dsn, $user, $pass, array(PDO::ATTR_EMULATE_PREPARES => true, PDO::MYSQL_ATTR_DIRECT_QUERY => false));
|
||||
if (!$db->getAttribute(PDO::ATTR_EMULATE_PREPARES))
|
||||
printf("[015] PDO::ATTR_EMULATE_PREPARES should be on\n");
|
||||
if (!$db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[016] PDO::MYSQL_ATTR_DIRECT_QUERY should be on\n");
|
||||
|
||||
$db = new PDO($dsn, $user, $pass, array(PDO::ATTR_EMULATE_PREPARES => false, PDO::MYSQL_ATTR_DIRECT_QUERY => true));
|
||||
if ($db->getAttribute(PDO::ATTR_EMULATE_PREPARES))
|
||||
printf("[017] PDO::ATTR_EMULATE_PREPARES should be off\n");
|
||||
if ($db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[018] PDO::MYSQL_ATTR_DIRECT_QUERY should be off\n");
|
||||
|
||||
set_option_and_check(19, PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1, 'PDO::MYSQL_ATTR_USE_BUFFERED_QUERY');
|
||||
set_option_and_check(20, PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 0, 'PDO::MYSQL_ATTR_USE_BUFFERED_QUERY');
|
||||
|
||||
set_option_and_check(21, PDO::MYSQL_ATTR_LOCAL_INFILE, true, 'PDO::MYSQL_ATTR_LOCAL_INFILE');
|
||||
set_option_and_check(22, PDO::MYSQL_ATTR_LOCAL_INFILE, false, 'PDO::MYSQL_ATTR_LOCAL_INFILE');
|
||||
|
||||
set_option_and_check(33, PDO::MYSQL_ATTR_DIRECT_QUERY, 1, 'PDO::MYSQL_ATTR_DIRECT_QUERY');
|
||||
set_option_and_check(34, PDO::MYSQL_ATTR_DIRECT_QUERY, 0, 'PDO::MYSQL_ATTR_DIRECT_QUERY');
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s, [%s] %s\n",
|
||||
$e->getMessage(),
|
||||
(is_object($db)) ? $db->errorCode() : 'n/a',
|
||||
(is_object($db)) ? implode(' ', $db->errorInfo()) : 'n/a');
|
||||
}
|
||||
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
[003] [TODO][CHANGEREQUEST] Please, lets not ignore invalid options and bail out!
|
||||
[003a] Expecting default value for 'PDO::ATTR_EMULATE_PREPARES' of '1'/integer, getAttribute() reports setting ''/boolean
|
||||
|
||||
Warning: PDO::getAttribute(): SQLSTATE[IM001]: Driver does not support this function: driver does not support that attribute in %s on line %d
|
||||
[010] [TODO][CHANGEREQUEST] ATTR_EMULATE_PREPARES should be on
|
||||
|
||||
Warning: PDO::getAttribute(): SQLSTATE[IM001]: Driver does not support this function: driver does not support that attribute in %s on line %d
|
||||
|
||||
Warning: PDO::getAttribute(): SQLSTATE[IM001]: Driver does not support this function: driver does not support that attribute in %s on line %d
|
||||
[015] PDO::ATTR_EMULATE_PREPARES should be on
|
||||
[016] PDO::MYSQL_ATTR_DIRECT_QUERY should be on
|
||||
|
||||
Warning: PDO::getAttribute(): SQLSTATE[IM001]: Driver does not support this function: driver does not support that attribute in %s on line %d
|
||||
[018] PDO::MYSQL_ATTR_DIRECT_QUERY should be off
|
||||
[021] Execting '1'/boolean got ''/boolean' for options 'PDO::MYSQL_ATTR_LOCAL_INFILE'
|
||||
done!
|
|
@ -0,0 +1,88 @@
|
|||
--TEST--
|
||||
MySQL PDO->__construct(), libmysql only options
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
if (MySQLPDOTest::isPDOMySQLnd())
|
||||
die("skip libmysql only options")
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
|
||||
function set_option_and_check($offset, $option, $value, $option_desc, $ignore_diff = false) {
|
||||
|
||||
$dsn = MySQLPDOTest::getDSN();
|
||||
$user = PDO_MYSQL_TEST_USER;
|
||||
$pass = PDO_MYSQL_TEST_PASS;
|
||||
|
||||
try {
|
||||
$db = new PDO($dsn, $user, $pass, array($option => $value));
|
||||
if (!is_object($db) || (!$ignore_diff && ($value !== ($tmp = @$db->getAttribute($option)))))
|
||||
printf("[%03d] Execting '%s'/%s got '%s'/%s' for options '%s'\n",
|
||||
$offset,
|
||||
$value, gettype($value),
|
||||
$tmp, gettype($tmp),
|
||||
$option_desc);
|
||||
} catch (PDOException $e) {
|
||||
printf("[%03d] %s\n", $offset, $e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
$dsn = MySQLPDOTest::getDSN();
|
||||
$user = PDO_MYSQL_TEST_USER;
|
||||
$pass = PDO_MYSQL_TEST_PASS;
|
||||
|
||||
$valid_options = array();
|
||||
$valid_options[PDO::MYSQL_ATTR_MAX_BUFFER_SIZE] = 'PDO::MYSQL_ATTR_MAX_BUFFER_SIZE';
|
||||
$valid_options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'PDO::MYSQL_ATTR_INIT_COMMAND';
|
||||
$valid_options[PDO::MYSQL_ATTR_READ_DEFAULT_FILE] = 'PDO::MYSQL_ATTR_READ_DEFAULT_FILE';
|
||||
$valid_options[PDO::MYSQL_ATTR_READ_DEFAULT_GROUP] = 'PDO::MYSQL_ATTR_READ_DEFAULT_GROUP';
|
||||
|
||||
$defaults[PDO::MYSQL_ATTR_MAX_BUFFER_SIZE] = 1048576;
|
||||
/* TODO getAttribute() does not handle it */
|
||||
$defaults[PDO::MYSQL_ATTR_INIT_COMMAND] = '';
|
||||
$defaults[PDO::MYSQL_ATTR_READ_DEFAULT_FILE] = false;
|
||||
$defaults[PDO::MYSQL_ATTR_READ_DEFAULT_GROUP] = false;
|
||||
|
||||
$db = new PDO($dsn, $user, $pass);
|
||||
foreach ($valid_options as $option => $name) {
|
||||
/* TODO getAttribute() is pretty poor in supporting the options, suppress errors */
|
||||
$tmp = @$db->getAttribute($option);
|
||||
if ($tmp !== $defaults[$option])
|
||||
printf("[001] Expecting default value for '%s' of '%s'/%s, getAttribute() reports setting '%s'/%s\n",
|
||||
$name, $defaults[$option], gettype($defaults[$option]),
|
||||
$tmp, gettype($tmp));
|
||||
}
|
||||
|
||||
set_option_and_check(23, PDO::MYSQL_ATTR_INIT_COMMAND, 'SET @a=1', 'PDO::MYSQL_ATTR_INIT_COMMAND');
|
||||
set_option_and_check(24, PDO::MYSQL_ATTR_INIT_COMMAND, '', 'PDO::MYSQL_ATTR_INIT_COMMAND');
|
||||
set_option_and_check(25, PDO::MYSQL_ATTR_INIT_COMMAND, 'INSERT INTO nonexistent(invalid) VALUES (1)', 'PDO::MYSQL_ATTR_INIT_COMMAND');
|
||||
|
||||
set_option_and_check(26, PDO::MYSQL_ATTR_READ_DEFAULT_FILE, true, 'PDO::MYSQL_ATTR_READ_DEFAULT_FILE');
|
||||
set_option_and_check(27, PDO::MYSQL_ATTR_READ_DEFAULT_FILE, false, 'PDO::MYSQL_ATTR_READ_DEFAULT_FILE');
|
||||
|
||||
set_option_and_check(30, PDO::MYSQL_ATTR_MAX_BUFFER_SIZE, -1, 'PDO::MYSQL_ATTR_MAX_BUFFER_SIZE', true);
|
||||
set_option_and_check(31, PDO::MYSQL_ATTR_MAX_BUFFER_SIZE, PHP_INT_MAX, 'PDO::MYSQL_ATTR_MAX_BUFFER_SIZE');
|
||||
set_option_and_check(32, PDO::MYSQL_ATTR_MAX_BUFFER_SIZE, 1, 'PDO::MYSQL_ATTR_MAX_BUFFER_SIZE');
|
||||
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s, [%s] %s\n",
|
||||
$e->getMessage(),
|
||||
(is_object($db)) ? $db->errorCode() : 'n/a',
|
||||
(is_object($db)) ? implode(' ', $db->errorInfo()) : 'n/a');
|
||||
}
|
||||
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
[001] Expecting default value for 'PDO::MYSQL_ATTR_INIT_COMMAND' of ''/string, getAttribute() reports setting ''/boolean
|
||||
[023] Execting 'SET @a=1'/string got ''/boolean' for options 'PDO::MYSQL_ATTR_INIT_COMMAND'
|
||||
[024] SQLSTATE[42000] [1065] Query was empty
|
||||
[025] SQLSTATE[42S02] [1146] Table '%snonexistent' doesn't exist
|
||||
[026] Execting '1'/boolean got ''/boolean' for options 'PDO::MYSQL_ATTR_READ_DEFAULT_FILE'
|
||||
done!
|
75
ext/pdo_mysql/tests/pdo_mysql___construct_uri.phpt
Normal file
75
ext/pdo_mysql/tests/pdo_mysql___construct_uri.phpt
Normal file
|
@ -0,0 +1,75 @@
|
|||
--TEST--
|
||||
MySQL PDO->__construct() - URI
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
|
||||
try {
|
||||
|
||||
if ($tmp = MySQLPDOTest::getTempDir()) {
|
||||
|
||||
$file = $tmp . DIRECTORY_SEPARATOR . 'pdomuri.tst';
|
||||
$dsn = MySQLPDOTest::getDSN();
|
||||
$user = PDO_MYSQL_TEST_USER;
|
||||
$pass = PDO_MYSQL_TEST_PASS;
|
||||
$uri = sprintf('uri:file:%s', $file);
|
||||
|
||||
if ($fp = @fopen($file, 'w')) {
|
||||
// ok, great we can create a file with a DSN in it
|
||||
fwrite($fp, $dsn);
|
||||
fclose($fp);
|
||||
clearstatcache();
|
||||
assert(file_exists($file));
|
||||
try {
|
||||
$db = new PDO($uri, $user, $pass);
|
||||
} catch (PDOException $e) {
|
||||
printf("[002] URI=%s, DSN=%s, File=%s (%d bytes, '%s'), %s\n",
|
||||
$uri, $dsn,
|
||||
$file, filesize($file), file_get_contents($file),
|
||||
$e->getMessage());
|
||||
}
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
if ($fp = @fopen($file, 'w')) {
|
||||
fwrite($fp, sprintf('mysql:dbname=letshopeinvalid;%s%s',
|
||||
chr(0), $dsn));
|
||||
fclose($fp);
|
||||
clearstatcache();
|
||||
assert(file_exists($file));
|
||||
try {
|
||||
$db = new PDO($uri, $user, $pass);
|
||||
} catch (PDOException $e) {
|
||||
printf("[003] URI=%s, DSN=%s, File=%s (%d bytes, '%s'), chr(0) test, %s\n",
|
||||
$uri, $dsn,
|
||||
$file, filesize($file), file_get_contents($file),
|
||||
$e->getMessage());
|
||||
}
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* TODO: safe mode */
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s, [%s] %s\n",
|
||||
$e->getMessage(),
|
||||
(is_object($db)) ? $db->errorCode() : 'n/a',
|
||||
(is_object($db)) ? implode(' ', $db->errorInfo()) : 'n/a');
|
||||
}
|
||||
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
Warning: PDO::__construct(%s
|
||||
[002] URI=uri:file:%spdomuri.tst, DSN=mysql%sdbname=%s, File=%spdomuri.tst (%d bytes, 'mysql%sdbname=%s'), invalid data source URI
|
||||
|
||||
Warning: PDO::__construct(%s
|
||||
[003] URI=uri:file:%spdomuri.tst, DSN=mysql%sdbname=%s, File=%spdomuri.tst (%d bytes, 'mysql%sdbname=letshopeinvalid%s'), chr(0) test, invalid data source URI
|
||||
done!
|
93
ext/pdo_mysql/tests/pdo_mysql_attr_autocommit.phpt
Normal file
93
ext/pdo_mysql/tests/pdo_mysql_attr_autocommit.phpt
Normal file
|
@ -0,0 +1,93 @@
|
|||
--TEST--
|
||||
PDO::ATTR_AUTOCOMMIT
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
// autocommit should be on by default
|
||||
if (1 !== ($tmp = $db->getAttribute(PDO::ATTR_AUTOCOMMIT)))
|
||||
printf("[001] Expecting int/1 got %s\n", var_export($tmp, true));
|
||||
|
||||
// lets see if the server agrees to that
|
||||
$row = $db->query('SELECT @@autocommit AS _autocommit')->fetch(PDO::FETCH_ASSOC);
|
||||
if (!$row['_autocommit'])
|
||||
printf("[002] Server autocommit mode should be on, got '%s'\n", var_export($row['_autocommit']));
|
||||
|
||||
// on -> off
|
||||
if (!$db->setAttribute(PDO::ATTR_AUTOCOMMIT, 0))
|
||||
printf("[003] Cannot turn off autocommit\n");
|
||||
|
||||
$row = $db->query('SELECT @@autocommit AS _autocommit')->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row['_autocommit'])
|
||||
printf("[004] Server autocommit mode should be off, got '%s'\n", var_export($row['_autocommit']));
|
||||
|
||||
// PDO thinks autocommit is off, but its manually turned on...
|
||||
if (!$db->query('SET autocommit = 1'))
|
||||
printf("[005] Cannot turn on server autocommit mode, %s\n", var_export($db->errorInfo(), true));
|
||||
|
||||
if (0 !== ($tmp = $db->getAttribute(PDO::ATTR_AUTOCOMMIT)))
|
||||
printf("[006] Expecting int/0 got %s\n", var_export($tmp, true));
|
||||
|
||||
// off -> on
|
||||
if (!$db->query('SET autocommit = 0'))
|
||||
printf("[007] Cannot turn off server autocommit mode, %s\n", var_export($db->errorInfo(), true));
|
||||
|
||||
if (!$db->setAttribute(PDO::ATTR_AUTOCOMMIT, 1))
|
||||
printf("[008] Cannot turn on autocommit\n");
|
||||
|
||||
$row = $db->query('SELECT @@autocommit AS _autocommit')->fetch(PDO::FETCH_ASSOC);
|
||||
if (!$row['_autocommit'])
|
||||
printf("[009] Server autocommit mode should be on, got '%s'\n", var_export($row['_autocommit']));
|
||||
|
||||
if (1 !== ($tmp = $db->getAttribute(PDO::ATTR_AUTOCOMMIT)))
|
||||
printf("[010] Expecting int/1 got %s\n", var_export($tmp, true));
|
||||
|
||||
if (MySQLPDOTest::detect_transactional_mysql_engine($db)) {
|
||||
// nice, we have a transactional engine to play with
|
||||
|
||||
MySQLPDOTest::createTestTable($db, MySQLPDOTest::detect_transactional_mysql_engine($db));
|
||||
$row = $db->query('SELECT COUNT(*) AS _num FROM test')->fetch(PDO::FETCH_ASSOC);
|
||||
$num = $row['_num'];
|
||||
|
||||
$db->query('INSERT INTO test(id, label) VALUES (100, "z")');
|
||||
$num++;
|
||||
$row = $db->query('SELECT COUNT(*) AS _num FROM test')->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row['_num'] != $num)
|
||||
printf("[011] Insert has failed, test will fail\n");
|
||||
|
||||
// autocommit is on, no rollback possible
|
||||
$db->query('ROLLBACK');
|
||||
$row = $db->query('SELECT COUNT(*) AS _num FROM test')->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row['_num'] != $num)
|
||||
printf("[012] ROLLBACK should not have undone anything\n");
|
||||
|
||||
if (!$db->setAttribute(PDO::ATTR_AUTOCOMMIT, 0))
|
||||
printf("[013] Cannot turn off autocommit\n");
|
||||
|
||||
$db->query('DELETE FROM test WHERE id = 100');
|
||||
$db->query('ROLLBACK');
|
||||
$row = $db->query('SELECT COUNT(*) AS _num FROM test')->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row['_num'] != $num)
|
||||
printf("[014] ROLLBACK should have undone the DELETE\n");
|
||||
|
||||
$db->query('DELETE FROM test WHERE id = 100');
|
||||
$db->query('COMMIT');
|
||||
$num--;
|
||||
$row = $db->query('SELECT COUNT(*) AS _num FROM test')->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row['_num'] != $num)
|
||||
printf("[015] DELETE should have been committed\n");
|
||||
|
||||
}
|
||||
|
||||
$db->exec(sprintf('DROP TABLE IF EXISTS test'));
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
done!
|
219
ext/pdo_mysql/tests/pdo_mysql_attr_case.phpt
Normal file
219
ext/pdo_mysql/tests/pdo_mysql_attr_case.phpt
Normal file
|
@ -0,0 +1,219 @@
|
|||
--TEST--
|
||||
PDO::ATTR_CASE
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
$default = $db->getAttribute(PDO::ATTR_CASE);
|
||||
$known = array(
|
||||
PDO::CASE_LOWER => 'PDO::CASE_LOWER',
|
||||
PDO::CASE_UPPER => 'PDO::CASE_UPPER',
|
||||
PDO::CASE_NATURAL => 'PDO::CASE_NATURAL'
|
||||
);
|
||||
if (!isset($known[$default]))
|
||||
printf("[001] getAttribute(PDO::ATTR_CASE) returns unknown value '%s'\n",
|
||||
var_export($default, true));
|
||||
else
|
||||
var_dump($known[$default]);
|
||||
|
||||
// lets see what the default is...
|
||||
if (!is_object($stmt = $db->query('SELECT id, id AS "ID_UPPER", label FROM test ORDER BY id ASC LIMIT 2')))
|
||||
printf("[002] %s - %s\n",
|
||||
var_export($db->errorInfo(), true), var_export($db->errorCode(), true));
|
||||
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_BOTH));
|
||||
|
||||
if (true !== $db->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER))
|
||||
printf("[003] Cannot set PDO::ATTR_CASE = PDO::CASE_LOWER, %s - %s\n",
|
||||
var_export($db->errorInfo(), true), var_export($db->errorCode(), true));
|
||||
|
||||
if (($tmp = $db->getAttribute(PDO::ATTR_CASE)) !== PDO::CASE_LOWER)
|
||||
printf("[004] getAttribute(PDO::ATTR_CASE) returns wrong value '%s'\n",
|
||||
var_export($tmp, true));
|
||||
|
||||
if (true === $db->exec('ALTER TABLE test ADD MiXeD CHAR(1)'))
|
||||
printf("[005] Cannot add column %s - %s\n",
|
||||
var_export($db->errorInfo(), true), var_export($db->errorCode(), true));
|
||||
|
||||
if (false === $db->exec('ALTER TABLE test ADD MYUPPER CHAR(1)'))
|
||||
printf("[006] Cannot add column %s - %s\n",
|
||||
var_export($db->errorInfo(), true), var_export($db->errorCode(), true));
|
||||
|
||||
if (!is_object($stmt = $db->query('SELECT id, id AS "ID_UPPER", label, MiXeD, MYUPPER FROM test ORDER BY id ASC LIMIT 2')))
|
||||
printf("[007] %s - %s\n",
|
||||
var_export($db->errorInfo(), true), var_export($db->errorCode(), true));
|
||||
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_BOTH));
|
||||
|
||||
if (true !== $db->setAttribute(PDO::ATTR_CASE, PDO::CASE_UPPER))
|
||||
printf("[008] Cannot set PDO::ATTR_CASE = PDO::CASE_UPPER %s - %s\n",
|
||||
var_export($db->errorInfo(), true), var_export($db->errorCode(), true));
|
||||
|
||||
if (($tmp = $db->getAttribute(PDO::ATTR_CASE)) !== PDO::CASE_UPPER)
|
||||
printf("[009] getAttribute(PDO::ATTR_CASE) returns wrong value '%s'\n",
|
||||
var_export($tmp, true));
|
||||
|
||||
if (!is_object($stmt = $db->query('SELECT id, label, MiXeD, MYUPPER, MYUPPER AS "lower" FROM test ORDER BY id ASC LIMIT 1')))
|
||||
printf("[010] %s - %s\n",
|
||||
var_export($db->errorInfo(), true), var_export($db->errorCode(), true));
|
||||
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_BOTH));
|
||||
|
||||
if (true !== $db->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL))
|
||||
printf("[011] Cannot set PDO::ATTR_CASE = PDO::CASE_NATURAL %s - %s\n",
|
||||
var_export($db->errorInfo(), true), var_export($db->errorCode(), true));
|
||||
|
||||
if (($tmp = $db->getAttribute(PDO::ATTR_CASE)) !== PDO::CASE_NATURAL)
|
||||
printf("[012] getAttribute(PDO::ATTR_CASE) returns wrong value '%s'\n",
|
||||
var_export($tmp, true));
|
||||
|
||||
if (!is_object($stmt = $db->query('SELECT id, label, MiXeD, MYUPPER, id AS "ID" FROM test ORDER BY id ASC LIMIT 1')))
|
||||
printf("[013] %s - %s\n",
|
||||
var_export($db->errorInfo(), true), var_export($db->errorCode(), true));
|
||||
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_BOTH));
|
||||
|
||||
$db->exec(sprintf('DROP TABLE IF EXISTS test'));
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
string(15) "PDO::CASE_LOWER"
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(6) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
[0]=>
|
||||
string(1) "1"
|
||||
["id_upper"]=>
|
||||
string(1) "1"
|
||||
[1]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
[2]=>
|
||||
string(1) "a"
|
||||
}
|
||||
[1]=>
|
||||
array(6) {
|
||||
["id"]=>
|
||||
string(1) "2"
|
||||
[0]=>
|
||||
string(1) "2"
|
||||
["id_upper"]=>
|
||||
string(1) "2"
|
||||
[1]=>
|
||||
string(1) "2"
|
||||
["label"]=>
|
||||
string(1) "b"
|
||||
[2]=>
|
||||
string(1) "b"
|
||||
}
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(10) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
[0]=>
|
||||
string(1) "1"
|
||||
["id_upper"]=>
|
||||
string(1) "1"
|
||||
[1]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
[2]=>
|
||||
string(1) "a"
|
||||
["mixed"]=>
|
||||
NULL
|
||||
[3]=>
|
||||
NULL
|
||||
["myupper"]=>
|
||||
NULL
|
||||
[4]=>
|
||||
NULL
|
||||
}
|
||||
[1]=>
|
||||
array(10) {
|
||||
["id"]=>
|
||||
string(1) "2"
|
||||
[0]=>
|
||||
string(1) "2"
|
||||
["id_upper"]=>
|
||||
string(1) "2"
|
||||
[1]=>
|
||||
string(1) "2"
|
||||
["label"]=>
|
||||
string(1) "b"
|
||||
[2]=>
|
||||
string(1) "b"
|
||||
["mixed"]=>
|
||||
NULL
|
||||
[3]=>
|
||||
NULL
|
||||
["myupper"]=>
|
||||
NULL
|
||||
[4]=>
|
||||
NULL
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(10) {
|
||||
["ID"]=>
|
||||
string(1) "1"
|
||||
[0]=>
|
||||
string(1) "1"
|
||||
["LABEL"]=>
|
||||
string(1) "a"
|
||||
[1]=>
|
||||
string(1) "a"
|
||||
["MIXED"]=>
|
||||
NULL
|
||||
[2]=>
|
||||
NULL
|
||||
["MYUPPER"]=>
|
||||
NULL
|
||||
[3]=>
|
||||
NULL
|
||||
["LOWER"]=>
|
||||
NULL
|
||||
[4]=>
|
||||
NULL
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(10) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
[0]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
[1]=>
|
||||
string(1) "a"
|
||||
["MiXeD"]=>
|
||||
NULL
|
||||
[2]=>
|
||||
NULL
|
||||
["MYUPPER"]=>
|
||||
NULL
|
||||
[3]=>
|
||||
NULL
|
||||
["ID"]=>
|
||||
string(1) "1"
|
||||
[4]=>
|
||||
string(1) "1"
|
||||
}
|
||||
}
|
||||
done!
|
36
ext/pdo_mysql/tests/pdo_mysql_attr_client_version.phpt
Normal file
36
ext/pdo_mysql/tests/pdo_mysql_attr_client_version.phpt
Normal file
|
@ -0,0 +1,36 @@
|
|||
--TEST--
|
||||
PDO::ATTR_CLIENT_VERSION
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
assert(('' == $db->errorCode()) || ('00000' == $db->errorCode()));
|
||||
|
||||
$version = $db->getAttribute(PDO::ATTR_CLIENT_VERSION);
|
||||
|
||||
// No more constraints - mysqlnd and libmysql return different strings at least
|
||||
// with mysqli. Return type check is already performed in the generic test.
|
||||
// According to the manual we should get an int but as of today we do get a string...
|
||||
if ('' == $version)
|
||||
printf("[001] Client version must not be empty\n");
|
||||
|
||||
|
||||
// Read-only
|
||||
if (false !== $db->setAttribute(PDO::ATTR_CLIENT_VERSION, '1.0'))
|
||||
printf("[002] Wonderful, I can change the client version!\n");
|
||||
|
||||
$new_version = $db->getAttribute(PDO::ATTR_CLIENT_VERSION);
|
||||
if ($new_version !== $version)
|
||||
printf("[003] Did we change it from '%s' to '%s'?\n", $version, $new_version);
|
||||
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
done!
|
36
ext/pdo_mysql/tests/pdo_mysql_attr_connection_status.phpt
Normal file
36
ext/pdo_mysql/tests/pdo_mysql_attr_connection_status.phpt
Normal file
|
@ -0,0 +1,36 @@
|
|||
--TEST--
|
||||
PDO::ATTR_CONNECTION_STATUS
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
$status = $db->getAttribute(PDO::ATTR_CONNECTION_STATUS);
|
||||
if (ini_get('unicode.semantics')) {
|
||||
if (!is_unicode($status))
|
||||
printf("[001] Expecting unicode, got '%s'\n", var_export($status, true));
|
||||
} else {
|
||||
if (!is_string($status))
|
||||
printf("[002] Expecting string, got '%s'\n", var_export($status, true));
|
||||
}
|
||||
|
||||
if ('' == $status)
|
||||
printf("[003] Connection status string must not be empty\n");
|
||||
|
||||
if (false !== $db->setAttribute(PDO::ATTR_CONNECTION_STATUS, 'my own connection status'))
|
||||
printf("[004] Changing read only attribute\n");
|
||||
|
||||
$status2 = $db->getAttribute(PDO::ATTR_CONNECTION_STATUS);
|
||||
if ($status !== $status2)
|
||||
printf("[005] Connection status should not have changed\n");
|
||||
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
done!
|
30
ext/pdo_mysql/tests/pdo_mysql_attr_driver_name.phpt
Normal file
30
ext/pdo_mysql/tests/pdo_mysql_attr_driver_name.phpt
Normal file
|
@ -0,0 +1,30 @@
|
|||
--TEST--
|
||||
PDO::ATTR_DRIVER_NAME
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
assert(('' == $db->errorCode()) || ('00000' == $db->errorCode()));
|
||||
|
||||
$name = $db->getAttribute(PDO::ATTR_DRIVER_NAME);
|
||||
var_dump($name);
|
||||
|
||||
if (false !== $db->setAttribute(PDO::ATTR_DRIVER_NAME, 'mydriver'))
|
||||
printf("[001] Wonderful, I can create new PDO drivers!\n");
|
||||
|
||||
$new_name = $db->getAttribute(PDO::ATTR_DRIVER_NAME);
|
||||
if ($name != $new_name)
|
||||
printf("[002] Did we change it from '%s' to '%s'?\n", $name, $new_name);
|
||||
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
string(5) "mysql"
|
||||
done!
|
166
ext/pdo_mysql/tests/pdo_mysql_attr_errmode.phpt
Normal file
166
ext/pdo_mysql/tests/pdo_mysql_attr_errmode.phpt
Normal file
|
@ -0,0 +1,166 @@
|
|||
--TEST--
|
||||
PDO::ATTR_ERRMODE
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--INI--
|
||||
error_reporting=E_ALL
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
$valid = array(PDO::ERRMODE_SILENT, PDO::ERRMODE_WARNING, PDO::ERRMODE_EXCEPTION);
|
||||
do {
|
||||
$invalid = mt_rand(-1000, 1000);
|
||||
} while (in_array($invalid, $valid));
|
||||
|
||||
|
||||
$tmp = array();
|
||||
if (false != @$db->setAttribute(PDO::ATTR_ERRMODE, $tmp))
|
||||
printf("[001] Maybe PDO could indicate that this is not a proper way of setting the ERRMODE...\n");
|
||||
|
||||
$tmp = new stdClass();
|
||||
$ret = @$db->setAttribute(PDO::ATTR_ERRMODE, $tmp);
|
||||
if (false != $ret)
|
||||
printf("[002] Maybe PDO could indicate that this is not a proper way of setting the ERRMODE...%s\n",
|
||||
var_export($ret, true));
|
||||
|
||||
$ret = @$db->setAttribute(PDO::ATTR_ERRMODE, 'pdo');
|
||||
if (false != $ret)
|
||||
printf("[003] Maybe PDO could indicate that this is not a proper way of setting the ERRMODE...%s\n",
|
||||
var_export($ret, true));
|
||||
|
||||
if (false != @$db->setAttribute(PDO::ATTR_ERRMODE, $invalid))
|
||||
printf("[004] Invalid ERRMODE should be rejected\n");
|
||||
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
|
||||
// no message for any PDO call but...
|
||||
$db->query('THIS IS NOT VALID SQL');
|
||||
// ... still messages for everything else
|
||||
$code = $db->errorCode();
|
||||
$info = $db->errorInfo();
|
||||
|
||||
if ($code != '42000')
|
||||
printf("[005] Expecting SQL code 42000 got '%s'\n", $code);
|
||||
if ($code !== $info[0])
|
||||
printf("[006] Code and info should be identical, got errorCode() = %s, errorInfo()[0] = %s\n",
|
||||
$code, $info[0]);
|
||||
if ('' == $info[1])
|
||||
printf("[007] Driver specific error code not set\n");
|
||||
if ('' == $info[2])
|
||||
printf("[008] Driver specific error message not set\n");
|
||||
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
|
||||
$db->query('THIS IS NOT VALID SQL');
|
||||
|
||||
$code = $db->errorCode();
|
||||
$info = $db->errorInfo();
|
||||
|
||||
if ($code != '42000')
|
||||
printf("[009] Expecting SQL code 42000 got '%s'\n", $code);
|
||||
if ($code !== $info[0])
|
||||
printf("[010] Code and info should be identical, got errorCode() = %s, errorInfo()[0] = %s\n",
|
||||
$code, $info[0]);
|
||||
if ('' == $info[1])
|
||||
printf("[011] Driver specific error code not set\n");
|
||||
if ('' == $info[2])
|
||||
printf("[012] Driver specific error message not set\n");
|
||||
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
try {
|
||||
$line = __LINE__ + 1;
|
||||
$db->query('THIS IS NOT VALID SQL');
|
||||
} catch (PDOException $e) {
|
||||
|
||||
$code = $db->errorCode();
|
||||
$info = $db->errorInfo();
|
||||
|
||||
if ($code != '42000')
|
||||
printf("[013] Expecting SQL code 42000 got '%s'\n", $code);
|
||||
if ($code !== $info[0])
|
||||
printf("[014] Code and info should be identical, got errorCode() = %s, errorInfo()[0] = %s\n",
|
||||
$code, $info[0]);
|
||||
if ('' == $info[1])
|
||||
printf("[015] Driver specific error code not set\n");
|
||||
if ('' == $info[2])
|
||||
printf("[016] Driver specific error message not set\n");
|
||||
|
||||
if ($e->getCode() !== $code)
|
||||
printf("[017] Exception code '%s' differs from errorCode '%s'\n",
|
||||
$e->getCode(), $code);
|
||||
|
||||
$msg = $e->getMessage();
|
||||
foreach ($info as $k => $v) {
|
||||
if (false === stristr($msg, (string)$v)) {
|
||||
printf("[018] Cannot find all parts of the error info ('%s') in the exception message '%s'\n",
|
||||
$v, $msg);
|
||||
}
|
||||
}
|
||||
|
||||
if ($e->getLine() !== $line)
|
||||
printf("[019] Exception has been thrown in line %d, exception object reports line %d\n",
|
||||
$line, $e->getLine());
|
||||
|
||||
if ($e->getFile() !== __FILE__)
|
||||
printf("[020] Exception has been thrown in file '%s', exception object reports file '%s'\n",
|
||||
__FILE__, $e->getFile());
|
||||
|
||||
}
|
||||
|
||||
function my_handler($e) {
|
||||
global $db, $line;
|
||||
|
||||
$code = $db->errorCode();
|
||||
$info = $db->errorInfo();
|
||||
|
||||
if ($code != '42000')
|
||||
printf("[021] Expecting SQL code 42000 got '%s'\n", $code);
|
||||
if ($code !== $info[0])
|
||||
printf("[022] Code and info should be identical, got errorCode() = %s, errorInfo()[0] = %s\n",
|
||||
$code, $info[0]);
|
||||
if ('' == $info[1])
|
||||
printf("[023] Driver specific error code not set\n");
|
||||
if ('' == $info[2])
|
||||
printf("[024] Driver specific error message not set\n");
|
||||
|
||||
if ($e->getCode() !== $code)
|
||||
printf("[025] Exception code '%s' differs from errorCode '%s'\n",
|
||||
$e->getCode(), $code);
|
||||
|
||||
$msg = $e->getMessage();
|
||||
foreach ($info as $k => $v) {
|
||||
if (false === stristr($msg, (string)$v)) {
|
||||
printf("[026] Cannot find all parts of the error info ('%s') in the exception message '%s'\n",
|
||||
$v, $msg);
|
||||
}
|
||||
}
|
||||
|
||||
if ($e->getLine() !== $line)
|
||||
printf("[027] Exception has been thrown in line %d, exception object reports line %d\n",
|
||||
$line, $e->getLine());
|
||||
|
||||
if ($e->getFile() !== __FILE__)
|
||||
printf("[028] Exception has been thrown in file '%s', exception object reports file '%s'\n",
|
||||
__FILE__, $e->getFile());
|
||||
|
||||
if (get_class($e) != 'PDOException')
|
||||
printf("[029] Expecting PDO exception got exception of type '%s'\n", get_class($e));
|
||||
|
||||
print "\nend of execution";
|
||||
}
|
||||
set_exception_handler('my_handler');
|
||||
$line = __LINE__ + 1;
|
||||
$db->query('THIS IS NOT VALID SQL');
|
||||
|
||||
print "done!\n";
|
||||
--EXPECTF--
|
||||
[003] Maybe PDO could indicate that this is not a proper way of setting the ERRMODE...true
|
||||
|
||||
Warning: PDO::query(): SQLSTATE[42000]: Syntax error or access violation: %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 '%s' at line %d in %s on line %d
|
||||
|
||||
end of execution
|
41
ext/pdo_mysql/tests/pdo_mysql_attr_fetch_table_names.phpt
Normal file
41
ext/pdo_mysql/tests/pdo_mysql_attr_fetch_table_names.phpt
Normal file
|
@ -0,0 +1,41 @@
|
|||
--TEST--
|
||||
PDO::ATTR_FETCH_TABLE_NAMES
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
$db->setAttribute(PDO::ATTR_FETCH_TABLE_NAMES, 1);
|
||||
$stmt = $db->query('SELECT label FROM test LIMIT 1');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
$stmt->closeCursor();
|
||||
|
||||
$db->setAttribute(PDO::ATTR_FETCH_TABLE_NAMES, 0);
|
||||
$stmt = $db->query('SELECT label FROM test LIMIT 1');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
$stmt->closeCursor();
|
||||
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["test.label"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
}
|
||||
done!
|
51
ext/pdo_mysql/tests/pdo_mysql_attr_init_command.phpt
Normal file
51
ext/pdo_mysql/tests/pdo_mysql_attr_init_command.phpt
Normal file
|
@ -0,0 +1,51 @@
|
|||
--TEST--
|
||||
PDO::MYSQL_ATTR_INIT_COMMAND
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
if (MySQLPDOTest::isPDOMySQLnd())
|
||||
die("skip PDO::MYSQL_ATTR_MAX_INIT_COMMAND not supported with mysqlnd");
|
||||
?>
|
||||
--INI--
|
||||
error_reporting=E_ALL
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
|
||||
$dsn = MySQLPDOTest::getDSN();
|
||||
$user = PDO_MYSQL_TEST_USER;
|
||||
$pass = PDO_MYSQL_TEST_PASS;
|
||||
|
||||
$table = sprintf("test_%s", md5(mt_rand(0, PHP_INT_MAX)));
|
||||
$db = new PDO($dsn, $user, $pass);
|
||||
$db->exec(sprintf('DROP TABLE IF EXISTS %s', $table));
|
||||
|
||||
$create = sprintf('CREATE TABLE %s(id INT)', $table);
|
||||
var_dump($create);
|
||||
$db = new PDO($dsn, $user, $pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => $create));
|
||||
|
||||
var_dump($db->errorInfo());
|
||||
|
||||
$db->exec(sprintf('INSERT INTO %s(id) VALUES (1)', $table));
|
||||
$stmt = $db->query(sprintf('SELECT id FROM %s', $table));
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
$db->exec(sprintf('DROP TABLE IF EXISTS %s', $table));
|
||||
print "done!\n";
|
||||
--EXPECTF--
|
||||
string(58) "CREATE TABLE test_%s(id INT)"
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(5) "00000"
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
}
|
||||
}
|
||||
done!
|
70
ext/pdo_mysql/tests/pdo_mysql_attr_max_buffer_size.phpt
Normal file
70
ext/pdo_mysql/tests/pdo_mysql_attr_max_buffer_size.phpt
Normal file
|
@ -0,0 +1,70 @@
|
|||
--TEST--
|
||||
MySQL PDO->__construct(), PDO::MYSQL_ATTR_MAX_BUFFER_SIZE
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
if (MySQLPDOTest::isPDOMySQLnd())
|
||||
die("skip PDO::MYSQL_ATTR_MAX_BUFFER_SIZE not supported with mysqlnd");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
|
||||
function try_buffer_size($offset, $buffer_size) {
|
||||
|
||||
try {
|
||||
|
||||
$dsn = MySQLPDOTest::getDSN();
|
||||
$user = PDO_MYSQL_TEST_USER;
|
||||
$pass = PDO_MYSQL_TEST_PASS;
|
||||
|
||||
/* unsigned overflow possible ? */
|
||||
$db = new PDO($dsn, $user, $pass,
|
||||
array(
|
||||
PDO::MYSQL_ATTR_MAX_BUFFER_SIZE => $buffer_size,
|
||||
/* buffer is only relevant with native PS */
|
||||
PDO::MYSQL_ATTR_DIRECT_QUERY => 0,
|
||||
PDO::ATTR_EMULATE_PREPARES => 0,
|
||||
));
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$db->exec(sprintf('CREATE TABLE test(id INT, val LONGBLOB) ENGINE = %s', PDO_MYSQL_TEST_ENGINE));
|
||||
|
||||
// 10 * (10 * 1024) = 10 * (10 * 1k) = 100k
|
||||
$db->exec('INSERT INTO test(id, val) VALUES (1, REPEAT("01234567890", 10240))');
|
||||
|
||||
$stmt = $db->prepare('SELECT id, val FROM test');
|
||||
$stmt->execute();
|
||||
|
||||
$id = $val = NULL;
|
||||
$stmt->bindColumn(1, $id);
|
||||
$stmt->bindColumn(2, $val);
|
||||
while ($row = $stmt->fetch(PDO::FETCH_BOUND)) {
|
||||
printf("[%03d] id = %d, val = %s... (length: %d)\n",
|
||||
$offset, $id, substr($val, 0, 10), strlen($val));
|
||||
}
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[%03d] %s, [%s] %s\n",
|
||||
$offset,
|
||||
$e->getMessage(),
|
||||
(is_object($db)) ? $db->errorCode() : 'n/a',
|
||||
(is_object($db)) ? implode(' ', $db->errorInfo()) : 'n/a');
|
||||
}
|
||||
}
|
||||
|
||||
try_buffer_size(1, -1);
|
||||
try_buffer_size(2, 1000);
|
||||
try_buffer_size(3, NULL);
|
||||
try_buffer_size(4, 2000);
|
||||
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
[001] id = 1, val = 0123456789... (length: %d)
|
||||
[002] id = 1, val = 0123456789... (length: 1000)
|
||||
[003] id = 1, val = 0123456789... (length: %d)
|
||||
[004] id = 1, val = 0123456789... (length: 2000)
|
||||
done!
|
120
ext/pdo_mysql/tests/pdo_mysql_attr_oracle_nulls.phpt
Normal file
120
ext/pdo_mysql/tests/pdo_mysql_attr_oracle_nulls.phpt
Normal file
|
@ -0,0 +1,120 @@
|
|||
--TEST--
|
||||
PDO::ATTR_ORACLE_NULLS
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
$tmp = array();
|
||||
if (false !== @$db->setAttribute(PDO::ATTR_ORACLE_NULLS, $tmp))
|
||||
printf("[001] Maybe PDO could indicate that this is not a proper way of setting ATTR_ORACLE_NULLS...\n");
|
||||
|
||||
$tmp = new stdClass();
|
||||
if (false !== @$db->setAttribute(PDO::ATTR_ORACLE_NULLS, $tmp));
|
||||
printf("[002] Maybe PDO could indicate that this is not a proper way of setting ATTR_ORACLE_NULLS...\n");
|
||||
|
||||
if (false !== @$db->setAttribute(PDO::ATTR_ORACLE_NULLS, 'pdo'))
|
||||
printf("[003] Maybe PDO could indicate that this is not a proper way of setting ATTR_ORACLE_NULLS...\n");
|
||||
|
||||
$db->setAttribute(PDO::ATTR_ORACLE_NULLS, 1);
|
||||
$stmt = $db->query('SELECT NULL AS z, "" AS a, " " AS b, TRIM(" ") as c, " d" AS d, "' . chr(0) . ' e" AS e');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
$db->setAttribute(PDO::ATTR_ORACLE_NULLS, 0);
|
||||
$stmt = $db->query('SELECT NULL AS z, "" AS a, " " AS b, TRIM(" ") as c, " d" AS d, "' . chr(0) . ' e" AS e');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
$db->setAttribute(PDO::ATTR_ORACLE_NULLS, 1);
|
||||
$stmt = $db->query('SELECT VERSION() as _version');
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ((int)substr($row['_version'], 0, 1) >= 5)
|
||||
$have_procedures = true;
|
||||
else
|
||||
$have_procedures = false;
|
||||
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
|
||||
|
||||
if ($have_procedures && (false !== $db->exec('DROP PROCEDURE IF EXISTS p')) &&
|
||||
(false !== $db->exec('CREATE PROCEDURE p() BEGIN SELECT NULL as z, "" AS a, " " AS b, TRIM(" ") as c, " d" AS d, " e" AS e; END;'))) {
|
||||
// requires MySQL 5+
|
||||
$stmt = $db->prepare('CALL p()');
|
||||
$stmt->execute();
|
||||
$expected = array(
|
||||
array(
|
||||
"z" => NULL,
|
||||
"a" => NULL,
|
||||
"b" => " ",
|
||||
"c" => NULL,
|
||||
"d" => " d",
|
||||
"e" => " e",
|
||||
),
|
||||
);
|
||||
do {
|
||||
$tmp = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if ($tmp != $expected) {
|
||||
printf("[004] Expecting %s got %s\n",
|
||||
var_export($expected, true), var_export($tmp, true));
|
||||
}
|
||||
} while ($stmt->nextRowset());
|
||||
|
||||
$stmt->execute();
|
||||
do {
|
||||
$tmp = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if ($tmp != $expected) {
|
||||
printf("[005] Expecting %s got %s\n",
|
||||
var_export($expected, true), var_export($tmp, true));
|
||||
}
|
||||
} while ($stmt->nextRowset());
|
||||
|
||||
}
|
||||
|
||||
if ($have_procedures)
|
||||
@$db->exec('DROP PROCEDURE IF EXISTS p');
|
||||
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
[002] Maybe PDO could indicate that this is not a proper way of setting ATTR_ORACLE_NULLS...
|
||||
[003] Maybe PDO could indicate that this is not a proper way of setting ATTR_ORACLE_NULLS...
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(6) {
|
||||
["z"]=>
|
||||
NULL
|
||||
["a"]=>
|
||||
NULL
|
||||
["b"]=>
|
||||
string(1) " "
|
||||
["c"]=>
|
||||
NULL
|
||||
["d"]=>
|
||||
string(2) " d"
|
||||
["e"]=>
|
||||
string(3) "%se"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(6) {
|
||||
["z"]=>
|
||||
NULL
|
||||
["a"]=>
|
||||
string(0) ""
|
||||
["b"]=>
|
||||
string(1) " "
|
||||
["c"]=>
|
||||
string(0) ""
|
||||
["d"]=>
|
||||
string(2) " d"
|
||||
["e"]=>
|
||||
string(3) "%se"
|
||||
}
|
||||
}
|
||||
done!
|
21
ext/pdo_mysql/tests/pdo_mysql_attr_prefetch.phpt
Normal file
21
ext/pdo_mysql/tests/pdo_mysql_attr_prefetch.phpt
Normal file
|
@ -0,0 +1,21 @@
|
|||
--TEST--
|
||||
PDO::ATTR_PREFETCH
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
var_dump($db->getAttribute(PDO::ATTR_PREFETCH));
|
||||
var_dump($db->setAttribute(PDO::ATTR_PREFETCH, true));
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
Warning: PDO::getAttribute(): SQLSTATE[IM001]: Driver does not support this function: driver does not support that attribute in %s on line %d
|
||||
bool(false)
|
||||
bool(false)
|
||||
done!
|
48
ext/pdo_mysql/tests/pdo_mysql_attr_server_info.phpt
Normal file
48
ext/pdo_mysql/tests/pdo_mysql_attr_server_info.phpt
Normal file
|
@ -0,0 +1,48 @@
|
|||
--TEST--
|
||||
PDO::ATTR_SERVER_INFO
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
assert(('' == $db->errorCode()) || ('00000' == $db->errorCode()));
|
||||
|
||||
$info = $db->getAttribute(PDO::ATTR_SERVER_INFO);
|
||||
if ('' == $info)
|
||||
printf("[001] Server info must not be empty\n");
|
||||
|
||||
// Read-only?
|
||||
if (false !== $db->setAttribute(PDO::ATTR_SERVER_INFO, 'new uptime: 0s'))
|
||||
printf("[002] Wonderful, I can change the client version!\n");
|
||||
|
||||
$new_info = $db->getAttribute(PDO::ATTR_SERVER_INFO);
|
||||
if ($new_info !== $info)
|
||||
printf("[003] Did we change it from '%s' to '%s'?\n", $info, $info);
|
||||
|
||||
// lets hope we always run this in the same second as we did run the server info request...
|
||||
if (!$stmt = $db->query('SHOW STATUS LIKE "%uptime%"'))
|
||||
printf("[004] Cannot run SHOW STATUS, [%s]\n", $db->errorCode());
|
||||
else {
|
||||
if (!$row = $stmt->fetch(PDO::FETCH_NUM))
|
||||
printf("[005] Unable to fetch uptime, [%s]\n", $db->errorCode());
|
||||
else
|
||||
$uptime = $row[1];
|
||||
$stmt->closeCursor();
|
||||
}
|
||||
|
||||
if (!preg_match('/Uptime/i', $info))
|
||||
printf("[006] Can't find uptime in server info '%s'\n", $info);
|
||||
|
||||
if (isset($uptime) && !preg_match(sprintf('/Uptime: %d/i', $uptime), $info))
|
||||
printf("[007] SHOW STATUS and server info have reported a different uptime, please check. Server info: '%s', SHOW STATUS: '%s'\n", $info, $uptime);
|
||||
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
done!
|
64
ext/pdo_mysql/tests/pdo_mysql_attr_server_version.phpt
Normal file
64
ext/pdo_mysql/tests/pdo_mysql_attr_server_version.phpt
Normal file
|
@ -0,0 +1,64 @@
|
|||
--TEST--
|
||||
PDO::ATTR_SERVER_VERSION
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
assert(('' == $db->errorCode()) || ('00000' == $db->errorCode()));
|
||||
|
||||
$version = $db->getAttribute(PDO::ATTR_SERVER_VERSION);
|
||||
if ('' == $version)
|
||||
printf("[001] Server version must not be empty\n");
|
||||
|
||||
// Ideally the server version would be an integer - as documented but BC break!
|
||||
// If its a version string it should be of the format \d+\.\d+\.\d+.*
|
||||
|
||||
if (is_string($version)) {
|
||||
// Its not an int like documented but a string - maybe for BC reasons...
|
||||
if (!preg_match('/(\d+)\.(\d+)\.(\d+)(.*)/', $version, $matches))
|
||||
printf("[002] Client version string seems wrong, got '%s'\n", $version);
|
||||
else {
|
||||
// Difficult to define any meaningful constraints
|
||||
// A possible better check would be calling mysqli_get_server_version() and
|
||||
// comparing what we get. However, mysqli_get_server_version() needs a mysqli handle
|
||||
// for which in turn one needs to parse the PDO test environment variables
|
||||
// for connection parameter...
|
||||
if ($matches[1] < 3)
|
||||
printf("[003] Strange major version: '%s'. Should be more than 3\n", $matches[1]);
|
||||
if ($matches[2] < 0)
|
||||
printf("[004] Minor version should be at least 0, got '%s'\n", $matches[2]);
|
||||
if ($matches[3] < 0)
|
||||
printf("[005] Sub version should be at least 0, got '%s'\n", $matches[2]);
|
||||
}
|
||||
} else if (is_int($version)) {
|
||||
// Lets accept also int if it follows the rules from the original MYSQL C API
|
||||
$major = floor($version / 10000);
|
||||
$minor = floor(($version - ($main * 10000)) / 100);
|
||||
$sub = $version - ($main * 10000) - ($minor * 100);
|
||||
if ($major < 3)
|
||||
printf("[006] Strange major version: '%s'. Should be more than 3\n", $major);
|
||||
if ($minor < 0)
|
||||
printf("[007] Minor version should be at least 0, got '%s'\n", $minor);
|
||||
if ($sub < 0)
|
||||
printf("[008] Sub version should be at least 0, got '%s'\n", $sub);
|
||||
}
|
||||
|
||||
// Read-only?
|
||||
if (false !== $db->setAttribute(PDO::ATTR_CLIENT_VERSION, '1.0'))
|
||||
printf("[009] Wonderful, I can change the client version!\n");
|
||||
|
||||
$new_version = $db->getAttribute(PDO::ATTR_SERVER_VERSION);
|
||||
if ($new_version !== $version)
|
||||
printf("[010] Did we change it from '%s' to '%s'?\n", $version, $new_version);
|
||||
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
done!
|
154
ext/pdo_mysql/tests/pdo_mysql_attr_statement_class.phpt
Normal file
154
ext/pdo_mysql/tests/pdo_mysql_attr_statement_class.phpt
Normal file
|
@ -0,0 +1,154 @@
|
|||
--TEST--
|
||||
PDO::ATTR_STATEMENT_CLASS
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
$default = $db->getAttribute(PDO::ATTR_STATEMENT_CLASS);
|
||||
var_dump($default);
|
||||
|
||||
if (false !== ($tmp = @$db->setAttribute(PDO::ATTR_STATEMENT_CLASS)))
|
||||
printf("[001] Expecting boolean/false got %s\n", var_export($tmp, true));
|
||||
|
||||
if (false !== ($tmp = @$db->setAttribute(PDO::ATTR_STATEMENT_CLASS, 'foo')))
|
||||
printf("[002] Expecting boolean/false got %s\n", var_export($tmp, true));
|
||||
|
||||
if (false !== ($tmp = @$db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('classname'))))
|
||||
printf("[003] Expecting boolean/false got %s\n", var_export($tmp, true));
|
||||
|
||||
// unknown class
|
||||
if (false !== ($tmp = $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('classname', array()))))
|
||||
printf("[004] Expecting boolean/false got %s\n", var_export($tmp, true));
|
||||
|
||||
// class not derived from PDOStatement
|
||||
class myclass {
|
||||
function __construct() {
|
||||
printf("myclass\n");
|
||||
}
|
||||
}
|
||||
if (false !== ($tmp = $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('myclass', array()))))
|
||||
printf("[005] Expecting boolean/false got %s\n", var_export($tmp, true));
|
||||
|
||||
// public constructor not allowed
|
||||
class mystatement extends PDOStatement {
|
||||
public function __construct() {
|
||||
printf("mystatement\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (false !== ($tmp = $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('mystatement', array()))))
|
||||
printf("[006] Expecting boolean/false got %s\n", var_export($tmp, true));
|
||||
|
||||
// ... but a public destructor is allowed
|
||||
class mystatement2 extends PDOStatement {
|
||||
public function __destruct() {
|
||||
printf("mystatement\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (true !== ($tmp = $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('mystatement2', array()))))
|
||||
printf("[007] Expecting boolean/true got %s\n", var_export($tmp, true));
|
||||
|
||||
// private constructor
|
||||
class mystatement3 extends PDOStatement {
|
||||
private function __construct($msg) {
|
||||
printf("mystatement3\n");
|
||||
var_dump($msg);
|
||||
}
|
||||
}
|
||||
if (true !== ($tmp = $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('mystatement3', array('param1')))))
|
||||
printf("[008] Expecting boolean/true got %s\n", var_export($tmp, true));
|
||||
|
||||
// private constructor
|
||||
class mystatement4 extends PDOStatement {
|
||||
private function __construct($msg) {
|
||||
printf("%s\n", get_class($this));
|
||||
var_dump($msg);
|
||||
}
|
||||
}
|
||||
if (true !== ($tmp = $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('mystatement4', array('param1')))))
|
||||
printf("[008] Expecting boolean/true got %s\n", var_export($tmp, true));
|
||||
|
||||
var_dump($db->getAttribute(PDO::ATTR_STATEMENT_CLASS));
|
||||
$stmt = $db->query('SELECT id, label FROM test ORDER BY id ASC LIMIT 2');
|
||||
|
||||
class mystatement5 extends mystatement4 {
|
||||
public function fetchAll($fetch_style = 1, $column_index = 1, $ctor_args = array()) {
|
||||
return "no data :)";
|
||||
}
|
||||
}
|
||||
|
||||
if (true !== ($tmp = $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('mystatement5', array('mystatement5')))))
|
||||
printf("[009] Expecting boolean/true got %s\n", var_export($tmp, true));
|
||||
$stmt = $db->query('SELECT id, label FROM test ORDER BY id ASC LIMIT 2');
|
||||
var_dump($stmt->fetchAll());
|
||||
|
||||
if (true !== ($tmp = $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('PDOStatement'))))
|
||||
printf("[010] Expecting boolean/true got %s\n", var_export($tmp, true));
|
||||
|
||||
$stmt = $db->query('SELECT id, label FROM test ORDER BY id ASC LIMIT 1');
|
||||
var_dump($stmt->fetchAll());
|
||||
|
||||
// Yes, this is a fatal error and I want it to fail.
|
||||
abstract class mystatement6 extends mystatement5 {
|
||||
}
|
||||
if (true !== ($tmp = $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('mystatement6', array('mystatement6')))))
|
||||
printf("[011] Expecting boolean/true got %s\n", var_export($tmp, true));
|
||||
$stmt = $db->query('SELECT id, label FROM test ORDER BY id ASC LIMIT 1');
|
||||
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(12) "PDOStatement"
|
||||
}
|
||||
|
||||
Warning: PDO::setAttribute(): SQLSTATE[HY000]: General error: PDO::ATTR_STATEMENT_CLASS requires format array(classname, array(ctor_args)); the classname must be a string specifying an existing class in %s on line %d
|
||||
|
||||
Warning: PDO::setAttribute(): SQLSTATE[HY000]: General error in %s on line %d
|
||||
|
||||
Warning: PDO::setAttribute(): SQLSTATE[HY000]: General error: user-supplied statement class must be derived from PDOStatement in %s on line %d
|
||||
|
||||
Warning: PDO::setAttribute(): SQLSTATE[HY000]: General error in %s on line %d
|
||||
|
||||
Warning: PDO::setAttribute(): SQLSTATE[HY000]: General error: user-supplied statement class cannot have a public constructor in %s on line %d
|
||||
|
||||
Warning: PDO::setAttribute(): SQLSTATE[HY000]: General error in %s on line %d
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(12) "mystatement4"
|
||||
[1]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(6) "param1"
|
||||
}
|
||||
}
|
||||
mystatement4
|
||||
string(6) "param1"
|
||||
mystatement5
|
||||
string(12) "mystatement5"
|
||||
string(10) "no data :)"
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(4) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
[0]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
[1]=>
|
||||
string(1) "a"
|
||||
}
|
||||
}
|
||||
|
||||
Fatal error: Cannot instantiate abstract class mystatement6 in %s on line %d
|
201
ext/pdo_mysql/tests/pdo_mysql_begintransaction.phpt
Normal file
201
ext/pdo_mysql/tests/pdo_mysql_begintransaction.phpt
Normal file
|
@ -0,0 +1,201 @@
|
|||
--TEST--
|
||||
PDO->beginTransaction()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
if (false == MySQLPDOTest::detect_transactional_mysql_engine($db))
|
||||
die("skip Transactional engine not found");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db, MySQLPDOTest::detect_transactional_mysql_engine($db));
|
||||
|
||||
if (1 !== $db->getAttribute(PDO::ATTR_AUTOCOMMIT))
|
||||
printf("[001] Autocommit should be on by default\n");
|
||||
|
||||
if (false == $db->beginTransaction())
|
||||
printf("[002] Cannot start a transaction, [%s] [%s]\n",
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
if (1 !== $db->getAttribute(PDO::ATTR_AUTOCOMMIT))
|
||||
printf("[003] Autocommit should be on by default, beginTransaction() shall not impact it\n");
|
||||
|
||||
if (0 == $db->exec('DELETE FROM test'))
|
||||
printf("[004] No rows deleted, can't be true.\n");
|
||||
|
||||
/* This is the PDO way to close a connection */
|
||||
$db = null;
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
/* Autocommit was off - by definition. Commit was not issued. DELETE should have been rolled back. */
|
||||
if (!($stmt = $db->query('SELECT id, label FROM test ORDER BY id ASC')))
|
||||
printf("[005] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
var_dump($row);
|
||||
|
||||
if (!$db->beginTransaction())
|
||||
printf("[006] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
if (1 !== $db->exec(sprintf('DELETE FROM test WHERE id = %d', $row['id'])))
|
||||
printf("[007] DELETE should have indicated 1 deleted row, [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
if (!$db->commit())
|
||||
printf("[008] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
if (1 !== $db->getAttribute(PDO::ATTR_AUTOCOMMIT))
|
||||
printf("[009] Autocommit should be on after commit()\n");
|
||||
|
||||
if (!($stmt = $db->query(sprintf('SELECT id, label FROM test WHERE id = %d', $row['id']))))
|
||||
printf("[010] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
var_dump($stmt->fetch(PDO::FETCH_ASSOC));
|
||||
|
||||
if (!$db->beginTransaction())
|
||||
printf("[011] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
$db->exec(sprintf('INSERT INTO test(id, label) VALUES (%d, "z")', $row['id']));
|
||||
|
||||
if (!($stmt = $db->query(sprintf('SELECT id, label FROM test WHERE id = %d', $row['id']))))
|
||||
printf("[012] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
$new_row1 = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
var_dump($new_row1);
|
||||
|
||||
if (!$db->commit())
|
||||
printf("[013] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
if (!($stmt = $db->query(sprintf('SELECT id, label FROM test WHERE id = %d', $row['id']))))
|
||||
printf("[014] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
$new_row2 = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($new_row1 != $new_row2) {
|
||||
printf("[015] Results must not differ!\n");
|
||||
var_dump($new_row1);
|
||||
var_dump($new_row2);
|
||||
}
|
||||
|
||||
if (!$db->beginTransaction())
|
||||
printf("[016] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
if (1 !== $db->exec(sprintf('DELETE FROM test WHERE id = %d', $row['id'])))
|
||||
printf("[017] DELETE should have indicated 1 deleted row, [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
if (!$db->rollback())
|
||||
printf("[018] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
if (1 !== $db->getAttribute(PDO::ATTR_AUTOCOMMIT))
|
||||
printf("[019] Autocommit should be on after rollback\n");
|
||||
|
||||
if (!($stmt = $db->query(sprintf('SELECT id, label FROM test WHERE id = %d', $row['id']))))
|
||||
printf("[020] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
$new_row2 = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($new_row1 != $new_row2) {
|
||||
printf("[021] Results must not differ!\n");
|
||||
var_dump($new_row1);
|
||||
var_dump($new_row2);
|
||||
}
|
||||
|
||||
// now, lets check the server variables
|
||||
if (!($stmt = $db->query('SELECT @@autocommit as auto_commit')))
|
||||
printf("[022] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
$tmp = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($tmp['auto_commit'] != 1)
|
||||
printf("[023] MySQL Server should indicate autocommit mode, expecting 1, got '%s', [%d] %s\n",
|
||||
$tmp['auto_commit'], $stmt->errorCode(), $stmt->errorInfo());
|
||||
|
||||
if (!$db->beginTransaction())
|
||||
printf("[024] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
if (!($stmt = $db->query('SELECT @@autocommit as auto_commit')))
|
||||
printf("[025] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
$tmp = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($tmp['auto_commit'] != 0)
|
||||
printf("[026] Autocommit mode of the MySQL Server should be off, got '%s', [%d] %s\n",
|
||||
$tmp['auto_commit'], $stmt->errorCode(), implode(' ', $stmt->errorInfo()));
|
||||
|
||||
$db->commit();
|
||||
// Now we should be back to autocommit - we've issues a commit
|
||||
if ($tmp['auto_commit'] != 1)
|
||||
printf("[027] MySQL Server should indicate autocommit mode, expecting 1, got '%s', [%d] %s\n",
|
||||
$tmp['auto_commit'], $stmt->errorCode(), $stmt->errorInfo());
|
||||
|
||||
// Turn off autocommit using a server variable
|
||||
$db->exec('SET @@autocommit = 0');
|
||||
if (1 === $db->getAttribute(PDO::ATTR_AUTOCOMMIT))
|
||||
printf("[028] I'm confused, how can autocommit be on? Didn't I say I want to manually control transactions?\n");
|
||||
|
||||
if (!$db->beginTransaction())
|
||||
printf("[029] Cannot start a transaction, [%d] %s\n",
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
try {
|
||||
if (false !== $db->beginTransaction()) {
|
||||
printf("[030] No false and no exception - that's wrong.\n");
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
assert($e->getMessage() != '');
|
||||
}
|
||||
|
||||
// TODO: What about an engine that does not support transactions?
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db, 'MyISAM');
|
||||
|
||||
if (false == $db->beginTransaction())
|
||||
printf("[031] Cannot start a transaction, [%s] [%s]\n",
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
if (1 !== $db->getAttribute(PDO::ATTR_AUTOCOMMIT))
|
||||
printf("[032] Autocommit should be on my default, beginTransaction() should not change that\n");
|
||||
|
||||
if (0 == $db->exec('DELETE FROM test'))
|
||||
printf("[033] No rows deleted, can't be true.\n");
|
||||
|
||||
if (!$db->commit())
|
||||
printf("[034] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
if (false == $db->beginTransaction())
|
||||
printf("[035] Cannot start a transaction, [%s] [%s]\n",
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
if (0 == $db->exec('INSERT INTO test(id, label) VALUES (1, "a")'))
|
||||
printf("[036] Cannot insert data, [%s] [%s]\n",
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
// Should cause a Server warning but no error
|
||||
if (!$db->rollback())
|
||||
printf("[037] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
var_dump($db->errorCode());
|
||||
|
||||
if (1 != $db->exec('DELETE FROM test'))
|
||||
printf("[038] No rows deleted, can't be true.\n");
|
||||
|
||||
$db->exec(sprintf('DROP TABLE IF EXISTS test'));
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
bool(false)
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(1) "z"
|
||||
}
|
||||
[026] Autocommit mode of the MySQL Server should be off, got '1', [0] 00000
|
||||
[028] I'm confused, how can autocommit be on? Didn't I say I want to manually control transactions?
|
||||
string(5) "00000"
|
||||
done!
|
59
ext/pdo_mysql/tests/pdo_mysql_bit.phpt
Normal file
59
ext/pdo_mysql/tests/pdo_mysql_bit.phpt
Normal file
|
@ -0,0 +1,59 @@
|
|||
--TEST--
|
||||
MySQL PDO->exec(), BIT columns - remove after fix!
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
if (MySQLPDOTest::isPDOMySQLnd())
|
||||
die("skip Known bug - mysqlnd handles BIT incorrectly!");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
/* TODO: remove this test after fix and enable the BIT test in pdo_mysql_types.phpt again */
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
|
||||
function test_type(&$db, $offset, $sql_type, $value, $ret_value = NULL, $pattern = NULL) {
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$sql = sprintf('CREATE TABLE test(id INT, label %s) ENGINE=%s', $sql_type, MySQLPDOTest::getTableEngine());
|
||||
@$db->exec($sql);
|
||||
if ($db->errorCode() != 0) {
|
||||
// not all MySQL Server versions and/or engines might support the type
|
||||
return true;
|
||||
}
|
||||
|
||||
$stmt = $db->prepare('INSERT INTO test(id, label) VALUES (?, ?)');
|
||||
$stmt->bindValue(1, $offset);
|
||||
$stmt->bindValue(2, $value);
|
||||
if (!$stmt->execute()) {
|
||||
printf("[%03d + 1] INSERT failed, %s\n", $offset, var_export($stmt->errorInfo(), true));
|
||||
return false;
|
||||
}
|
||||
$stmt = $db->query('SELECT id, label FROM test');
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
var_dump($row);
|
||||
var_dump($value);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
|
||||
|
||||
test_type($db, 20, 'BIT(8)', 1);
|
||||
|
||||
echo "done!\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(2) "20"
|
||||
["label"]=>
|
||||
string(1) "1"
|
||||
}
|
||||
int(1)
|
||||
done!
|
78
ext/pdo_mysql/tests/pdo_mysql_class_constants.phpt
Normal file
78
ext/pdo_mysql/tests/pdo_mysql_class_constants.phpt
Normal file
|
@ -0,0 +1,78 @@
|
|||
--TEST--
|
||||
PDO MySQL specific class constants
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
|
||||
$expected = array(
|
||||
'MYSQL_ATTR_USE_BUFFERED_QUERY' => true,
|
||||
'MYSQL_ATTR_LOCAL_INFILE' => true,
|
||||
'MYSQL_ATTR_DIRECT_QUERY' => true,
|
||||
);
|
||||
|
||||
if (!MySQLPDOTest::isPDOMySQLnd()) {
|
||||
$expected['MYSQL_ATTR_MAX_BUFFER_SIZE'] = true;
|
||||
$expected['MYSQL_ATTR_INIT_COMMAND'] = true;
|
||||
$expected['MYSQL_ATTR_READ_DEFAULT_FILE'] = true;
|
||||
$expected['MYSQL_ATTR_READ_DEFAULT_GROUP'] = true;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
TODO
|
||||
|
||||
MYSQLI_OPT_CONNECT_TIMEOUT != PDO::ATTR_TIMEOUT (integer)
|
||||
Sets the timeout value in seconds for communications with the database.
|
||||
^ Potential BUG, PDO::ATTR_TIMEOUT is used in pdo_mysql_handle_factory
|
||||
|
||||
MYSQLI_SET_CHARSET_NAME -> DSN/charset=<charset_name>
|
||||
^ Undocumented and pitfall for ext/mysqli users
|
||||
|
||||
Assorted mysqlnd settings missing
|
||||
*/
|
||||
$ref = new ReflectionClass('PDO');
|
||||
$constants = $ref->getConstants();
|
||||
$values = array();
|
||||
|
||||
foreach ($constants as $name => $value)
|
||||
if (substr($name, 0, 11) == 'MYSQL_ATTR_') {
|
||||
if (!isset($values[$value]))
|
||||
$values[$value] = array($name);
|
||||
else
|
||||
$values[$value][] = $name;
|
||||
|
||||
if (isset($expected[$name])) {
|
||||
unset($expected[$name]);
|
||||
unset($constants[$name]);
|
||||
}
|
||||
|
||||
} else {
|
||||
unset($constants[$name]);
|
||||
}
|
||||
|
||||
if (!empty($constants)) {
|
||||
printf("[001] Dumping list of unexpected constants\n");
|
||||
var_dump($constants);
|
||||
}
|
||||
|
||||
if (!empty($expected)) {
|
||||
printf("[002] Dumping list of missing constants\n");
|
||||
var_dump($expected);
|
||||
}
|
||||
|
||||
if (!empty($values)) {
|
||||
foreach ($values as $value => $constants) {
|
||||
if (count($constants) > 1) {
|
||||
printf("[003] Several constants share the same value '%s'\n", $value);
|
||||
var_dump($constants);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print "done!";
|
||||
--EXPECT--
|
||||
done!
|
84
ext/pdo_mysql/tests/pdo_mysql_commit.phpt
Normal file
84
ext/pdo_mysql/tests/pdo_mysql_commit.phpt
Normal file
|
@ -0,0 +1,84 @@
|
|||
--TEST--
|
||||
MySQL PDO->commit()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
if (false == MySQLPDOTest::detect_transactional_mysql_engine($db))
|
||||
die("skip Transactional engine not found");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db, MySQLPDOTest::detect_transactional_mysql_engine($db));
|
||||
|
||||
try {
|
||||
if (true !== ($tmp = $db->beginTransaction())) {
|
||||
printf("[001] Expecting true, got %s/%s\n", gettype($tmp), $tmp);
|
||||
}
|
||||
|
||||
// DDL will issue an implicit commit
|
||||
$db->exec(sprintf('DROP TABLE IF EXISTS test_commit'));
|
||||
$db->exec(sprintf('CREATE TABLE test_commit(id INT) ENGINE=%s', MySQLPDOTest::detect_transactional_mysql_engine($db)));
|
||||
if (true !== ($tmp = $db->commit())) {
|
||||
printf("[002] No commit allowed? [%s] %s\n",
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
// pdo_transaction_transitions should check this as well...
|
||||
// ... just to be sure the most basic stuff really works we check it again...
|
||||
if (1 !== ($tmp = $db->getAttribute(PDO::ATTR_AUTOCOMMIT)))
|
||||
printf("[003] According to the manual we should be back to autocommit mode, got %s/%s\n",
|
||||
gettype($tmp), var_export($tmp, true));
|
||||
|
||||
if (true !== ($tmp = $db->beginTransaction()))
|
||||
printf("[004] Expecting true, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
$db->exec('INSERT INTO test(id, label) VALUES (100, "z")');
|
||||
|
||||
if (true !== ($tmp = $db->commit()))
|
||||
printf("[005] No commit allowed? [%s] %s\n",
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
// a weak test without unicode etc. - lets leave that to dedicated tests
|
||||
$stmt = $db->query('SELECT id, label FROM test WHERE id = 100');
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (!isset($rows[0]['label']) || ($rows[0]['label'] != 'z')) {
|
||||
printf("[006] Record data is strange, dumping rows\n");
|
||||
var_dump($rows);
|
||||
}
|
||||
|
||||
// Ok, lets check MyISAM resp. any other non-transactional engine
|
||||
// pdo_mysql_begin_transaction has more on this, quick check only
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db, 'MyISAM');
|
||||
|
||||
if (true !== ($tmp = $db->beginTransaction()))
|
||||
printf("[007] Expecting true, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
$db->exec('INSERT INTO test(id, label) VALUES (100, "z")');
|
||||
if (true !== ($tmp = $db->commit()))
|
||||
printf("[008] No commit allowed? [%s] %s\n",
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
// a weak test without unicode etc. - lets leave that to dedicated tests
|
||||
$stmt = $db->query('SELECT id, label FROM test WHERE id = 100');
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (!isset($rows[0]['label']) || ($rows[0]['label'] != 'z')) {
|
||||
printf("[009] Record data is strange, dumping rows\n");
|
||||
var_dump($rows);
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[002] %s, [%s] %s\n",
|
||||
$e->getMessage(),
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec(sprintf('DROP TABLE IF EXISTS test_commit'));
|
||||
print "done!";
|
||||
--EXPECT--
|
||||
done!
|
81
ext/pdo_mysql/tests/pdo_mysql_errorcode.phpt
Normal file
81
ext/pdo_mysql/tests/pdo_mysql_errorcode.phpt
Normal file
|
@ -0,0 +1,81 @@
|
|||
--TEST--
|
||||
MySQL PDO->errorCode()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
function check_error($offset, &$obj, $expected = '00000') {
|
||||
|
||||
$code = $obj->errorCode();
|
||||
if (($code != $expected) && (($expected != '00000') && ($code != ''))) {
|
||||
printf("[%03d] Expecting error code '%s' got code '%s'\n",
|
||||
$offset, $expected, $code);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
/*
|
||||
If you create a PDOStatement object through PDO->prepare()
|
||||
or PDO->query() and invoke an error on the statement handle,
|
||||
PDO->errorCode() will not reflect that error. You must call
|
||||
PDOStatement->errorCode() to return the error code for an
|
||||
operation performed on a particular statement handle.
|
||||
*/
|
||||
$code = $db->errorCode();
|
||||
check_error(2, $db);
|
||||
|
||||
$stmt = $db->query('SELECT id, label FROM test');
|
||||
$stmt2 = &$stmt;
|
||||
check_error(3, $db);
|
||||
check_error(4, $stmt);
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
@$stmt->execute();
|
||||
check_error(4, $db);
|
||||
check_error(5, $stmt, '42S02');
|
||||
check_error(6, $stmt2, '42S02');
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS unknown');
|
||||
@$stmt = $db->query('SELECT id, label FROM unknown');
|
||||
check_error(7, $db, '42S02');
|
||||
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
$stmt = $db->query('SELECT id, label FROM test');
|
||||
check_error(8, $db);
|
||||
check_error(9, $stmt);
|
||||
|
||||
$db2 = &$db;
|
||||
@$db->query('SELECT id, label FROM unknown');
|
||||
check_error(10, $db, '42S02');
|
||||
check_error(11, $db2, '42S02');
|
||||
check_error(12, $stmt);
|
||||
check_error(13, $stmt2);
|
||||
|
||||
// lets hope this is an invalid attribute code
|
||||
$invalid_attr = -1 * PHP_INT_MAX + 3;
|
||||
$tmp = @$db->getAttribute($invalid_attr);
|
||||
check_error(14, $db, 'IM001');
|
||||
check_error(15, $db2, 'IM001');
|
||||
check_error(16, $stmt);
|
||||
check_error(17, $stmt2);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
done!
|
173
ext/pdo_mysql/tests/pdo_mysql_errorinfo.phpt
Normal file
173
ext/pdo_mysql/tests/pdo_mysql_errorinfo.phpt
Normal file
|
@ -0,0 +1,173 @@
|
|||
--TEST--
|
||||
MySQL PDO->errorInfo()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
function check_error($offset, &$obj, $expected = '00000') {
|
||||
|
||||
$info = $obj->errorInfo();
|
||||
if (count($info) != 3)
|
||||
printf("[%03d] Info should have three fields, got %s\n",
|
||||
$offset, var_export($info, true));
|
||||
|
||||
$code = $info[0];
|
||||
if (($code != $expected) && (($expected != '00000') && ($code != ''))) {
|
||||
printf("[%03d] Expecting error code '%s' got code '%s'\n",
|
||||
$offset, $expected, $code);
|
||||
}
|
||||
|
||||
if ($expected != '00000') {
|
||||
if (!isset($info[1]) || $info[1] == '')
|
||||
printf("[%03d] Driver-specific error code not set\n", $offset);
|
||||
if (!isset($info[2]) || $info[2] == '')
|
||||
printf("[%03d] Driver-specific error message.not set\n", $offset);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function pdo_mysql_errorinfo($db, $offset) {
|
||||
|
||||
try {
|
||||
|
||||
/*
|
||||
If you create a PDOStatement object through PDO->prepare()
|
||||
or PDO->query() and invoke an error on the statement handle,
|
||||
PDO->errorCode() will not reflect that error. You must call
|
||||
PDOStatement->errorCode() to return the error code for an
|
||||
operation performed on a particular statement handle.
|
||||
*/
|
||||
$code = $db->errorCode();
|
||||
check_error($offset + 2, $db);
|
||||
|
||||
$stmt = $db->query('SELECT id, label FROM test');
|
||||
$stmt2 = &$stmt;
|
||||
check_error($offset + 3, $db);
|
||||
check_error($offset + 4, $stmt);
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
@$stmt->execute();
|
||||
check_error($offset + 5, $db);
|
||||
check_error($offset + 6, $stmt, '42S02');
|
||||
check_error($offset + 7, $stmt2, '42S02');
|
||||
|
||||
@$stmt = $db->query('SELECT id, label FROM unknown');
|
||||
check_error($offset + 8, $db, '42S02');
|
||||
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
$stmt = $db->query('SELECT id, label FROM test');
|
||||
check_error($offset + 9, $db);
|
||||
check_error($offset + 10, $stmt);
|
||||
|
||||
$db2 = &$db;
|
||||
$db->exec('DROP TABLE IF EXISTS unknown');
|
||||
@$db->query('SELECT id, label FROM unknown');
|
||||
check_error($offset + 11, $db, '42S02');
|
||||
check_error($offset + 12, $db2, '42S02');
|
||||
check_error($offset + 13, $stmt);
|
||||
check_error($offset + 14, $stmt2);
|
||||
|
||||
// lets hope this is an invalid attribute code
|
||||
$invalid_attr = -1 * PHP_INT_MAX + 3;
|
||||
$tmp = @$db->getAttribute($invalid_attr);
|
||||
check_error($offset + 15, $db, 'IM001');
|
||||
check_error($offset + 16, $db2, 'IM001');
|
||||
check_error($offset + 17, $stmt);
|
||||
check_error($offset + 18, $stmt2);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[%03d] %s [%s] %s\n",
|
||||
$offset + 19, $e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
}
|
||||
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
|
||||
printf("Emulated Prepared Statements...\n");
|
||||
pdo_mysql_errorinfo($db, 0);
|
||||
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
|
||||
printf("Native Prepared Statements...\n");
|
||||
pdo_mysql_errorinfo($db, 20);
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
Emulated Prepared Statements...
|
||||
[002] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
[003] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
[004] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
[005] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
[009] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
[010] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
[013] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
[014] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
[015] Info should have three fields, got array (
|
||||
0 => 'IM001',
|
||||
)
|
||||
[015] Driver-specific error code not set
|
||||
[015] Driver-specific error message.not set
|
||||
[016] Info should have three fields, got array (
|
||||
0 => 'IM001',
|
||||
)
|
||||
[016] Driver-specific error code not set
|
||||
[016] Driver-specific error message.not set
|
||||
[017] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
[018] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
Native Prepared Statements...
|
||||
[022] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
[023] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
[024] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
[025] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
[030] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
[033] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
[034] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
[037] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
[038] Info should have three fields, got array (
|
||||
0 => '00000',
|
||||
)
|
||||
done!
|
179
ext/pdo_mysql/tests/pdo_mysql_exec.phpt
Normal file
179
ext/pdo_mysql/tests/pdo_mysql_exec.phpt
Normal file
|
@ -0,0 +1,179 @@
|
|||
--TEST--
|
||||
MySQL PDO->exec(), affected rows
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
function exec_and_count($offset, &$db, $sql, $exp = NULL) {
|
||||
|
||||
try {
|
||||
|
||||
$ret = $db->exec($sql);
|
||||
if (!is_null($exp) && ($ret !== $exp)) {
|
||||
printf("[%03d] Expecting '%s'/%s got '%s'/%s when running '%s', [%s] %s\n",
|
||||
$offset, $exp, gettype($exp), $ret, gettype($ret), $sql,
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
return false;
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[%03d] '%s' has failed, [%s] %s\n",
|
||||
$offset, $sql, $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db, MySQLPDOTest::detect_transactional_mysql_engine($db));
|
||||
|
||||
/* affected rows related */
|
||||
try {
|
||||
|
||||
exec_and_count(2, $db, 'DROP TABLE IF EXISTS test', 0);
|
||||
exec_and_count(3, $db, sprintf('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, col1 CHAR(10)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE), 0);
|
||||
exec_and_count(4, $db, 'INSERT INTO test(id, col1) VALUES (1, "a")', 1);
|
||||
exec_and_count(5, $db, 'INSERT INTO test(id, col1) VALUES (2, "b"), (3, "c")', 2);
|
||||
exec_and_count(6, $db, 'UPDATE test SET id = 4 WHERE id = 3', 1);
|
||||
exec_and_count(7, $db, 'INSERT INTO test(id, col1) VALUES (1, "d") ON DUPLICATE KEY UPDATE id = 3', 2);
|
||||
exec_and_count(8, $db, 'UPDATE test SET id = 5 WHERE id = 5', 0);
|
||||
exec_and_count(9, $db, 'INSERT INTO test(id, col1) VALUES (5, "e") ON DUPLICATE KEY UPDATE id = 6', 1);
|
||||
exec_and_count(10, $db, 'REPLACE INTO test(id, col1) VALUES (5, "f")', 2);
|
||||
exec_and_count(11, $db, 'REPLACE INTO test(id, col1) VALUES (6, "g")', 1);
|
||||
exec_and_count(12, $db, 'DELETE FROM test WHERE id > 2', 4);
|
||||
exec_and_count(13, $db, 'DROP TABLE test', 0);
|
||||
exec_and_count(14, $db, 'SET @myvar = 1', 0);
|
||||
|
||||
exec_and_count(15, $db, 'THIS IS NOT VALID SQL, I HOPE', false);
|
||||
printf("[016] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
exec_and_count(36, $db, sprintf('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, col1 CHAR(10)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE), 0);
|
||||
exec_and_count(37, $db, 'INSERT INTO test(id, col1) VALUES (1, "a")', 1);
|
||||
// Results may vary. Typically you will get 1. But the MySQL 5.1 manual states: Truncation operations do not return the number of deleted rows.
|
||||
// Don't rely on any return value!
|
||||
exec_and_count(38, $db, 'TRUNCATE TABLE test', NULL);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s, [%s] %s\n",
|
||||
$e->getMessage(),
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
|
||||
/* CREATE, DROP, CALL SP and SF */
|
||||
if (MySQLPDOTest::getServerVersion($db) > 50000) {
|
||||
// let's try to play with stored procedures
|
||||
try {
|
||||
$ignore_exception = true;
|
||||
exec_and_count(18, $db, 'DROP PROCEDURE IF EXISTS p', 0);
|
||||
exec_and_count(19, $db, 'CREATE PROCEDURE p(OUT ver_param VARCHAR(255)) BEGIN SELECT VERSION() INTO ver_param; END;', 0);
|
||||
// we got this far without problems. If there's an issue from now on, its a failure
|
||||
$ignore_exception = false;
|
||||
exec_and_count(20, $db, 'CALL p(@version)', 0);
|
||||
$stmt = $db->query('SELECT @version AS p_version');
|
||||
$tmp = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (count($tmp) > 1 || !isset($tmp[0]['p_version'])) {
|
||||
printf("[022] Data seems wrong, dumping\n");
|
||||
var_dump($tmp);
|
||||
} else {
|
||||
$p_version = $tmp[0]['p_version'];
|
||||
}
|
||||
|
||||
$stmt = $db->query('SELECT VERSION() AS _version');
|
||||
$tmp = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (count($tmp) > 1 || !isset($tmp[0]['_version'])) {
|
||||
printf("[023] Data seems wrong, dumping\n");
|
||||
var_dump($tmp);
|
||||
} else {
|
||||
if ($p_version !== $tmp[0]['_version']) {
|
||||
printf("[024] Found different version strings, SP returned '%s'/%s, SELECT returned '%s'/%s\n",
|
||||
$p_version, gettype($p_version),
|
||||
$tmp[0]['_version'], gettype($tmp[0]['_version']));
|
||||
}
|
||||
}
|
||||
exec_and_count(25, $db, 'DROP PROCEDURE IF EXISTS p', 0);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
// ignore it, we might not have sufficient permissions
|
||||
if (!$ignore_exception)
|
||||
printf("[021] %s, [%s] %s\n",
|
||||
$e->getMessage(),
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
// stored function
|
||||
try {
|
||||
$ignore_exception = true;
|
||||
exec_and_count(27, $db, 'DROP FUNCTION IF EXISTS f', 0);
|
||||
exec_and_count(28, $db, 'CREATE FUNCTION f( ver_param VARCHAR(255)) RETURNS VARCHAR(255) DETERMINISTIC RETURN ver_param;', 0);
|
||||
// we got this far without problems. If there's an issue from now on, its a failure
|
||||
$ignore_exception = false;
|
||||
$stmt = $db->query('SELECT f(VERSION()) AS f_version');
|
||||
$tmp = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (count($tmp) > 1 || !isset($tmp[0]['f_version'])) {
|
||||
printf("[029] Data seems wrong, dumping\n");
|
||||
var_dump($tmp);
|
||||
} else {
|
||||
$f_version = $tmp[0]['f_version'];
|
||||
}
|
||||
$stmt = $db->query('SELECT VERSION() AS _version');
|
||||
$tmp = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (count($tmp) > 1 || !isset($tmp[0]['_version'])) {
|
||||
printf("[030] Data seems wrong, dumping\n");
|
||||
var_dump($tmp);
|
||||
} else {
|
||||
if ($f_version !== $tmp[0]['_version']) {
|
||||
printf("[031] Found different version strings, SF returned '%s'/%s, SELECT returned '%s'/%s\n",
|
||||
$f_version, gettype($f_version),
|
||||
$tmp[0]['_version'], gettype($tmp[0]['_version']));
|
||||
}
|
||||
}
|
||||
exec_and_count(32, $db, 'DROP FUNCTION IF EXISTS f', 0);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
// ignore it, we might not have sufficient permissions
|
||||
if (!$ignore_exception)
|
||||
printf("[026] %s, [%s] %s\n",
|
||||
$e->getMessage(),
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
}
|
||||
|
||||
// multi query
|
||||
try {
|
||||
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
|
||||
$exp = 0;
|
||||
|
||||
$tmp = @$db->exec(sprintf('DROP TABLE IF EXISTS test; CREATE TABLE test(id INT) ENGINE=%s', PDO_MYSQL_TEST_ENGINE));
|
||||
if ($exp !== $tmp)
|
||||
printf("[034] Expecting %s/%s got %s/%s, [%s] %s\n",
|
||||
$exp, gettype($exp),
|
||||
$tmp, gettype($tmp),
|
||||
$db->errorCode(), var_export($db->errorInfo(), true));
|
||||
|
||||
// this is interesting: if we get sort of affected rows, what will happen now?
|
||||
$tmp = @$db->exec('INSERT INTO test(id) VALUES (1); INSERT INTO test(id) VALUES (2)');
|
||||
printf("[035] With emulated PS it works but makes no sense given that exec() returns sort of affected rows...\n");
|
||||
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[033] %s, [%s] %s\n",
|
||||
$e->getMessage(),
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
|
||||
|
||||
@$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
Warning: PDO::exec(): SQLSTATE[42000]: Syntax error or access violation: 1064 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 'THIS IS NOT VALID SQL, I HOPE' at line 1 in %s on line %d
|
||||
[016] [42000] 42000 1064 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 'THIS IS NOT VALID SQL, I HOPE' at line %d
|
||||
[035] With emulated PS it works but makes no sense given that exec() returns sort of affected rows...
|
||||
done!
|
88
ext/pdo_mysql/tests/pdo_mysql_exec_ddl.phpt
Normal file
88
ext/pdo_mysql/tests/pdo_mysql_exec_ddl.phpt
Normal file
|
@ -0,0 +1,88 @@
|
|||
--TEST--
|
||||
MySQL PDO->exec(), affected rows
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
function exec_and_count($offset, &$db, $sql, $exp, $suppress_warning = false) {
|
||||
|
||||
try {
|
||||
|
||||
if ($suppress_warning)
|
||||
$ret = @$db->exec($sql);
|
||||
else
|
||||
$ret = $db->exec($sql);
|
||||
|
||||
if ($ret !== $exp) {
|
||||
printf("[%03d] Expecting '%s'/%s got '%s'/%s when running '%s', [%s] %s\n",
|
||||
$offset, $exp, gettype($exp), $ret, gettype($ret), $sql,
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
return false;
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[%03d] '%s' has failed, [%s] %s\n",
|
||||
$offset, $sql, $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db, MySQLPDOTest::detect_transactional_mysql_engine($db));
|
||||
|
||||
/* affected rows related */
|
||||
try {
|
||||
|
||||
@$db->exec('DROP DATABASE IF EXISTS pdo_exec_ddl');
|
||||
@$db->exec('DROP DATABASE IF EXISTS pdo_exec_ddl2');
|
||||
if (1 === @$db->exec('CREATE DATABASE pdo_exec_ddl')) {
|
||||
// yippie - we can create databases etc.
|
||||
exec_and_count(3, $db, 'ALTER DATABASE pdo_exec_ddl CHARACTER SET latin1', 1);
|
||||
}
|
||||
|
||||
exec_and_count(4, $db, 'DROP TABLE IF EXISTS pdo_exec_ddl', 0);
|
||||
exec_and_count(5, $db, 'DROP TABLE IF EXISTS pdo_exec_ddl2', 0);
|
||||
if (0 === $db->exec('CREATE TABLE pdo_exec_ddl(id INT, col1 CHAR(2))')) {
|
||||
exec_and_count(5, $db, 'CREATE INDEX idx1 ON pdo_exec_ddl(id)', 0);
|
||||
exec_and_count(6, $db, 'DROP INDEX idx1 ON pdo_exec_ddl', 0);
|
||||
exec_and_count(7, $db, 'ALTER TABLE pdo_exec_ddl DROP id', 0);
|
||||
exec_and_count(8, $db, 'ALTER TABLE pdo_exec_ddl ADD id INT', 0);
|
||||
exec_and_count(9, $db, 'ALTER TABLE pdo_exec_ddl ALTER id SET DEFAULT 1', 0);
|
||||
exec_and_count(10, $db, 'RENAME TABLE pdo_exec_ddl TO pdo_exec_ddl2', 0);
|
||||
}
|
||||
|
||||
/*
|
||||
11.1.2. ALTER LOGFILE GROUP Syntax
|
||||
11.1.3. ALTER SERVER Syntax
|
||||
11.1.5. ALTER TABLESPACE Syntax
|
||||
11.1.8. CREATE LOGFILE GROUP Syntax
|
||||
11.1.9. CREATE SERVER Syntax
|
||||
11.1.11. CREATE TABLESPACE Syntax
|
||||
11.1.14. DROP LOGFILE GROUP Syntax
|
||||
11.1.15. DROP SERVER Syntax
|
||||
11.1.17. DROP TABLESPACE Syntax
|
||||
*/
|
||||
|
||||
// clean up
|
||||
@$db->exec('DROP TABLE IF EXISTS pdo_exec_ddl');
|
||||
@$db->exec('DROP TABLE IF EXISTS pdo_exec_ddl2');
|
||||
@$db->exec('DROP DATABASE IF EXISTS pdo_exec_ddl');
|
||||
@$db->exec('DROP DATABASE IF EXISTS pdo_exec_ddl2');
|
||||
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s, [%s] %s\n",
|
||||
$e->getMessage(),
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
done!
|
102
ext/pdo_mysql/tests/pdo_mysql_exec_load_data.phpt
Normal file
102
ext/pdo_mysql/tests/pdo_mysql_exec_load_data.phpt
Normal file
|
@ -0,0 +1,102 @@
|
|||
--TEST--
|
||||
MySQL PDO->exec(), affected rows
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
|
||||
// Run test only locally - not against remote hosts
|
||||
$db = MySQLPDOTest::factory();
|
||||
$stmt = $db->query('SELECT USER() as _user');
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$tmp = explode('@', $row['_user']);
|
||||
if (count($tmp) < 2)
|
||||
die("skip Cannot detect if test is run against local or remote database server");
|
||||
if (($tmp[1] !== 'localhost') && ($tmp[1] !== '127.0.0.1'))
|
||||
die("skip Test cannot be run against remote database server");
|
||||
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
function exec_and_count($offset, &$db, $sql, $exp) {
|
||||
|
||||
try {
|
||||
|
||||
$ret = $db->exec($sql);
|
||||
if ($ret !== $exp) {
|
||||
printf("[%03d] Expecting '%s'/%s got '%s'/%s when running '%s', [%s] %s\n",
|
||||
$offset, $exp, gettype($exp), $ret, gettype($ret), $sql,
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
return false;
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
|
||||
if (42000 == $db->errorCode()) {
|
||||
// Error: 1148 SQLSTATE: 42000 (ER_NOT_ALLOWED_COMMAND)
|
||||
// Load data infile not allowed
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("[%03d] '%s' has failed, [%s] %s\n",
|
||||
$offset, $sql, $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db, MySQLPDOTest::detect_transactional_mysql_engine($db));
|
||||
|
||||
/* affected rows related */
|
||||
try {
|
||||
|
||||
exec_and_count(2, $db, 'DROP TABLE IF EXISTS test', 0);
|
||||
exec_and_count(3, $db, sprintf('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, col1 CHAR(10)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE), 0);
|
||||
|
||||
$stmt = $db->query('SHOW VARIABLES LIKE "secure_file_priv"');
|
||||
if (($row = $stmt->fetch(PDO::FETCH_ASSOC)) && ($row['value'] != '')) {
|
||||
$filename = $row['value'] . DIRECTORY_SEPARATOR . "pdo_mysql_exec_load_data.csv";
|
||||
} else {
|
||||
$filename = MySQLPDOTest::getTempDir() . DIRECTORY_SEPARATOR . "pdo_mysql_exec_load_data.csv";
|
||||
}
|
||||
|
||||
$fp = fopen($filename, "w");
|
||||
fwrite($fp, b"1;foo\n");
|
||||
fwrite($fp, b"2;bar");
|
||||
fclose($fp);
|
||||
|
||||
$sql = sprintf("LOAD DATA INFILE %s INTO TABLE test FIELDS TERMINATED BY ';' LINES TERMINATED BY '\n'", $db->quote($filename));
|
||||
|
||||
if (exec_and_count(4, $db, $sql, 2)) {
|
||||
|
||||
$stmt = $db->query('SELECT id, col1 FROM test ORDER BY id ASC');
|
||||
$expected = array(array("id" => 1, "col1" => "foo"), array("id" => 2, "col1" => "bar"));
|
||||
$ret = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
foreach ($expected as $offset => $exp) {
|
||||
foreach ($exp as $key => $value) {
|
||||
if ($ret[$offset][$key] != $value) {
|
||||
printf("Results seem wrong, check manually\n");
|
||||
var_dump($ret);
|
||||
var_dump($expected);
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unlink($filename);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s, [%s] %s\n",
|
||||
$e->getMessage(),
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
done!
|
59
ext/pdo_mysql/tests/pdo_mysql_exec_select.phpt
Normal file
59
ext/pdo_mysql/tests/pdo_mysql_exec_select.phpt
Normal file
|
@ -0,0 +1,59 @@
|
|||
--TEST--
|
||||
MySQL PDO->exec(), SELECT
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
function exec_and_count($offset, &$db, $sql, $exp) {
|
||||
|
||||
try {
|
||||
|
||||
$ret = $db->exec($sql);
|
||||
if ($ret !== $exp) {
|
||||
printf("[%03d] Expecting '%s'/%s got '%s'/%s when running '%s', [%s] %s\n",
|
||||
$offset, $exp, gettype($exp), $ret, gettype($ret), $sql,
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
return false;
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[%03d] '%s' has failed, [%s] %s\n",
|
||||
$offset, $sql, $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db, MySQLPDOTest::detect_transactional_mysql_engine($db));
|
||||
|
||||
/* affected rows related */
|
||||
try {
|
||||
|
||||
exec_and_count(2, $db, 'DROP TABLE IF EXISTS test', 0);
|
||||
exec_and_count(3, $db, sprintf('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, col1 CHAR(10)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE), 0);
|
||||
exec_and_count(4, $db, 'INSERT INTO test(id, col1) VALUES (1, "a")', 1);
|
||||
// question is: will the result set be cleaned up, will it be possible to run more queries on the line?
|
||||
// buffered or unbuffered does not matter!
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
|
||||
exec_and_count(5, $db, 'SELECT id FROM test', 0);
|
||||
exec_and_count(6, $db, 'INSERT INTO test(id, col1) VALUES (2, "b")', 1);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s, [%s] %s\n",
|
||||
$e->getMessage(),
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
@$db->exec(sprintf('DROP TABLE IF EXISTS test'));
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
Warning: PDO::exec(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d
|
||||
[006] Expecting '1'/integer got ''/boolean when running 'INSERT INTO test(id, col1) VALUES (2, "b")', [HY000] HY000 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.
|
||||
done!
|
88
ext/pdo_mysql/tests/pdo_mysql_fetch_both.phpt
Normal file
88
ext/pdo_mysql/tests/pdo_mysql_fetch_both.phpt
Normal file
|
@ -0,0 +1,88 @@
|
|||
--TEST--
|
||||
MySQL PDOStatement->fetch()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
function fetch($offset, &$db, $query, $expect = null) {
|
||||
|
||||
try {
|
||||
$stmt = $db->query('SELECT 1');
|
||||
$num = $stmt->fetch(PDO::FETCH_NUM);
|
||||
|
||||
$stmt = $db->query('SELECT 1');
|
||||
$assoc = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$stmt = $db->query('SELECT 1');
|
||||
$both = $stmt->fetch(PDO::FETCH_BOTH);
|
||||
|
||||
$computed_both = array_merge($num, $assoc);
|
||||
if ($computed_both != $both) {
|
||||
printf("[%03d] Suspicious FETCH_BOTH result, dumping\n", $offset);
|
||||
var_dump($computed_both);
|
||||
var_dump($both);
|
||||
}
|
||||
|
||||
if (!is_null($expect) && ($expect != $both)) {
|
||||
printf("[%03d] Expected differes from returned data, dumping\n", $offset);
|
||||
var_dump($expect);
|
||||
var_dump($both);
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
|
||||
printf("[%03d] %s, [%s] %s\n",
|
||||
$offset,
|
||||
$e->getMessage(), $db->errroCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
fetch(2, &$db, 'SELECT 1', array(0 => '1', '1' => '1'));
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec(sprintf('DROP TABLE IF EXISTS test'));
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
[002] Suspicious FETCH_BOTH result, dumping
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(1) "1"
|
||||
[1]=>
|
||||
string(1) "1"
|
||||
}
|
||||
array(2) {
|
||||
[1]=>
|
||||
string(1) "1"
|
||||
[2]=>
|
||||
string(1) "1"
|
||||
}
|
||||
[002] Expected differes from returned data, dumping
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(1) "1"
|
||||
[1]=>
|
||||
string(1) "1"
|
||||
}
|
||||
array(2) {
|
||||
[1]=>
|
||||
string(1) "1"
|
||||
[2]=>
|
||||
string(1) "1"
|
||||
}
|
||||
done!
|
101
ext/pdo_mysql/tests/pdo_mysql_get_attribute.phpt
Normal file
101
ext/pdo_mysql/tests/pdo_mysql_get_attribute.phpt
Normal file
|
@ -0,0 +1,101 @@
|
|||
--TEST--
|
||||
MySQL PDO->getAttribute()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
if (false == MySQLPDOTest::detect_transactional_mysql_engine($db))
|
||||
die("skip Transactional engine not found");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db, MySQLPDOTest::detect_transactional_mysql_engine($db));
|
||||
|
||||
function find_invalid_int($valid_options) {
|
||||
do {
|
||||
$invalid = mt_rand(-10000, 10000);
|
||||
} while (in_array($invalid, $valid_options));
|
||||
return $invalid;
|
||||
}
|
||||
|
||||
function set_and_get($offset, $db, $attribute, $value) {
|
||||
|
||||
$value_type = gettype($value);
|
||||
try {
|
||||
|
||||
if (!$db->setAttribute($attribute, $value)) {
|
||||
printf("[%03d] Cannot set attribute '%s' to value '%s'\n",
|
||||
$offset, $attribute, var_export($tmp, true));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gettype($value) != $value_type) {
|
||||
printf("[%03d] Call to PDO::setAttribute(int attribute, mixed value) has changed the type of value from %s to %s, test will not work properly\n",
|
||||
$offset, $value_type, gettype($value));
|
||||
return false;
|
||||
}
|
||||
|
||||
$tmp = $db->getAttribute($attribute);
|
||||
if ($tmp !== $value) {
|
||||
printf("[%03d] Attribute '%s' was set to '%s'/%s but getAttribute() reports '%s'/%s\n",
|
||||
$offset, $attribute, var_export($value, true), gettype($value), var_export($tmp, true), gettype($tmp));
|
||||
return false;
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[%03d] %s, [%s] %s\n",
|
||||
$offset, $e->getMessage(),
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
set_and_get(1, $db, PDO::ATTR_AUTOCOMMIT, 1);
|
||||
/*
|
||||
set_and_get(2, $db, PDO::ATTR_AUTOCOMMIT, 0);
|
||||
set_and_get(3, $db, PDO::ATTR_AUTOCOMMIT, -1);
|
||||
$obj = new stdClass();
|
||||
set_and_get(4, $db, PDO::ATTR_AUTOCOMMIT, $obj);
|
||||
|
||||
set_and_get(5, $db, PDO::MYSQL_ATTR_LOCAL_INFILE, 1);
|
||||
set_and_get(6, $db, PDO::MYSQL_ATTR_LOCAL_INFILE, 0);
|
||||
set_and_get(7, $db, PDO::MYSQL_ATTR_LOCAL_INFILE, -1);
|
||||
$tmp = array();
|
||||
set_and_get(8, $db, PDO::MYSQL_ATTR_LOCAL_INFILE, $tmp);
|
||||
|
||||
set_and_get(9, $db, PPDO::MYSQL_ATTR_INIT_COMMAND, '');
|
||||
set_and_get(10, $db, PPDO::MYSQL_ATTR_INIT_COMMAND, 'SOME SQL');
|
||||
set_and_get(11, $db, PPDO::MYSQL_ATTR_INIT_COMMAND, -1);
|
||||
|
||||
*/
|
||||
/*
|
||||
PDO::MYSQL_ATTR_READ_DEFAULT_FILE (integer)
|
||||
|
||||
Read options from the named option file instead of from my.cnf.
|
||||
PDO::MYSQL_ATTR_READ_DEFAULT_GROUP (integer)
|
||||
|
||||
Read options from the named group from my.cnf or the file specified with MYSQL_READ_DEFAULT_FILE.
|
||||
PDO::MYSQL_ATTR_MAX_BUFFER_SIZE (integer)
|
||||
|
||||
Maximum buffer size. Defaults to 1 MiB.
|
||||
PDO::MYSQL_ATTR_DIRECT_QUERY (integer)
|
||||
|
||||
Perform direct queries, don't use prepared statements.
|
||||
*/
|
||||
/*
|
||||
TODO - read only
|
||||
PDO::ATTR_CONNECTION_STATUS
|
||||
PDO::ATTR_SERVER_INFO
|
||||
*/
|
||||
|
||||
$db->exec(sprintf('DROP TABLE IF EXISTS test'));
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
[001] Call to PDO::setAttribute(int attribute, mixed value) has changed the type of value from integer to boolean, test will not work properly
|
||||
done!
|
58
ext/pdo_mysql/tests/pdo_mysql_interface.phpt
Normal file
58
ext/pdo_mysql/tests/pdo_mysql_interface.phpt
Normal file
|
@ -0,0 +1,58 @@
|
|||
--TEST--
|
||||
MySQL PDO class interface
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::getDriver();
|
||||
if (false == MySQLPDOTest::detect_transactional_mysql_engine($db))
|
||||
die("skip Transactional engine not found");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
$expected = array(
|
||||
'__construct' => true,
|
||||
'prepare' => true,
|
||||
'beginTransaction' => true,
|
||||
'commit' => true,
|
||||
'rollBack' => true,
|
||||
'setAttribute' => true,
|
||||
'exec' => true,
|
||||
'query' => true,
|
||||
'lastInsertId' => true,
|
||||
'errorCode' => true,
|
||||
'errorInfo' => true,
|
||||
'getAttribute' => true,
|
||||
'quote' => true,
|
||||
'__wakeup' => true,
|
||||
'__sleep' => true,
|
||||
'getAvailableDrivers' => true,
|
||||
);
|
||||
$classname = get_class($db);
|
||||
|
||||
$methods = get_class_methods($classname);
|
||||
foreach ($methods as $k => $method) {
|
||||
if (isset($expected[$method])) {
|
||||
unset($expected[$method]);
|
||||
unset($methods[$k]);
|
||||
}
|
||||
if ($method == $classname) {
|
||||
unset($expected['__construct']);
|
||||
unset($methods[$k]);
|
||||
}
|
||||
}
|
||||
if (!empty($expected)) {
|
||||
printf("Dumping missing class methods\n");
|
||||
var_dump($expected);
|
||||
}
|
||||
if (!empty($methods)) {
|
||||
printf("Found more methods than expected, dumping list\n");
|
||||
var_dump($methods);
|
||||
}
|
||||
|
||||
print "done!";
|
||||
--EXPECT--
|
||||
done!
|
114
ext/pdo_mysql/tests/pdo_mysql_last_insert_id.phpt
Normal file
114
ext/pdo_mysql/tests/pdo_mysql_last_insert_id.phpt
Normal file
|
@ -0,0 +1,114 @@
|
|||
--TEST--
|
||||
MySQL PDO->lastInsertId()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
try {
|
||||
if ('0' !== ($tmp = $db->lastInsertId()))
|
||||
printf("[001] No query has been run, lastInsertId() should return '0'/string got '%s'/%s\n",
|
||||
var_export($tmp, true), gettype($tmp));
|
||||
|
||||
if ('0' !== ($tmp = $db->lastInsertId('sequence_name')))
|
||||
printf("[002] MySQL does not support sequences, expecting '0'/string got '%s'/%s\n",
|
||||
var_export($tmp, true), gettype($tmp));
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
if ('0' !== ($tmp = $db->lastInsertId()))
|
||||
printf("[003] Expecting '0'/string got '%s'/%s", var_export($tmp, true), gettype($tmp));
|
||||
|
||||
$db->exec(sprintf('CREATE TABLE test(id INT, col1 CHAR(10)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE));
|
||||
if ('0' !== ($tmp = $db->lastInsertId()))
|
||||
printf("[004] Expecting '0'/string got '%s'/%s", var_export($tmp, true), gettype($tmp));
|
||||
|
||||
$stmt = $db->query('SELECT id FROM test LIMIT 1');
|
||||
if ('0' !== ($tmp = $db->lastInsertId()))
|
||||
printf("[005] Expecting '0'/string got '%s'/%s", var_export($tmp, true), gettype($tmp));
|
||||
|
||||
// no auto increment column
|
||||
$db->exec('INSERT INTO test(id, col1) VALUES (100, "a")');
|
||||
if ('0' !== ($tmp = $db->lastInsertId()))
|
||||
printf("[006] Expecting '0'/string got '%s'/%s", var_export($tmp, true), gettype($tmp));
|
||||
|
||||
$db->exec('ALTER TABLE test MODIFY id INT AUTO_INCREMENT PRIMARY KEY');
|
||||
if ('0' !== ($tmp = $db->lastInsertId()))
|
||||
printf("[006] Expecting '0'/string got '%s'/%s", var_export($tmp, true), gettype($tmp));
|
||||
|
||||
// duplicate key
|
||||
@$db->exec('INSERT INTO test(id, col1) VALUES (100, "a")');
|
||||
if ('0' !== ($tmp = $db->lastInsertId()))
|
||||
printf("[007] Expecting '0'/string got '%s'/%s", var_export($tmp, true), gettype($tmp));
|
||||
|
||||
$db->exec('INSERT INTO test(id, col1) VALUES (101, "b")');
|
||||
if ('101' !== ($tmp = $db->lastInsertId()))
|
||||
printf("[008] Expecting '0'/string got '%s'/%s", var_export($tmp, true), gettype($tmp));
|
||||
|
||||
$db->exec('ALTER TABLE test MODIFY col1 CHAR(10) UNIQUE');
|
||||
// replace = delete + insert -> new auto increment value
|
||||
$db->exec('REPLACE INTO test(col1) VALUES ("b")');
|
||||
$next_id = (int)$db->lastInsertId();
|
||||
|
||||
if ($next_id <= 101)
|
||||
printf("[009] Expecting at least 102, got %d\n",$next_id);
|
||||
|
||||
$stmt = $db->query('SELECT LAST_INSERT_ID() as _last_id');
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$last_id = $row['_last_id'];
|
||||
if ($next_id != $last_id) {
|
||||
printf("[010] LAST_INSERT_ID() = %d and lastInserId() = %d differ\n",
|
||||
$last_id, $next_id);
|
||||
}
|
||||
|
||||
$db->exec('INSERT INTO test(col1) VALUES ("c"), ("d"), ("e")');
|
||||
$next_id = (int)$db->lastInsertId();
|
||||
if ($next_id <= $last_id)
|
||||
printf("[011] Expecting at least %d, got %d\n", $last_id + 1, $next_id);
|
||||
|
||||
// warnings are unhandy, lets go for exceptions for a second
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
try {
|
||||
$ignore_exception = true;
|
||||
$db->exec('LOCK TABLE test WRITE');
|
||||
$ignore_exception = false;
|
||||
|
||||
if (MySQLPDOTest::getServerVersion($db) >= 50000) {
|
||||
$stmt = $db->query('SELECT @@auto_increment_increment AS inc');
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$inc = $row['inc'];
|
||||
} else {
|
||||
$inc = 1;
|
||||
}
|
||||
|
||||
$stmt = $db->query('SELECT LAST_INSERT_ID() as _last_id');
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$last_id = $row['_last_id'];
|
||||
|
||||
$db->exec('INSERT INTO test(col1) VALUES ("z")');
|
||||
$next_id = (int)$db->lastInsertId();
|
||||
if ($next_id < ($last_id + $inc))
|
||||
printf("[012] Expecting at least %d, got %d\n", $last_id + $inc, $next_id);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
if (!$ignore_exception)
|
||||
printf("[014] %s, [%s} %s\n", $e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
|
||||
@$db->exec('UNLOCK TABLE test');
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec(sprintf('DROP TABLE IF EXISTS test'));
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
done!
|
101
ext/pdo_mysql/tests/pdo_mysql_pconnect.phpt
Normal file
101
ext/pdo_mysql/tests/pdo_mysql_pconnect.phpt
Normal file
|
@ -0,0 +1,101 @@
|
|||
--TEST--
|
||||
MySQL PDO->__construct(), PDO::ATTR_PERSISTENT
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
|
||||
try {
|
||||
|
||||
$dsn = MySQLPDOTest::getDSN();
|
||||
$user = PDO_MYSQL_TEST_USER;
|
||||
$pass = PDO_MYSQL_TEST_PASS;
|
||||
|
||||
$db1 = new PDO($dsn, $user, $pass, array(PDO::ATTR_PERSISTENT => true));
|
||||
$db2 = new PDO($dsn, $user, $pass, array(PDO::ATTR_PERSISTENT => true));
|
||||
$db1->exec('SET @pdo_persistent_connection=1');
|
||||
$stmt = $db2->query('SELECT @pdo_persistent_connection as _pers');
|
||||
$tmp = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($tmp['_pers'] !== '1')
|
||||
printf("[001] Both handles should use the same connection.");
|
||||
|
||||
$stmt = $db1->query('SELECT CONNECTION_ID() as _con1');
|
||||
$tmp = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$con1 = $tmp['_con1'];
|
||||
|
||||
$stmt = $db2->query('SELECT CONNECTION_ID() as _con2');
|
||||
$tmp = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$con2 = $tmp['_con2'];
|
||||
|
||||
if ($con1 !== $con2)
|
||||
printf("[002] Both handles should report the same MySQL thread ID");
|
||||
|
||||
$db1 = NULL; /* should be equal to closing to my understanding */
|
||||
$db1 = new PDO($dsn, $user, $pass, array(PDO::ATTR_PERSISTENT => true));
|
||||
$stmt = $db1->query('SELECT CONNECTION_ID() as _con1');
|
||||
$tmp = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$con1 = $tmp['_con1'];
|
||||
|
||||
if ($con1 !== $con2)
|
||||
printf("[003] Both handles should report the same MySQL thread ID");
|
||||
|
||||
$affected = $db1->exec(sprintf('KILL %d', $con1));
|
||||
// Server needs some think-time sometimes
|
||||
sleep(1);
|
||||
if ('00000' == $db1->errorCode()) {
|
||||
// looks like KILL has worked ? Or not... TODO: why no warning with libmysql?!
|
||||
@$db1->exec("SET @pdo_persistent_connection=2");
|
||||
// but now I want to see some error...
|
||||
if ('HY000' != $db1->errorCode())
|
||||
printf("[004] Wrong error code %s\n", $db1->errorCode());
|
||||
|
||||
$tmp = implode(' ', $db1->errorInfo());
|
||||
if (!strstr($tmp, '2006'))
|
||||
printf("[005] Wrong error info %s\n", $tmp);
|
||||
}
|
||||
|
||||
$db1 = new PDO($dsn, $user, $pass, array(PDO::ATTR_PERSISTENT => false));
|
||||
$stmt = $db1->query('SELECT CONNECTION_ID() as _con1');
|
||||
$tmp = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$con1 = $tmp['_con1'];
|
||||
|
||||
$db2 = new PDO($dsn, $user, $pass, array(PDO::ATTR_PERSISTENT => true));
|
||||
$stmt = $db2->query('SELECT CONNECTION_ID() as _con2');
|
||||
$tmp = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$con2 = $tmp['_con2'];
|
||||
|
||||
if ($con1 == $con2)
|
||||
printf("[006] Looks like the persistent and the non persistent connection are using the same link?!\n");
|
||||
|
||||
// lets go crazy and create a few pconnections...
|
||||
$connections = array();
|
||||
for ($i = 0; $i <= 20; $i++) {
|
||||
$connections[$i] = new PDO($dsn, $user, $pass, array(PDO::ATTR_PERSISTENT => true));
|
||||
}
|
||||
do {
|
||||
$i = mt_rand(0, 20);
|
||||
if (isset($connections[$i]))
|
||||
unset($connections[$i]);
|
||||
} while (!empty($connections));
|
||||
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s, [%s] %s\n",
|
||||
$e->getMessage(),
|
||||
(is_object($db)) ? $db->errorCode() : 'n/a',
|
||||
(is_object($db)) ? implode(' ', $db->errorInfo()) : 'n/a');
|
||||
}
|
||||
|
||||
print "done!";
|
||||
--XFAIL--
|
||||
Expected to fail in debug mode as PDO doesn't properly clean persistent connections
|
||||
--EXPECTF--
|
||||
Warning: PDO::exec(): MySQL server has gone away in %s on line %d
|
||||
|
||||
Warning: PDO::exec(): Error while reading SET_OPTION's EOF packet. PID=%d in %s on line %d
|
||||
done!
|
34
ext/pdo_mysql/tests/pdo_mysql_phpinfo.phpt
Normal file
34
ext/pdo_mysql/tests/pdo_mysql_phpinfo.phpt
Normal file
|
@ -0,0 +1,34 @@
|
|||
--TEST--
|
||||
MySQL PDO phpinfo() output
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
ob_start();
|
||||
phpinfo();
|
||||
$tmp = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
/* PDO Driver for MySQL, client library version => 6.0.3-alpha */
|
||||
$expected = sprintf('PDO Driver for MySQL, client library version => %s',
|
||||
$db->getAttribute(PDO::ATTR_CLIENT_VERSION));
|
||||
|
||||
if (false === stristr($tmp, $expected)) {
|
||||
// maybe its PDO_MYSQLND
|
||||
$expected = sprintf('PDO Driver for MySQL, mysql native driver version => %s',
|
||||
$db->getAttribute(PDO::ATTR_CLIENT_VERSION));
|
||||
if (false === stristr($tmp, $expected))
|
||||
printf("[001] Cannot find MySQL PDO driver line in phpinfo() output\n");
|
||||
}
|
||||
|
||||
print "done!";
|
||||
--EXPECT--
|
||||
done!
|
414
ext/pdo_mysql/tests/pdo_mysql_prepare_emulated.phpt
Normal file
414
ext/pdo_mysql/tests/pdo_mysql_prepare_emulated.phpt
Normal file
|
@ -0,0 +1,414 @@
|
|||
--TEST--
|
||||
MySQL PDO->prepare(), emulated PS
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
function prepex($offset, &$db, $query, $input_params = null, $error_info = null) {
|
||||
|
||||
try {
|
||||
|
||||
if (is_array($error_info) && isset($error_info['prepare']))
|
||||
$stmt = @$db->prepare($query);
|
||||
else
|
||||
$stmt = $db->prepare($query);
|
||||
|
||||
if (is_array($error_info) && isset($error_info['prepare'])) {
|
||||
$tmp = $db->errorInfo();
|
||||
|
||||
if (isset($error_info['prepare']['sqlstate']) &&
|
||||
($error_info['prepare']['sqlstate'] !== $tmp[0])) {
|
||||
printf("[%03d] prepare() - expecting SQLSTATE '%s' got '%s'\n",
|
||||
$offset, $error_info['prepare']['sqlstate'], $tmp[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($error_info['prepare']['mysql']) &&
|
||||
($error_info['prepare']['mysql'] !== $tmp[1])) {
|
||||
printf("[%03d] prepare() - expecting MySQL Code '%s' got '%s'\n",
|
||||
$offset, $error_info['prepare']['mysql'], $tmp[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_null($input_params))
|
||||
$input_params = array();
|
||||
|
||||
if (is_array($error_info) && isset($error_info['execute']))
|
||||
$ret = @$stmt->execute($input_params);
|
||||
else
|
||||
$ret = $stmt->execute($input_params);
|
||||
|
||||
if (!is_bool($ret))
|
||||
printf("[%03d] PDO::execute() should return a boolean value, got %s/%s\n",
|
||||
var_export($ret, true), $ret);
|
||||
|
||||
if (is_array($error_info) && isset($error_info['execute'])) {
|
||||
$tmp = $stmt->errorInfo();
|
||||
|
||||
if (isset($error_info['execute']['sqlstate']) &&
|
||||
($error_info['execute']['sqlstate'] !== $tmp[0])) {
|
||||
printf("[%03d] execute() - expecting SQLSTATE '%s' got '%s'\n",
|
||||
$offset, $error_info['execute']['sqlstate'], $tmp[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($error_info['execute']['mysql']) &&
|
||||
($error_info['execute']['mysql'] !== $tmp[1])) {
|
||||
printf("[%03d] execute() - expecting MySQL Code '%s' got '%s'\n",
|
||||
$offset, $error_info['execute']['mysql'], $tmp[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[%03d] %s, [%s} %s\n",
|
||||
$offset, $e->getMessage(),
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
try {
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1);
|
||||
if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to switch to emulated prepared statements, test will fail\n");
|
||||
|
||||
// TODO - that's PDO - you can prepare empty statements!
|
||||
prepex(3, $db, '',
|
||||
array(), array('execute' => array('sqlstate' => '42000')));
|
||||
|
||||
// lets be fair and do the most simple SELECT first
|
||||
$stmt = prepex(4, $db, 'SELECT 1 as "one"');
|
||||
var_dump($stmt->fetch(PDO::FETCH_ASSOC));
|
||||
|
||||
prepex(5, $db, 'DROP TABLE IF EXISTS test');
|
||||
prepex(6, $db, sprintf('CREATE TABLE test(id INT, label CHAR(255)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE));
|
||||
prepex(7, $db, 'INSERT INTO test(id, label) VALUES(1, ":placeholder")');
|
||||
$stmt = prepex(8, $db, 'SELECT label FROM test');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
prepex(9, $db, 'DELETE FROM test');
|
||||
prepex(10, $db, 'INSERT INTO test(id, label) VALUES(1, ":placeholder")',
|
||||
array(':placeholder' => 'first row'));
|
||||
$stmt = prepex(11, $db, 'SELECT label FROM test');
|
||||
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
prepex(12, $db, 'DELETE FROM test');
|
||||
prepex(13, $db, 'INSERT INTO test(id, label) VALUES(1, :placeholder)',
|
||||
array(':placeholder' => 'first row'));
|
||||
prepex(14, $db, 'INSERT INTO test(id, label) VALUES(2, :placeholder)',
|
||||
array(':placeholder' => 'second row'));
|
||||
$stmt = prepex(15, $db, 'SELECT label FROM test');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
// Is PDO fun?
|
||||
prepex(16, $db, 'SELECT label FROM test WHERE :placeholder > 1',
|
||||
array(':placeholder' => 'id'));
|
||||
prepex(17, $db, 'SELECT :placeholder FROM test WHERE id > 1',
|
||||
array(':placeholder' => 'id'));
|
||||
prepex(18, $db, 'SELECT :placeholder FROM test WHERE :placeholder > :placeholder',
|
||||
array(':placeholder' => 'test'));
|
||||
|
||||
for ($num_params = 2; $num_params < 100; $num_params++) {
|
||||
$params = array(':placeholder' => 'a');
|
||||
for ($i = 1; $i < $num_params; $i++) {
|
||||
$params[str_repeat('a', $i)] = 'some data';
|
||||
}
|
||||
prepex(19, $db, 'SELECT id, label FROM test WHERE label > :placeholder',
|
||||
$params, array('execute' => array('sqlstate' => 'HY093')));
|
||||
}
|
||||
|
||||
prepex(20, $db, 'DELETE FROM test');
|
||||
prepex(21, $db, 'INSERT INTO test(id, label) VALUES (1, :placeholder), (2, :placeholder)',
|
||||
array(':placeholder' => 'row'));
|
||||
$stmt = prepex(22, $db, 'SELECT id, label FROM test');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
$stmt = prepex(23, $db, 'SELECT id, label FROM test WHERE :placeholder IS NOT NULL',
|
||||
array(':placeholder' => 1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 2)
|
||||
printf("[024] '1' IS NOT NULL evaluates to true, expecting two rows, got %d rows\n", $tmp);
|
||||
|
||||
$stmt = prepex(25, $db, 'SELECT id, label FROM test WHERE :placeholder IS NULL',
|
||||
array(':placeholder' => 1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 0)
|
||||
printf("[026] '1' IS NOT NULL evaluates to true, expecting zero rows, got %d rows\n", $tmp);
|
||||
|
||||
prepex(27, $db, 'DROP TABLE IF EXISTS test');
|
||||
prepex(28, $db, 'CREATE TABLE test(id INT, label CHAR(255)) ENGINE=MyISAM');
|
||||
if (is_object(prepex(29, $db, 'CREATE FULLTEXT INDEX idx1 ON test(label)'))) {
|
||||
prepex(30, $db, 'INSERT INTO test(id, label) VALUES (1, :placeholder)',
|
||||
array(':placeholder' => 'MySQL is the best database in the world!'));
|
||||
prepex(31, $db, 'INSERT INTO test(id, label) VALUES (1, :placeholder)',
|
||||
array(':placeholder' => 'If I have the freedom to choose, I would always go again for the MySQL Server'));
|
||||
$stmt = prepex(32, $db, 'SELECT id, label FROM test WHERE MATCH label AGAINST (:placeholder)',
|
||||
array(':placeholder' => 'mysql'));
|
||||
/*
|
||||
Lets ignore this
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 2)
|
||||
printf("[033] Expecting two rows, got %d rows\n", $tmp);
|
||||
*/
|
||||
}
|
||||
prepex(34, $db, 'DELETE FROM test');
|
||||
prepex(35, $db, 'INSERT INTO test(id, label) VALUES (1, :placeholder), (2, :placeholder)',
|
||||
array(':placeholder' => 'row'));
|
||||
/*
|
||||
$stmt = prepex(36, $db, 'SELECT id, label FROM "test WHERE MATCH label AGAINST (:placeholder)',
|
||||
array(':placeholder' => 'row'),
|
||||
array('execute' => array('sqlstate' => '42000', 'mysql' => 1064)));
|
||||
*/
|
||||
$stmt = prepex(37, $db, 'SELECT id, label FROM \'test WHERE MATCH label AGAINST (:placeholder)',
|
||||
array(':placeholder' => 'row'),
|
||||
array('execute' => array('sqlstate' => '42000', 'mysql' => 1064)));
|
||||
|
||||
$stmt = prepex(38, $db, 'SELECT id, label AS "label" FROM test WHERE label = :placeholder',
|
||||
array(':placeholder' => 'row'));
|
||||
|
||||
$sql = sprintf("SELECT id, label FROM test WHERE (label LIKE %s) AND (id = :placeholder)",
|
||||
$db->quote('%ro%'));
|
||||
$stmt = prepex(39, $db, $sql, array('placeholder' => -1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 0)
|
||||
printf("[040] Expecting zero rows, got %d rows\n", $tmp);
|
||||
|
||||
|
||||
$sql = sprintf("SELECT id, label FROM test WHERE (id = :placeholder) OR (label LIKE %s)",
|
||||
$db->quote('%ro%'));
|
||||
$stmt = prepex(41, $db, $sql, array('placeholder' => 1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 2)
|
||||
printf("[042] Expecting two rows, got %d rows\n", $tmp);
|
||||
|
||||
$sql = "SELECT id, label FROM test WHERE id = :placeholder AND label = (SELECT label AS 'SELECT' FROM test WHERE id = :placeholder)";
|
||||
$stmt = prepex(43, $db, $sql, array('placeholder' => 1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 1)
|
||||
printf("[044] Expecting onw row, got %d rows\n", $tmp);
|
||||
|
||||
// and now, the same with anonymous placeholders...
|
||||
prepex(45, $db, 'DROP TABLE IF EXISTS test');
|
||||
prepex(46, $db, sprintf('CREATE TABLE test(id INT, label CHAR(255)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE));
|
||||
prepex(47, $db, 'INSERT INTO test(id, label) VALUES(1, "?")');
|
||||
$stmt = prepex(48, $db, 'SELECT label FROM test');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
prepex(49, $db, 'DELETE FROM test');
|
||||
prepex(50, $db, 'INSERT INTO test(id, label) VALUES(1, "?")',
|
||||
array('first row'));
|
||||
$stmt = prepex(51, $db, 'SELECT label FROM test');
|
||||
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
prepex(52, $db, 'DELETE FROM test');
|
||||
prepex(53, $db, 'INSERT INTO test(id, label) VALUES(1, ?)',
|
||||
array('first row'));
|
||||
prepex(54, $db, 'INSERT INTO test(id, label) VALUES(2, ?)',
|
||||
array('second row'));
|
||||
$stmt = prepex(55, $db, 'SELECT label FROM test');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
// Is PDO fun?
|
||||
prepex(56, $db, 'SELECT label FROM test WHERE ? > 1',
|
||||
array('id'));
|
||||
prepex(57, $db, 'SELECT ? FROM test WHERE id > 1',
|
||||
array('id'));
|
||||
prepex(58, $db, 'SELECT ? FROM test WHERE ? > ?',
|
||||
array('test'), array('execute' => array('sqlstate' => 'HY093')));
|
||||
|
||||
prepex(59, $db, 'SELECT ? FROM test WHERE ? > ?',
|
||||
array('id', 'label', 'value'));
|
||||
|
||||
for ($num_params = 2; $num_params < 100; $num_params++) {
|
||||
$params = array('a');
|
||||
for ($i = 1; $i < $num_params; $i++) {
|
||||
$params[] = 'some data';
|
||||
}
|
||||
prepex(60, $db, 'SELECT id, label FROM test WHERE label > ?',
|
||||
$params, array('execute' => array('sqlstate' => 'HY093')));
|
||||
}
|
||||
|
||||
prepex(61, $db, 'DELETE FROM test');
|
||||
prepex(62, $db, 'INSERT INTO test(id, label) VALUES (1, ?), (2, ?)',
|
||||
array('row', 'row'));
|
||||
$stmt = prepex(63, $db, 'SELECT id, label FROM test');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
$stmt = prepex(64, $db, 'SELECT id, label FROM test WHERE ? IS NOT NULL',
|
||||
array(1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 2)
|
||||
printf("[065] '1' IS NOT NULL evaluates to true, expecting two rows, got %d rows\n", $tmp);
|
||||
|
||||
$stmt = prepex(66, $db, 'SELECT id, label FROM test WHERE ? IS NULL',
|
||||
array(1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 0)
|
||||
printf("[067] '1' IS NOT NULL evaluates to true, expecting zero rows, got %d rows\n", $tmp);
|
||||
|
||||
prepex(68, $db, 'DROP TABLE IF EXISTS test');
|
||||
prepex(69, $db, 'CREATE TABLE test(id INT, label CHAR(255)) ENGINE=MyISAM');
|
||||
if (is_object(prepex(70, $db, 'CREATE FULLTEXT INDEX idx1 ON test(label)'))) {
|
||||
prepex(71, $db, 'INSERT INTO test(id, label) VALUES (1, ?)',
|
||||
array('MySQL is the best database in the world!'));
|
||||
prepex(72, $db, 'INSERT INTO test(id, label) VALUES (1, ?)',
|
||||
array('If I have the freedom to choose, I would always go again for the MySQL Server'));
|
||||
$stmt = prepex(73, $db, 'SELECT id, label FROM test WHERE MATCH label AGAINST (?)',
|
||||
array('mysql'));
|
||||
/*
|
||||
Lets ignore that
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 2)
|
||||
printf("[074] Expecting two rows, got %d rows\n", $tmp);
|
||||
*/
|
||||
}
|
||||
|
||||
prepex(74, $db, 'DELETE FROM test');
|
||||
prepex(75, $db, 'INSERT INTO test(id, label) VALUES (1, ?), (2, ?)',
|
||||
array('row', 'row'));
|
||||
|
||||
$stmt = prepex(76, $db, 'SELECT id, label FROM "test WHERE MATCH label AGAINST (?)',
|
||||
array('row'),
|
||||
array('execute' => array('sqlstate' => '42000', 'mysql' => 1064)));
|
||||
|
||||
/*
|
||||
TODO enable after fix
|
||||
$stmt = prepex(37, $db, 'SELECT id, label FROM \'test WHERE MATCH label AGAINST (:placeholder)',
|
||||
array(':placeholder' => 'row'),
|
||||
array('execute' => array('sqlstate' => '42000', 'mysql' => 1064)));
|
||||
*/
|
||||
|
||||
$stmt = prepex(78, $db, 'SELECT id, label AS "label" FROM test WHERE label = ?',
|
||||
array('row'));
|
||||
|
||||
$sql = sprintf("SELECT id, label FROM test WHERE (label LIKE %s) AND (id = ?)",
|
||||
$db->quote('%ro%'));
|
||||
$stmt = prepex(79, $db, $sql, array(-1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 0)
|
||||
printf("[080] Expecting zero rows, got %d rows\n", $tmp);
|
||||
|
||||
|
||||
$sql = sprintf("SELECT id, label FROM test WHERE (id = ?) OR (label LIKE %s)",
|
||||
$db->quote('%ro%'));
|
||||
$stmt = prepex(81, $db, $sql, array(1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 2)
|
||||
printf("[082] Expecting two rows, got %d rows\n", $tmp);
|
||||
|
||||
$sql = "SELECT id, label FROM test WHERE id = ? AND label = (SELECT label AS 'SELECT' FROM test WHERE id = ?)";
|
||||
$stmt = prepex(83, $db, $sql, array(1, 1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 1)
|
||||
printf("[084] Expecting one row, got %d rows\n", $tmp);
|
||||
|
||||
$sql = "SELECT id, label FROM test WHERE id = :placeholder AND label = (SELECT label AS 'SELECT' FROM test WHERE id = ?)";
|
||||
$stmt = prepex(85, $db, $sql, array(1, 1), array('execute' => array('sqlstate' => 'HY093')));
|
||||
if (is_object($stmt) && count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 0)
|
||||
printf("[086] Expecting no rows, got %d rows\n", $tmp);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--XFAIL--
|
||||
PDO's PS parser has some problems with invalid SQL and crashes from time to time
|
||||
(check with valgrind...)
|
||||
--EXPECTF--
|
||||
array(1) {
|
||||
["one"]=>
|
||||
string(1) "1"
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["label"]=>
|
||||
string(12) ":placeholder"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["label"]=>
|
||||
string(12) ":placeholder"
|
||||
}
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["label"]=>
|
||||
string(9) "first row"
|
||||
}
|
||||
[1]=>
|
||||
array(1) {
|
||||
["label"]=>
|
||||
string(10) "second row"
|
||||
}
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(3) "row"
|
||||
}
|
||||
[1]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "2"
|
||||
["label"]=>
|
||||
string(3) "row"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["label"]=>
|
||||
string(1) "?"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["label"]=>
|
||||
string(1) "?"
|
||||
}
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["label"]=>
|
||||
string(9) "first row"
|
||||
}
|
||||
[1]=>
|
||||
array(1) {
|
||||
["label"]=>
|
||||
string(10) "second row"
|
||||
}
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(3) "row"
|
||||
}
|
||||
[1]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "2"
|
||||
["label"]=>
|
||||
string(3) "row"
|
||||
}
|
||||
}
|
||||
done!
|
|
@ -0,0 +1,78 @@
|
|||
--TEST--
|
||||
MySQL PDO->prepare(), emulated PS, anonymous placeholder
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
try {
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1);
|
||||
if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to switch to emulated prepared statements, test will fail\n");
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$db->exec(sprintf('CREATE TABLE test(id INT, label CHAR(255)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE));
|
||||
|
||||
$stmt = $db->prepare('INSERT INTO test(id, label) VALUES(1, "?")');
|
||||
// you can bind as many values as you want no matter if they can be replaced or not
|
||||
$stmt->execute(array('first row'));
|
||||
if ('00000' !== $stmt->errorCode())
|
||||
printf("[003] Execute has failed, %s %s\n",
|
||||
var_export($stmt->errorCode(), true),
|
||||
var_export($stmt->errorInfo(), true));
|
||||
|
||||
$stmt = $db->prepare('SELECT id, label FROM test');
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
// now the same with native PS
|
||||
printf("now the same with native PS\n");
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[004] Unable to switch off emulated prepared statements, test will fail\n");
|
||||
|
||||
$db->exec('DELETE FROM test');
|
||||
$stmt = $db->prepare('INSERT INTO test(id, label) VALUES(1, "?")');
|
||||
// you can bind as many values as you want no matter if they can be replaced or not
|
||||
$stmt->execute(array('first row'));
|
||||
if ('00000' !== $stmt->errorCode())
|
||||
printf("[005] Execute has failed, %s %s\n",
|
||||
var_export($stmt->errorCode(), true),
|
||||
var_export($stmt->errorInfo(), true));
|
||||
|
||||
$stmt = $db->prepare('SELECT id, label FROM test');
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(1) "?"
|
||||
}
|
||||
}
|
||||
now the same with native PS
|
||||
[005] Execute has failed, 'HY093' array (
|
||||
0 => 'HY093',
|
||||
)
|
||||
array(0) {
|
||||
}
|
||||
done!
|
|
@ -0,0 +1,75 @@
|
|||
--TEST--
|
||||
MySQL PDO->prepare(), emulated PS, anonymous placeholder
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
// TODO: This test is MySQL version specific - for whatever reason
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
try {
|
||||
// native PS
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to switch off emulated prepared statements, test will fail\n");
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$db->exec(sprintf('CREATE TABLE test(id INT, label CHAR(255)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE));
|
||||
$db->exec('INSERT INTO test(id, label) VALUES (1, "row1")');
|
||||
|
||||
// So, what will happen? More placeholder but values and
|
||||
// placeholders in interesting places...
|
||||
$stmt = $db->prepare('SELECT ? FROM test WHERE ? > ?');
|
||||
$stmt->execute(array('test'));
|
||||
if ('00000' !== $stmt->errorCode()) {
|
||||
printf("[003] Execute has failed, %s %s\n",
|
||||
var_export($stmt->errorCode(), true),
|
||||
var_export($stmt->errorInfo(), true));
|
||||
}
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
// now the same with emulated PS
|
||||
printf("now the same with emulated PS\n");
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1);
|
||||
if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[004] Unable to switch on emulated prepared statements, test will fail\n");
|
||||
|
||||
$stmt = $db->prepare('SELECT ? FROM test WHERE ? > ?');
|
||||
$stmt->execute(array('test'));
|
||||
if ('00000' !== $stmt->errorCode())
|
||||
printf("[005] Execute has failed, %s %s\n",
|
||||
var_export($stmt->errorCode(), true),
|
||||
var_export($stmt->errorInfo(), true));
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec(sprintf('DROP TABLE IF EXISTS test'));
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number in %s on line %d
|
||||
[003] Execute has failed, 'HY093' array (
|
||||
0 => 'HY093',
|
||||
)
|
||||
array(0) {
|
||||
}
|
||||
now the same with emulated PS
|
||||
|
||||
Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in %s on line %d
|
||||
|
||||
Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number in %s on line 33
|
||||
[005] Execute has failed, 'HY093' array (
|
||||
0 => 'HY093',
|
||||
)
|
||||
array(0) {
|
||||
}
|
||||
done!
|
48
ext/pdo_mysql/tests/pdo_mysql_prepare_match_against.phpt
Normal file
48
ext/pdo_mysql/tests/pdo_mysql_prepare_match_against.phpt
Normal file
|
@ -0,0 +1,48 @@
|
|||
--TEST--
|
||||
MySQL PDO->prepare(MATCH ... AGAINST (:placeholder)) - similar: http://bugs.php.net/bug.php?id=41876
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
try {
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$db->exec('CREATE TABLE test(id INT, label CHAR(255)) ENGINE=MyISAM');
|
||||
$db->exec('CREATE FULLTEXT INDEX idx1 ON test(label)');
|
||||
|
||||
$stmt = $db->prepare('SELECT id, label FROM test WHERE MATCH label AGAINST (:placeholder)');
|
||||
$stmt->execute(array(':placeholder' => 'row'));
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
$stmt = $db->prepare('SELECT id, label FROM test WHERE MATCH label AGAINST (:placeholder)');
|
||||
$stmt->execute(array('placeholder' => 'row'));
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
$stmt = $db->prepare('SELECT id, label FROM test WHERE MATCH label AGAINST (?)');
|
||||
$stmt->execute(array('row'));
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
} catch (PDOException $e) {
|
||||
|
||||
printf("[001] %s, [%s} %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
array(0) {
|
||||
}
|
||||
array(0) {
|
||||
}
|
||||
array(0) {
|
||||
}
|
||||
done!
|
380
ext/pdo_mysql/tests/pdo_mysql_prepare_native.phpt
Normal file
380
ext/pdo_mysql/tests/pdo_mysql_prepare_native.phpt
Normal file
|
@ -0,0 +1,380 @@
|
|||
--TEST--
|
||||
MySQL PDO->prepare(), native PS
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
function prepex($offset, &$db, $query, $input_params = null, $error_info = null, $suppress_warning = false) {
|
||||
|
||||
try {
|
||||
|
||||
if ($suppress_warning || (is_array($error_info) && isset($error_info['prepare'])))
|
||||
$stmt = @$db->prepare($query);
|
||||
else
|
||||
$stmt = $db->prepare($query);
|
||||
|
||||
if (is_array($error_info) && isset($error_info['prepare'])) {
|
||||
$tmp = $db->errorInfo();
|
||||
|
||||
if (isset($error_info['prepare']['sqlstate']) &&
|
||||
($error_info['prepare']['sqlstate'] !== $tmp[0])) {
|
||||
printf("[%03d] prepare() - expecting SQLSTATE '%s' got '%s'\n",
|
||||
$offset, $error_info['prepare']['sqlstate'], $tmp[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($error_info['prepare']['mysql']) &&
|
||||
($error_info['prepare']['mysql'] !== $tmp[1])) {
|
||||
printf("[%03d] prepare() - expecting MySQL Code '%s' got '%s'\n",
|
||||
$offset, $error_info['prepare']['mysql'], $tmp[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_object($stmt))
|
||||
return false;
|
||||
|
||||
if (is_null($input_params))
|
||||
$input_params = array();
|
||||
// 5.0.18, 5.1.14 @ 15
|
||||
// printf("[%03d]\n", $offset);
|
||||
if ($suppress_warning || (is_array($error_info) && isset($error_info['execute'])))
|
||||
$ret = @$stmt->execute($input_params);
|
||||
else
|
||||
$ret = $stmt->execute($input_params);
|
||||
|
||||
if (!is_bool($ret))
|
||||
printf("[%03d] PDO::execute() should return a boolean value, got %s/%s\n",
|
||||
var_export($ret, true), $ret);
|
||||
|
||||
$tmp = $stmt->errorInfo();
|
||||
if (isset($tmp[1]) && ($tmp[1] == 2030)) {
|
||||
// Trying to hack around MySQL Server version dependent features
|
||||
// 2030 This command is not supported in the prepared statement protocol yet
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_array($error_info) && isset($error_info['execute'])) {
|
||||
|
||||
if (isset($error_info['execute']['sqlstate']) &&
|
||||
($error_info['execute']['sqlstate'] !== $tmp[0])) {
|
||||
printf("[%03d] execute() - expecting SQLSTATE '%s' got '%s'\n",
|
||||
$offset, $error_info['execute']['sqlstate'], $tmp[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($error_info['execute']['mysql']) &&
|
||||
($error_info['execute']['mysql'] !== $tmp[1])) {
|
||||
printf("[%03d] execute() - expecting MySQL Code '%s' got '%s'\n",
|
||||
$offset, $error_info['execute']['mysql'], $tmp[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[%03d] %s, [%s} %s\n",
|
||||
$offset, $e->getMessage(),
|
||||
$db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
try {
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to turn off emulated prepared statements\n");
|
||||
|
||||
// TODO - that's PDO - you can prepare empty statements!
|
||||
prepex(3, $db, '',
|
||||
array(), array('prepare' => array('sqlstate' => '42000')));
|
||||
|
||||
// lets be fair and do the most simple SELECT first
|
||||
$stmt = prepex(4, $db, 'SELECT 1 as "one"');
|
||||
if (MySQLPDOTest::isPDOMySQLnd())
|
||||
// native types - int
|
||||
$expected = array('one' => 1);
|
||||
else
|
||||
// always strings, like STRINGIFY flag
|
||||
$expected = array('one' => '1');
|
||||
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row !== $expected) {
|
||||
printf("[004a] Expecting %s got %s\n", var_export($expected, true), vat_export($row, true));
|
||||
}
|
||||
|
||||
prepex(5, $db, 'DROP TABLE IF EXISTS test');
|
||||
prepex(6, $db, sprintf('CREATE TABLE test(id INT, label CHAR(255)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE));
|
||||
prepex(7, $db, 'INSERT INTO test(id, label) VALUES(1, ":placeholder")');
|
||||
$stmt = prepex(8, $db, 'SELECT label FROM test ORDER BY id ASC');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
prepex(9, $db, 'DELETE FROM test');
|
||||
prepex(10, $db, 'INSERT INTO test(id, label) VALUES(1, :placeholder)',
|
||||
array(':placeholder' => 'first row'));
|
||||
prepex(11, $db, 'INSERT INTO test(id, label) VALUES(2, :placeholder)',
|
||||
array(':placeholder' => 'second row'));
|
||||
$stmt = prepex(12, $db, 'SELECT label FROM test ORDER BY id ASC');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
// Is PDO fun?
|
||||
$stmt = prepex(13, $db, 'SELECT label FROM test WHERE :placeholder > 1',
|
||||
array(':placeholder' => 'id'));
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
for ($num_params = 2; $num_params < 100; $num_params++) {
|
||||
$params = array(':placeholder' => 'a');
|
||||
for ($i = 1; $i < $num_params; $i++) {
|
||||
$params[str_repeat('a', $i)] = 'some data';
|
||||
}
|
||||
prepex(16, $db, 'SELECT id, label FROM test WHERE label > :placeholder',
|
||||
$params, array('execute' => array('sqlstate' => 'HY093')));
|
||||
}
|
||||
|
||||
$stmt = prepex(16, $db, 'SELECT id, label FROM test WHERE :placeholder IS NOT NULL',
|
||||
array(':placeholder' => 1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 2)
|
||||
printf("[017] '1' IS NOT NULL evaluates to true, expecting two rows, got %d rows\n", $tmp);
|
||||
|
||||
$stmt = prepex(18, $db, 'SELECT id, label FROM test WHERE :placeholder IS NULL',
|
||||
array(':placeholder' => 1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 0)
|
||||
printf("[019] '1' IS NOT NULL evaluates to true, expecting zero rows, got %d rows\n", $tmp);
|
||||
|
||||
prepex(20, $db, 'DROP TABLE IF EXISTS test');
|
||||
prepex(21, $db, 'CREATE TABLE test(id INT, label CHAR(255)) ENGINE=MyISAM');
|
||||
// Not every MySQL Server version supports this
|
||||
if (is_object(prepex(22, $db, 'CREATE FULLTEXT INDEX idx1 ON test(label)', null, null, true))) {
|
||||
prepex(23, $db, 'INSERT INTO test(id, label) VALUES (1, :placeholder)',
|
||||
array(':placeholder' => 'MySQL is the best database in the world!'));
|
||||
prepex(24, $db, 'INSERT INTO test(id, label) VALUES (2, :placeholder)',
|
||||
array(':placeholder' => 'If I have the freedom to choose, I would always go again for the MySQL Server'));
|
||||
$stmt = prepex(25, $db, 'SELECT id, label FROM test WHERE MATCH label AGAINST (:placeholder)',
|
||||
array(':placeholder' => 'mysql'), null, true);
|
||||
if (is_object($stmt)) {
|
||||
/*
|
||||
Lets ignore this
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 2)
|
||||
printf("[033] Expecting two rows, got %d rows\n", $tmp);
|
||||
*/
|
||||
$stmt = prepex(26, $db, 'SELECT id, label FROM test ORDER BY id ASC');
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 2)
|
||||
printf("[027] Expecting two rows, got %d rows\n", $tmp);
|
||||
|
||||
if ($tmp[0]['label'] !== 'MySQL is the best database in the world!') {
|
||||
printf("[028] INSERT seems to have failed, dumping data, check manually\n");
|
||||
var_dump($tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$db->exec('DELETE FROM test');
|
||||
$db->exec('INSERT INTO test(id, label) VALUES (1, "row1")');
|
||||
$db->exec('INSERT INTO test(id, label) VALUES (2, "row2")');
|
||||
|
||||
$sql = sprintf("SELECT id, label FROM test WHERE (label LIKE %s) AND (id = :placeholder)",
|
||||
$db->quote('%ro%'));
|
||||
$stmt = prepex(29, $db, $sql, array('placeholder' => -1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 0)
|
||||
printf("[030] Expecting zero rows, got %d rows\n", $tmp);
|
||||
|
||||
$sql = sprintf("SELECT id, label FROM test WHERE (id = :placeholder) OR (label LIKE %s)",
|
||||
$db->quote('%go%'));
|
||||
$stmt = prepex(31, $db, $sql, array('placeholder' => 1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 1)
|
||||
printf("[032] Expecting one row, got %d rows\n", $tmp);
|
||||
|
||||
// and now, the same with anonymous placeholders...
|
||||
prepex(33, $db, 'DROP TABLE IF EXISTS test');
|
||||
prepex(34, $db, sprintf('CREATE TABLE test(id INT, label CHAR(255)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE));
|
||||
prepex(35, $db, 'INSERT INTO test(id, label) VALUES(1, "?")');
|
||||
$stmt = prepex(36, $db, 'SELECT label FROM test');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
prepex(37, $db, 'DELETE FROM test');
|
||||
prepex(38, $db, 'INSERT INTO test(id, label) VALUES(1, ?)',
|
||||
array('first row'));
|
||||
prepex(39, $db, 'INSERT INTO test(id, label) VALUES(2, ?)',
|
||||
array('second row'));
|
||||
$stmt = prepex(40, $db, 'SELECT label FROM test');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
// Is PDO fun?
|
||||
prepex(40, $db, 'SELECT label FROM test WHERE ? > 1',
|
||||
array('id'));
|
||||
prepex(41, $db, 'SELECT ? FROM test WHERE id > 1',
|
||||
array('id'));
|
||||
prepex(42, $db, 'SELECT ? FROM test WHERE ? > ?',
|
||||
array('id', 'label', 'value'));
|
||||
|
||||
for ($num_params = 2; $num_params < 100; $num_params++) {
|
||||
$params = array('a');
|
||||
for ($i = 1; $i < $num_params; $i++) {
|
||||
$params[] = 'some data';
|
||||
}
|
||||
prepex(43, $db, 'SELECT id, label FROM test WHERE label > ?',
|
||||
$params, array('execute' => array('sqlstate' => 'HY093')));
|
||||
}
|
||||
|
||||
prepex(44, $db, 'DELETE FROM test');
|
||||
prepex(45, $db, 'INSERT INTO test(id, label) VALUES (1, ?), (2, ?)',
|
||||
array('row', 'row'));
|
||||
$stmt = prepex(46, $db, 'SELECT id, label FROM test');
|
||||
$tmp = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$exp = array(
|
||||
0 => array(
|
||||
"id" => "1",
|
||||
"label" => "row"
|
||||
),
|
||||
1 => array(
|
||||
"id" => "2",
|
||||
"label" => "row"
|
||||
),
|
||||
);
|
||||
|
||||
if (MySQLPDOTest::isPDOMySQLnd()) {
|
||||
// mysqlnd returns native types
|
||||
$exp[0]['id'] = 1;
|
||||
$exp[1]['id'] = 2;
|
||||
}
|
||||
if ($tmp !== $exp) {
|
||||
printf("[064] Results seem wrong. Please check dumps manually.\n");
|
||||
var_dump($exp);
|
||||
var_dump($tmp);
|
||||
}
|
||||
|
||||
$stmt = prepex(47, $db, 'SELECT id, label FROM test WHERE ? IS NOT NULL',
|
||||
array(1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 2)
|
||||
printf("[048] '1' IS NOT NULL evaluates to true, expecting two rows, got %d rows\n", $tmp);
|
||||
|
||||
$stmt = prepex(49, $db, 'SELECT id, label FROM test WHERE ? IS NULL',
|
||||
array(1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 0)
|
||||
printf("[050] '1' IS NOT NULL evaluates to true, expecting zero rows, got %d rows\n", $tmp);
|
||||
|
||||
prepex(51, $db, 'DROP TABLE IF EXISTS test');
|
||||
prepex(52, $db, 'CREATE TABLE test(id INT, label CHAR(255)) ENGINE=MyISAM');
|
||||
if (is_object(prepex(53, $db, 'CREATE FULLTEXT INDEX idx1 ON test(label)', null, null, true))) {
|
||||
prepex(54, $db, 'INSERT INTO test(id, label) VALUES (1, ?)',
|
||||
array('MySQL is the best database in the world!'));
|
||||
prepex(55, $db, 'INSERT INTO test(id, label) VALUES (1, ?)',
|
||||
array('If I have the freedom to choose, I would always go again for the MySQL Server'));
|
||||
$stmt = prepex(56, $db, 'SELECT id, label FROM test WHERE MATCH label AGAINST (?)',
|
||||
array('mysql'), null, true);
|
||||
/*
|
||||
Lets ignore that
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 2)
|
||||
printf("[074] Expecting two rows, got %d rows\n", $tmp);
|
||||
*/
|
||||
}
|
||||
|
||||
prepex(57, $db, 'DELETE FROM test');
|
||||
prepex(58, $db, 'INSERT INTO test(id, label) VALUES (1, ?), (2, ?)',
|
||||
array('row1', 'row2'));
|
||||
|
||||
/*
|
||||
TODO enable after fix
|
||||
$stmt = prepex(37, $db, 'SELECT id, label FROM \'test WHERE MATCH label AGAINST (:placeholder)',
|
||||
array(':placeholder' => 'row'),
|
||||
array('execute' => array('sqlstate' => '42000', 'mysql' => 1064)));
|
||||
*/
|
||||
|
||||
$stmt = prepex(59, $db, 'SELECT id, label AS "label" FROM test WHERE label = ?',
|
||||
array('row1'));
|
||||
$tmp = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$exp = array(
|
||||
0 => array("id" => "1", "label" => "row1")
|
||||
);
|
||||
|
||||
if (MySQLPDOTest::isPDOMySQLnd()) {
|
||||
// mysqlnd returns native types
|
||||
$exp[0]['id'] = 1;
|
||||
}
|
||||
if ($tmp !== $exp) {
|
||||
printf("[065] Results seem wrong. Please check dumps manually.\n");
|
||||
var_dump($exp);
|
||||
var_dump($tmp);
|
||||
}
|
||||
|
||||
$sql = sprintf("SELECT id, label FROM test WHERE (label LIKE %s) AND (id = ?)",
|
||||
$db->quote('%ro%'));
|
||||
$stmt = prepex(60, $db, $sql, array(-1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 0)
|
||||
printf("[061] Expecting zero rows, got %d rows\n", $tmp);
|
||||
|
||||
$sql = sprintf("SELECT id, label FROM test WHERE (id = ?) OR (label LIKE %s)",
|
||||
$db->quote('%ro%'));
|
||||
$stmt = prepex(61, $db, $sql, array(1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 2)
|
||||
printf("[062] Expecting two rows, got %d rows\n", $tmp);
|
||||
|
||||
$sql = "SELECT id, label FROM test WHERE id = ? AND label = (SELECT label AS 'SELECT' FROM test WHERE id = ?)";
|
||||
$stmt = prepex(63, $db, $sql, array(1, 1));
|
||||
if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 1)
|
||||
printf("[064] Expecting one row, got %d rows\n", $tmp);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["label"]=>
|
||||
string(12) ":placeholder"
|
||||
}
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["label"]=>
|
||||
string(9) "first row"
|
||||
}
|
||||
[1]=>
|
||||
array(1) {
|
||||
["label"]=>
|
||||
string(10) "second row"
|
||||
}
|
||||
}
|
||||
array(0) {
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["label"]=>
|
||||
string(1) "?"
|
||||
}
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["label"]=>
|
||||
string(9) "first row"
|
||||
}
|
||||
[1]=>
|
||||
array(1) {
|
||||
["label"]=>
|
||||
string(10) "second row"
|
||||
}
|
||||
}
|
||||
done!
|
|
@ -0,0 +1,91 @@
|
|||
--TEST--
|
||||
MySQL PDO->prepare(), native PS, clear line after error
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
try {
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$db->exec(sprintf('CREATE TABLE test(id INT, label CHAR(255)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE));
|
||||
|
||||
// We need to run the emulated version first. Native version will cause a fatal error
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1);
|
||||
if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to turn on emulated prepared statements\n");
|
||||
|
||||
// INSERT a single row
|
||||
$db->exec('INSERT INTO test(id, label) VALUES (1, "row1")');
|
||||
|
||||
$stmt = $db->prepare('SELECT unknown_column FROM test WHERE id > :placeholder ORDER BY id ASC');
|
||||
$stmt->execute(array(':placeholder' => 0));
|
||||
if ('00000' !== $stmt->errorCode())
|
||||
printf("[003] Execute has failed, %s %s\n",
|
||||
var_export($stmt->errorCode(), true),
|
||||
var_export($stmt->errorInfo(), true));
|
||||
|
||||
$stmt = $db->prepare('SELECT id, label FROM test WHERE id > :placeholder ORDER BY id ASC');
|
||||
$stmt->execute(array(':placeholder' => 0));
|
||||
if ('00000' !== $stmt->errorCode())
|
||||
printf("[004] Execute has failed, %s %s\n",
|
||||
var_export($stmt->errorCode(), true),
|
||||
var_export($stmt->errorInfo(), true));
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
// Native PS
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[005] Unable to turn off emulated prepared statements\n");
|
||||
|
||||
$stmt = $db->prepare('SELECT unknown_column FROM test WHERE id > :placeholder ORDER BY id ASC');
|
||||
$stmt->execute(array(':placeholder' => 0));
|
||||
if ('00000' !== $stmt->errorCode())
|
||||
printf("[006] Execute has failed, %s %s\n",
|
||||
var_export($stmt->errorCode(), true),
|
||||
var_export($stmt->errorInfo(), true));
|
||||
|
||||
$stmt = $db->prepare('SELECT id, label FROM test WHERE id > :placeholder ORDER BY id ASC');
|
||||
$stmt->execute(array(':placeholder' => 0));
|
||||
if ('00000' !== $stmt->errorCode())
|
||||
printf("[007] Execute has failed, %s %s\n",
|
||||
var_export($stmt->errorCode(), true),
|
||||
var_export($stmt->errorInfo(), true));
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: PDOStatement::execute(): SQLSTATE[42S22]: Column not found: 1054 Unknown column 'unknown_column' in 'field list' in %s on line %d
|
||||
[003] Execute has failed, '42S22' array (
|
||||
0 => '42S22',
|
||||
1 => 1054,
|
||||
2 => 'Unknown column \'unknown_column\' in \'field list\'',
|
||||
)
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(4) "row1"
|
||||
}
|
||||
}
|
||||
|
||||
Warning: PDO::prepare(): SQLSTATE[42S22]: Column not found: 1054 Unknown column 'unknown_column' in 'field list' in %s on line %d
|
||||
|
||||
Fatal error: Call to a member function execute() on a non-object in %s on line %d
|
44
ext/pdo_mysql/tests/pdo_mysql_prepare_native_column.phpt
Normal file
44
ext/pdo_mysql/tests/pdo_mysql_prepare_native_column.phpt
Normal file
|
@ -0,0 +1,44 @@
|
|||
--TEST--
|
||||
MySQL PDO->prepare(), native PS, named placeholder
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to turn off emulated prepared statements\n");
|
||||
|
||||
$stmt = $db->prepare("SELECT :param FROM test ORDER BY id ASC LIMIT 1");
|
||||
$stmt->execute(array(':param' => 'id'));
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
$db->prepare('SELECT :placeholder FROM test WHERE :placeholder > :placeholder');
|
||||
$stmt->execute(array(':placeholder' => 'test'));
|
||||
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["?"]=>
|
||||
string(2) "id"
|
||||
}
|
||||
}
|
||||
|
||||
Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in %s on line %d
|
||||
array(0) {
|
||||
}
|
||||
done!
|
|
@ -0,0 +1,136 @@
|
|||
--TEST--
|
||||
MySQL PDO->prepare(), native PS, named placeholder II
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
try {
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$db->exec(sprintf('CREATE TABLE test(id INT, label1 CHAR(255), label2 CHAR(255)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE));
|
||||
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to turn off emulated prepared statements\n");
|
||||
printf("Native...\n");
|
||||
|
||||
// INSERT a single row
|
||||
$stmt = $db->prepare('INSERT INTO test(id, label1, label2) VALUES (1, :placeholder, :placeholder)');
|
||||
|
||||
$stmt->execute(array(':placeholder' => 'row1'));
|
||||
if ('00000' !== $stmt->errorCode())
|
||||
printf("[003] Execute has failed, %s %s\n",
|
||||
var_export($stmt->errorCode(), true),
|
||||
var_export($stmt->errorInfo(), true));
|
||||
|
||||
// Ok, what has happened: anything inserted into the DB?
|
||||
$stmt = $db->prepare('SELECT id, label1, label2 FROM test WHERE id = 1');
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
// Now the same with emulated PS.
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1);
|
||||
if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[004] Unable to turn on emulated prepared statements\n");
|
||||
printf("Emulated...\n");
|
||||
|
||||
$stmt = $db->prepare('INSERT INTO test(id, label1, label2) VALUES(2, :placeholder, :placeholder)');
|
||||
// No replacement shall be made
|
||||
$stmt->execute(array(':placeholder' => 'row2'));
|
||||
if ('00000' !== $stmt->errorCode())
|
||||
printf("[005] Execute has failed, %s %s\n",
|
||||
var_export($stmt->errorCode(), true),
|
||||
var_export($stmt->errorInfo(), true));
|
||||
|
||||
// Now, what do we have in the DB?
|
||||
$stmt = $db->prepare('SELECT id, label1, label2 FROM test WHERE id = 2');
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
//
|
||||
// Another variation of the theme
|
||||
//
|
||||
|
||||
$db->exec('DELETE FROM test');
|
||||
$db->exec('INSERT INTO test (id, label1, label2) VALUES (1, "row1", "row2")');
|
||||
$sql = "SELECT id, label1 FROM test WHERE id = :placeholder AND label1 = (SELECT label1 AS 'SELECT' FROM test WHERE id = :placeholder)";
|
||||
|
||||
// emulated...
|
||||
$stmt = $db->prepare($sql);
|
||||
$stmt->execute(array(':placeholder' => 1));
|
||||
if ('00000' !== $stmt->errorCode())
|
||||
printf("[006] Execute has failed, %s %s\n",
|
||||
var_export($stmt->errorCode(), true),
|
||||
var_export($stmt->errorInfo(), true));
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
// native...
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[007] Unable to turn off emulated prepared statements\n");
|
||||
printf("Native...\n");
|
||||
|
||||
$stmt = $db->prepare($sql);
|
||||
$stmt->execute(array(':placeholder' => 1));
|
||||
if ('00000' !== $stmt->errorCode())
|
||||
printf("[008] Execute has failed, %s %s\n",
|
||||
var_export($stmt->errorCode(), true),
|
||||
var_export($stmt->errorInfo(), true));
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Native...
|
||||
|
||||
Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number in %s on line %d
|
||||
[003] Execute has failed, 'HY093' array (
|
||||
0 => 'HY093',
|
||||
)
|
||||
array(0) {
|
||||
}
|
||||
Emulated...
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(3) {
|
||||
["id"]=>
|
||||
string(1) "2"
|
||||
["label1"]=>
|
||||
string(4) "row2"
|
||||
["label2"]=>
|
||||
string(4) "row2"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["label1"]=>
|
||||
string(4) "row1"
|
||||
}
|
||||
}
|
||||
Native...
|
||||
|
||||
Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number in %s on line %d
|
||||
[008] Execute has failed, 'HY093' array (
|
||||
0 => 'HY093',
|
||||
)
|
||||
array(0) {
|
||||
}
|
||||
done!
|
|
@ -0,0 +1,35 @@
|
|||
--TEST--
|
||||
MySQL PDO->prepare(), native PS, mixed, wired style
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to turn off emulated prepared statements\n");
|
||||
|
||||
$stmt = $db->query('DELETE FROM test');
|
||||
$stmt = $db->prepare('INSERT INTO test(id, label) VALUES (1, ?), (2, ?)');
|
||||
$stmt->execute(array('a', 'b'));
|
||||
$stmt = $db->prepare("SELECT id, label FROM test WHERE id = :placeholder AND label = (SELECT label AS 'SELECT' FROM test WHERE id = ?)");
|
||||
$stmt->execute(array(1, 1));
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: PDO::prepare(): SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters in %s on line %d
|
||||
|
||||
Warning: PDO::prepare(): SQLSTATE[HY093]: Invalid parameter number in %s on line %d
|
||||
|
||||
Fatal error: Call to a member function execute() on a non-object in %s on line %d
|
|
@ -0,0 +1,85 @@
|
|||
--TEST--
|
||||
MySQL PDO->prepare(), native PS, named placeholder
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
try {
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$db->exec(sprintf('CREATE TABLE test(id INT, label CHAR(255)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE));
|
||||
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to turn off emulated prepared statements\n");
|
||||
|
||||
// INSERT a single row
|
||||
$stmt = $db->prepare('INSERT INTO test(id, label) VALUES (100, ":placeholder")');
|
||||
|
||||
// Yes, there is no placeholder to bind to and named placeholder
|
||||
// do not work with MySQL native PS, but lets see what happens!
|
||||
// The ':placeholder' is a string constant in the INSERT statement.
|
||||
// I would expect to get an error message, but this is not what happens.
|
||||
$stmt->execute(array(':placeholder' => 'row1'));
|
||||
if ('00000' !== $stmt->errorCode())
|
||||
printf("[003] Execute has failed, %s %s\n",
|
||||
var_export($stmt->errorCode(), true),
|
||||
var_export($stmt->errorInfo(), true));
|
||||
|
||||
// Ok, what has happened: anything inserted into the DB?
|
||||
$stmt = $db->prepare('SELECT id, label FROM test');
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
// Now the same with emulated PS.
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1);
|
||||
if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[004] Unable to turn on emulated prepared statements\n");
|
||||
|
||||
// Note that the "named placeholder" is enclosed by double quotes.
|
||||
$stmt = $db->prepare('INSERT INTO test(id, label) VALUES(101, ":placeholder")');
|
||||
// No replacement shall be made
|
||||
$stmt->execute(array(':placeholder' => 'row1'));
|
||||
// Again, I'd like to see an error message
|
||||
if ('00000' !== $stmt->errorCode())
|
||||
printf("[005] Execute has failed, %s %s\n",
|
||||
var_export($stmt->errorCode(), true),
|
||||
var_export($stmt->errorInfo(), true));
|
||||
|
||||
// Now, what do we have in the DB?
|
||||
$stmt = $db->prepare('SELECT id, label FROM test ORDER BY id');
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
[003] Execute has failed, 'HY093' array (
|
||||
0 => 'HY093',
|
||||
)
|
||||
array(0) {
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(3) "101"
|
||||
["label"]=>
|
||||
string(12) ":placeholder"
|
||||
}
|
||||
}
|
||||
done!
|
|
@ -0,0 +1,85 @@
|
|||
--TEST--
|
||||
MySQL PDO->prepare(),native PS, anonymous placeholder
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
try {
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1);
|
||||
if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to switch on emulated prepared statements, test will fail\n");
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$db->exec(sprintf('CREATE TABLE test(id INT, label CHAR(255)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE));
|
||||
$db->exec('INSERT INTO test(id, label) VALUES (1, "row1")');
|
||||
|
||||
$stmt = $db->prepare('SELECT ?, id, label FROM test WHERE ? = ? ORDER BY id ASC');
|
||||
$stmt->execute(array('id', 'label', 'label'));
|
||||
if ('00000' !== $stmt->errorCode())
|
||||
printf("[003] Execute has failed, %s %s\n",
|
||||
var_export($stmt->errorCode(), true),
|
||||
var_export($stmt->errorInfo(), true));
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
// now the same with native PS
|
||||
printf("now the same with native PS\n");
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[004] Unable to switch off emulated prepared statements, test will fail\n");
|
||||
|
||||
$stmt = $db->prepare('SELECT ?, id, label FROM test WHERE ? = ? ORDER BY id ASC');
|
||||
$stmt->execute(array('id', 'label', 'label'));
|
||||
if ('00000' !== $stmt->errorCode())
|
||||
printf("[005] Execute has failed, %s %s\n",
|
||||
var_export($stmt->errorCode(), true),
|
||||
var_export($stmt->errorInfo(), true));
|
||||
|
||||
$tmp = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (!MySQLPDOTest::isPDOMySQLnd()) {
|
||||
if (isset($tmp[0]['id'])) {
|
||||
// libmysql should return a string here whereas mysqlnd returns a native int
|
||||
if (gettype($tmp[0]['id']) == 'string')
|
||||
// convert to int for the test output...
|
||||
settype($tmp[0]['id'], 'integer');
|
||||
}
|
||||
}
|
||||
var_dump($tmp);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(4) "row1"
|
||||
}
|
||||
}
|
||||
now the same with native PS
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(3) {
|
||||
["?"]=>
|
||||
string(2) "id"
|
||||
["id"]=>
|
||||
int(1)
|
||||
["label"]=>
|
||||
string(4) "row1"
|
||||
}
|
||||
}
|
||||
done!
|
90
ext/pdo_mysql/tests/pdo_mysql_rollback.phpt
Normal file
90
ext/pdo_mysql/tests/pdo_mysql_rollback.phpt
Normal file
|
@ -0,0 +1,90 @@
|
|||
--TEST--
|
||||
PDO::rollBack()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
if (false == MySQLPDOTest::detect_transactional_mysql_engine($db))
|
||||
die("skip Transactional engine not found");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db, MySQLPDOTest::detect_transactional_mysql_engine($db));
|
||||
|
||||
$db->beginTransaction();
|
||||
|
||||
$row = $db->query('SELECT COUNT(*) AS _num FROM test')->fetch(PDO::FETCH_ASSOC);
|
||||
$num = $row['_num'];
|
||||
|
||||
$db->query('INSERT INTO test(id, label) VALUES (100, "z")');
|
||||
$num++;
|
||||
$row = $db->query('SELECT COUNT(*) AS _num FROM test')->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row['_num'] != $num)
|
||||
printf("[001] INSERT has failed, test will fail\n");
|
||||
|
||||
$db->rollBack();
|
||||
$num--;
|
||||
$row = $db->query('SELECT COUNT(*) AS _num FROM test')->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row['_num'] != $num)
|
||||
printf("[002] ROLLBACK has failed\n");
|
||||
|
||||
$db->beginTransaction();
|
||||
$db->query('INSERT INTO test(id, label) VALUES (100, "z")');
|
||||
$db->query('DROP TABLE IF EXISTS test2');
|
||||
$db->query('CREATE TABLE test2(id INT)');
|
||||
$num++;
|
||||
$db->rollBack();
|
||||
$row = $db->query('SELECT COUNT(*) AS _num FROM test')->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row['_num'] != $num)
|
||||
printf("[002] ROLLBACK should have no effect because of the implicit COMMIT
|
||||
triggered by DROP/CREATE TABLE\n");
|
||||
|
||||
|
||||
$db->query('DROP TABLE IF EXISTS test2');
|
||||
$db->query('CREATE TABLE test2(id INT) ENGINE=MyISAM');
|
||||
$db->beginTransaction();
|
||||
$db->query('INSERT INTO test2(id) VALUES (1)');
|
||||
$db->rollBack();
|
||||
$row = $db->query('SELECT COUNT(*) AS _num FROM test2')->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row['_num'] != 1)
|
||||
printf("[003] ROLLBACK should have no effect\n");
|
||||
|
||||
$db->query('DROP TABLE IF EXISTS test2');
|
||||
|
||||
$db->setAttribute(PDO::ATTR_AUTOCOMMIT, 1);
|
||||
$db->beginTransaction();
|
||||
$db->query('DELETE FROM test');
|
||||
$db->rollBack();
|
||||
var_dump($db->getAttribute(PDO::ATTR_AUTOCOMMIT));
|
||||
|
||||
$db->setAttribute(PDO::ATTR_AUTOCOMMIT, 0);
|
||||
$db->beginTransaction();
|
||||
$db->query('DELETE FROM test');
|
||||
$db->rollBack();
|
||||
var_dump($db->getAttribute(PDO::ATTR_AUTOCOMMIT));
|
||||
|
||||
$db->setAttribute(PDO::ATTR_AUTOCOMMIT, 1);
|
||||
$db->beginTransaction();
|
||||
$db->query('DELETE FROM test');
|
||||
$db->commit();
|
||||
var_dump($db->getAttribute(PDO::ATTR_AUTOCOMMIT));
|
||||
|
||||
$db->setAttribute(PDO::ATTR_AUTOCOMMIT, 0);
|
||||
$db->beginTransaction();
|
||||
$db->query('DELETE FROM test');
|
||||
$db->commit();
|
||||
var_dump($db->getAttribute(PDO::ATTR_AUTOCOMMIT));
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$db->exec('DROP TABLE IF EXISTS test2');
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
int(1)
|
||||
int(0)
|
||||
int(1)
|
||||
int(0)
|
||||
done!
|
110
ext/pdo_mysql/tests/pdo_mysql_stmt_bindcolumn.phpt
Normal file
110
ext/pdo_mysql/tests/pdo_mysql_stmt_bindcolumn.phpt
Normal file
|
@ -0,0 +1,110 @@
|
|||
--TEST--
|
||||
MySQL PDOStatement->bindColumn()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
try {
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1);
|
||||
if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to turn on emulated prepared statements\n");
|
||||
|
||||
$stmt = $db->prepare('SELECT id, label FROM test ORDER BY id ASC LIMIT 2');
|
||||
$stmt->execute();
|
||||
$id = $label = null;
|
||||
|
||||
if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT))
|
||||
printf("[003] Cannot bind integer column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR))
|
||||
printf("[004] Cannot bind string column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
$data = array();
|
||||
while ($stmt->fetch(PDO::FETCH_BOUND)) {
|
||||
printf("id = %s (%s) / label = %s (%s)\n",
|
||||
var_export($id, true), gettype($id),
|
||||
var_export($label, true), gettype($label));
|
||||
$data[] = array('id' => $id, 'label' => $label);
|
||||
}
|
||||
|
||||
$stmt = $db->query('SELECT id, label FROM test ORDER BY id ASC LIMIT 2');
|
||||
$index = 0;
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
if ($row['id'] != $data[$index]['id']) {
|
||||
printf("[005] Fetch bound and fetch assoc differ - column 'id', bound: %s/%s, assoc: %s/%s\n",
|
||||
var_export($data[$index]['id'], true), gettype($data[$index]['id']),
|
||||
var_export($row['id'], true), gettype($row['id']));
|
||||
}
|
||||
if ($row['label'] != $data[$index]['label']) {
|
||||
printf("[006] Fetch bound and fetch assoc differ - column 'label', bound: %s/%s, assoc: %s/%s\n",
|
||||
var_export($data[$index]['label'], true), gettype($data[$index]['label']),
|
||||
var_export($row['label'], true), gettype($row['label']));
|
||||
}
|
||||
$index++;
|
||||
}
|
||||
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[007] Unable to turn off emulated prepared statements\n");
|
||||
|
||||
$stmt = $db->prepare('SELECT id, label FROM test ORDER BY id ASC LIMIT 2, 2');
|
||||
$stmt->execute();
|
||||
$id = $label = null;
|
||||
|
||||
if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT))
|
||||
printf("[008] Cannot bind integer column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR))
|
||||
printf("[009] Cannot bind string column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
$data = array();
|
||||
while ($stmt->fetch(PDO::FETCH_BOUND)) {
|
||||
printf("id = %s (%s) / label = %s (%s)\n",
|
||||
var_export($id, true), gettype($id),
|
||||
var_export($label, true), gettype($label));
|
||||
$data[] = array('id' => $id, 'label' => $label);
|
||||
}
|
||||
|
||||
$stmt = $db->query('SELECT id, label FROM test ORDER BY id ASC LIMIT 2, 2');
|
||||
$index = 0;
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
if ($row['id'] != $data[$index]['id']) {
|
||||
printf("[010] Fetch bound and fetch assoc differ - column 'id', bound: %s/%s, assoc: %s/%s\n",
|
||||
var_export($data[$index]['id'], true), gettype($data[$index]['id']),
|
||||
var_export($row['id'], true), gettype($row['id']));
|
||||
}
|
||||
if ($row['label'] != $data[$index]['label']) {
|
||||
printf("[011] Fetch bound and fetch assoc differ - column 'label', bound: %s/%s, assoc: %s/%s\n",
|
||||
var_export($data[$index]['label'], true), gettype($data[$index]['label']),
|
||||
var_export($row['label'], true), gettype($row['label']));
|
||||
}
|
||||
$index++;
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
id = 1 (integer) / label = 'a' (string)
|
||||
id = 2 (integer) / label = 'b' (string)
|
||||
id = 3 (integer) / label = 'c' (string)
|
||||
id = 4 (integer) / label = 'd' (string)
|
||||
done!
|
155
ext/pdo_mysql/tests/pdo_mysql_stmt_bindparam.phpt
Normal file
155
ext/pdo_mysql/tests/pdo_mysql_stmt_bindparam.phpt
Normal file
|
@ -0,0 +1,155 @@
|
|||
--TEST--
|
||||
MySQL PDOStatement->bindParam()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
|
||||
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
function pdo_mysql_stmt_bindparam($db, $offset) {
|
||||
|
||||
$stmt = $db->prepare('SELECT id, label FROM test WHERE id > ? ORDER BY id ASC LIMIT 2');
|
||||
$in = 0;
|
||||
if (!$stmt->bindParam(1, $in))
|
||||
printf("[%03d + 1] Cannot bind parameter, %s %s\n", $offset,
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
$stmt->execute();
|
||||
$id = $label = null;
|
||||
|
||||
if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT))
|
||||
printf("[%03d + 2] Cannot bind integer column, %s %s\n", $offset,
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR))
|
||||
printf("[%03d + 3] Cannot bind string column, %s %s\n", $offset,
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
while ($stmt->fetch(PDO::FETCH_BOUND))
|
||||
printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
|
||||
$in,
|
||||
var_export($id, true), gettype($id),
|
||||
var_export($label, true), gettype($label));
|
||||
|
||||
printf("Same again...\n");
|
||||
$stmt->execute();
|
||||
while ($stmt->fetch(PDO::FETCH_BOUND))
|
||||
printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
|
||||
$in,
|
||||
var_export($id, true), gettype($id),
|
||||
var_export($label, true), gettype($label));
|
||||
|
||||
// NULL values
|
||||
printf("NULL...\n");
|
||||
$stmt = $db->prepare('INSERT INTO test(id, label) VALUES (100, ?)');
|
||||
$label = null;
|
||||
if (!$stmt->bindParam(1, $label))
|
||||
printf("[%03d + 4] Cannot bind parameter, %s %s\n", $offset,
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->execute())
|
||||
printf("[%03d + 5] Cannot execute statement, %s %s\n", $offset,
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
/* NOTE: you cannot use PDO::query() with unbuffered, native PS - see extra test */
|
||||
$stmt = $db->prepare('SELECT id, NULL AS _label FROM test WHERE label IS NULL');
|
||||
$stmt->execute();
|
||||
|
||||
$id = $label = 'bogus';
|
||||
if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT))
|
||||
printf("[%03d + 6] Cannot bind NULL column, %s %s\n", $offset,
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR))
|
||||
printf("[%03d + 3] Cannot bind string column, %s %s\n", $offset,
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
while ($stmt->fetch(PDO::FETCH_BOUND))
|
||||
printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
|
||||
$in,
|
||||
var_export($id, true), gettype($id),
|
||||
var_export($label, true), gettype($label));
|
||||
}
|
||||
|
||||
try {
|
||||
printf("Emulated PS...\n");
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1);
|
||||
if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to turn on emulated prepared statements\n");
|
||||
|
||||
printf("Buffered...\n");
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
|
||||
pdo_mysql_stmt_bindparam($db, 3);
|
||||
|
||||
printf("Unbuffered...\n");
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
|
||||
pdo_mysql_stmt_bindparam($db, 4);
|
||||
|
||||
printf("Native PS...\n");
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[004] Unable to turn off emulated prepared statements\n");
|
||||
|
||||
printf("Buffered...\n");
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
|
||||
pdo_mysql_stmt_bindparam($db, 5);
|
||||
|
||||
printf("Unbuffered...\n");
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
|
||||
pdo_mysql_stmt_bindparam($db, 6);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Emulated PS...
|
||||
Buffered...
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
Same again...
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
NULL...
|
||||
in = 0 -> id = 100 (integer) / label = NULL (NULL)
|
||||
Unbuffered...
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
Same again...
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
NULL...
|
||||
in = 0 -> id = 100 (integer) / label = NULL (NULL)
|
||||
Native PS...
|
||||
Buffered...
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
Same again...
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
NULL...
|
||||
in = 0 -> id = 100 (integer) / label = NULL (NULL)
|
||||
Unbuffered...
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
Same again...
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
NULL...
|
||||
in = 0 -> id = 100 (integer) / label = NULL (NULL)
|
||||
done!
|
169
ext/pdo_mysql/tests/pdo_mysql_stmt_bindparam_types.phpt
Normal file
169
ext/pdo_mysql/tests/pdo_mysql_stmt_bindparam_types.phpt
Normal file
|
@ -0,0 +1,169 @@
|
|||
--TEST--
|
||||
MySQL PDOStatement->bindParam() - SQL column types
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
function pdo_mysql_stmt_bindparam_types_do($db, $offset, $native, $sql_type, $value) {
|
||||
|
||||
if ($native)
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
else
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1);
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$sql = sprintf('CREATE TABLE test(id INT, label %s) ENGINE=%s', $sql_type, MySQLPDOTest::getTableEngine());
|
||||
if ((!$stmt = @$db->prepare($sql)) || (!@$stmt->execute()))
|
||||
// Server might not support column type - skip it
|
||||
return true;
|
||||
|
||||
$stmt = $db->prepare('INSERT INTO test(id, label) VALUES (1, ?)');
|
||||
if (!$stmt->bindParam(1, $value)) {
|
||||
printf("[%03d/%s + 1] %s\n", $offset, ($native) ? 'native' : 'emulated',
|
||||
var_export($stmt->errorInfo(), true));
|
||||
return false;
|
||||
}
|
||||
if (!$stmt->execute()) {
|
||||
printf("[%03d/%s + 2] %s\n", $offset, ($native) ? 'native' : 'emulated',
|
||||
var_export($stmt->errorInfo(), true));
|
||||
return false;
|
||||
}
|
||||
|
||||
$stmt = $db->query('SELECT id, label FROM test');
|
||||
$id = $label = null;
|
||||
if (!$stmt->bindColumn(1, $id)) {
|
||||
printf("[%03d/%s + 3] %s\n", $offset, ($native) ? 'native' : 'emulated',
|
||||
var_export($stmt->errorInfo(), true));
|
||||
return false;
|
||||
}
|
||||
if (!$stmt->bindColumn(2, $label)) {
|
||||
printf("[%03d/%s + 4] %s\n", $offset, ($native) ? 'native' : 'emulated',
|
||||
var_export($stmt->errorInfo(), true));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$stmt->fetch(PDO::FETCH_BOUND)) {
|
||||
printf("[%03d/%s + 5] %s\n", $offset, ($native) ? 'native' : 'emulated',
|
||||
var_export($stmt->errorInfo(), true));
|
||||
return false;
|
||||
}
|
||||
$stmt->closeCursor();
|
||||
|
||||
if ($label != $value) {
|
||||
printf("[%03d/%s + 6] Got %s expecting %s - plase check manually\n",
|
||||
$offset, ($native) ? 'native' : 'emulated',
|
||||
var_export($label, true), var_export($value, true));
|
||||
// fall through
|
||||
}
|
||||
|
||||
$stmt->execute();
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if (empty($row)) {
|
||||
printf("[%03d/%s + 7] %s\n", $offset, ($native) ? 'native' : 'emulated',
|
||||
var_export($stmt->errorInfo(), true));
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($row['label'] != $value) {
|
||||
printf("[%03d/%s + 8] Got %s expecting %s - plase check manually\n",
|
||||
$offset, ($native) ? 'native' : 'emulated',
|
||||
var_export($row['label'], true), var_export($value, true));
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($row['label'] != $label) {
|
||||
printf("[%03d/%s + 9] Got %s from FETCH_ASSOC and %s from FETCH_BOUND- plase check manually\n",
|
||||
$offset, ($native) ? 'native' : 'emulated',
|
||||
var_export($row['label'], true), var_export($value, true));
|
||||
return false;
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
return true;
|
||||
}
|
||||
|
||||
function pdo_mysql_stmt_bindparam_types($db, $offset, $sql_type, $value) {
|
||||
|
||||
pdo_mysql_stmt_bindparam_types_do($db, $offset, true, $sql_type, $value);
|
||||
pdo_mysql_stmt_bindparam_types_do($db, $offset, false, $sql_type, $value);
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
// pdo_mysql_stmt_bindparam_types($db, 2, 'BIT(8)', 1);
|
||||
pdo_mysql_stmt_bindparam_types($db, 3, 'TINYINT', -127);
|
||||
pdo_mysql_stmt_bindparam_types($db, 4, 'TINYINT UNSIGNED', 255);
|
||||
pdo_mysql_stmt_bindparam_types($db, 5, 'BOOLEAN', 1);
|
||||
pdo_mysql_stmt_bindparam_types($db, 6, 'SMALLINT', -32768);
|
||||
pdo_mysql_stmt_bindparam_types($db, 7, 'SMALLINT UNSIGNED', 65535);
|
||||
pdo_mysql_stmt_bindparam_types($db, 8, 'MEDIUMINT', -8388608);
|
||||
pdo_mysql_stmt_bindparam_types($db, 9, 'MEDIUMINT UNSIGNED', 16777215);
|
||||
pdo_mysql_stmt_bindparam_types($db, 10, 'INT', -2147483648);
|
||||
pdo_mysql_stmt_bindparam_types($db, 11, 'INT UNSIGNED', 4294967295);
|
||||
pdo_mysql_stmt_bindparam_types($db, 12, 'BIGINT', -1000);
|
||||
pdo_mysql_stmt_bindparam_types($db, 13, 'BIGINT UNSIGNED', 1000);
|
||||
pdo_mysql_stmt_bindparam_types($db, 14, 'REAL', -1000);
|
||||
pdo_mysql_stmt_bindparam_types($db, 15, 'REAL UNSIGNED', 1000);
|
||||
pdo_mysql_stmt_bindparam_types($db, 16, 'REAL ZEROFILL', '0000000000000000000000');
|
||||
pdo_mysql_stmt_bindparam_types($db, 17, 'REAL UNSIGNED ZEROFILL', '0000000000000000000010');
|
||||
pdo_mysql_stmt_bindparam_types($db, 18, 'DOUBLE', -1000);
|
||||
pdo_mysql_stmt_bindparam_types($db, 19, 'DOUBLE UNSIGNED', 1000);
|
||||
pdo_mysql_stmt_bindparam_types($db, 20, 'DOUBLE ZEROFILL', '000000000000');
|
||||
pdo_mysql_stmt_bindparam_types($db, 21, 'DOUBLE ZEROFILL UNSIGNED', '000000001000');
|
||||
pdo_mysql_stmt_bindparam_types($db, 22, 'FLOAT', -1000);
|
||||
pdo_mysql_stmt_bindparam_types($db, 23, 'FLOAT UNSIGNED', 1000);
|
||||
pdo_mysql_stmt_bindparam_types($db, 24, 'FLOAT ZEROFILL', '000000000000');
|
||||
pdo_mysql_stmt_bindparam_types($db, 25, 'FLOAT ZEROFILL UNSIGNED', '000000001000');
|
||||
pdo_mysql_stmt_bindparam_types($db, 26, 'DECIMAL', -1000);
|
||||
pdo_mysql_stmt_bindparam_types($db, 27, 'DECIMAL UNSIGNED', 1000);
|
||||
pdo_mysql_stmt_bindparam_types($db, 28, 'DECIMAL ZEROFILL', '000000000000');
|
||||
pdo_mysql_stmt_bindparam_types($db, 29, 'DECIMAL ZEROFILL UNSIGNED', '000000001000');
|
||||
pdo_mysql_stmt_bindparam_types($db, 30, 'NUMERIC', -1000);
|
||||
pdo_mysql_stmt_bindparam_types($db, 31, 'NUMERIC UNSIGNED', 1000);
|
||||
pdo_mysql_stmt_bindparam_types($db, 32, 'NUMERIC ZEROFILL', '000000000000');
|
||||
pdo_mysql_stmt_bindparam_types($db, 33, 'NUMERIC ZEROFILL UNSIGNED', '000000001000');
|
||||
pdo_mysql_stmt_bindparam_types($db, 34, 'DATE', '2008-04-23');
|
||||
pdo_mysql_stmt_bindparam_types($db, 35, 'TIME', '16:43:12');
|
||||
pdo_mysql_stmt_bindparam_types($db, 36, 'TIMESTAMP', '2008-04-23 16:44:53');
|
||||
pdo_mysql_stmt_bindparam_types($db, 37, 'DATETIME', '2008-04-23 16:44:53');
|
||||
pdo_mysql_stmt_bindparam_types($db, 38, 'YEAR', '2008');
|
||||
pdo_mysql_stmt_bindparam_types($db, 39, 'CHAR(1)', 'a');
|
||||
pdo_mysql_stmt_bindparam_types($db, 40, 'CHAR(255)', 'abc');
|
||||
pdo_mysql_stmt_bindparam_types($db, 41, 'VARCHAR(255)', str_repeat('a', 255));
|
||||
pdo_mysql_stmt_bindparam_types($db, 42, 'BINARY(255)', str_repeat('a', 255));
|
||||
pdo_mysql_stmt_bindparam_types($db, 43, 'VARBINARY(255)', str_repeat('a', 255));
|
||||
pdo_mysql_stmt_bindparam_types($db, 44, 'TINYBLOB', str_repeat('a', 255));
|
||||
pdo_mysql_stmt_bindparam_types($db, 45, 'BLOB', str_repeat('b', 300));
|
||||
pdo_mysql_stmt_bindparam_types($db, 46, 'MEDIUMBLOB', str_repeat('b', 300));
|
||||
pdo_mysql_stmt_bindparam_types($db, 47, 'LONGBLOB', str_repeat('b', 300));
|
||||
pdo_mysql_stmt_bindparam_types($db, 48, 'TINYTEXT', str_repeat('c', 255));
|
||||
pdo_mysql_stmt_bindparam_types($db, 49, 'TINYTEXT BINARY', str_repeat('c', 255));
|
||||
pdo_mysql_stmt_bindparam_types($db, 50, 'TEXT', str_repeat('d', 300));
|
||||
pdo_mysql_stmt_bindparam_types($db, 51, 'TEXT BINARY', str_repeat('d', 300));
|
||||
pdo_mysql_stmt_bindparam_types($db, 52, 'MEDIUMTEXT', str_repeat('d', 300));
|
||||
pdo_mysql_stmt_bindparam_types($db, 53, 'MEDIUMTEXT BINARY', str_repeat('d', 300));
|
||||
pdo_mysql_stmt_bindparam_types($db, 54, 'LONGTEXT', str_repeat('d', 300));
|
||||
pdo_mysql_stmt_bindparam_types($db, 55, 'LONGTEXT BINARY', str_repeat('d', 300));
|
||||
pdo_mysql_stmt_bindparam_types($db, 56, "ENUM('yes', 'no') DEFAULT 'yes'", "no");
|
||||
pdo_mysql_stmt_bindparam_types($db, 57, "SET('yes', 'no') DEFAULT 'yes'", "no");
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
done!
|
332
ext/pdo_mysql/tests/pdo_mysql_stmt_bindvalue.phpt
Normal file
332
ext/pdo_mysql/tests/pdo_mysql_stmt_bindvalue.phpt
Normal file
|
@ -0,0 +1,332 @@
|
|||
--TEST--
|
||||
MySQL PDOStatement->bindValue()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
printf("Testing native PS...\n");
|
||||
try {
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to turn off emulated prepared statements\n");
|
||||
|
||||
printf("Binding variable...\n");
|
||||
$stmt = $db->prepare('SELECT id, label FROM test WHERE id > ? ORDER BY id ASC LIMIT 2');
|
||||
$in = 0;
|
||||
if (!$stmt->bindValue(1, $in))
|
||||
printf("[003] Cannot bind value, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
$stmt->execute();
|
||||
$id = $label = null;
|
||||
|
||||
if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT))
|
||||
printf("[004] Cannot bind integer column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR))
|
||||
printf("[005] Cannot bind string column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
while ($stmt->fetch(PDO::FETCH_BOUND))
|
||||
printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
|
||||
$in,
|
||||
var_export($id, true), gettype($id),
|
||||
var_export($label, true), gettype($label));
|
||||
|
||||
printf("Binding value and not variable...\n");
|
||||
if (!$stmt->bindValue(1, 0))
|
||||
printf("[006] Cannot bind value, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
$stmt->execute();
|
||||
$id = $label = null;
|
||||
|
||||
if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT))
|
||||
printf("[007] Cannot bind integer column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR))
|
||||
printf("[008] Cannot bind string column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
while ($stmt->fetch(PDO::FETCH_BOUND))
|
||||
printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
|
||||
$in,
|
||||
var_export($id, true), gettype($id),
|
||||
var_export($label, true), gettype($label));
|
||||
|
||||
printf("Binding variable which references another variable...\n");
|
||||
$in = 0;
|
||||
$in_ref = &$in;
|
||||
if (!$stmt->bindValue(1, $in_ref))
|
||||
printf("[009] Cannot bind value, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
$stmt->execute();
|
||||
$id = $label = null;
|
||||
|
||||
if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT))
|
||||
printf("[010] Cannot bind integer column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR))
|
||||
printf("[011] Cannot bind string column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
while ($stmt->fetch(PDO::FETCH_BOUND))
|
||||
printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
|
||||
$in,
|
||||
var_export($id, true), gettype($id),
|
||||
var_export($label, true), gettype($label));
|
||||
|
||||
|
||||
printf("Binding a variable and a value...\n");
|
||||
$stmt = $db->prepare('SELECT id, label FROM test WHERE id > ? AND id <= ? ORDER BY id ASC LIMIT 2');
|
||||
$in = 0;
|
||||
if (!$stmt->bindValue(1, $in))
|
||||
printf("[012] Cannot bind value, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->bindValue(2, 2))
|
||||
printf("[013] Cannot bind value, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
$stmt->execute();
|
||||
$id = $label = null;
|
||||
|
||||
if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT))
|
||||
printf("[014] Cannot bind integer column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR))
|
||||
printf("[015] Cannot bind string column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
while ($stmt->fetch(PDO::FETCH_BOUND))
|
||||
printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
|
||||
$in,
|
||||
var_export($id, true), gettype($id),
|
||||
var_export($label, true), gettype($label));
|
||||
|
||||
printf("Binding a variable to two placeholders and changing the variable value in between the binds...\n");
|
||||
// variable value change shall have no impact
|
||||
$stmt = $db->prepare('SELECT id, label FROM test WHERE id > ? AND id <= ? ORDER BY id ASC LIMIT 2');
|
||||
$in = 0;
|
||||
if (!$stmt->bindValue(1, $in))
|
||||
printf("[016] Cannot bind value, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
$in = 2;
|
||||
if (!$stmt->bindValue(2, $in))
|
||||
printf("[017] Cannot bind value, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
$stmt->execute();
|
||||
$id = $label = null;
|
||||
|
||||
if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT))
|
||||
printf("[018] Cannot bind integer column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR))
|
||||
printf("[019] Cannot bind string column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
while ($stmt->fetch(PDO::FETCH_BOUND))
|
||||
printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
|
||||
$in,
|
||||
var_export($id, true), gettype($id),
|
||||
var_export($label, true), gettype($label));
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
printf("Testing emulated PS...\n");
|
||||
try {
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1);
|
||||
if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to turn on emulated prepared statements\n");
|
||||
|
||||
printf("Binding variable...\n");
|
||||
$stmt = $db->prepare('SELECT id, label FROM test WHERE id > ? ORDER BY id ASC LIMIT 2');
|
||||
$in = 0;
|
||||
if (!$stmt->bindValue(1, $in))
|
||||
printf("[003] Cannot bind value, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
$stmt->execute();
|
||||
$id = $label = null;
|
||||
|
||||
if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT))
|
||||
printf("[004] Cannot bind integer column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR))
|
||||
printf("[005] Cannot bind string column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
while ($stmt->fetch(PDO::FETCH_BOUND))
|
||||
printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
|
||||
$in,
|
||||
var_export($id, true), gettype($id),
|
||||
var_export($label, true), gettype($label));
|
||||
|
||||
printf("Binding value and not variable...\n");
|
||||
if (!$stmt->bindValue(1, 0))
|
||||
printf("[006] Cannot bind value, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
$stmt->execute();
|
||||
$id = $label = null;
|
||||
|
||||
if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT))
|
||||
printf("[007] Cannot bind integer column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR))
|
||||
printf("[008] Cannot bind string column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
while ($stmt->fetch(PDO::FETCH_BOUND))
|
||||
printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
|
||||
$in,
|
||||
var_export($id, true), gettype($id),
|
||||
var_export($label, true), gettype($label));
|
||||
|
||||
printf("Binding variable which references another variable...\n");
|
||||
$in = 0;
|
||||
$in_ref = &$in;
|
||||
if (!$stmt->bindValue(1, $in_ref))
|
||||
printf("[009] Cannot bind value, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
$stmt->execute();
|
||||
$id = $label = null;
|
||||
|
||||
if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT))
|
||||
printf("[010] Cannot bind integer column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR))
|
||||
printf("[011] Cannot bind string column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
while ($stmt->fetch(PDO::FETCH_BOUND))
|
||||
printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
|
||||
$in,
|
||||
var_export($id, true), gettype($id),
|
||||
var_export($label, true), gettype($label));
|
||||
|
||||
|
||||
printf("Binding a variable and a value...\n");
|
||||
$stmt = $db->prepare('SELECT id, label FROM test WHERE id > ? AND id <= ? ORDER BY id ASC LIMIT 2');
|
||||
$in = 0;
|
||||
if (!$stmt->bindValue(1, $in))
|
||||
printf("[012] Cannot bind value, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->bindValue(2, 2))
|
||||
printf("[013] Cannot bind value, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
$stmt->execute();
|
||||
$id = $label = null;
|
||||
|
||||
if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT))
|
||||
printf("[014] Cannot bind integer column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR))
|
||||
printf("[015] Cannot bind string column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
while ($stmt->fetch(PDO::FETCH_BOUND))
|
||||
printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
|
||||
$in,
|
||||
var_export($id, true), gettype($id),
|
||||
var_export($label, true), gettype($label));
|
||||
|
||||
printf("Binding a variable to two placeholders and changing the variable value in between the binds...\n");
|
||||
// variable value change shall have no impact
|
||||
$stmt = $db->prepare('SELECT id, label FROM test WHERE id > ? AND id <= ? ORDER BY id ASC LIMIT 2');
|
||||
$in = 0;
|
||||
if (!$stmt->bindValue(1, $in))
|
||||
printf("[016] Cannot bind value, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
$in = 2;
|
||||
if (!$stmt->bindValue(2, $in))
|
||||
printf("[017] Cannot bind value, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
$stmt->execute();
|
||||
$id = $label = null;
|
||||
|
||||
if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT))
|
||||
printf("[018] Cannot bind integer column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR))
|
||||
printf("[019] Cannot bind string column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
while ($stmt->fetch(PDO::FETCH_BOUND))
|
||||
printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
|
||||
$in,
|
||||
var_export($id, true), gettype($id),
|
||||
var_export($label, true), gettype($label));
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Testing native PS...
|
||||
Binding variable...
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
Binding value and not variable...
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
Binding variable which references another variable...
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
Binding a variable and a value...
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
Binding a variable to two placeholders and changing the variable value in between the binds...
|
||||
in = 2 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 2 -> id = 2 (integer) / label = 'b' (string)
|
||||
Testing emulated PS...
|
||||
Binding variable...
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
Binding value and not variable...
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
Binding variable which references another variable...
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
Binding a variable and a value...
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
Binding a variable to two placeholders and changing the variable value in between the binds...
|
||||
in = 2 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 2 -> id = 2 (integer) / label = 'b' (string)
|
||||
done!
|
143
ext/pdo_mysql/tests/pdo_mysql_stmt_blobfromsteam.phpt
Normal file
143
ext/pdo_mysql/tests/pdo_mysql_stmt_blobfromsteam.phpt
Normal file
|
@ -0,0 +1,143 @@
|
|||
--TEST--
|
||||
MySQL PDOStatement - inserting BLOB from stream
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
|
||||
$tmp = MySQLPDOTest::getTempDir();
|
||||
if (!$tmp)
|
||||
die("skip Can't create temporary file");
|
||||
|
||||
$file = $tmp . DIRECTORY_SEPARATOR . 'pdoblob.tst';
|
||||
$fp = fopen($file, 'w');
|
||||
if (!$fp)
|
||||
die("skip Can't create temporary file");
|
||||
|
||||
if (4 != fwrite($fp, 'test')) {
|
||||
die("skip Can't create temporary file");
|
||||
}
|
||||
fclose($fp);
|
||||
clearstatcache();
|
||||
|
||||
if (!file_exists($file))
|
||||
die("skip Can't create temporary file");
|
||||
|
||||
unlink($file);
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
|
||||
function blob_from_stream($offset, $db, $file, $blob) {
|
||||
|
||||
@unlink($file);
|
||||
clearstatcache();
|
||||
if (file_exists($file)) {
|
||||
printf("[%03d + 1] Cannot remove old test file\n", $offset);
|
||||
return false;
|
||||
}
|
||||
|
||||
$fp = fopen($file, 'w');
|
||||
if (!$fp || !fwrite($fp, $blob)) {
|
||||
printf("[%03d + 2] Cannot create test file '%s'\n", $offset, $file);
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
clearstatcache();
|
||||
if (!file_exists($file)) {
|
||||
printf("[%03d + 3] Failed to create test file '%s'\n", $offset, $file);
|
||||
return false;
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$sql = sprintf('CREATE TABLE test(id INT, label BLOB) ENGINE=%s', PDO_MYSQL_TEST_ENGINE);
|
||||
$db->exec($sql);
|
||||
|
||||
if (!$stmt = $db->prepare('INSERT INTO test(id, label) VALUES (?, ?)')) {
|
||||
printf("[%03d + 4] %s\n", $offset, var_export($db->errorInfo(), true));
|
||||
return false;
|
||||
}
|
||||
|
||||
$fp = fopen($file, 'r');
|
||||
if (!$fp) {
|
||||
printf("[%03d + 5] Cannot create test file '%s'\n", $offset, $file);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$id = 1;
|
||||
$stmt->bindParam(1, $id);
|
||||
if (true !== ($tmp = $stmt->bindParam(2, $fp, PDO::PARAM_LOB))) {
|
||||
printf("[%03d + 6] Expecting true, got %s. %s\n",
|
||||
$offset,
|
||||
var_export($tmp, true),
|
||||
var_export($db->errorInfo(), true));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (true !== $stmt->execute()) {
|
||||
printf("[%03d + 7] Failed to INSERT data, %s\n", $offset, var_export($stmt->errorInfo(), true));
|
||||
return false;
|
||||
}
|
||||
|
||||
$stmt2 = $db->query('SELECT id, label FROM test WHERE id = 1');
|
||||
$row = $stmt2->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row['label'] != $blob) {
|
||||
printf("[%03d + 8] INSERT and/or SELECT has failed, dumping data.\n", $offset);
|
||||
var_dump($row);
|
||||
var_dump($blob);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Lets test the chr(0) handling in case the streaming has failed:
|
||||
// is the bug about chr(0) or the streaming...
|
||||
$db->exec('DELETE FROM test');
|
||||
$stmt = $db->prepare('INSERT INTO test(id, label) VALUES (?, ?)');
|
||||
$stmt->bindParam(1, $id);
|
||||
$stmt->bindParam(2, $blob);
|
||||
if (true !== $stmt->execute())
|
||||
printf("[%03d + 9] %s\n", $offset, var_export($stmt->errorInfo(), true));
|
||||
|
||||
$stmt2 = $db->query('SELECT id, label FROM test WHERE id = 1');
|
||||
$row = $stmt2->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row['label'] != $blob) {
|
||||
printf("[%03d + 10] INSERT and/or SELECT has failed, dumping data.\n", $offset);
|
||||
var_dump($row);
|
||||
var_dump($blob);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$db = MySQLPDOTest::factory();
|
||||
$blob = 'I am a mighty BLOB!' . chr(0) . "I am a binary thingie!";
|
||||
$tmp = MySQLPDOTest::getTempDir();
|
||||
$file = $tmp . DIRECTORY_SEPARATOR . 'pdoblob.tst';
|
||||
|
||||
try {
|
||||
|
||||
printf("Emulated PS...\n");
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
|
||||
blob_from_stream(10, $db, $file, $blob);
|
||||
|
||||
printf("Native PS...\n");
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
|
||||
blob_from_stream(30, $db, $file, $blob);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
@unlink($file);
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Emulated PS...
|
||||
Native PS...
|
||||
done!
|
91
ext/pdo_mysql/tests/pdo_mysql_stmt_blobs.phpt
Normal file
91
ext/pdo_mysql/tests/pdo_mysql_stmt_blobs.phpt
Normal file
|
@ -0,0 +1,91 @@
|
|||
--TEST--
|
||||
MySQL Prepared Statements and BLOBs
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
$blobs = array(
|
||||
'TINYBLOB' => 255,
|
||||
'TINYTEXT' => 255,
|
||||
'BLOB' => 32767,
|
||||
'TEXT' => 32767,
|
||||
'MEDIUMBLOB' => 100000,
|
||||
'MEDIUMTEXT' => 100000,
|
||||
'LONGBLOB' => 100000,
|
||||
'LONGTEXT' => 100000,
|
||||
);
|
||||
|
||||
function test_blob($db, $offset, $sql_type, $test_len) {
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$db->exec(sprintf('CREATE TABLE test(id INT, label %s) ENGINE=%s', $sql_type, PDO_MYSQL_TEST_ENGINE));
|
||||
|
||||
$value = str_repeat('a', $test_len);
|
||||
$stmt = $db->prepare('INSERT INTO test(id, label) VALUES (?, ?)');
|
||||
$stmt->bindValue(1, 1);
|
||||
$stmt->bindValue(2, $value);
|
||||
if (!$stmt->execute()) {
|
||||
printf("[%03d + 1] %d %s\n",
|
||||
$offset, $stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
return false;
|
||||
}
|
||||
|
||||
$stmt = $db->query('SELECT id, label FROM test');
|
||||
$id = $label = NULL;
|
||||
$stmt->bindColumn(1, $id, PDO::PARAM_INT);
|
||||
$stmt->bindColumn(2, $label, PDO::PARAM_LOB);
|
||||
|
||||
if (!$stmt->fetch(PDO::FETCH_BOUND)) {
|
||||
printf("[%03d + 2] %d %s\n",
|
||||
$offset, $stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($label !== $value) {
|
||||
printf("[%03d + 3] Returned value seems to be wrong (%d vs. %d charachters). Check manually\n",
|
||||
$offset, strlen($label), strlen($value));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (1 != $id) {
|
||||
printf("[%03d + 3] Returned id column value seems wrong, expecting 1 got %s.\n",
|
||||
$offset, var_export($id, true));
|
||||
return false;
|
||||
}
|
||||
|
||||
$stmt = $db->query('SELECT id, label FROM test');
|
||||
$ret = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($ret['label'] !== $value) {
|
||||
printf("[%03d + 3] Returned value seems to be wrong (%d vs. %d charachters). Check manually\n",
|
||||
$offset, strlen($ret['label']), strlen($value));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (1 != $ret['id']) {
|
||||
printf("[%03d + 3] Returned id column value seems wrong, expecting 1 got %s.\n",
|
||||
$offset, var_export($ret['id'], true));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$offset = 0;
|
||||
foreach ($blobs as $sql_type => $test_len) {
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
|
||||
test_blob($db, ++$offset, $sql_type, $test_len);
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
|
||||
test_blob($db, ++$offset, $sql_type, $test_len);
|
||||
}
|
||||
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
done!
|
172
ext/pdo_mysql/tests/pdo_mysql_stmt_closecursor.phpt
Normal file
172
ext/pdo_mysql/tests/pdo_mysql_stmt_closecursor.phpt
Normal file
|
@ -0,0 +1,172 @@
|
|||
--TEST--
|
||||
MySQL PDOStatement->closeCursor()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
/* TODO the results look wrong, why do we get 2014 with buffered AND unbuffered queries */
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
function pdo_mysql_stmt_closecursor($db) {
|
||||
|
||||
// This one should fail. I let it fail to prove that closeCursor() makes a difference.
|
||||
// If no error messages gets printed do not know if proper usage of closeCursor() makes any
|
||||
// difference or not. That's why we need to cause an error here.
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
|
||||
$stmt1 = $db->query('SELECT id, label FROM test ORDER BY id ASC');
|
||||
// query() shall fail!
|
||||
$stmt2 = $db->query('SELECT id, label FROM test ORDER BY id ASC');
|
||||
$stmt1->closeCursor();
|
||||
|
||||
// This is proper usage of closeCursor(). It shall prevent any further error messages.
|
||||
if (MySQLPDOTest::isPDOMySQLnd()) {
|
||||
$stmt1 = $db->query('SELECT id, label FROM test ORDER BY id ASC');
|
||||
} else {
|
||||
// see pdo_mysql_stmt_unbuffered_2050.phpt for an explanation
|
||||
unset($stmt1);
|
||||
$stmt1 = $db->query('SELECT id, label FROM test ORDER BY id ASC');
|
||||
}
|
||||
// fetch only the first rows and let closeCursor() clean up
|
||||
$row1 = $stmt1->fetch(PDO::FETCH_ASSOC);
|
||||
$stmt1->closeCursor();
|
||||
|
||||
$stmt2 = $db->prepare('UPDATE test SET label = ? WHERE id = ?');
|
||||
$stmt2->bindValue(1, "z");
|
||||
|
||||
$stmt2->bindValue(2, $row1['id']);
|
||||
$stmt2->execute();
|
||||
$stmt2->closeCursor();
|
||||
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
|
||||
// check if changing the fetch mode from unbuffered to buffered will
|
||||
// cause any harm to a statement created prior to the change
|
||||
$stmt1->execute();
|
||||
$row2 = $stmt1->fetch(PDO::FETCH_ASSOC);
|
||||
$stmt1->closeCursor();
|
||||
if (!isset($row2['label']) || ('z' !== $row2['label']))
|
||||
printf("Expecting array(id => 1, label => z) got %s\n", var_export($row2, true));
|
||||
unset($stmt1);
|
||||
|
||||
$stmt1 = $db->query('SELECT id, label FROM test ORDER BY id ASC');
|
||||
// should work
|
||||
$stmt2 = $db->query('SELECT id, label FROM test ORDER BY id ASC');
|
||||
$stmt1->closeCursor();
|
||||
|
||||
$stmt1 = $db->query('SELECT id, label FROM test ORDER BY id ASC');
|
||||
// fetch only the first rows and let closeCursor() clean up
|
||||
$row3 = $stmt1->fetch(PDO::FETCH_ASSOC);
|
||||
$stmt1->closeCursor();
|
||||
assert($row3 == $row2);
|
||||
|
||||
$stmt2 = $db->prepare('UPDATE test SET label = ? WHERE id = ?');
|
||||
$stmt2->bindValue(1, "a");
|
||||
$stmt2->bindValue(2, $row1['id']);
|
||||
$stmt2->execute();
|
||||
$stmt2->closeCursor();
|
||||
|
||||
$stmt1->execute();
|
||||
$row4 = $stmt1->fetch(PDO::FETCH_ASSOC);
|
||||
$stmt1->closeCursor();
|
||||
assert($row4 == $row1);
|
||||
|
||||
$offset = 0;
|
||||
$stmt = $db->prepare('SELECT id, label FROM test WHERE id > ? ORDER BY id ASC LIMIT 2');
|
||||
$in = 0;
|
||||
if (!$stmt->bindParam(1, $in))
|
||||
printf("[%03d + 1] Cannot bind parameter, %s %s\n", $offset,
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
$stmt->execute();
|
||||
$id = $label = null;
|
||||
|
||||
if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT))
|
||||
printf("[%03d + 2] Cannot bind integer column, %s %s\n", $offset,
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR))
|
||||
printf("[%03d + 3] Cannot bind string column, %s %s\n", $offset,
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
while ($stmt->fetch(PDO::FETCH_BOUND))
|
||||
printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
|
||||
$in,
|
||||
var_export($id, true), gettype($id),
|
||||
var_export($label, true), gettype($label));
|
||||
|
||||
$stmt->closeCursor();
|
||||
$stmt->execute();
|
||||
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
|
||||
printf("Testing emulated PS...\n");
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1);
|
||||
if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to turn on emulated prepared statements\n");
|
||||
|
||||
printf("Buffered...\n");
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
pdo_mysql_stmt_closecursor($db);
|
||||
|
||||
printf("Unbuffered...\n");
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
pdo_mysql_stmt_closecursor($db);
|
||||
|
||||
printf("Testing native PS...\n");
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to turn off emulated prepared statements\n");
|
||||
|
||||
printf("Buffered...\n");
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
|
||||
pdo_mysql_stmt_closecursor($db);
|
||||
|
||||
printf("Unbuffered...\n");
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
|
||||
pdo_mysql_stmt_closecursor($db);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Testing emulated PS...
|
||||
Buffered...
|
||||
|
||||
Warning: PDO::query(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
Unbuffered...
|
||||
|
||||
Warning: PDO::query(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
Testing native PS...
|
||||
Buffered...
|
||||
|
||||
Warning: PDO::query(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
Unbuffered...
|
||||
|
||||
Warning: PDO::query(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
done!
|
69
ext/pdo_mysql/tests/pdo_mysql_stmt_closecursor_empty.phpt
Normal file
69
ext/pdo_mysql/tests/pdo_mysql_stmt_closecursor_empty.phpt
Normal file
|
@ -0,0 +1,69 @@
|
|||
--TEST--
|
||||
MySQL PDOStatement->closeCursor()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
|
||||
try {
|
||||
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to turn off emulated prepared statements\n");
|
||||
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
$stmt = $db->prepare('SELECT id, label FROM test WHERE id > ? ORDER BY id ASC LIMIT 2');
|
||||
$in = 0;
|
||||
if (!$stmt->bindParam(1, $in))
|
||||
printf("[003] Cannot bind parameter, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
$stmt->execute();
|
||||
$id = $label = null;
|
||||
|
||||
if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT))
|
||||
printf("[004] Cannot bind integer column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR))
|
||||
printf("[005] Cannot bind string column, %s %s\n",
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
|
||||
while ($stmt->fetch(PDO::FETCH_BOUND))
|
||||
printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
|
||||
$in,
|
||||
var_export($id, true), gettype($id),
|
||||
var_export($label, true), gettype($label));
|
||||
|
||||
$stmt->closeCursor();
|
||||
$stmt->execute();
|
||||
while ($stmt->fetch(PDO::FETCH_BOUND))
|
||||
printf("in = %d -> id = %s (%s) / label = %s (%s)\n",
|
||||
$in,
|
||||
var_export($id, true), gettype($id),
|
||||
var_export($label, true), gettype($label));
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
in = 0 -> id = 1 (integer) / label = 'a' (string)
|
||||
in = 0 -> id = 2 (integer) / label = 'b' (string)
|
||||
done!
|
65
ext/pdo_mysql/tests/pdo_mysql_stmt_columncount.phpt
Normal file
65
ext/pdo_mysql/tests/pdo_mysql_stmt_columncount.phpt
Normal file
|
@ -0,0 +1,65 @@
|
|||
--TEST--
|
||||
MySQL PDOStatement->columnCount()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
// The only purpose of this is to check if emulated and native PS
|
||||
// return the same. If it works for one, it should work for all.
|
||||
// Internal data structures should be the same in both cases.
|
||||
printf("Testing emulated PS...\n");
|
||||
try {
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1);
|
||||
if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to turn on emulated prepared statements\n");
|
||||
|
||||
$stmt = $db->prepare('SELECT id, label, "?" as foo FROM test');
|
||||
$stmt->execute();
|
||||
var_dump($stmt->columnCount());
|
||||
|
||||
$stmt = $db->query('SELECT * FROM test');
|
||||
var_dump($stmt->columnCount());
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
printf("Testing native PS...\n");
|
||||
try {
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[004] Unable to turn off emulated prepared statements\n");
|
||||
|
||||
$stmt = $db->prepare('SELECT id, label, "?" as foo, "TODO - Stored Procedure" as bar FROM test');
|
||||
$stmt->execute();
|
||||
var_dump($stmt->columnCount());
|
||||
|
||||
$stmt = $db->query('SELECT * FROM test');
|
||||
var_dump($stmt->columnCount());
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[003] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Testing emulated PS...
|
||||
int(3)
|
||||
int(2)
|
||||
Testing native PS...
|
||||
int(4)
|
||||
int(2)
|
||||
done!
|
61
ext/pdo_mysql/tests/pdo_mysql_stmt_errorcode.phpt
Normal file
61
ext/pdo_mysql/tests/pdo_mysql_stmt_errorcode.phpt
Normal file
|
@ -0,0 +1,61 @@
|
|||
--TEST--
|
||||
MySQL PDOStatement->errorCode();
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS ihopeitdoesnotexist');
|
||||
|
||||
printf("Testing emulated PS...\n");
|
||||
try {
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1);
|
||||
if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to turn on emulated prepared statements\n");
|
||||
|
||||
$stmt = $db->prepare('SELECT id FROM ihopeitdoesnotexist ORDER BY id ASC');
|
||||
$stmt->execute();
|
||||
var_dump($stmt->errorCode());
|
||||
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
printf("Testing native PS...\n");
|
||||
try {
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[004] Unable to turn off emulated prepared statements\n");
|
||||
|
||||
$stmt = $db->prepare('SELECT id FROM ihopeitdoesnotexist ORDER BY id ASC');
|
||||
$stmt->execute();
|
||||
var_dump($stmt->errorCode());
|
||||
|
||||
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[003] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Testing emulated PS...
|
||||
|
||||
Warning: PDOStatement::execute(): SQLSTATE[42S02]: Base table or view not found: 1146 Table '%s.ihopeitdoesnotexist' doesn't exist in %s on line %d
|
||||
string(5) "42S02"
|
||||
Testing native PS...
|
||||
|
||||
Warning: PDO::prepare(): SQLSTATE[42S02]: Base table or view not found: 1146 Table '%s.ihopeitdoesnotexist' doesn't exist in %s on line %d
|
||||
|
||||
Fatal error: Call to a member function execute() on a non-object in %s on line %d
|
119
ext/pdo_mysql/tests/pdo_mysql_stmt_errorinfo.phpt
Normal file
119
ext/pdo_mysql/tests/pdo_mysql_stmt_errorinfo.phpt
Normal file
|
@ -0,0 +1,119 @@
|
|||
--TEST--
|
||||
MySQL PDOStatement->errorInfo();
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
printf("Testing emulated PS...\n");
|
||||
try {
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1);
|
||||
if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to turn on emulated prepared statements\n");
|
||||
|
||||
$stmt = $db->prepare('SELECT id FROM ihopeitdoesnotexist ORDER BY id ASC');
|
||||
var_dump($stmt->errorInfo());
|
||||
$stmt->execute();
|
||||
var_dump($stmt->errorInfo());
|
||||
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
$stmt = $db->prepare('SELECT label FROM test ORDER BY id ASC LIMIT 1');
|
||||
$db->exec('DROP TABLE test');
|
||||
var_dump($stmt->execute());
|
||||
var_dump($stmt->errorInfo());
|
||||
var_dump($db->errorInfo());
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorInfo(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
printf("Testing native PS...\n");
|
||||
try {
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[004] Unable to turn off emulated prepared statements\n");
|
||||
|
||||
$stmt = $db->prepare('SELECT id FROM ihopeitdoesnotexist ORDER BY id ASC');
|
||||
var_dump($stmt);
|
||||
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
$stmt = $db->prepare('SELECT label FROM test ORDER BY id ASC LIMIT 1');
|
||||
var_dump($stmt->errorInfo());
|
||||
$db->exec('DROP TABLE test');
|
||||
$stmt->execute();
|
||||
var_dump($stmt->errorInfo());
|
||||
var_dump($db->errorInfo());
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[003] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorInfo(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Testing emulated PS...
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(0) ""
|
||||
}
|
||||
|
||||
Warning: PDOStatement::execute(): SQLSTATE[42S02]: Base table or view not found: 1146 Table '%s.ihopeitdoesnotexist' doesn't exist in %s on line %d
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(5) "42S02"
|
||||
[1]=>
|
||||
int(1146)
|
||||
[2]=>
|
||||
string(%d) "Table '%s.ihopeitdoesnotexist' doesn't exist"
|
||||
}
|
||||
|
||||
Warning: PDOStatement::execute(): SQLSTATE[42S02]: Base table or view not found: 1146 Table '%s.test' doesn't exist in %s on line %d
|
||||
bool(false)
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(5) "42S02"
|
||||
[1]=>
|
||||
int(1146)
|
||||
[2]=>
|
||||
string(%d) "Table '%s.test' doesn't exist"
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(5) "00000"
|
||||
}
|
||||
Testing native PS...
|
||||
|
||||
Warning: PDO::prepare(): SQLSTATE[42S02]: Base table or view not found: 1146 Table '%s.ihopeitdoesnotexist' doesn't exist in %s on line %d
|
||||
bool(false)
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(0) ""
|
||||
}
|
||||
|
||||
Warning: PDOStatement::execute(): SQLSTATE[42S02]: Base table or view not found: 1146 Table '%s.test' doesn't exist in %s on line %d
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(5) "42S02"
|
||||
[1]=>
|
||||
int(1146)
|
||||
[2]=>
|
||||
string(%d) "Table '%s.test' doesn't exist"
|
||||
}
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(5) "00000"
|
||||
[1]=>
|
||||
int(1146)
|
||||
[2]=>
|
||||
string(%d) "Table '%s.ihopeitdoesnotexist' doesn't exist"
|
||||
}
|
||||
done!
|
187
ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_non_select.phpt
Normal file
187
ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_non_select.phpt
Normal file
|
@ -0,0 +1,187 @@
|
|||
--TEST--
|
||||
MySQL PDOStatement->execute()/fetch(), Non-SELECT
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
try {
|
||||
|
||||
// Emulated PS first
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1);
|
||||
if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to turn on emulated prepared statements\n");
|
||||
|
||||
if (!is_object($stmt = $db->query('DESCRIBE test id')))
|
||||
printf("[003] Emulated PS, DESCRIBE failed, %s\n", var_export($db->errorInfo(), true));
|
||||
|
||||
$describe = array();
|
||||
$valid = false;
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$describe[] = $row;
|
||||
foreach ($row as $column => $value)
|
||||
if (isset($row['field']) && ($row['field'] == 'id'))
|
||||
$valid = true;
|
||||
}
|
||||
if (empty($describe))
|
||||
printf("[004] Emulated PS, DESCRIBE returned no results\n");
|
||||
else if (!$valid)
|
||||
printf("[005] Emulated PS, DESCRIBE, returned data seems wrong, dumping %s\n",
|
||||
var_export($describe, true));
|
||||
|
||||
if (!is_object($stmt = $db->query('SHOW ENGINES')))
|
||||
printf("[006] Emulated PS, SHOW failed, %s\n", var_export($db->errorInfo(), true));
|
||||
|
||||
$show = array();
|
||||
$valid = false;
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$show[] = $row;
|
||||
foreach ($row as $column => $value)
|
||||
// MyISAM engine should be part of _every_ MySQL today
|
||||
if ($value == 'MyISAM')
|
||||
$valid = true;
|
||||
}
|
||||
if (empty($show))
|
||||
printf("[007] Emulated PS, SHOW returned no results\n");
|
||||
else if (!$valid)
|
||||
printf("[008] Emulated PS, SHOW data seems wrong, dumping %s\n",
|
||||
var_export($show, true));
|
||||
|
||||
if (!is_object($stmt = $db->query("EXPLAIN SELECT id FROM test")))
|
||||
printf("[009] Emulated PS, EXPLAIN returned no results\n");
|
||||
|
||||
$explain = array();
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
|
||||
$explain[] = $row;
|
||||
|
||||
if (empty($explain))
|
||||
printf("[010] Emulated PS, EXPLAIN returned no results\n");
|
||||
|
||||
// And now native PS
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[011] Unable to turn off emulated prepared statements\n");
|
||||
|
||||
$native_support = 'no';
|
||||
if ($db->exec('PREPARE mystmt FROM "DESCRIBE test id"')) {
|
||||
$native_support = 'yes';
|
||||
$db->exec('DEALLOCATE PREPARE mystmt');
|
||||
}
|
||||
|
||||
if (!is_object($stmt = $db->query('DESCRIBE test id')))
|
||||
printf("[012] Native PS (native support: %s), DESCRIBE failed, %s\n",
|
||||
$native_support,
|
||||
var_export($db->errorInfo(), true));
|
||||
|
||||
$describe_native = array();
|
||||
$valid = false;
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$describe_native[] = $row;
|
||||
foreach ($row as $column => $value)
|
||||
if (isset($row['field']) && ($row['field'] == 'id'))
|
||||
$valid = true;
|
||||
}
|
||||
if (empty($describe_native))
|
||||
printf("[013] Native PS (native support: %s), DESCRIBE returned no results\n",
|
||||
$native_support);
|
||||
else if (!$valid)
|
||||
printf("[014] Native PS (native support: %s), DESCRIBE, returned data seems wrong, dumping %s\n",
|
||||
$native_support,
|
||||
var_export($describe_native, true));
|
||||
|
||||
if ($describe != $describe_native)
|
||||
printf("[015] Emulated and native PS (native support: %s) results of DESCRIBE differ: %s vs. %s\n",
|
||||
$native_support,
|
||||
var_export($describe, true),
|
||||
var_export($describe_native, true));
|
||||
|
||||
|
||||
$native_support = 'no';
|
||||
if ($db->exec('PREPARE mystmt FROM "SHOW ENGINES"')) {
|
||||
$native_support = 'yes';
|
||||
$db->exec('DEALLOCATE PREPARE mystmt');
|
||||
}
|
||||
|
||||
if (!is_object($stmt = $db->query('SHOW ENGINES')))
|
||||
printf("[016] Native PS (native support: %s), SHOW failed, %s\n",
|
||||
$native_support,
|
||||
var_export($db->errorInfo(), true));
|
||||
|
||||
$show_native = array();
|
||||
$valid = false;
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$show_native[] = $row;
|
||||
foreach ($row as $column => $value)
|
||||
// MyISAM engine should be part of _every_ MySQL today
|
||||
if ($value == 'MyISAM')
|
||||
$valid = true;
|
||||
}
|
||||
if (empty($show_native))
|
||||
printf("[017] Native PS (native support: %s), SHOW returned no results\n",
|
||||
$native_support);
|
||||
else if (!$valid)
|
||||
printf("[018] Native PS (native support: %s), SHOW data seems wrong, dumping %s\n",
|
||||
var_export($show_native, true));
|
||||
|
||||
if ($show != $show_native)
|
||||
printf("Native PS (native support: %s) and emulated PS returned different data for SHOW: %s vs. %s\n",
|
||||
$native_support,
|
||||
var_export($show, true),
|
||||
var_export($show_native, true));
|
||||
|
||||
$native_support = 'no';
|
||||
if ($db->exec('PREPARE mystmt FROM "EXPLAIN SELECT id FROM test"')) {
|
||||
$native_support = 'yes';
|
||||
$db->exec('DEALLOCATE PREPARE mystmt');
|
||||
}
|
||||
|
||||
if (!is_object($stmt = $db->query("EXPLAIN SELECT id FROM test")))
|
||||
printf("[012] Native PS (native support: %s), EXPLAIN failed, %s\n",
|
||||
$native_support,
|
||||
var_export($db->errorInfo(), true));
|
||||
|
||||
$explain_native = array();
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
|
||||
$explain_native[] = $row;
|
||||
|
||||
if (empty($explain_native))
|
||||
printf("[013] Native PS (native support: %s), EXPLAIN returned no results\n",
|
||||
$native_support);
|
||||
|
||||
if ($explain != $explain_native)
|
||||
printf("Native PS (native support: %s) and emulated PS returned different data for EXPLAIN: %s vs. %s\n",
|
||||
$native_support,
|
||||
var_export($explain, true),
|
||||
var_export($explain_native, true));
|
||||
|
||||
$stmt->execute();
|
||||
$explain_native = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if ($explain != $explain_native)
|
||||
printf("Native PS (native support: %s) and emulated PS returned different data for EXPLAIN: %s vs. %s\n",
|
||||
$native_support,
|
||||
var_export($explain, true),
|
||||
var_export($explain_native, true));
|
||||
|
||||
$stmt->execute();
|
||||
$stmt->execute();
|
||||
// libmysql needs this - otherwise we get a 2015 error
|
||||
if (!MYSQLPDOTest::isPDOMySQLnd())
|
||||
$stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
done!
|
151
ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_serialize.phpt
Normal file
151
ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_serialize.phpt
Normal file
|
@ -0,0 +1,151 @@
|
|||
--TEST--
|
||||
MySQL PDOStatement->fetch(), PDO::FETCH_SERIALIZE
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
if (version_compare(PHP_VERSION, '5.1.0', '<'))
|
||||
die("skip Needs 5.1.0 and Interface Serializable");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
try {
|
||||
|
||||
class myclass implements Serializable {
|
||||
|
||||
private static $instance = null;
|
||||
protected $myprotected = 'a protected propery';
|
||||
|
||||
// Good old magic stuff
|
||||
private function __construct($caller = NULL) {
|
||||
printf("%s(%s)\n", __METHOD__, $caller);
|
||||
}
|
||||
|
||||
|
||||
public function __destruct() {
|
||||
// printf("%s()\n", __METHOD__);
|
||||
}
|
||||
|
||||
public function __sleep() {
|
||||
printf("%s()\n", __METHOD__);
|
||||
}
|
||||
|
||||
public function __wakeup() {
|
||||
printf("%s()\n", __METHOD__);
|
||||
}
|
||||
|
||||
public function __call($method, $params) {
|
||||
printf("%s(%s, %s)\n", __METHOD__, $method, var_export($params, true));
|
||||
}
|
||||
|
||||
public function __set($prop, $value) {
|
||||
printf("%s(%s, %s)\n", __METHOD__, $prop, var_export($value, true));
|
||||
$this->{$prop} = $value;
|
||||
}
|
||||
|
||||
public function __get($prop) {
|
||||
printf("%s(%s)\n", __METHOD__, $prop);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Singleton
|
||||
public static function singleton($caller) {
|
||||
printf("%s(%s)\n", __METHOD__, $caller);
|
||||
|
||||
if (!self::$instance) {
|
||||
$c = __CLASS__;
|
||||
self::$instance = new $c($caller);
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
// Serializable
|
||||
public function serialize() {
|
||||
printf("%s()\n", __METHOD__);
|
||||
return 'Data from serialize';
|
||||
}
|
||||
|
||||
public function unserialize($data) {
|
||||
printf("%s(%s)\n", __METHOD__, var_export($data, true));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[002] Unable to turn off emulated prepared statements\n");
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$db->exec(sprintf('CREATE TABLE test(id INT, myobj BLOB) ENGINE=%s',
|
||||
MySQLPDOTest::getTableEngine()));
|
||||
|
||||
printf("Creating an object, serializing it and writing it to DB...\n");
|
||||
$id = 1;
|
||||
$obj = myclass::singleton('Creating object');
|
||||
$myobj = serialize($obj);
|
||||
$stmt = $db->prepare('INSERT INTO test(id, myobj) VALUES (?, ?)');
|
||||
$stmt->bindValue(1, $id);
|
||||
$stmt->bindValue(2, $myobj);
|
||||
$stmt->execute();
|
||||
|
||||
printf("\nUnserializing the previously serialized object...\n");
|
||||
var_dump(unserialize($myobj));
|
||||
|
||||
printf("\nUsing PDO::FETCH_CLASS|PDO::FETCH_SERIALIZE to fetch the object from DB and unserialize it...\n");
|
||||
$stmt = $db->prepare('SELECT myobj FROM test');
|
||||
$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_SERIALIZE, 'myclass', array('PDO shall not call __construct()'));
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetch());
|
||||
|
||||
printf("\nUsing PDO::FETCH_CLASS to fetch the object from DB and unserialize it...\n");
|
||||
$stmt = $db->prepare('SELECT myobj FROM test');
|
||||
$stmt->setFetchMode(PDO::FETCH_CLASS, 'myclass', array('PDO shall call __construct()'));
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetch());
|
||||
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Creating an object, serializing it and writing it to DB...
|
||||
myclass::singleton(Creating object)
|
||||
myclass::__construct(Creating object)
|
||||
myclass::serialize()
|
||||
|
||||
Unserializing the previously serialized object...
|
||||
myclass::unserialize('Data from serialize')
|
||||
object(myclass)#4 (1) {
|
||||
["myprotected":protected]=>
|
||||
string(19) "a protected propery"
|
||||
}
|
||||
|
||||
Using PDO::FETCH_CLASS|PDO::FETCH_SERIALIZE to fetch the object from DB and unserialize it...
|
||||
myclass::__set(myobj, 'C:7:"myclass":19:{Data from serialize}')
|
||||
myclass::__construct(PDO shall not call __construct())
|
||||
object(myclass)#%d (2) {
|
||||
["myprotected":protected]=>
|
||||
string(19) "a protected propery"
|
||||
["myobj"]=>
|
||||
string(38) "C:7:"myclass":19:{Data from serialize}"
|
||||
}
|
||||
|
||||
Using PDO::FETCH_CLASS to fetch the object from DB and unserialize it...
|
||||
myclass::__set(myobj, 'C:7:"myclass":19:{Data from serialize}')
|
||||
myclass::__construct(PDO shall call __construct())
|
||||
object(myclass)#%d (2) {
|
||||
["myprotected":protected]=>
|
||||
string(19) "a protected propery"
|
||||
["myobj"]=>
|
||||
string(38) "C:7:"myclass":19:{Data from serialize}"
|
||||
}
|
||||
done!
|
|
@ -0,0 +1,98 @@
|
|||
--TEST--
|
||||
MySQL PDOStatement->fetch(), PDO::FETCH_SERIALIZE
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
if (version_compare(PHP_VERSION, '5.1.0', '<'))
|
||||
die("skip Needs 5.1.0 and Interface Serializable");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
try {
|
||||
|
||||
class myclass implements Serializable {
|
||||
|
||||
public function __construct($caller = null) {
|
||||
printf("%s(%s) - note that it must not be called when unserializing\n", __METHOD__, var_export($caller, true));
|
||||
}
|
||||
|
||||
public function __set($prop, $value) {
|
||||
printf("%s(%s, %s)\n", __METHOD__, var_export($prop, true), var_export($value, true));
|
||||
$this->{$prop} = $value;
|
||||
}
|
||||
|
||||
public function serialize() {
|
||||
printf("%s()\n", __METHOD__);
|
||||
return 'Value from serialize()';
|
||||
}
|
||||
|
||||
public function unserialize($data) {
|
||||
printf("%s(%s)\n", __METHOD__, var_export($data, true));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
printf("Lets see what the Serializeable interface makes our object behave like...\n");
|
||||
$obj = new myclass('Called by script');
|
||||
$tmp = unserialize(serialize($obj));
|
||||
var_dump($tmp);
|
||||
|
||||
printf("\nAnd now magic PDO using fetchAll(PDO::FETCH_CLASS|PDO::FETCH_SERIALIZE)...\n");
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$db->exec(sprintf('CREATE TABLE test(myobj BLOB) ENGINE=%s', MySQLPDOTest::getTableEngine()));
|
||||
$db->exec('INSERT INTO test(myobj) VALUES ("Data fetched from DB to be given to unserialize()")');
|
||||
|
||||
$stmt = $db->prepare('SELECT myobj FROM test');
|
||||
$stmt->execute();
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_SERIALIZE, 'myclass', array('Called by PDO'));
|
||||
var_dump($rows[0]);
|
||||
|
||||
$stmt->execute();
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_SERIALIZE, 'myclass');
|
||||
var_dump($rows[0]);
|
||||
|
||||
printf("\nAnd now PDO using setFetchMode(PDO::FETCH:CLASS|PDO::FETCH_SERIALIZE) + fetch()...\n");
|
||||
$stmt = $db->prepare('SELECT myobj FROM test');
|
||||
$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_SERIALIZE, 'myclass', array('Called by PDO'));
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetch());
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Lets see what the Serializeable interface makes our object behave like...
|
||||
myclass::__construct('Called by script') - note that it must not be called when unserializing
|
||||
myclass::serialize()
|
||||
myclass::unserialize('Value from serialize()')
|
||||
object(myclass)#%d (0) {
|
||||
}
|
||||
|
||||
And now magic PDO using fetchAll(PDO::FETCH_CLASS|PDO::FETCH_SERIALIZE)...
|
||||
myclass::unserialize('Data fetched from DB to be given to unserialize()')
|
||||
myclass::__construct('Called by PDO') - note that it must not be called when unserializing
|
||||
object(myclass)#%d (0) {
|
||||
}
|
||||
myclass::unserialize('Data fetched from DB to be given to unserialize()')
|
||||
myclass::__construct(NULL) - note that it must not be called when unserializing
|
||||
object(myclass)#%d (0) {
|
||||
}
|
||||
|
||||
And now PDO using setFetchMode(PDO::FETCH:CLASS|PDO::FETCH_SERIALIZE) + fetch()...
|
||||
myclass::__set('myobj', 'Data fetched from DB to be given to unserialize()')
|
||||
myclass::__construct('Called by PDO') - note that it must not be called when unserializing
|
||||
object(myclass)#%d (1) {
|
||||
["myobj"]=>
|
||||
string(49) "Data fetched from DB to be given to unserialize()"
|
||||
}
|
||||
done!
|
95
ext/pdo_mysql/tests/pdo_mysql_stmt_fetchobject.phpt
Normal file
95
ext/pdo_mysql/tests/pdo_mysql_stmt_fetchobject.phpt
Normal file
|
@ -0,0 +1,95 @@
|
|||
--TEST--
|
||||
MySQL PDO: PDOStatement->fetchObject()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
try {
|
||||
|
||||
// default settings
|
||||
$query = "SELECT id, '', NULL, \"\" FROM test ORDER BY id ASC LIMIT 3";
|
||||
$stmt = $db->prepare($query);
|
||||
|
||||
class myclass {
|
||||
|
||||
private $set_calls = 0;
|
||||
protected static $static_set_calls = 0;
|
||||
|
||||
// NOTE: PDO does not care about protected
|
||||
protected $grp;
|
||||
|
||||
// NOTE: PDO does not care about private and calls __construct() after __set()
|
||||
private function __construct($param1, $param2) {
|
||||
printf("myclass::__construct(%s, %s): %d / %d\n",
|
||||
$param1, $param2,
|
||||
self::$static_set_calls, $this->set_calls);
|
||||
}
|
||||
|
||||
// NOTE: PDO will call __set() prior to calling __construct()
|
||||
public function __set($prop, $value) {
|
||||
$this->not_a_magic_one();
|
||||
printf("myclass::__set(%s, -%s-) %d\n",
|
||||
$prop, var_export($value, true), $this->set_calls, self::$static_set_calls);
|
||||
$this->{$prop} = $value;
|
||||
}
|
||||
|
||||
// NOTE: PDO can call regular methods prior to calling __construct()
|
||||
public function not_a_magic_one() {
|
||||
$this->set_calls++;
|
||||
self::$static_set_calls++;
|
||||
}
|
||||
|
||||
}
|
||||
$stmt->execute();
|
||||
$rowno = 0;
|
||||
$rows[] = array();
|
||||
while (is_object($rows[] = $stmt->fetchObject('myclass', array($rowno++, $rowno))))
|
||||
;
|
||||
|
||||
var_dump($rows[$rowno - 1]);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
// we should never get here, we use warnings, but never trust a system...
|
||||
printf("[001] %s, [%s} %s\n",
|
||||
$e->getMessage(), $db->errorInfo(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
myclass::__set(id, -'1'-) 1
|
||||
myclass::__set(, -''-) 2
|
||||
myclass::__set(null, -NULL-) 3
|
||||
myclass::__set(, -''-) 4
|
||||
myclass::__construct(0, 1): 4 / 4
|
||||
myclass::__set(id, -'2'-) 1
|
||||
myclass::__set(, -''-) 2
|
||||
myclass::__set(null, -NULL-) 3
|
||||
myclass::__set(, -''-) 4
|
||||
myclass::__construct(1, 2): 8 / 4
|
||||
myclass::__set(id, -'3'-) 1
|
||||
myclass::__set(, -''-) 2
|
||||
myclass::__set(null, -NULL-) 3
|
||||
myclass::__set(, -''-) 4
|
||||
myclass::__construct(2, 3): 12 / 4
|
||||
object(myclass)#%d (4) {
|
||||
["set_calls":"myclass":private]=>
|
||||
int(4)
|
||||
["grp":protected]=>
|
||||
NULL
|
||||
["id"]=>
|
||||
string(1) "3"
|
||||
["null"]=>
|
||||
NULL
|
||||
}
|
||||
done!
|
309
ext/pdo_mysql/tests/pdo_mysql_stmt_getcolumnmeta.phpt
Normal file
309
ext/pdo_mysql/tests/pdo_mysql_stmt_getcolumnmeta.phpt
Normal file
|
@ -0,0 +1,309 @@
|
|||
--TEST--
|
||||
MySQL: PDOStatement->getColumnMeta()
|
||||
--SKIPIF--
|
||||
<?php # vim:ft=php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
// Too many differences among MySQL version - run only with a recent one
|
||||
$db = MySQLPDOTest::factory();
|
||||
$stmt = $db->query('SELECT VERSION() as _version');
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$version = ((int)substr($row['_version'], 0, 1) * 10) + (int)substr($row['_version'], 2, 1);
|
||||
if ($version < 51)
|
||||
die("skip Test needs MySQL 5.1+");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
try {
|
||||
|
||||
$stmt = $db->prepare('SELECT id FROM test ORDER BY id ASC');
|
||||
|
||||
// execute() has not been called yet
|
||||
// NOTE: no warning
|
||||
if (false !== ($tmp = $stmt->getColumnMeta(0)))
|
||||
printf("[002] Expecting false got %s\n", var_export($tmp, true));
|
||||
|
||||
$stmt->execute();
|
||||
// Warning: PDOStatement::getColumnMeta() expects exactly 1 parameter, 0 given in
|
||||
if (false !== ($tmp = @$stmt->getColumnMeta()))
|
||||
printf("[003] Expecting false got %s\n", var_export($tmp, true));
|
||||
|
||||
// invalid offset
|
||||
if (false !== ($tmp = @$stmt->getColumnMeta(-1)))
|
||||
printf("[004] Expecting false got %s\n", var_export($tmp, true));
|
||||
|
||||
// Warning: PDOStatement::getColumnMeta() expects parameter 1 to be long, array given in
|
||||
if (false !== ($tmp = @$stmt->getColumnMeta(array())))
|
||||
printf("[005] Expecting false got %s\n", var_export($tmp, true));
|
||||
|
||||
// Warning: PDOStatement::getColumnMeta() expects exactly 1 parameter, 2 given in
|
||||
if (false !== ($tmp = @$stmt->getColumnMeta(1, 1)))
|
||||
printf("[006] Expecting false got %s\n", var_export($tmp, true));
|
||||
|
||||
$emulated = $stmt->getColumnMeta(0);
|
||||
|
||||
printf("Testing native PS...\n");
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[007] Unable to turn off emulated prepared statements\n");
|
||||
|
||||
$stmt = $db->prepare('SELECT id FROM test ORDER BY id ASC');
|
||||
$stmt->execute();
|
||||
$native = $stmt->getColumnMeta(0);
|
||||
if (count($native) == 0) {
|
||||
printf("[008] Meta data seems wrong, %s / %s\n",
|
||||
var_export($native, true), var_export($emulated, true));
|
||||
}
|
||||
|
||||
// invalid offset
|
||||
if (false !== ($tmp = $stmt->getColumnMeta(1)))
|
||||
printf("[009] Expecting false because of invalid offset got %s\n", var_export($tmp, true));
|
||||
|
||||
|
||||
function test_meta(&$db, $offset, $sql_type, $value, $native_type, $pdo_type) {
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
|
||||
$sql = sprintf('CREATE TABLE test(id INT, label %s) ENGINE=%s', $sql_type, MySQLPDOTest::getTableEngine());
|
||||
if (!($stmt = @$db->prepare($sql)) || (!@$stmt->execute())) {
|
||||
// Some engines and/or MySQL server versions might not support the data type
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$db->exec(sprintf('INSERT INTO test(id, label) VALUES (1, "%s")', $value))) {
|
||||
printf("[%03d] + 1] Insert failed, %d - %s\n", $offset,
|
||||
$db->errorCode(), var_export($db->errorInfo(), true));
|
||||
return false;
|
||||
}
|
||||
|
||||
$stmt = $db->prepare('SELECT id, label FROM test');
|
||||
$stmt->execute();
|
||||
$meta = $stmt->getColumnMeta(1);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (empty($meta)) {
|
||||
printf("[%03d + 2] getColumnMeta() failed, %d - %s\n", $offset,
|
||||
$stmt->errorCode(), var_export($stmt->errorInfo(), true));
|
||||
return false;
|
||||
}
|
||||
|
||||
$elements = array('flags', 'table', 'name', 'len', 'precision', 'pdo_type');
|
||||
foreach ($elements as $k => $element)
|
||||
if (!isset($meta[$element])) {
|
||||
printf("[%03d + 3] Element %s missing, %s\n", $offset,
|
||||
$element, var_export($meta, true));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (($meta['table'] != 'test') || ($meta['name'] != 'label')) {
|
||||
printf("[%03d + 4] Table or field name is wrong, %s\n", $offset,
|
||||
var_export($meta, true));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_null($native_type)) {
|
||||
if (!isset($meta['native_type'])) {
|
||||
printf("[%03d + 5] Element native_type missing, %s\n", $offset,
|
||||
var_export($meta, true));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_array($native_type))
|
||||
$native_type = array($native_type);
|
||||
|
||||
$found = false;
|
||||
foreach ($native_type as $k => $type) {
|
||||
if ($meta['native_type'] == $type) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
printf("[%03d + 6] Expecting native type %s, %s\n", $offset,
|
||||
var_export($native_type, true), var_export($meta, true));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_null($pdo_type) && ($meta['pdo_type'] != $pdo_type)) {
|
||||
printf("[%03d + 6] Expecting PDO type %s got %s (%s)\n", $offset,
|
||||
$pdo_type, var_export($meta, true), var_export($meta['native_type']));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
|
||||
$is_mysqlnd = MySQLPDOTest::isPDOMySQLnd();
|
||||
test_meta($db, 20, 'BIT(8)', 1, NULL, ($is_mysqlnd) ? PDO::PARAM_INT : PDO::PARAM_STR);
|
||||
test_meta($db, 30, 'TINYINT', -127, NULL, ($is_mysqlnd) ? PDO::PARAM_INT : PDO::PARAM_STR);
|
||||
test_meta($db, 40, 'TINYINT UNSIGNED', 255, NULL, ($is_mysqlnd) ? PDO::PARAM_INT : PDO::PARAM_STR);
|
||||
test_meta($db, 50, 'BOOLEAN', 1, NULL, ($is_mysqlnd) ? PDO::PARAM_INT : PDO::PARAM_STR);
|
||||
|
||||
test_meta($db, 60, 'SMALLINT', -32768, 'SHORT', ($is_mysqlnd) ? PDO::PARAM_INT : PDO::PARAM_STR);
|
||||
test_meta($db, 70, 'SMALLINT UNSIGNED', 65535, 'SHORT', ($is_mysqlnd) ? PDO::PARAM_INT : PDO::PARAM_STR);
|
||||
|
||||
test_meta($db, 80, 'MEDIUMINT', -8388608, 'INT24', ($is_mysqlnd) ? PDO::PARAM_INT : PDO::PARAM_STR);
|
||||
test_meta($db, 90, 'MEDIUMINT UNSIGNED', 16777215, 'INT24', ($is_mysqlnd) ? PDO::PARAM_INT : PDO::PARAM_STR);
|
||||
|
||||
test_meta($db, 100, 'INT', -2147483648, 'LONG', ($is_mysqlnd) ? PDO::PARAM_INT : PDO::PARAM_STR);
|
||||
test_meta($db, 110, 'INT UNSIGNED', 4294967295, 'LONG', ($is_mysqlnd) ? PDO::PARAM_INT : PDO::PARAM_STR);
|
||||
|
||||
test_meta($db, 120, 'BIGINT', -9223372036854775808, 'LONGLONG', ($is_mysqlnd) ? ((PHP_INT_SIZE == 4) ? PDO::PARAM_STR : PDO::PARAM_INT) : PDO::PARAM_STR);
|
||||
test_meta($db, 130, 'BIGINT UNSIGNED', 18446744073709551615, 'LONGLONG', ($is_mysqlnd) ? ((PHP_INT_SIZE == 4) ? PDO::PARAM_STR : PDO::PARAM_INT) : PDO::PARAM_STR);
|
||||
|
||||
test_meta($db, 130, 'REAL', -1.01, 'DOUBLE', PDO::PARAM_STR);
|
||||
test_meta($db, 140, 'REAL UNSIGNED', 1.01, 'DOUBLE', PDO::PARAM_STR);
|
||||
test_meta($db, 150, 'REAL ZEROFILL', -1.01, 'DOUBLE', PDO::PARAM_STR);
|
||||
test_meta($db, 160, 'REAL UNSIGNED ZEROFILL', 1.01, 'DOUBLE', PDO::PARAM_STR);
|
||||
|
||||
test_meta($db, 170, 'DOUBLE', -1.01, 'DOUBLE', PDO::PARAM_STR);
|
||||
test_meta($db, 180, 'DOUBLE UNSIGNED', 1.01, 'DOUBLE', PDO::PARAM_STR);
|
||||
test_meta($db, 190, 'DOUBLE ZEROFILL', -1.01, 'DOUBLE', PDO::PARAM_STR);
|
||||
test_meta($db, 200, 'DOUBLE UNSIGNED ZEROFILL', 1.01, 'DOUBLE', PDO::PARAM_STR);
|
||||
|
||||
test_meta($db, 210, 'FLOAT', -1.01, 'FLOAT', PDO::PARAM_STR);
|
||||
test_meta($db, 220, 'FLOAT UNSIGNED', 1.01, 'FLOAT', PDO::PARAM_STR);
|
||||
test_meta($db, 230, 'FLOAT ZEROFILL', -1.01, 'FLOAT', PDO::PARAM_STR);
|
||||
test_meta($db, 240, 'FLOAT UNSIGNED ZEROFILL', 1.01, 'FLOAT', PDO::PARAM_STR);
|
||||
|
||||
test_meta($db, 250, 'DECIMAL', -1.01, array('DECIMAL', 'NEWDECIMAL'), PDO::PARAM_STR);
|
||||
test_meta($db, 260, 'DECIMAL UNSIGNED', 1.01, array('DECIMAL', 'NEWDECIMAL'), PDO::PARAM_STR);
|
||||
test_meta($db, 270, 'DECIMAL ZEROFILL', -1.01, array('DECIMAL', 'NEWDECIMAL'), PDO::PARAM_STR);
|
||||
test_meta($db, 280, 'DECIMAL UNSIGNED ZEROFILL', 1.01, array('DECIMAL', 'NEWDECIMAL'), PDO::PARAM_STR);
|
||||
|
||||
test_meta($db, 290, 'NUMERIC', -1.01, array('DECIMAL', 'NEWDECIMAL'), PDO::PARAM_STR);
|
||||
test_meta($db, 300, 'NUMERIC UNSIGNED', 1.01, array('DECIMAL', 'NEWDECIMAL'), PDO::PARAM_STR);
|
||||
test_meta($db, 310, 'NUMERIC ZEROFILL', -1.01, array('DECIMAL', 'NEWDECIMAL'), PDO::PARAM_STR);
|
||||
test_meta($db, 320, 'NUMERIC UNSIGNED ZEROFILL', 1.01, array('DECIMAL', 'NEWDECIMAL'), PDO::PARAM_STR);
|
||||
|
||||
test_meta($db, 330, 'DATE', '2008-04-23', array('DATE', 'NEWDATE'), PDO::PARAM_STR);
|
||||
test_meta($db, 340, 'TIME', '14:37:00', 'TIME', PDO::PARAM_STR);
|
||||
test_meta($db, 350, 'TIMESTAMP', time(), 'TIMESTAMP', PDO::PARAM_STR);
|
||||
test_meta($db, 360, 'DATETIME', '2008-03-23 14:38:00', 'DATETIME', PDO::PARAM_STR);
|
||||
test_meta($db, 370, 'YEAR', '2008', NULL, ($is_mysqlnd) ? PDO::PARAM_INT : PDO::PARAM_STR);
|
||||
|
||||
test_meta($db, 380, 'CHAR(1)', 'a', 'STRING', PDO::PARAM_STR);
|
||||
test_meta($db, 390, 'CHAR(10)', '0123456789', 'STRING', PDO::PARAM_STR);
|
||||
test_meta($db, 400, 'CHAR(255)', str_repeat('z', 255), 'STRING', PDO::PARAM_STR);
|
||||
test_meta($db, 410, 'VARCHAR(1)', 'a', 'VAR_STRING', PDO::PARAM_STR);
|
||||
test_meta($db, 420, 'VARCHAR(10)', '0123456789', 'VAR_STRING', PDO::PARAM_STR);
|
||||
test_meta($db, 430, 'VARCHAR(255)', str_repeat('z', 255), 'VAR_STRING', PDO::PARAM_STR);
|
||||
|
||||
test_meta($db, 440, 'BINARY(1)', str_repeat('a', 1), 'STRING', PDO::PARAM_STR);
|
||||
test_meta($db, 450, 'BINARY(255)', str_repeat('b', 255), 'STRING', PDO::PARAM_STR);
|
||||
test_meta($db, 460, 'VARBINARY(1)', str_repeat('a', 1), 'VAR_STRING', PDO::PARAM_STR);
|
||||
test_meta($db, 470, 'VARBINARY(255)', str_repeat('b', 255), 'VAR_STRING', PDO::PARAM_STR);
|
||||
|
||||
test_meta($db, 480, 'TINYBLOB', str_repeat('b', 255), 'BLOB', PDO::PARAM_STR);
|
||||
test_meta($db, 490, 'BLOB', str_repeat('b', 256), 'BLOB', PDO::PARAM_STR);
|
||||
test_meta($db, 500, 'MEDIUMBLOB', str_repeat('b', 256), 'BLOB', PDO::PARAM_STR);
|
||||
test_meta($db, 510, 'LONGBLOB', str_repeat('b', 256), 'BLOB', PDO::PARAM_STR);
|
||||
|
||||
test_meta($db, 520, 'TINYTEXT', str_repeat('b', 255), 'BLOB', PDO::PARAM_STR);
|
||||
test_meta($db, 530, 'TINYTEXT BINARY', str_repeat('b', 255), 'BLOB', PDO::PARAM_STR);
|
||||
|
||||
test_meta($db, 560, 'TEXT', str_repeat('b', 256), 'BLOB', PDO::PARAM_STR);
|
||||
test_meta($db, 570, 'TEXT BINARY', str_repeat('b', 256), 'BLOB', PDO::PARAM_STR);
|
||||
|
||||
test_meta($db, 580, 'MEDIUMTEXT', str_repeat('b', 256), 'BLOB', PDO::PARAM_STR);
|
||||
test_meta($db, 590, 'MEDIUMTEXT BINARY', str_repeat('b', 256), 'BLOB', PDO::PARAM_STR);
|
||||
|
||||
test_meta($db, 600, 'LONGTEXT', str_repeat('b', 256), 'BLOB', PDO::PARAM_STR);
|
||||
test_meta($db, 610, 'LONGTEXT BINARY', str_repeat('b', 256), 'BLOB', PDO::PARAM_STR);
|
||||
|
||||
test_meta($db, 620, "ENUM('yes', 'no') DEFAULT 'yes'", 'no', NULL, PDO::PARAM_STR);
|
||||
test_meta($db, 630, "SET('yes', 'no') DEFAULT 'yes'", 'no', NULL, PDO::PARAM_STR);
|
||||
|
||||
/*
|
||||
| spatial_type
|
||||
*/
|
||||
|
||||
// unique key
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$sql = sprintf('CREATE TABLE test(id INT, label INT UNIQUE) ENGINE = %s', MySQLPDOTest::getTableEngine());
|
||||
if (($stmt = @$db->prepare($sql)) && @$stmt->execute()) {
|
||||
$db->exec('INSERT INTO test(id, label) VALUES (1, 2)');
|
||||
$stmt = $db->query('SELECT id, label FROM test');
|
||||
$meta = $stmt->getColumnMeta(1);
|
||||
if (!isset($meta['flags'])) {
|
||||
printf("[1000] No flags contained in metadata %s\n", var_export($meta, true));
|
||||
} else {
|
||||
$flags = $meta['flags'];
|
||||
$found = false;
|
||||
foreach ($flags as $k => $flag) {
|
||||
if ($flag == 'unique_key')
|
||||
$found = true;
|
||||
}
|
||||
if (!$found)
|
||||
printf("[1001] Flags seem wrong %s\n", var_export($meta, true));
|
||||
}
|
||||
}
|
||||
|
||||
// primary key
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$sql = sprintf('CREATE TABLE test(id INT PRIMARY KEY NOT NULL AUTO_INCREMENT) ENGINE = %s', MySQLPDOTest::getTableEngine());
|
||||
if (($stmt = @$db->prepare($sql)) && @$stmt->execute()) {
|
||||
$db->exec('INSERT INTO test(id) VALUES (1)');
|
||||
$stmt = $db->query('SELECT id FROM test');
|
||||
$meta = $stmt->getColumnMeta(0);
|
||||
if (!isset($meta['flags'])) {
|
||||
printf("[1002] No flags contained in metadata %s\n", var_export($meta, true));
|
||||
} else {
|
||||
$flags = $meta['flags'];
|
||||
$found = false;
|
||||
foreach ($flags as $k => $flag) {
|
||||
if ($flag == 'primary_key')
|
||||
$found = true;
|
||||
}
|
||||
if (!$found)
|
||||
printf("[1003] Flags seem wrong %s\n", var_export($meta, true));
|
||||
}
|
||||
}
|
||||
|
||||
// multiple key
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$sql = sprintf('CREATE TABLE test(id INT, label1 INT, label2 INT, INDEX idx1(label1, label2)) ENGINE = %s', MySQLPDOTest::getTableEngine());
|
||||
if (($stmt = @$db->prepare($sql)) && @$stmt->execute()) {
|
||||
$db->exec('INSERT INTO test(id, label1, label2) VALUES (1, 2, 3)');
|
||||
$stmt = $db->query('SELECT id, label1, label2 FROM test');
|
||||
$meta = $stmt->getColumnMeta(1);
|
||||
if (!isset($meta['flags'])) {
|
||||
printf("[1004] No flags contained in metadata %s\n", var_export($meta, true));
|
||||
} else {
|
||||
$flags = $meta['flags'];
|
||||
$found = false;
|
||||
foreach ($flags as $k => $flag) {
|
||||
if ($flag == 'multiple_key')
|
||||
$found = true;
|
||||
}
|
||||
if (!$found)
|
||||
printf("[1005] Flags seem wrong %s\n", var_export($meta, true));
|
||||
}
|
||||
}
|
||||
|
||||
$stmt = $db->query('SELECT NULL AS col1');
|
||||
$meta = $stmt->getColumnMeta(0);
|
||||
if ('NULL' !== $meta['native_type'])
|
||||
printf("[1006] Expecting NULL got %s\n", $meta['native_type']);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
// we should never get here, we use warnings, but never trust a system...
|
||||
printf("[001] %s, [%s} %s\n",
|
||||
$e->getMessage(), $db->errorInfo(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Testing native PS...
|
||||
done!
|
90
ext/pdo_mysql/tests/pdo_mysql_stmt_multiquery.phpt
Normal file
90
ext/pdo_mysql/tests/pdo_mysql_stmt_multiquery.phpt
Normal file
|
@ -0,0 +1,90 @@
|
|||
--TEST--
|
||||
PDOStatements and multi query
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
|
||||
function mysql_stmt_multiquery_wrong_usage($db) {
|
||||
|
||||
$stmt = $db->query('SELECT label FROM test ORDER BY id ASC LIMIT 1; SELECT label FROM test ORDER BY id ASC LIMIT 1');
|
||||
var_dump($stmt->errorInfo());
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
var_dump($stmt->errorInfo());
|
||||
|
||||
}
|
||||
|
||||
function mysql_stmt_multiquery_proper_usage($db) {
|
||||
|
||||
$stmt = $db->query('SELECT label FROM test ORDER BY id ASC LIMIT 1; SELECT label FROM test ORDER BY id ASC LIMIT 1');
|
||||
do {
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
} while ($stmt->nextRowset());
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
printf("Emulated Prepared Statements...\n");
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
|
||||
mysql_stmt_multiquery_wrong_usage($db);
|
||||
mysql_stmt_multiquery_proper_usage($db);
|
||||
|
||||
printf("Native Prepared Statements...\n");
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
|
||||
mysql_stmt_multiquery_wrong_usage($db);
|
||||
mysql_stmt_multiquery_proper_usage($db);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Emulated Prepared Statements...
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(5) "00000"
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(5) "00000"
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
}
|
||||
Native Prepared Statements...
|
||||
|
||||
Warning: PDO::query(): SQLSTATE[42000]: Syntax error or access violation: 1064 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 '; SELECT label FROM test ORDER BY id ASC LIMIT 1' at line %d in %s on line %d
|
||||
|
||||
Fatal error: Call to a member function errorInfo() on a non-object in %s on line %d
|
309
ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt
Normal file
309
ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt
Normal file
|
@ -0,0 +1,309 @@
|
|||
--TEST--
|
||||
MySQL PDOStatement->nextRowSet()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
$row = $db->query('SELECT VERSION() as _version')->fetch(PDO::FETCH_ASSOC);
|
||||
$matches = array();
|
||||
if (!preg_match('/^(\d+)\.(\d+)\.(\d+)/ismU', $row['_version'], $matches))
|
||||
die(sprintf("skip Cannot determine MySQL Server version\n"));
|
||||
|
||||
$version = $matches[0] * 10000 + $matches[1] * 100 + $matches[2];
|
||||
if ($version < 50000)
|
||||
die(sprintf("skip Need MySQL Server 5.0.0+, found %d.%02d.%02d (%d)\n",
|
||||
$matches[0], $matches[1], $matches[2], $version));
|
||||
|
||||
if (!MySQLPDOTest::isPDOMySQLnd())
|
||||
die("skip This will not work with libmysql");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
|
||||
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
$stmt = $db->query('SELECT id FROM test');
|
||||
if (false !== ($tmp = $stmt->nextRowSet()))
|
||||
printf("[002] Expecting false got %s\n", var_export($tmp, true));
|
||||
|
||||
// TODO: should give a warning, but its PDO, let's ignore the missing warning for now
|
||||
if (false !== ($tmp = $stmt->nextRowSet(1)))
|
||||
printf("[003] Expecting false got %s\n", var_export($tmp, true));
|
||||
|
||||
function test_proc1($db) {
|
||||
|
||||
$stmt = $db->query('SELECT @VERSION as _version');
|
||||
$tmp = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
assert($tmp['_version'] === NULL);
|
||||
while ($stmt->fetch()) ;
|
||||
|
||||
$db->exec('DROP PROCEDURE IF EXISTS p');
|
||||
$db->exec('CREATE PROCEDURE p(OUT ver_param VARCHAR(25)) BEGIN SELECT VERSION() INTO ver_param; END;');
|
||||
$db->exec('CALL p(@VERSION)');
|
||||
$stmt = $db->query('SELECT @VERSION as _version');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
var_dump($stmt->nextRowSet());
|
||||
|
||||
}
|
||||
|
||||
function test_proc2($db) {
|
||||
|
||||
$db->exec('DROP PROCEDURE IF EXISTS p');
|
||||
$db->exec('CREATE PROCEDURE p() BEGIN SELECT id FROM test ORDER BY id ASC LIMIT 3; SELECT id, label FROM test WHERE id < 4 ORDER BY id DESC LIMIT 3; END;');
|
||||
$stmt = $db->query('CALL p()');
|
||||
do {
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
} while ($stmt->nextRowSet());
|
||||
var_dump($stmt->nextRowSet());
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
// Emulated PS
|
||||
printf("Emulated PS...\n");
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
|
||||
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1);
|
||||
test_proc1($db);
|
||||
test_proc2($db);
|
||||
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 0);
|
||||
test_proc1($db);
|
||||
test_proc2($db);
|
||||
|
||||
// Native PS
|
||||
printf("Native PS...\n");
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1);
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
|
||||
test_proc1($db);
|
||||
test_proc2($db);
|
||||
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 0);
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
|
||||
|
||||
test_proc1($db);
|
||||
test_proc2($db);
|
||||
|
||||
@$db->exec('DROP PROCEDURE IF EXISTS p');
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Emulated PS...
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["_version"]=>
|
||||
string(%d) "%s"
|
||||
}
|
||||
}
|
||||
bool(false)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
}
|
||||
[1]=>
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(1) "2"
|
||||
}
|
||||
[2]=>
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(1) "3"
|
||||
}
|
||||
}
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "3"
|
||||
["label"]=>
|
||||
string(1) "c"
|
||||
}
|
||||
[1]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "2"
|
||||
["label"]=>
|
||||
string(1) "b"
|
||||
}
|
||||
[2]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
}
|
||||
bool(false)
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["_version"]=>
|
||||
string(%d) "%s"
|
||||
}
|
||||
}
|
||||
bool(false)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
}
|
||||
[1]=>
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(1) "2"
|
||||
}
|
||||
[2]=>
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(1) "3"
|
||||
}
|
||||
}
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "3"
|
||||
["label"]=>
|
||||
string(1) "c"
|
||||
}
|
||||
[1]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "2"
|
||||
["label"]=>
|
||||
string(1) "b"
|
||||
}
|
||||
[2]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
}
|
||||
bool(false)
|
||||
Native PS...
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["_version"]=>
|
||||
string(%d) "%s"
|
||||
}
|
||||
}
|
||||
bool(false)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
}
|
||||
[1]=>
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(1) "2"
|
||||
}
|
||||
[2]=>
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(1) "3"
|
||||
}
|
||||
}
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "3"
|
||||
["label"]=>
|
||||
string(1) "c"
|
||||
}
|
||||
[1]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "2"
|
||||
["label"]=>
|
||||
string(1) "b"
|
||||
}
|
||||
[2]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
}
|
||||
bool(false)
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["_version"]=>
|
||||
string(%d) "%s"
|
||||
}
|
||||
}
|
||||
bool(false)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
}
|
||||
[1]=>
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(1) "2"
|
||||
}
|
||||
[2]=>
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(1) "3"
|
||||
}
|
||||
}
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "3"
|
||||
["label"]=>
|
||||
string(1) "c"
|
||||
}
|
||||
[1]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "2"
|
||||
["label"]=>
|
||||
string(1) "b"
|
||||
}
|
||||
[2]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
}
|
||||
bool(false)
|
||||
done!
|
32
ext/pdo_mysql/tests/pdo_mysql_stmt_rowcount.phpt
Normal file
32
ext/pdo_mysql/tests/pdo_mysql_stmt_rowcount.phpt
Normal file
|
@ -0,0 +1,32 @@
|
|||
--TEST--
|
||||
MySQL PDOStatement->rowCount() @ SELECT
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
|
||||
try {
|
||||
|
||||
if (0 !== ($tmp = $db->query('SELECT id FROM test WHERE 1 = 0')->rowCount()))
|
||||
printf("[002] Expecting 0 got %s", var_export($tmp, true));
|
||||
|
||||
if (1 !== ($tmp = $db->query('SELECT id FROM test WHERE id = 1')->rowCount()))
|
||||
printf("[003] Expecting 1 got %s", var_export($tmp, true));
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
done!
|
180
ext/pdo_mysql/tests/pdo_mysql_stmt_unbuffered_2050.phpt
Normal file
180
ext/pdo_mysql/tests/pdo_mysql_stmt_unbuffered_2050.phpt
Normal file
|
@ -0,0 +1,180 @@
|
|||
--TEST--
|
||||
MySQL PDO:query() vs. PDO::prepare() and MySQL error 2050
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
if (MYSQLPDOTest::isPDOMySQLnd())
|
||||
die("skip libmysql only test");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
try {
|
||||
|
||||
printf("Native PS...\n");
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
|
||||
if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY))
|
||||
printf("[004] Unable to turn off emulated prepared statements\n");
|
||||
|
||||
printf("Buffered...\n");
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
|
||||
$stmt = $db->query('SELECT id, label FROM test WHERE id = 1');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
$stmt = $db->query('SELECT id, label FROM test WHERE id = 1');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
printf("Unbuffered...\n");
|
||||
MySQLPDOTest::createTestTable($db);
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
|
||||
$stmt = $db->query('SELECT id, label FROM test WHERE id = 1');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
/*
|
||||
NOTE - this will cause an error and it OK
|
||||
When using unbuffered prepared statements MySQL expects you to
|
||||
fetch all data from the row before sending new data to the server.
|
||||
PDO::query() will prepare and execute a statement in one step.
|
||||
After the execution of PDO::query(), MySQL expects you to fetch
|
||||
the results from the line before sending new commands. However,
|
||||
PHP/PDO will send a CLOSE message as part of the PDO::query() call.
|
||||
|
||||
The following happens:
|
||||
|
||||
$stmt = PDO::query(<some query>)
|
||||
mysql_stmt_prepare()
|
||||
mysql_stmt_execute()
|
||||
|
||||
$stmt->fetchAll()
|
||||
mysql_stmt_fetch()
|
||||
|
||||
And now the right side of the expression will be executed first:
|
||||
$stmt = PDO::query(<some query>)
|
||||
PDO::query(<some query>)
|
||||
mysql_stmt_prepare
|
||||
mysql_stmt_execute
|
||||
|
||||
PHP continues at the left side of the expression:
|
||||
|
||||
$stmt = PDO::query(<some query>)
|
||||
|
||||
What happens is that $stmt gets overwritten. The reference counter of the
|
||||
zval representing the current value of $stmt. PDO gets a callback that
|
||||
it has to free the resources associated with the zval representing the
|
||||
current value of stmt:
|
||||
mysql_stmt_close
|
||||
---> ERROR
|
||||
---> execute() has been send on the line, you are supposed to fetch
|
||||
---> you must not try to send a CLOSE after execute()
|
||||
---> Error: 2050 (CR_FETCH_CANCELED)
|
||||
---> Message: Row retrieval was canceled by mysql_stmt_close() call
|
||||
---> MySQL does its best to recover the line and cancels the retrieval
|
||||
|
||||
PHP proceeds and assigns the new statement object/zval obtained from
|
||||
PDO to $stmt.
|
||||
|
||||
Solutions:
|
||||
- use mysqlnd
|
||||
- use prepare() + execute() instead of query()
|
||||
- as there is no explicit close() in PDO, try unset($stmt) before the new assignment
|
||||
- fix PDO::query() [not the driver, fix PDO itself]
|
||||
*/
|
||||
|
||||
$stmt = $db->query('SELECT id, label FROM test WHERE id = 1');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
$stmt = $db->prepare('SELECT id, label FROM test WHERE id = 1');
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
$stmt = $db->prepare('SELECT id, label FROM test WHERE id = 1');
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
unset($stmt);
|
||||
$stmt = $db->query('SELECT id, label FROM test WHERE id = 1');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
unset($stmt);
|
||||
$stmt = $db->query('SELECT id, label FROM test WHERE id = 1');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Native PS...
|
||||
Buffered...
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
}
|
||||
Unbuffered...
|
||||
|
||||
Warning: PDOStatement::fetchAll(): SQLSTATE[HY000]: General error: 2050 in %s on line %d
|
||||
array(0) {
|
||||
}
|
||||
|
||||
Warning: PDOStatement::fetchAll(): SQLSTATE[HY000]: General error: 2050 in %s on line %d
|
||||
array(0) {
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
["label"]=>
|
||||
string(1) "a"
|
||||
}
|
||||
}
|
||||
done!
|
122
ext/pdo_mysql/tests/pdo_mysql_stmt_variable_columncount.phpt
Normal file
122
ext/pdo_mysql/tests/pdo_mysql_stmt_variable_columncount.phpt
Normal file
|
@ -0,0 +1,122 @@
|
|||
--TEST--
|
||||
MySQL Prepared Statements and different column counts
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
$row = $db->query('SELECT VERSION() as _version')->fetch(PDO::FETCH_ASSOC);
|
||||
$matches = array();
|
||||
if (!preg_match('/^(\d+)\.(\d+)\.(\d+)/ismU', $row['_version'], $matches))
|
||||
die(sprintf("skip Cannot determine MySQL Server version\n"));
|
||||
|
||||
$version = $matches[0] * 10000 + $matches[1] * 100 + $matches[2];
|
||||
if ($version < 50000)
|
||||
die(sprintf("skip Need MySQL Server 5.0.0+, found %d.%02d.%02d (%d)\n",
|
||||
$matches[0], $matches[1], $matches[2], $version));
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
$db = MySQLPDOTest::factory();
|
||||
|
||||
function check_result($offset, $stmt, $columns) {
|
||||
|
||||
do {
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
} while ($stmt->nextRowSet());
|
||||
|
||||
if (!isset($row['one']) || ($row['one'] != 1)) {
|
||||
printf("[%03d + 1] Expecting array('one' => 1), got %s\n", $offset, var_export($row, true));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (($columns == 2) &&
|
||||
(!isset($row['two']) || ($row['two'] != 2))) {
|
||||
printf("[%03d + 2] Expecting array('one' => 1, 'two' => 2), got %s\n", $offset, var_export($row, true));
|
||||
return false;
|
||||
} else if (($columns == 1) && isset($row['two'])) {
|
||||
printf("[%03d + 3] Expecting one array element got two\n", $offset);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
// What will happen if a PS returns a differen number of result set column upon each execution?
|
||||
// Lets try with a SP accepting parameters...
|
||||
$db->exec('DROP PROCEDURE IF EXISTS p');
|
||||
$db->exec('CREATE PROCEDURE p(IN cols INT) BEGIN IF cols < 2 THEN SELECT cols AS "one"; ELSE SELECT 1 AS "one", cols AS "two"; END IF; END;');
|
||||
|
||||
// Emulates PS first
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
|
||||
$stmt = $db->prepare('CALL p(?)');
|
||||
|
||||
$columns = null;
|
||||
$stmt->bindParam(1, $columns);
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$columns = ($i % 2) + 1;
|
||||
$stmt->execute();
|
||||
check_result($i, $stmt, $columns);
|
||||
}
|
||||
|
||||
if (MySQLPDOTest::isPDOMySQLnd()) {
|
||||
// Native PS
|
||||
// Libmysql cannot handle such a stored procedure. You will see leaks with libmysql
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1);
|
||||
$stmt = $db->prepare('CALL p(?)');
|
||||
$stmt->bindParam(1, $columns);
|
||||
for ($i = 5; $i < 10; $i++) {
|
||||
$columns = ($i % 2) + 1;
|
||||
$stmt->execute();
|
||||
check_result($i, $stmt, $columns);
|
||||
}
|
||||
}
|
||||
|
||||
// And now without parameters... - this gives a different control flow inside PDO
|
||||
$db->exec('DROP PROCEDURE IF EXISTS p');
|
||||
$db->exec('CREATE PROCEDURE p() BEGIN DECLARE cols INT; SELECT @numcols INTO cols; IF cols < 2 THEN SET @numcols = 2; SELECT cols AS "one"; ELSE SET @numcols = 1; SELECT 1 AS "one", cols AS "two"; END IF; END;');
|
||||
|
||||
// Emulates PS first
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
|
||||
$db->exec('SET @numcols = 1');
|
||||
$stmt = $db->prepare('CALL p()');
|
||||
$stmt->execute();
|
||||
check_result(11, $stmt, 1);
|
||||
$stmt->execute();
|
||||
check_result(12, $stmt, 2);
|
||||
$db->exec('SET @numcols = 1');
|
||||
$stmt->execute();
|
||||
check_result(13, $stmt, 1);
|
||||
|
||||
if (MySQLPDOTest::isPDOMySQLnd()) {
|
||||
// Native PS
|
||||
// Libmysql cannot handle such a stored procedure. You will see leaks with libmysql
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
|
||||
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1);
|
||||
$db->exec('SET @numcols = 1');
|
||||
$stmt = $db->prepare('CALL p()');
|
||||
$stmt->execute();
|
||||
check_result(14, $stmt, 1);
|
||||
$stmt->execute();
|
||||
check_result(15, $stmt, 2);
|
||||
$db->exec('SET @numcols = 1');
|
||||
$stmt->execute();
|
||||
check_result(16, $stmt, 1);
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[99] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
print "done!";
|
||||
--EXPECTF--
|
||||
done!
|
101
ext/pdo_mysql/tests/pdo_mysql_subclass.phpt
Normal file
101
ext/pdo_mysql/tests/pdo_mysql_subclass.phpt
Normal file
|
@ -0,0 +1,101 @@
|
|||
--TEST--
|
||||
MySQL PDOStatement->execute()/fetch(), Non-SELECT
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
if (version_compare(PHP_VERSION, '5.0.0', '<'))
|
||||
die("skip Requires PHP 5.0+");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
|
||||
// No silly strict mode warnings, please!
|
||||
error_reporting(E_ALL^E_STRICT);
|
||||
ini_set('display_errors', false);
|
||||
|
||||
try {
|
||||
|
||||
class MyPDO extends PDO {
|
||||
|
||||
public function __construct() {
|
||||
$this->protocol();
|
||||
return call_user_func_array(array($this, 'parent::__construct'), func_get_args());
|
||||
}
|
||||
|
||||
public function exec() {
|
||||
$this->protocol();
|
||||
return call_user_func_array(array($this, 'parent::exec'), func_get_args());
|
||||
}
|
||||
|
||||
public function query() {
|
||||
$this->protocol();
|
||||
return call_user_func_array(array($this, 'parent::query'), func_get_args());
|
||||
}
|
||||
|
||||
public function __call($method, $args) {
|
||||
print "__call()";
|
||||
// $this->protocol();
|
||||
}
|
||||
|
||||
private function protocol() {
|
||||
$stack = debug_backtrace();
|
||||
if (!isset($stack[1]))
|
||||
return;
|
||||
|
||||
printf("%s(", $stack[1]['function']);
|
||||
$args = '';
|
||||
foreach ($stack[1]['args'] as $k => $v)
|
||||
$args .= sprintf("%s, ", var_export($v, true));
|
||||
if ($args != '')
|
||||
printf("%s", substr($args, 0, -2));
|
||||
printf(")\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$db = new MyPDO(PDO_MYSQL_TEST_DSN, PDO_MYSQL_TEST_USER, PDO_MYSQL_TEST_PASS);
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$db->exec('CREATE TABLE test(id INT)');
|
||||
$db->exec('INSERT INTO test(id) VALUES (1), (2)');
|
||||
$stmt = $db->query('SELECT * FROM test ORDER BY id ASC');
|
||||
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
var_dump($stmt->fetch());
|
||||
$db->intercept_call();
|
||||
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printf("[001] %s [%s] %s\n",
|
||||
$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
|
||||
}
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
print "done!\n";
|
||||
?>
|
||||
--XFAIL--
|
||||
PDO doesn't like __call()
|
||||
--EXPECTF--
|
||||
__construct('%s', '%s', '%s')
|
||||
exec('DROP TABLE IF EXISTS test')
|
||||
exec('CREATE TABLE test(id INT)')
|
||||
exec('INSERT INTO test(id) VALUES (1), (2)')
|
||||
query('SELECT * FROM test ORDER BY id ASC')
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
}
|
||||
[1]=>
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(1) "2"
|
||||
}
|
||||
}
|
||||
bool(false)
|
||||
__call('intercept_call', array (
|
||||
))
|
||||
exec('DROP TABLE IF EXISTS test')
|
||||
done!
|
174
ext/pdo_mysql/tests/pdo_mysql_types.phpt
Normal file
174
ext/pdo_mysql/tests/pdo_mysql_types.phpt
Normal file
|
@ -0,0 +1,174 @@
|
|||
--TEST--
|
||||
MySQL PDO->exec(), native types wo ZEROFILL
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
|
||||
function test_type(&$db, $offset, $sql_type, $value, $ret_value = NULL, $pattern = NULL) {
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$sql = sprintf('CREATE TABLE test(id INT, label %s) ENGINE=%s', $sql_type, MySQLPDOTest::getTableEngine());
|
||||
@$db->exec($sql);
|
||||
if ($db->errorCode() != 0) {
|
||||
// not all MySQL Server versions and/or engines might support the type
|
||||
return true;
|
||||
}
|
||||
|
||||
$stmt = $db->prepare('INSERT INTO test(id, label) VALUES (?, ?)');
|
||||
$stmt->bindValue(1, $offset);
|
||||
$stmt->bindValue(2, $value);
|
||||
if (!$stmt->execute()) {
|
||||
printf("[%03d + 1] INSERT failed, %s\n", $offset, var_export($stmt->errorInfo(), true));
|
||||
return false;
|
||||
}
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
|
||||
$stmt = $db->query('SELECT id, label FROM test');
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
if (!isset($row['id']) || !isset($row['label'])) {
|
||||
printf("[%03d + 2] Fetched result seems wrong, dumping result: %s\n", $offset, var_export($row, true));
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($row['id'] != $offset) {
|
||||
printf("[%03d + 3] Expecting %s got %s\n", $offset, $row['id']);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_null($pattern)) {
|
||||
if (!preg_match($pattern, $row['label'])) {
|
||||
printf("[%03d + 5] Value seems wrong, accepting pattern %s got %s, check manually\n",
|
||||
$offset, $pattern, var_export($row['label'], true));
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$exp = $value;
|
||||
if (!is_null($ret_value)) {
|
||||
// we expect a different return value than our input value
|
||||
// typically the difference is only the type
|
||||
$exp = $ret_value;
|
||||
}
|
||||
if ($row['label'] !== $exp) {
|
||||
printf("[%03d + 4] %s - input = %s/%s, output = %s/%s\n", $offset,
|
||||
$sql_type, var_export($exp, true), gettype($exp),
|
||||
var_export($row['label'], true), gettype($row['label']));
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
|
||||
$stmt = $db->query('SELECT id, label FROM test');
|
||||
$row_string = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
if (is_null($pattern) && ($row['label'] != $row_string['label'])) {
|
||||
printf("%s - STRINGIGY = %s, NATIVE = %s\n", $sql_type, var_export($row_string['label'], true), var_export($row['label'], true));
|
||||
return false;
|
||||
} else if (!is_null($pattern) && !preg_match($pattern, $row_string['label'])) {
|
||||
printf("%s - STRINGIGY = %s, NATIVE = %s, pattern '%s'\n", $sql_type, var_export($row_string['label'], true), var_export($row['label'], true), $pattern);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
|
||||
|
||||
/*
|
||||
test_type($db, 20, 'BIT(8)', 1);
|
||||
*/
|
||||
$is_mysqlnd = MySQLPDOTest::isPDOMySQLnd();
|
||||
|
||||
test_type($db, 30, 'TINYINT', -127, ($is_mysqlnd) ? -127: '-127');
|
||||
test_type($db, 40, 'TINYINT UNSIGNED', 255, ($is_mysqlnd) ? 255 : '255');
|
||||
test_type($db, 50, 'BOOLEAN', 1, ($is_mysqlnd) ? 1 : '1');
|
||||
|
||||
test_type($db, 60, 'SMALLINT', -32768, ($is_mysqlnd) ? -32768 : '-32768');
|
||||
test_type($db, 70, 'SMALLINT UNSIGNED', 65535, ($is_mysqlnd) ? 65535 : '65535');
|
||||
|
||||
test_type($db, 80, 'MEDIUMINT', -8388608, ($is_mysqlnd) ? -8388608 : '-8388608');
|
||||
test_type($db, 90, 'MEDIUMINT UNSIGNED', 16777215, ($is_mysqlnd) ? 16777215 : '16777215');
|
||||
|
||||
test_type($db, 100, 'INT', -2147483648, ($is_mysqlnd) ? -2147483648 : '-2147483648');
|
||||
test_type($db, 110, 'INT UNSIGNED', 4294967295, ($is_mysqlnd) ? 4294967295 : '4294967295');
|
||||
|
||||
// no chance to return int with the current PDO version - we are forced to return strings
|
||||
test_type($db, 120, 'BIGINT', 1, ($is_mysqlnd) ? 1 : '1');
|
||||
// to avoid trouble with numeric ranges, lets pass the numbers as a string
|
||||
test_type($db, 130, 'BIGINT', '-9223372036854775808', NULL, '/^\-9[\.]*22/');
|
||||
test_type($db, 140, 'BIGINT UNSIGNED', '18446744073709551615', NULL, '/^1[\.]*844/');
|
||||
|
||||
test_type($db, 150, 'REAL', -1.01, ($is_mysqlnd) ? -1.01 : '-1.01');
|
||||
test_type($db, 160, 'REAL UNSIGNED', 1.01, ($is_mysqlnd) ? 1.01 : '1.01');
|
||||
|
||||
test_type($db, 170, 'DOUBLE', -1.01, ($is_mysqlnd) ? -1.01 : '-1.01');
|
||||
test_type($db, 180, 'DOUBLE UNSIGNED', 1.01, ($is_mysqlnd) ? 1.01 : '1.01');
|
||||
|
||||
test_type($db, 210, 'FLOAT', -1.01, NULL, '/^\-1.0\d+/');
|
||||
test_type($db, 220, 'FLOAT UNSIGNED', 1.01, NULL, '/^1.0\d+/');
|
||||
|
||||
test_type($db, 250, 'DECIMAL', -1.01, '-1');
|
||||
test_type($db, 260, 'DECIMAL UNSIGNED', 1.01, '1');
|
||||
|
||||
|
||||
test_type($db, 290, 'NUMERIC', -1.01, '-1');
|
||||
test_type($db, 300, 'NUMERIC UNSIGNED', 1.01, '1');
|
||||
|
||||
test_type($db, 330, 'DATE', '2008-04-23');
|
||||
test_type($db, 340, 'TIME', '14:37:00');
|
||||
test_type($db, 350, 'TIMESTAMP', '2008-05-06 21:09:00');
|
||||
test_type($db, 360, 'DATETIME', '2008-03-23 14:38:00');
|
||||
test_type($db, 370, 'YEAR', 2008, ($is_mysqlnd) ? 2008 : '2008');
|
||||
|
||||
test_type($db, 380, 'CHAR(1)', 'a');
|
||||
test_type($db, 390, 'CHAR(10)', '0123456789');
|
||||
test_type($db, 400, 'CHAR(255)', str_repeat('z', 255));
|
||||
test_type($db, 410, 'VARCHAR(1)', 'a');
|
||||
test_type($db, 420, 'VARCHAR(10)', '0123456789');
|
||||
test_type($db, 430, 'VARCHAR(255)', str_repeat('z', 255));
|
||||
|
||||
test_type($db, 440, 'BINARY(1)', str_repeat('a', 1));
|
||||
test_type($db, 450, 'BINARY(255)', str_repeat('b', 255));
|
||||
test_type($db, 460, 'VARBINARY(1)', str_repeat('a', 1));
|
||||
test_type($db, 470, 'VARBINARY(255)', str_repeat('b', 255));
|
||||
|
||||
test_type($db, 480, 'TINYBLOB', str_repeat('b', 255));
|
||||
test_type($db, 490, 'BLOB', str_repeat('b', 256));
|
||||
test_type($db, 500, 'MEDIUMBLOB', str_repeat('b', 256));
|
||||
test_type($db, 510, 'LONGBLOB', str_repeat('b', 256));
|
||||
|
||||
test_type($db, 520, 'TINYTEXT', str_repeat('b', 255));
|
||||
test_type($db, 530, 'TINYTEXT BINARY', str_repeat('b', 255));
|
||||
|
||||
test_type($db, 560, 'TEXT', str_repeat('b', 256));
|
||||
test_type($db, 570, 'TEXT BINARY', str_repeat('b', 256));
|
||||
|
||||
test_type($db, 580, 'MEDIUMTEXT', str_repeat('b', 256));
|
||||
test_type($db, 590, 'MEDIUMTEXT BINARY', str_repeat('b', 256));
|
||||
|
||||
test_type($db, 600, 'LONGTEXT', str_repeat('b', 256));
|
||||
test_type($db, 610, 'LONGTEXT BINARY', str_repeat('b', 256));
|
||||
|
||||
test_type($db, 620, "ENUM('yes', 'no') DEFAULT 'yes'", 'no');
|
||||
test_type($db, 630, "SET('yes', 'no') DEFAULT 'yes'", 'no');
|
||||
|
||||
test_type($db, 640, 'DECIMAL(3,2)', -1.01, '-1.01');
|
||||
|
||||
|
||||
echo "done!\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
done!
|
117
ext/pdo_mysql/tests/pdo_mysql_types_zerofill.phpt
Normal file
117
ext/pdo_mysql/tests/pdo_mysql_types_zerofill.phpt
Normal file
|
@ -0,0 +1,117 @@
|
|||
--TEST--
|
||||
MySQL PDO->exec(), native types - ZEROFILL
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
|
||||
|
||||
function test_type(&$db, $offset, $sql_type, $value, $ret_value = NULL, $pattern = NULL) {
|
||||
|
||||
$db->exec('DROP TABLE IF EXISTS test');
|
||||
$sql = sprintf('CREATE TABLE test(id INT, label %s) ENGINE=%s', $sql_type, MySQLPDOTest::getTableEngine());
|
||||
@$db->exec($sql);
|
||||
if ($db->errorCode() != 0) {
|
||||
// not all MySQL Server versions and/or engines might support the type
|
||||
return true;
|
||||
}
|
||||
|
||||
$stmt = $db->prepare('INSERT INTO test(id, label) VALUES (?, ?)');
|
||||
$stmt->bindValue(1, $offset);
|
||||
$stmt->bindValue(2, $value);
|
||||
try {
|
||||
if (!$stmt->execute()) {
|
||||
printf("[%03d + 1] INSERT failed, %s\n", $offset, var_export($stmt->errorInfo(), true));
|
||||
return false;
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
// This might be a SQL warning on signed values inserted in unsigned columns
|
||||
// Zerofill implies unsigned but the test plays with signed = negative values as well!
|
||||
return true;
|
||||
}
|
||||
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
|
||||
$stmt = $db->query('SELECT id, label FROM test');
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
if (!isset($row['id']) || !isset($row['label'])) {
|
||||
printf("[%03d + 2] Fetched result seems wrong, dumping result: %s\n", $offset, var_export($row, true));
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($row['id'] != $offset) {
|
||||
printf("[%03d + 3] Expecting %s got %s\n", $offset, $row['id']);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_null($pattern)) {
|
||||
|
||||
if (!preg_match($pattern, $row['label'])) {
|
||||
printf("[%03d + 5] Value seems wrong, accepting pattern %s got %s, check manually\n",
|
||||
$offset, $pattern, var_export($row['label'], true));
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$exp = $value;
|
||||
if (!is_null($ret_value)) {
|
||||
// we expect a different return value than our input value
|
||||
// typically the difference is only the type
|
||||
$exp = $ret_value;
|
||||
}
|
||||
|
||||
if ($row['label'] !== $exp) {
|
||||
printf("[%03d + 4] %s - input = %s/%s, output = %s/%s\n", $offset,
|
||||
$sql_type, var_export($exp, true), gettype($exp),
|
||||
var_export($row['label'], true), gettype($row['label']));
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
|
||||
$stmt = $db->query('SELECT id, label FROM test');
|
||||
$row_string = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
if ($row['label'] != $row_string['label']) {
|
||||
printf("%s - STRINGIGY = %s, NATIVE = %s\n", $sql_type, var_export($row_string['label'], true), var_export($row['label'], true));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
|
||||
|
||||
test_type($db, 100, 'REAL ZEROFILL', -1.01, NULL, '/^[0]*0$/');
|
||||
test_type($db, 110, 'REAL ZEROFILL', 1.01, NULL, '/^[0]*1\.01$/');
|
||||
test_type($db, 120, 'REAL UNSIGNED ZEROFILL', 1.01, NULL, '/^[0]*1\.01$/');
|
||||
|
||||
test_type($db, 130, 'DOUBLE ZEROFILL', -1.01, NULL, '/^[0]*0$/');
|
||||
test_type($db, 140, 'DOUBLE ZEROFILL', 1.01, NULL, '/^[0]*1\.01$/');
|
||||
test_type($db, 150, 'DOUBLE UNSIGNED ZEROFILL', 1.01, NULL, '/^[0]*1\.01$/');
|
||||
|
||||
test_type($db, 160, 'FLOAT ZEROFILL', -1.01, NULL, '/^[0]*0$/');
|
||||
test_type($db, 170, 'FLOAT ZEROFILL', 1, NULL, '/^[0]*1$/');
|
||||
test_type($db, 180, 'FLOAT UNSIGNED ZEROFILL', -1, NULL, '/^[0]*0$/');
|
||||
|
||||
test_type($db, 190, 'DECIMAL ZEROFILL', -1.01, NULL, '/^[0]*0$/');
|
||||
test_type($db, 200, 'DECIMAL ZEROFILL', 1.01, NULL, '/^[0]*1$/');
|
||||
test_type($db, 210, 'DECIMAL UNSIGNED ZEROFILL', 1.01, NULL, '/^[0]*1$/');
|
||||
|
||||
test_type($db, 220, 'NUMERIC ZEROFILL', -1, NULL, '/^[0]*0$/');
|
||||
test_type($db, 230, 'NUMERIC ZEROFILL', 1, NULL, '/^[0]*1$/');
|
||||
test_type($db, 240, 'NUMERIC UNSIGNED ZEROFILL', 1.01, NULL, '/^[0]*1$/');
|
||||
|
||||
echo "done!\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
done!
|
30
ext/pdo_mysql/tests/pecl_bug_5200.phpt
Normal file
30
ext/pdo_mysql/tests/pecl_bug_5200.phpt
Normal file
|
@ -0,0 +1,30 @@
|
|||
--TEST--
|
||||
PDO MySQL PECL Bug #5200 (Describe table gives unexpected result mysql and type enum)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
$db = PDOTest::test_factory(dirname(__FILE__). '/common.phpt');
|
||||
|
||||
$db->exec("CREATE TABLE test (bar INT NOT NULL, phase enum('please_select', 'I', 'II', 'IIa', 'IIb', 'III', 'IV'))");
|
||||
|
||||
foreach ($db->query('DESCRIBE test phase')->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
print_r($row);
|
||||
}
|
||||
|
||||
--EXPECT--
|
||||
Array
|
||||
(
|
||||
[field] => phase
|
||||
[type] => enum('please_select','I','II','IIa','IIb','III','IV')
|
||||
[null] => YES
|
||||
[key] =>
|
||||
[default] =>
|
||||
[extra] =>
|
||||
)
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue