diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2013-03-14 05:42:27 +0000 |
---|---|---|
committer | <> | 2013-04-03 16:25:08 +0000 |
commit | c4dd7a1a684490673e25aaf4fabec5df138854c4 (patch) | |
tree | 4d57c44caae4480efff02b90b9be86f44bf25409 /ext/mysql | |
download | php2-master.tar.gz |
Imported from /home/lorry/working-area/delta_php2/php-5.4.13.tar.bz2.HEADphp-5.4.13master
Diffstat (limited to 'ext/mysql')
86 files changed, 9138 insertions, 0 deletions
diff --git a/ext/mysql/CREDITS b/ext/mysql/CREDITS new file mode 100644 index 0000000..e5a6208 --- /dev/null +++ b/ext/mysql/CREDITS @@ -0,0 +1,2 @@ +MySQL +Zeev Suraski, Zak Greant, Georg Richter diff --git a/ext/mysql/config.m4 b/ext/mysql/config.m4 new file mode 100644 index 0000000..5968c43 --- /dev/null +++ b/ext/mysql/config.m4 @@ -0,0 +1,167 @@ +dnl +dnl $Id$ +dnl + +AC_DEFUN([MYSQL_LIB_CHK], [ + str="$MYSQL_DIR/$1/lib$MYSQL_LIBNAME.*" + for j in `echo $str`; do + if test -r $j; then + MYSQL_LIB_DIR=$MYSQL_DIR/$1 + break 2 + fi + done +]) + +AC_DEFUN([PHP_MYSQL_SOCKET_SEARCH], [ + for i in \ + /var/run/mysqld/mysqld.sock \ + /var/tmp/mysql.sock \ + /var/run/mysql/mysql.sock \ + /var/lib/mysql/mysql.sock \ + /var/mysql/mysql.sock \ + /usr/local/mysql/var/mysql.sock \ + /Private/tmp/mysql.sock \ + /private/tmp/mysql.sock \ + /tmp/mysql.sock \ + ; do + if test -r $i; then + MYSQL_SOCK=$i + break 2 + fi + done + + if test -n "$MYSQL_SOCK"; then + AC_DEFINE_UNQUOTED(PHP_MYSQL_UNIX_SOCK_ADDR, "$MYSQL_SOCK", [ ]) + AC_MSG_RESULT([$MYSQL_SOCK]) + else + AC_MSG_RESULT([no]) + fi +]) + + +PHP_ARG_WITH(mysql, for MySQL support, +[ --with-mysql[=DIR] Include MySQL support. DIR is the MySQL base + directory, if no DIR is passed or the value is + mysqlnd the MySQL native driver will be used]) + +PHP_ARG_WITH(mysql-sock, for specified location of the MySQL UNIX socket, +[ --with-mysql-sock[=DIR] MySQL/MySQLi/PDO_MYSQL: Location of the MySQL unix socket pointer. + If unspecified, the default locations are searched], no, no) + +if test -z "$PHP_ZLIB_DIR"; then + PHP_ARG_WITH(zlib-dir, for the location of libz, + [ --with-zlib-dir[=DIR] MySQL: Set the path to libz install prefix], no, no) +fi + +if test "$PHP_MYSQL" = "yes" || test "$PHP_MYSQL" = "mysqlnd"; then + dnl enables build of mysqnd library + PHP_MYSQLND_ENABLED=yes + +elif test "$PHP_MYSQL" != "no"; then + MYSQL_DIR= + MYSQL_INC_DIR= + + if test -r $PHP_MYSQL/include/mysql/mysql.h; then + MYSQL_DIR=$PHP_MYSQL + MYSQL_INC_DIR=$PHP_MYSQL/include/mysql + break + elif test -r $PHP_MYSQL/include/mysql.h; then + MYSQL_DIR=$PHP_MYSQL + MYSQL_INC_DIR=$PHP_MYSQL/include + break + fi + + if test -z "$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 "$enable_maintainer_zts" = "yes"; then + MYSQL_LIBNAME=mysqlclient_r + else + MYSQL_LIBNAME=mysqlclient + fi + case $host_alias in + *netware*[)] + MYSQL_LIBNAME=mysql + ;; + esac + + dnl for compat with PHP 4 build system + if test -z "$PHP_LIBDIR"; then + PHP_LIBDIR=lib + fi + + for i in $PHP_LIBDIR $PHP_LIBDIR/mysql; do + MYSQL_LIB_CHK($i) + done + + if test -z "$MYSQL_LIB_DIR"; then + MYSQL_LIB_CHK(lib/x86_64-linux-gnu) + fi + if test -z "$MYSQL_LIB_DIR"; then + MYSQL_LIB_CHK(lib/i386-linux-gnu) + fi + + if test -z "$MYSQL_LIB_DIR"; then + AC_MSG_ERROR([Cannot find lib$MYSQL_LIBNAME under $MYSQL_DIR. +Note that the MySQL client library is not bundled anymore!]) + fi + + PHP_CHECK_LIBRARY($MYSQL_LIBNAME, mysql_close, [ ], + [ + if test "$PHP_ZLIB_DIR" != "no"; then + PHP_ADD_LIBRARY_WITH_PATH(z, $PHP_ZLIB_DIR, MYSQL_SHARED_LIBADD) + PHP_CHECK_LIBRARY($MYSQL_LIBNAME, mysql_error, [], [ + AC_MSG_ERROR([mysql configure failed. Please check config.log for more information.]) + ], [ + -L$PHP_ZLIB_DIR/$PHP_LIBDIR -L$MYSQL_LIB_DIR + ]) + MYSQL_LIBS="-L$PHP_ZLIB_DIR/$PHP_LIBDIR -lz" + else + PHP_ADD_LIBRARY(z,, MYSQL_SHARED_LIBADD) + PHP_CHECK_LIBRARY($MYSQL_LIBNAME, mysql_errno, [], [ + AC_MSG_ERROR([Try adding --with-zlib-dir=<DIR>. Please check config.log for more information.]) + ], [ + -L$MYSQL_LIB_DIR + ]) + MYSQL_LIBS="-lz" + fi + ], [ + -L$MYSQL_LIB_DIR + ]) + + PHP_ADD_LIBRARY_WITH_PATH($MYSQL_LIBNAME, $MYSQL_LIB_DIR, MYSQL_SHARED_LIBADD) + PHP_ADD_INCLUDE($MYSQL_INC_DIR) + + MYSQL_MODULE_TYPE=external + MYSQL_LIBS="-L$MYSQL_LIB_DIR -l$MYSQL_LIBNAME $MYSQL_LIBS" + MYSQL_INCLUDE=-I$MYSQL_INC_DIR + + PHP_SUBST_OLD(MYSQL_MODULE_TYPE) + PHP_SUBST_OLD(MYSQL_LIBS) + PHP_SUBST_OLD(MYSQL_INCLUDE) +fi + +dnl Enable extension +if test "$PHP_MYSQL" != "no"; then + AC_MSG_CHECKING([for MySQL UNIX socket location]) + if test "$PHP_MYSQL_SOCK" != "no" && test "$PHP_MYSQL_SOCK" != "yes"; then + MYSQL_SOCK=$PHP_MYSQL_SOCK + AC_DEFINE_UNQUOTED(PHP_MYSQL_UNIX_SOCK_ADDR, "$MYSQL_SOCK", [ ]) + AC_MSG_RESULT([$MYSQL_SOCK]) + elif test "$PHP_MYSQL" = "yes" || test "$PHP_MYSQL_SOCK" = "yes"; then + PHP_MYSQL_SOCKET_SEARCH + else + AC_MSG_RESULT([no]) + fi + + AC_DEFINE(HAVE_MYSQL, 1, [Whether you have MySQL]) + PHP_NEW_EXTENSION(mysql, php_mysql.c, $ext_shared) + PHP_SUBST(MYSQL_SHARED_LIBADD) + + if test "$PHP_MYSQL" = "yes" || test "$PHP_MYSQL" = "mysqlnd"; then + PHP_ADD_EXTENSION_DEP(mysql, mysqlnd) + AC_DEFINE([MYSQL_USE_MYSQLND], 1, [Whether mysqlnd is enabled]) + fi +fi diff --git a/ext/mysql/config.w32 b/ext/mysql/config.w32 new file mode 100644 index 0000000..2a929b4 --- /dev/null +++ b/ext/mysql/config.w32 @@ -0,0 +1,28 @@ +// $Id$ +// vim:ft=javascript + +ARG_WITH("mysql", "MySQL support", "no"); + +if (PHP_MYSQL != "no") { + if ((PHP_MYSQL == "yes" || PHP_MYSQL == "mysqlnd")) { + AC_DEFINE('MYSQL_USE_MYSQLND', 1, 'Using MySQL native driver'); + if (!ADD_EXTENSION_DEP('mysql', 'mysqlnd', true)) { + PHP_MYSQL = "no"; + WARNING("mysql not enabled; mysqlnd is not enabled"); + } else { + EXTENSION("mysql", "php_mysql.c"); + AC_DEFINE('HAVE_MYSQL', 1, 'Have MySQL library'); + MESSAGE("\tusing mysqlnd build"); + } + } else if (PHP_MYSQL != "") { + if (CHECK_LIB("libmysql.lib", "mysql", PHP_MYSQL) && + CHECK_HEADER_ADD_INCLUDE("mysql.h", "CFLAGS_MYSQL", + PHP_MYSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\mysql;" + PHP_MYSQL)) { + EXTENSION("mysql", "php_mysql.c"); + AC_DEFINE('HAVE_MYSQL', 1, 'Have MySQL library'); + MESSAGE("\tusing libmysql"); + } else { + WARNING("mysql not enabled; libraries and headers not found"); + } + } +} diff --git a/ext/mysql/mysql.dsp b/ext/mysql/mysql.dsp new file mode 100644 index 0000000..dfc9c63 --- /dev/null +++ b/ext/mysql/mysql.dsp @@ -0,0 +1,171 @@ +# Microsoft Developer Studio Project File - Name="mysql" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mysql - Win32 Debug_TS
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysql.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysql.mak" CFG="mysql - Win32 Debug_TS"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysql - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mysql - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mysql - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mysql - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysql - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MYSQL_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\..\MySQL\include" /I "..\..\TSRM" /D "NDEBUG" /D "MYSQL_EXPORTS" /D "COMPILE_DL_MYSQL" /D HAVE_MYSQL=1 /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZEND_WIN32" /D "PHP_WIN32" /D "COMPILE_DL_MYSQL" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x40d /d "NDEBUG"
+# ADD RSC /l 0x40d /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libmySQL.lib php5nts.lib /nologo /dll /machine:I386 /out:"Release/php_mysql.dll" /libpath:"..\..\..\MySQL\lib\opt" /libpath:"..\..\Release"
+
+!ELSEIF "$(CFG)" == "mysql - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MYSQL_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\..\MySQL\include" /I "..\..\TSRM" /D "_DEBUG" /D ZEND_DEBUG=1 /D "MYSQL_EXPORTS" /D "COMPILE_DL_MYSQL" /D HAVE_MYSQL=1 /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZEND_WIN32" /D "PHP_WIN32" /D "COMPILE_DL_MYSQL" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x40d /d "_DEBUG"
+# ADD RSC /l 0x40d /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libmySQL.lib php5nts_debug.lib /nologo /dll /debug /machine:I386 /out:"Debug/php_mysql.dll" /pdbtype:sept /libpath:"..\..\..\MySQL\lib\Debug" /libpath:"..\..\Debug"
+
+!ELSEIF "$(CFG)" == "mysql - Win32 Debug_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug_TS"
+# PROP BASE Intermediate_Dir "Debug_TS"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug_TS"
+# PROP Intermediate_Dir "Debug_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\..\Zend" /I "..\..\..\bindlib_w32" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MYSQL_EXPORTS" /D "COMPILE_DL_MYSQL" /D HAVE_MYSQL=1 /FR /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\..\MySQL\include" /I "..\..\TSRM" /D "_DEBUG" /D ZEND_DEBUG=1 /D "ZTS" /D "MYSQL_EXPORTS" /D "COMPILE_DL_MYSQL" /D HAVE_MYSQL=1 /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZEND_WIN32" /D "PHP_WIN32" /D "COMPILE_DL_MYSQL" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x40d /d "_DEBUG"
+# ADD RSC /l 0x40d /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 php5ts_debug.lib libmySQL.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS/php_mysql.dll" /pdbtype:sept /libpath:"..\..\..\MySQL\lib\Debug" /libpath:"..\..\Debug_TS"
+
+!ELSEIF "$(CFG)" == "mysql - Win32 Release_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release_TS"
+# PROP BASE Intermediate_Dir "Release_TS"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_TS"
+# PROP Intermediate_Dir "Release_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\..\Zend" /I "..\..\..\bindlib_w32" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MYSQL_EXPORTS" /D "COMPILE_DL_MYSQL" /D HAVE_MYSQL=1 /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\..\MySQL\include" /I "..\..\TSRM" /D "NDEBUG" /D ZEND_DEBUG=0 /D "ZTS" /D "MYSQL_EXPORTS" /D "COMPILE_DL_MYSQL" /D HAVE_MYSQL=1 /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZEND_WIN32" /D "PHP_WIN32" /D "COMPILE_DL_MYSQL" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x40d /d "NDEBUG"
+# ADD RSC /l 0x40d /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libmySQL.lib php5ts.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_mysql.dll" /libpath:"..\..\..\MySQL\lib\opt" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline"
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysql - Win32 Release"
+# Name "mysql - Win32 Debug"
+# Name "mysql - Win32 Debug_TS"
+# Name "mysql - Win32 Release_TS"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\php_mysql.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\php_mysql.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# Begin Source File
+
+SOURCE=.\Readme_w32.txt
+# End Source File
+# End Target
+# End Project
diff --git a/ext/mysql/mysql.mak b/ext/mysql/mysql.mak new file mode 100644 index 0000000..2ed0f82 --- /dev/null +++ b/ext/mysql/mysql.mak @@ -0,0 +1,169 @@ +# Temporarily here -- later may go into some batch file +# which will set this as an environment variable +PROJECT_ROOT = ..\.. + +# Module details +MODULE_NAME = phpmysql +MODULE_DESC = "PHP 4.3 - MySQL Extension" +VMAJ = 3 +VMIN = 0 +VREV = 0 + +#include the common settings +include $(PROJECT_ROOT)/netware/common.mif + +# MYSQL stuff +MYSQL_DIR = P:/APPS/script/sw/mysql + +# Build type defaults to 'release' +ifndef BUILD +BUILD = release +endif + +# Extensions of all input and output files +.SUFFIXES: +.SUFFIXES: .nlm .lib .obj .cpp .c .msg .mlc .mdb .xdc .d + +# Source files +C_SRC = php_mysql.c \ + start.c + +CPP_SRC_NODIR = $(notdir $(CPP_SRC)) +C_SRC_NODIR = $(notdir $(C_SRC)) +SRC_DIR = $(dir $(CPP_SRC) $(C_SRC)) + +# Library files +LIBRARY = $(MYSQL_DIR)/lib/libmysqlclient.lib + +# Destination directories and files +OBJ_DIR = $(BUILD) +FINAL_DIR = $(BUILD) +OBJECTS = $(addprefix $(OBJ_DIR)/,$(CPP_SRC_NODIR:.c=.obj) $(C_SRC_NODIR:.c=.obj)) +DEPDS = $(addprefix $(OBJ_DIR)/,$(CPP_SRC_NODIR:.c=.d) $(C_SRC_NODIR:.c=.d)) + +# Binary file +ifndef BINARY + BINARY=$(FINAL_DIR)\$(MODULE_NAME).nlm +endif + +# Compile flags +C_FLAGS = -c -maxerrors 25 -msgstyle gcc -wchar_t on -bool on -processor Pentium +C_FLAGS += -nostdinc -nosyspath +C_FLAGS += -relax_pointers # To remove type-casting errors +C_FLAGS += -DNETWARE -DZTS -DNEW_LIBC -DUSE_OLD_FUNCTIONS -DCOMPILE_DL_MYSQL=1 +C_FLAGS += -I. -I- -I$(PROJECT_ROOT) -I$(PROJECT_ROOT)/main +C_FLAGS += -I$(PROJECT_ROOT)/ext/standard -I$(PROJECT_ROOT)/netware +C_FLAGS += -I$(PROJECT_ROOT)/zend -I$(PROJECT_ROOT)/tsrm +C_FLAGS += -I$(SDK_DIR)/include -I$(MWCIncludes) +C_FLAGS += -I$(MYSQL_DIR)/include +C_FLAGS += -I$(WINSOCK_DIR)/include/nlm -I$(WINSOCK_DIR)/include + + +# Extra stuff based on debug / release builds +ifeq '$(BUILD)' 'debug' + SYM_FILE = $(FINAL_DIR)\$(MODULE_NAME).sym + C_FLAGS += -inline smart -sym on -sym codeview4 -opt off -opt intrinsics -DDEBUGGING -DDKFBPON + C_FLAGS += -exc cw -DZEND_DEBUG=1 + LD_FLAGS += -sym on -sym codeview4 -osym $(SYM_FILE) + export MWLibraryFiles=$(SDK_DIR)/imports/libcpre.o;mwcrtld.lib +else + C_FLAGS += -opt speed -inline on -inline smart -inline auto -sym off -opt intrinsics + C_FLAGS += -opt level=4 -DZEND_DEBUG=0 + LD_FLAGS += -sym off + export MWLibraryFiles=$(SDK_DIR)/imports/libcpre.o;mwcrtl.lib +endif + + +# Dependencies +MODULE = LibC \ + phplib +IMPORT = @$(SDK_DIR)/imports/libc.imp \ + @$(SDK_DIR)/imports/ws2nlm.imp \ + @$(MPK_DIR)/import/mpkOrg.imp \ + @$(PROJECT_ROOT)/netware/phplib.imp +EXPORT = ($(MODULE_NAME)) get_module +API = OutputToScreen + +# Virtual paths +vpath %.cpp . +vpath %.c . ..\..\netware +vpath %.obj $(OBJ_DIR) + + +all: prebuild project + +.PHONY: all + +prebuild: + @if not exist $(OBJ_DIR) md $(OBJ_DIR) + +project: $(BINARY) + @echo Build complete. + +$(OBJ_DIR)/%.d: %.cpp + @echo Building Dependencies for $(<F) + @$(CC) -M $< $(C_FLAGS) -o $@ + +$(OBJ_DIR)/%.d: %.c + @echo Building Dependencies for $(<F) + @$(CC) -M $< $(C_FLAGS) -o $@ + +$(OBJ_DIR)/%.obj: %.cpp + @echo Compiling $?... + @$(CC) $< $(C_FLAGS) -o $@ + +$(OBJ_DIR)/%.obj: %.c + @echo Compiling $?... + @$(CC) $< $(C_FLAGS) -o $@ + + +$(BINARY): $(OBJECTS) + @echo Import $(IMPORT) > $(basename $@).def +ifdef API + @echo Import $(API) >> $(basename $@).def +endif + @echo Module $(MODULE) >> $(basename $@).def +ifdef EXPORT + @echo Export $(EXPORT) >> $(basename $@).def +endif + @echo AutoUnload >> $(basename $@).def +ifeq '$(BUILD)' 'debug' + @echo Debug >> $(basename $@).def +endif + @echo Flag_On 0x00000008 >> $(basename $@).def + @echo Start _LibCPrelude >> $(basename $@).def + @echo Exit _LibCPostlude >> $(basename $@).def + + $(MPKTOOL) $(XDCFLAGS) $(basename $@).xdc + @echo xdcdata $(basename $@).xdc >> $(basename $@).def + + @echo Linking $@... + @echo $(LD_FLAGS) -commandfile $(basename $@).def > $(basename $@).link + @echo $(LIBRARY) $(OBJECTS) >> $(basename $@).link + @$(LINK) @$(basename $@).link + + +.PHONY: clean +clean: cleanobj cleanbin + +.PHONY: cleand +cleand: + @echo Deleting all dependency files... + -@del "$(OBJ_DIR)\*.d" + +.PHONY: cleanobj +cleanobj: + @echo Deleting all object files... + -@del "$(OBJ_DIR)\*.obj" + +.PHONY: cleanbin +cleanbin: + @echo Deleting binary files... + -@del "$(FINAL_DIR)\$(MODULE_NAME).nlm" + @echo Deleting MAP, DEF files, etc.... + -@del "$(FINAL_DIR)\$(MODULE_NAME).map" + -@del "$(FINAL_DIR)\$(MODULE_NAME).def" + -@del "$(FINAL_DIR)\$(MODULE_NAME).link" +ifeq '$(BUILD)' 'debug' + -@del $(FINAL_DIR)\$(MODULE_NAME).sym +endif diff --git a/ext/mysql/mysql_mysqlnd.h b/ext/mysql/mysql_mysqlnd.h new file mode 100644 index 0000000..0c4c221 --- /dev/null +++ b/ext/mysql/mysql_mysqlnd.h @@ -0,0 +1,30 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 2006-2009 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Georg Richter <georg@mysql.com> | + | Andrey Hristov <andrey@mysql.com> | + | Ulf Wendel <uwendel@mysql.com> | + +----------------------------------------------------------------------+ + +*/ + +#ifndef MYSQL_MYSQLND_H +#define MYSQL_MYSQLND_H + +#include "ext/mysqlnd/mysqlnd_libmysql_compat.h" + +/* Here comes non-libmysql API to have less ifdefs in mysqli */ +#define mysql_result_is_unbuffered(r) ((r)->unbuf) + +#endif diff --git a/ext/mysql/package.xml b/ext/mysql/package.xml new file mode 100644 index 0000000..79fd6ba --- /dev/null +++ b/ext/mysql/package.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="ISO-8859-1" ?> +<!DOCTYPE package SYSTEM "../pear/package.dtd"> +<package> + <name>mysql</name> + <summary>MySQL database access functions</summary> + <maintainers> + <maintainer> + <user>georg</user> + <name>Georg Richter</name> + <email>georg@php.net</email> + <role>lead</role> + </maintainer> + <maintainer> + <user>zak</user> + <name>Zak Greant</name> + <email>zak@php.net</email> + <role>developer</role> + </maintainer> + <maintainer> + <user>zeev</user> + <name>Zeev Suraski</name> + <email>zeev@php.net</email> + <role>developer</role> + </maintainer> + </maintainers> + <description> +These functions allow you to access MySQL database servers. + </description> + <license>PHP</license> + <release> + <state>stable</state> + <version>1.0</version> + <date>2005-09-04</date> + <notes> +This is the MySQL driver, taken from the PHP 5.1 release. +It can also be built against PHP 4. + </notes> + <configureoptions> + <configureoption name="with-mysql" default="autodetect" prompt="mysql installation dir?"/> + <configureoption name="with-mysql-sock" default="autodetect" prompt="MySQL Unix socket?"/> + <configureoption name="with-zlib-dir" default="autodetect" prompt="zlib installation dir?"/> + </configureoptions> + <filelist> + <file role="src" name="config.m4"/> + <file role="src" name="config.w32"/> + <file role="doc" name="CREDITS"/> + <file role="src" name="mysql.dsp"/> + <file role="src" name="mysql.mak"/> + <file role="src" name="php_mysql.c"/> + <file role="src" name="php_mysql.h"/> + <file role="test" name="tests/001.phpt"/> + <file role="test" name="tests/002.phpt"/> + <file role="test" name="tests/003.phpt"/> + <file role="test" name="tests/connect.inc"/> + <file role="test" name="tests/skipif.inc"/> + </filelist> + <deps> + <dep type="php" rel="ge" version="4" /> + </deps> + </release> +</package> +<!-- +vim:et:ts=1:sw=1 +--> diff --git a/ext/mysql/php_mysql.c b/ext/mysql/php_mysql.c new file mode 100644 index 0000000..5ad7bc9 --- /dev/null +++ b/ext/mysql/php_mysql.c @@ -0,0 +1,2691 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Zeev Suraski <zeev@zend.com> | + | Zak Greant <zak@mysql.com> | + | Georg Richter <georg@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +/* TODO: + * + * ? Safe mode implementation + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "php.h" +#include "php_globals.h" +#include "ext/standard/info.h" +#include "ext/standard/php_string.h" +#include "ext/standard/basic_functions.h" + +#ifdef ZEND_ENGINE_2 +# include "zend_exceptions.h" +#else + /* PHP 4 compat */ +# define OnUpdateLong OnUpdateInt +# define E_STRICT E_NOTICE +#endif + +#if HAVE_MYSQL + +#ifdef PHP_WIN32 +# include <winsock2.h> +# define signal(a, b) NULL +#elif defined(NETWARE) +# include <sys/socket.h> +# define signal(a, b) NULL +#else +# if HAVE_SIGNAL_H +# include <signal.h> +# endif +# if HAVE_SYS_TYPES_H +# include <sys/types.h> +# endif +# include <netdb.h> +# include <netinet/in.h> +# if HAVE_ARPA_INET_H +# include <arpa/inet.h> +# endif +#endif + +#include "php_ini.h" +#include "php_mysql_structs.h" + +/* True globals, no need for thread safety */ +static int le_result, le_link, le_plink; + +#ifdef HAVE_MYSQL_REAL_CONNECT +# ifdef HAVE_ERRMSG_H +# include <errmsg.h> +# endif +#endif + +#define SAFE_STRING(s) ((s)?(s):"") + +#if MYSQL_VERSION_ID > 32199 || defined(MYSQL_USE_MYSQLND) +# define mysql_row_length_type unsigned long +# define HAVE_MYSQL_ERRNO +#else +# define mysql_row_length_type unsigned int +# ifdef mysql_errno +# define HAVE_MYSQL_ERRNO +# endif +#endif + +#if MYSQL_VERSION_ID >= 32032 || defined(MYSQL_USE_MYSQLND) +#define HAVE_GETINFO_FUNCS +#endif + +#if MYSQL_VERSION_ID > 32133 || defined(FIELD_TYPE_TINY) +#define MYSQL_HAS_TINY +#endif + +#if MYSQL_VERSION_ID >= 32200 +#define MYSQL_HAS_YEAR +#endif + +#define MYSQL_ASSOC 1<<0 +#define MYSQL_NUM 1<<1 +#define MYSQL_BOTH (MYSQL_ASSOC|MYSQL_NUM) + +#define MYSQL_USE_RESULT 0 +#define MYSQL_STORE_RESULT 1 + +#if MYSQL_VERSION_ID < 32224 +#define PHP_MYSQL_VALID_RESULT(mysql) \ + (mysql_num_fields(mysql)>0) +#else +#define PHP_MYSQL_VALID_RESULT(mysql) \ + (mysql_field_count(mysql)>0) +#endif + +ZEND_DECLARE_MODULE_GLOBALS(mysql) +static PHP_GINIT_FUNCTION(mysql); + +typedef struct _php_mysql_conn { + MYSQL *conn; + int active_result_id; + int multi_query; +} php_mysql_conn; + + +#if MYSQL_VERSION_ID >= 40101 +#define MYSQL_DISABLE_MQ if (mysql->multi_query) { \ + mysql_set_server_option(mysql->conn, MYSQL_OPTION_MULTI_STATEMENTS_OFF); \ + mysql->multi_query = 0; \ +} +#else +#define MYSQL_DISABLE_MQ +#endif + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_connect, 0, 0, 0) + ZEND_ARG_INFO(0, hostname) + ZEND_ARG_INFO(0, username) + ZEND_ARG_INFO(0, password) + ZEND_ARG_INFO(0, new) + ZEND_ARG_INFO(0, flags) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_pconnect, 0, 0, 0) + ZEND_ARG_INFO(0, hostname) + ZEND_ARG_INFO(0, username) + ZEND_ARG_INFO(0, password) + ZEND_ARG_INFO(0, flags) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo__optional_mysql_link, 0, 0, 0) + ZEND_ARG_INFO(0, link_identifier) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_select_db, 0, 0, 1) + ZEND_ARG_INFO(0, database_name) + ZEND_ARG_INFO(0, link_identifier) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo__void_mysql_arg, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_set_charset, 0, 0, 1) + ZEND_ARG_INFO(0, charset_name) + ZEND_ARG_INFO(0, link_identifier) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_query, 0, 0, 1) + ZEND_ARG_INFO(0, query) + ZEND_ARG_INFO(0, link_identifier) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_db_query, 0, 0, 2) + ZEND_ARG_INFO(0, database_name) + ZEND_ARG_INFO(0, query) + ZEND_ARG_INFO(0, link_identifier) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_list_fields, 0, 0, 2) + ZEND_ARG_INFO(0, database_name) + ZEND_ARG_INFO(0, table_name) + ZEND_ARG_INFO(0, link_identifier) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_escape_string, 0, 0, 1) + ZEND_ARG_INFO(0, string) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_real_escape_string, 0, 0, 1) + ZEND_ARG_INFO(0, string) + ZEND_ARG_INFO(0, link_identifier) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_result, 0, 0, 2) + ZEND_ARG_INFO(0, result) + ZEND_ARG_INFO(0, row) + ZEND_ARG_INFO(0, field) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo__result_mysql_arg, 0, 0, 1) + ZEND_ARG_INFO(0, result) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_fetch_object, 0, 0, 1) + ZEND_ARG_INFO(0, result) + ZEND_ARG_INFO(0, class_name) + ZEND_ARG_INFO(0, ctor_params) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_fetch_array, 0, 0, 1) + ZEND_ARG_INFO(0, result) + ZEND_ARG_INFO(0, result_type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_data_seek, 0, 0, 2) + ZEND_ARG_INFO(0, result) + ZEND_ARG_INFO(0, row_number) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_fetch_field, 0, 0, 1) + ZEND_ARG_INFO(0, result) + ZEND_ARG_INFO(0, field_offset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_field_seek, 0, 0, 2) + ZEND_ARG_INFO(0, result) + ZEND_ARG_INFO(0, field_offset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_field_name, 0, 0, 2) + ZEND_ARG_INFO(0, result) + ZEND_ARG_INFO(0, field_index) +ZEND_END_ARG_INFO() +/* }}} */ + +/* {{{ mysql_functions[] + */ +static const zend_function_entry mysql_functions[] = { + PHP_FE(mysql_connect, arginfo_mysql_connect) + PHP_FE(mysql_pconnect, arginfo_mysql_pconnect) + PHP_FE(mysql_close, arginfo__optional_mysql_link) + PHP_FE(mysql_select_db, arginfo_mysql_select_db) +#ifndef NETWARE /* The below two functions not supported on NetWare */ +#if MYSQL_VERSION_ID < 40000 + PHP_DEP_FE(mysql_create_db, arginfo_mysql_select_db) + PHP_DEP_FE(mysql_drop_db, arginfo_mysql_select_db) +#endif +#endif /* NETWARE */ + PHP_FE(mysql_query, arginfo_mysql_query) + PHP_FE(mysql_unbuffered_query, arginfo_mysql_query) + PHP_DEP_FE(mysql_db_query, arginfo_mysql_db_query) + PHP_DEP_FE(mysql_list_dbs, arginfo__optional_mysql_link) + PHP_DEP_FE(mysql_list_tables, arginfo_mysql_select_db) + PHP_FE(mysql_list_fields, arginfo_mysql_list_fields) + PHP_FE(mysql_list_processes, arginfo__optional_mysql_link) + PHP_FE(mysql_error, arginfo__optional_mysql_link) +#ifdef HAVE_MYSQL_ERRNO + PHP_FE(mysql_errno, arginfo__optional_mysql_link) +#endif + PHP_FE(mysql_affected_rows, arginfo__optional_mysql_link) + PHP_FE(mysql_insert_id, arginfo__optional_mysql_link) + PHP_FE(mysql_result, arginfo_mysql_result) + PHP_FE(mysql_num_rows, arginfo__result_mysql_arg) + PHP_FE(mysql_num_fields, arginfo__result_mysql_arg) + PHP_FE(mysql_fetch_row, arginfo__result_mysql_arg) + PHP_FE(mysql_fetch_array, arginfo_mysql_fetch_array) + PHP_FE(mysql_fetch_assoc, arginfo__result_mysql_arg) + PHP_FE(mysql_fetch_object, arginfo_mysql_fetch_object) + PHP_FE(mysql_data_seek, arginfo_mysql_data_seek) + PHP_FE(mysql_fetch_lengths, arginfo__result_mysql_arg) + PHP_FE(mysql_fetch_field, arginfo_mysql_fetch_field) + PHP_FE(mysql_field_seek, arginfo_mysql_field_seek) + PHP_FE(mysql_free_result, arginfo__result_mysql_arg) + PHP_FE(mysql_field_name, arginfo_mysql_field_name) + PHP_FE(mysql_field_table, arginfo_mysql_field_seek) + PHP_FE(mysql_field_len, arginfo_mysql_field_seek) + PHP_FE(mysql_field_type, arginfo_mysql_field_seek) + PHP_FE(mysql_field_flags, arginfo_mysql_field_seek) + PHP_FE(mysql_escape_string, arginfo_mysql_escape_string) + PHP_FE(mysql_real_escape_string, arginfo_mysql_real_escape_string) + PHP_FE(mysql_stat, arginfo__optional_mysql_link) + PHP_FE(mysql_thread_id, arginfo__optional_mysql_link) + PHP_FE(mysql_client_encoding, arginfo__optional_mysql_link) + PHP_FE(mysql_ping, arginfo__optional_mysql_link) +#ifdef HAVE_GETINFO_FUNCS + PHP_FE(mysql_get_client_info, arginfo__void_mysql_arg) + PHP_FE(mysql_get_host_info, arginfo__optional_mysql_link) + PHP_FE(mysql_get_proto_info, arginfo__optional_mysql_link) + PHP_FE(mysql_get_server_info, arginfo__optional_mysql_link) +#endif + + PHP_FE(mysql_info, arginfo__optional_mysql_link) +#ifdef MYSQL_HAS_SET_CHARSET + PHP_FE(mysql_set_charset, arginfo_mysql_set_charset) +#endif + /* for downwards compatability */ + PHP_FALIAS(mysql, mysql_db_query, arginfo_mysql_db_query) + PHP_FALIAS(mysql_fieldname, mysql_field_name, arginfo_mysql_field_name) + PHP_FALIAS(mysql_fieldtable, mysql_field_table, arginfo_mysql_field_seek) + PHP_FALIAS(mysql_fieldlen, mysql_field_len, arginfo_mysql_field_seek) + PHP_FALIAS(mysql_fieldtype, mysql_field_type, arginfo_mysql_field_seek) + PHP_FALIAS(mysql_fieldflags, mysql_field_flags, arginfo_mysql_field_seek) + PHP_FALIAS(mysql_selectdb, mysql_select_db, arginfo_mysql_select_db) +#ifndef NETWARE /* The below two functions not supported on NetWare */ +#if MYSQL_VERSION_ID < 40000 + PHP_DEP_FALIAS(mysql_createdb, mysql_create_db, arginfo_mysql_select_db) + PHP_DEP_FALIAS(mysql_dropdb, mysql_drop_db, arginfo_mysql_select_db) +#endif +#endif /* NETWARE */ + PHP_FALIAS(mysql_freeresult, mysql_free_result, arginfo__result_mysql_arg) + PHP_FALIAS(mysql_numfields, mysql_num_fields, arginfo__result_mysql_arg) + PHP_FALIAS(mysql_numrows, mysql_num_rows, arginfo__result_mysql_arg) + PHP_FALIAS(mysql_listdbs, mysql_list_dbs, arginfo__optional_mysql_link) + PHP_DEP_FALIAS(mysql_listtables,mysql_list_tables, arginfo_mysql_select_db) + PHP_FALIAS(mysql_listfields, mysql_list_fields, arginfo_mysql_list_fields) + PHP_FALIAS(mysql_db_name, mysql_result, arginfo_mysql_result) + PHP_FALIAS(mysql_dbname, mysql_result, arginfo_mysql_result) + PHP_FALIAS(mysql_tablename, mysql_result, arginfo_mysql_result) + PHP_FALIAS(mysql_table_name, mysql_result, arginfo_mysql_result) + PHP_FE_END +}; +/* }}} */ + +/* Dependancies */ +static const zend_module_dep mysql_deps[] = { +#if defined(MYSQL_USE_MYSQLND) + ZEND_MOD_REQUIRED("mysqlnd") +#endif + ZEND_MOD_END +}; + +/* {{{ mysql_module_entry + */ +zend_module_entry mysql_module_entry = { +#if ZEND_MODULE_API_NO >= 20050922 + STANDARD_MODULE_HEADER_EX, NULL, + mysql_deps, +#elif ZEND_MODULE_API_NO >= 20010901 + STANDARD_MODULE_HEADER, +#endif + "mysql", + mysql_functions, + ZEND_MODULE_STARTUP_N(mysql), + PHP_MSHUTDOWN(mysql), + PHP_RINIT(mysql), + PHP_RSHUTDOWN(mysql), + PHP_MINFO(mysql), + "1.0", + PHP_MODULE_GLOBALS(mysql), + PHP_GINIT(mysql), + NULL, + NULL, + STANDARD_MODULE_PROPERTIES_EX +}; +/* }}} */ + +#ifdef COMPILE_DL_MYSQL +ZEND_GET_MODULE(mysql) +#endif + +void timeout(int sig); + +#define CHECK_LINK(link) { if (link==-1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "A link to the server could not be established"); RETURN_FALSE; } } + +#if defined(MYSQL_USE_MYSQLND) +#define PHPMY_UNBUFFERED_QUERY_CHECK() \ +{\ + if (mysql->active_result_id) { \ + do { \ + int type; \ + MYSQL_RES *_mysql_result; \ + \ + _mysql_result = (MYSQL_RES *) zend_list_find(mysql->active_result_id, &type); \ + if (_mysql_result && type==le_result) { \ + if (mysql_result_is_unbuffered(_mysql_result) && !mysql_eof(_mysql_result)) { \ + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Function called without first fetching all rows from a previous unbuffered query"); \ + } \ + zend_list_delete(mysql->active_result_id); \ + mysql->active_result_id = 0; \ + } \ + } while(0); \ + }\ +} +#else +#define PHPMY_UNBUFFERED_QUERY_CHECK() \ +{ \ + if (mysql->active_result_id) { \ + do { \ + int type; \ + MYSQL_RES *mysql_result; \ + \ + mysql_result = (MYSQL_RES *) zend_list_find(mysql->active_result_id, &type); \ + if (mysql_result && type==le_result) { \ + if (!mysql_eof(mysql_result)) { \ + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Function called without first fetching all rows from a previous unbuffered query"); \ + while (mysql_fetch_row(mysql_result)); \ + } \ + zend_list_delete(mysql->active_result_id); \ + mysql->active_result_id = 0; \ + } \ + } while(0); \ + } \ +} +#endif + +/* {{{ _free_mysql_result + * This wrapper is required since mysql_free_result() returns an integer, and + * thus, cannot be used directly + */ +static void _free_mysql_result(zend_rsrc_list_entry *rsrc TSRMLS_DC) +{ + MYSQL_RES *mysql_result = (MYSQL_RES *)rsrc->ptr; + + mysql_free_result(mysql_result); + MySG(result_allocated)--; +} +/* }}} */ + +/* {{{ php_mysql_set_default_link + */ +static void php_mysql_set_default_link(int id TSRMLS_DC) +{ + if (MySG(default_link) != -1) { + zend_list_delete(MySG(default_link)); + } + MySG(default_link) = id; + zend_list_addref(id); +} +/* }}} */ + +/* {{{ php_mysql_select_db +*/ +static int php_mysql_select_db(php_mysql_conn *mysql, char *db TSRMLS_DC) +{ + PHPMY_UNBUFFERED_QUERY_CHECK(); + + if (mysql_select_db(mysql->conn, db) != 0) { + return 0; + } else { + return 1; + } +} +/* }}} */ + +/* {{{ _close_mysql_link + */ +static void _close_mysql_link(zend_rsrc_list_entry *rsrc TSRMLS_DC) +{ + php_mysql_conn *link = (php_mysql_conn *)rsrc->ptr; + void (*handler) (int); + + handler = signal(SIGPIPE, SIG_IGN); + mysql_close(link->conn); + signal(SIGPIPE, handler); + efree(link); + MySG(num_links)--; +} +/* }}} */ + +/* {{{ _close_mysql_plink + */ +static void _close_mysql_plink(zend_rsrc_list_entry *rsrc TSRMLS_DC) +{ + php_mysql_conn *link = (php_mysql_conn *)rsrc->ptr; + void (*handler) (int); + + handler = signal(SIGPIPE, SIG_IGN); + mysql_close(link->conn); + signal(SIGPIPE, handler); + + free(link); + MySG(num_persistent)--; + MySG(num_links)--; +} +/* }}} */ + +/* {{{ PHP_INI_MH + */ +static PHP_INI_MH(OnMySQLPort) +{ + if (new_value != NULL) { /* default port */ + MySG(default_port) = atoi(new_value); + } else { + MySG(default_port) = -1; + } + + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_INI */ +PHP_INI_BEGIN() + STD_PHP_INI_BOOLEAN("mysql.allow_persistent", "1", PHP_INI_SYSTEM, OnUpdateLong, allow_persistent, zend_mysql_globals, mysql_globals) + STD_PHP_INI_ENTRY_EX("mysql.max_persistent", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_persistent, zend_mysql_globals, mysql_globals, display_link_numbers) + STD_PHP_INI_ENTRY_EX("mysql.max_links", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_links, zend_mysql_globals, mysql_globals, display_link_numbers) + STD_PHP_INI_ENTRY("mysql.default_host", NULL, PHP_INI_ALL, OnUpdateString, default_host, zend_mysql_globals, mysql_globals) + STD_PHP_INI_ENTRY("mysql.default_user", NULL, PHP_INI_ALL, OnUpdateString, default_user, zend_mysql_globals, mysql_globals) + STD_PHP_INI_ENTRY("mysql.default_password", NULL, PHP_INI_ALL, OnUpdateString, default_password, zend_mysql_globals, mysql_globals) + PHP_INI_ENTRY("mysql.default_port", NULL, PHP_INI_ALL, OnMySQLPort) +#ifdef MYSQL_UNIX_ADDR + STD_PHP_INI_ENTRY("mysql.default_socket", MYSQL_UNIX_ADDR,PHP_INI_ALL,OnUpdateStringUnempty, default_socket, zend_mysql_globals, mysql_globals) +#else + STD_PHP_INI_ENTRY("mysql.default_socket", NULL, PHP_INI_ALL, OnUpdateStringUnempty, default_socket, zend_mysql_globals, mysql_globals) +#endif + STD_PHP_INI_ENTRY("mysql.connect_timeout", "60", PHP_INI_ALL, OnUpdateLong, connect_timeout, zend_mysql_globals, mysql_globals) + STD_PHP_INI_BOOLEAN("mysql.trace_mode", "0", PHP_INI_ALL, OnUpdateLong, trace_mode, zend_mysql_globals, mysql_globals) + STD_PHP_INI_BOOLEAN("mysql.allow_local_infile", "1", PHP_INI_SYSTEM, OnUpdateLong, allow_local_infile, zend_mysql_globals, mysql_globals) +PHP_INI_END() +/* }}} */ + +/* {{{ PHP_GINIT_FUNCTION + */ +static PHP_GINIT_FUNCTION(mysql) +{ + mysql_globals->num_persistent = 0; + mysql_globals->default_socket = NULL; + mysql_globals->default_host = NULL; + mysql_globals->default_user = NULL; + mysql_globals->default_password = NULL; + mysql_globals->connect_errno = 0; + mysql_globals->connect_error = NULL; + mysql_globals->connect_timeout = 0; + mysql_globals->trace_mode = 0; + mysql_globals->allow_local_infile = 1; + mysql_globals->result_allocated = 0; +} +/* }}} */ + +#ifdef MYSQL_USE_MYSQLND +#include "ext/mysqlnd/mysqlnd_reverse_api.h" +static MYSQLND * mysql_convert_zv_to_mysqlnd(zval * zv TSRMLS_DC) +{ + php_mysql_conn *mysql; + + if (Z_TYPE_P(zv) != IS_RESOURCE) { + /* Might be nicer to check resource type, too, but ext/mysql is the only one using resources so emitting an error is not to bad, while usually this hook should be silent */ + return NULL; + } + + mysql = (php_mysql_conn *)zend_fetch_resource(&zv TSRMLS_CC, -1, "MySQL-Link", NULL, 2, le_link, le_plink); + + if (!mysql) { + return NULL; + } + + return mysql->conn; +} + +static MYSQLND_REVERSE_API mysql_reverse_api = { + &mysql_module_entry, + mysql_convert_zv_to_mysqlnd +}; +#endif + +/* {{{ PHP_MINIT_FUNCTION + */ +ZEND_MODULE_STARTUP_D(mysql) +{ + REGISTER_INI_ENTRIES(); + le_result = zend_register_list_destructors_ex(_free_mysql_result, NULL, "mysql result", module_number); + le_link = zend_register_list_destructors_ex(_close_mysql_link, NULL, "mysql link", module_number); + le_plink = zend_register_list_destructors_ex(NULL, _close_mysql_plink, "mysql link persistent", module_number); + Z_TYPE(mysql_module_entry) = type; + + REGISTER_LONG_CONSTANT("MYSQL_ASSOC", MYSQL_ASSOC, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQL_NUM", MYSQL_NUM, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQL_BOTH", MYSQL_BOTH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQL_CLIENT_COMPRESS", CLIENT_COMPRESS, CONST_CS | CONST_PERSISTENT); +#if MYSQL_VERSION_ID >= 40000 + REGISTER_LONG_CONSTANT("MYSQL_CLIENT_SSL", CLIENT_SSL, CONST_CS | CONST_PERSISTENT); +#endif + REGISTER_LONG_CONSTANT("MYSQL_CLIENT_INTERACTIVE", CLIENT_INTERACTIVE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQL_CLIENT_IGNORE_SPACE", CLIENT_IGNORE_SPACE, CONST_CS | CONST_PERSISTENT); + +#ifndef MYSQL_USE_MYSQLND +#if MYSQL_VERSION_ID >= 40000 + if (mysql_server_init(0, NULL, NULL)) { + return FAILURE; + } +#endif +#endif + +#ifdef MYSQL_USE_MYSQLND + mysqlnd_reverse_api_register_api(&mysql_reverse_api TSRMLS_CC); +#endif + + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MSHUTDOWN_FUNCTION + */ +PHP_MSHUTDOWN_FUNCTION(mysql) +{ +#ifndef MYSQL_USE_MYSQLND +#if MYSQL_VERSION_ID >= 40000 +#ifdef PHP_WIN32 + unsigned long client_ver = mysql_get_client_version(); + /* + Can't call mysql_server_end() multiple times prior to 5.0.46 on Windows. + PHP bug#41350 MySQL bug#25621 + */ + if ((client_ver >= 50046 && client_ver < 50100) || client_ver > 50122) { + mysql_server_end(); + } +#else + mysql_server_end(); +#endif +#endif +#endif + + UNREGISTER_INI_ENTRIES(); + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_RINIT_FUNCTION + */ +PHP_RINIT_FUNCTION(mysql) +{ +#if !defined(MYSQL_USE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000 + if (mysql_thread_init()) { + return FAILURE; + } +#endif + MySG(default_link)=-1; + MySG(num_links) = MySG(num_persistent); + /* Reset connect error/errno on every request */ + MySG(connect_error) = NULL; + MySG(connect_errno) =0; + MySG(result_allocated) = 0; + + return SUCCESS; +} +/* }}} */ + + +#if defined(A0) && defined(MYSQL_USE_MYSQLND) +static int php_mysql_persistent_helper(zend_rsrc_list_entry *le TSRMLS_DC) +{ + if (le->type == le_plink) { + mysqlnd_end_psession(((php_mysql_conn *) le->ptr)->conn); + } + return ZEND_HASH_APPLY_KEEP; +} /* }}} */ +#endif + + +/* {{{ PHP_RSHUTDOWN_FUNCTION + */ +PHP_RSHUTDOWN_FUNCTION(mysql) +{ +#if !defined(MYSQL_USE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000 + mysql_thread_end(); +#endif + + if (MySG(trace_mode)) { + if (MySG(result_allocated)){ + php_error_docref("function.mysql-free-result" TSRMLS_CC, E_WARNING, "%lu result set(s) not freed. Use mysql_free_result to free result sets which were requested using mysql_query()", MySG(result_allocated)); + } + } + + if (MySG(connect_error)!=NULL) { + efree(MySG(connect_error)); + } + +#if defined(A0) && defined(MYSQL_USE_MYSQLND) + zend_hash_apply(&EG(persistent_list), (apply_func_t) php_mysql_persistent_helper TSRMLS_CC); +#endif + + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MINFO_FUNCTION + */ +PHP_MINFO_FUNCTION(mysql) +{ + char buf[32]; + + php_info_print_table_start(); + php_info_print_table_header(2, "MySQL Support", "enabled"); + snprintf(buf, sizeof(buf), "%ld", MySG(num_persistent)); + php_info_print_table_row(2, "Active Persistent Links", buf); + snprintf(buf, sizeof(buf), "%ld", MySG(num_links)); + php_info_print_table_row(2, "Active Links", buf); + php_info_print_table_row(2, "Client API version", mysql_get_client_info()); +#if !defined (PHP_WIN32) && !defined (NETWARE) && !defined(MYSQL_USE_MYSQLND) + php_info_print_table_row(2, "MYSQL_MODULE_TYPE", PHP_MYSQL_TYPE); + php_info_print_table_row(2, "MYSQL_SOCKET", MYSQL_UNIX_ADDR); + php_info_print_table_row(2, "MYSQL_INCLUDE", PHP_MYSQL_INCLUDE); + php_info_print_table_row(2, "MYSQL_LIBS", PHP_MYSQL_LIBS); +#endif + + php_info_print_table_end(); + + DISPLAY_INI_ENTRIES(); + +} +/* }}} */ + +/* {{{ php_mysql_do_connect + */ +#define MYSQL_DO_CONNECT_CLEANUP() \ + if (free_host) { \ + efree(host); \ + } + +#define MYSQL_DO_CONNECT_RETURN_FALSE() \ + MYSQL_DO_CONNECT_CLEANUP(); \ + RETURN_FALSE; + +#ifdef MYSQL_USE_MYSQLND +#define MYSQL_PORT 0 +#endif + +static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) +{ + char *user=NULL, *passwd=NULL, *host_and_port=NULL, *socket=NULL, *tmp=NULL, *host=NULL; + int user_len, passwd_len, host_len; + char *hashed_details=NULL; + int hashed_details_length, port = MYSQL_PORT; + long client_flags = 0; + php_mysql_conn *mysql=NULL; +#if MYSQL_VERSION_ID <= 32230 + void (*handler) (int); +#endif + zend_bool free_host=0, new_link=0; + long connect_timeout; + +#if !defined(MYSQL_USE_MYSQLND) + if ((MYSQL_VERSION_ID / 100) != (mysql_get_client_version() / 100)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "Headers and client library minor version mismatch. Headers:%d Library:%ld", + MYSQL_VERSION_ID, mysql_get_client_version()); + } +#endif + + connect_timeout = MySG(connect_timeout); + + socket = MySG(default_socket); + + if (MySG(default_port) < 0) { +#if !defined(PHP_WIN32) && !defined(NETWARE) + struct servent *serv_ptr; + char *env; + + MySG(default_port) = MYSQL_PORT; + if ((serv_ptr = getservbyname("mysql", "tcp"))) { + MySG(default_port) = (uint) ntohs((ushort) serv_ptr->s_port); + } + if ((env = getenv("MYSQL_TCP_PORT"))) { + MySG(default_port) = (uint) atoi(env); + } +#else + MySG(default_port) = MYSQL_PORT; +#endif + } + + if (PG(sql_safe_mode)) { + if (ZEND_NUM_ARGS()>0) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "SQL safe mode in effect - ignoring host/user/password information"); + } + host_and_port=passwd=NULL; + user=php_get_current_user(TSRMLS_C); + hashed_details_length = spprintf(&hashed_details, 0, "mysql__%s_", user); + client_flags = CLIENT_INTERACTIVE; + } else { + /* mysql_pconnect does not support new_link parameter */ + if (persistent) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!l", &host_and_port, &host_len, + &user, &user_len, &passwd, &passwd_len, + &client_flags)==FAILURE) { + return; + } + } else { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!bl", &host_and_port, &host_len, + &user, &user_len, &passwd, &passwd_len, + &new_link, &client_flags)==FAILURE) { + return; + } + } + + if (!host_and_port) { + host_and_port = MySG(default_host); + } + if (!user) { + user = MySG(default_user); + } + if (!passwd) { + passwd = MySG(default_password); + passwd_len = passwd? strlen(passwd):0; + } + + /* disable local infile option for open_basedir */ +#if PHP_API_VERSION < 20100412 + if (((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode)) && (client_flags & CLIENT_LOCAL_FILES)) { +#else + if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') && (client_flags & CLIENT_LOCAL_FILES)) { +#endif + client_flags ^= CLIENT_LOCAL_FILES; + } + +#ifdef CLIENT_MULTI_RESULTS + client_flags |= CLIENT_MULTI_RESULTS; /* compatibility with 5.2, see bug#50416 */ +#endif +#ifdef CLIENT_MULTI_STATEMENTS + client_flags &= ~CLIENT_MULTI_STATEMENTS; /* don't allow multi_queries via connect parameter */ +#endif + hashed_details_length = spprintf(&hashed_details, 0, "mysql_%s_%s_%s_%ld", SAFE_STRING(host_and_port), SAFE_STRING(user), SAFE_STRING(passwd), client_flags); + } + + /* We cannot use mysql_port anymore in windows, need to use + * mysql_real_connect() to set the port. + */ + if (host_and_port && (tmp=strchr(host_and_port, ':'))) { + host = estrndup(host_and_port, tmp-host_and_port); + free_host = 1; + tmp++; + if (tmp[0] != '/') { + port = atoi(tmp); + if ((tmp=strchr(tmp, ':'))) { + tmp++; + socket=tmp; + } + } else { + socket = tmp; + } + } else { + host = host_and_port; + port = MySG(default_port); + } + +#if MYSQL_VERSION_ID < 32200 + mysql_port = port; +#endif + + if (!MySG(allow_persistent)) { + persistent=0; + } + if (persistent) { + zend_rsrc_list_entry *le; + + /* try to find if we already have this link in our persistent list */ + if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) { /* we don't */ + zend_rsrc_list_entry new_le; + + if (MySG(max_links) != -1 && MySG(num_links) >= MySG(max_links)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MySG(num_links)); + efree(hashed_details); + MYSQL_DO_CONNECT_RETURN_FALSE(); + } + if (MySG(max_persistent) != -1 && MySG(num_persistent) >= MySG(max_persistent)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open persistent links (%ld)", MySG(num_persistent)); + efree(hashed_details); + MYSQL_DO_CONNECT_RETURN_FALSE(); + } + /* create the link */ + mysql = (php_mysql_conn *) malloc(sizeof(php_mysql_conn)); + if (!mysql) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Out of memory while allocating memory for a persistent link"); + } + mysql->active_result_id = 0; +#ifdef CLIENT_MULTI_STATEMENTS + mysql->multi_query = client_flags & CLIENT_MULTI_STATEMENTS? 1:0; +#else + mysql->multi_query = 0; +#endif + +#ifndef MYSQL_USE_MYSQLND + mysql->conn = mysql_init(NULL); +#else + mysql->conn = mysql_init(persistent); +#endif + + if (connect_timeout != -1) { + mysql_options(mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout); + } +#ifndef MYSQL_USE_MYSQLND + if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL) +#else + if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags TSRMLS_CC) == NULL) +#endif + { + /* Populate connect error globals so that the error functions can read them */ + if (MySG(connect_error) != NULL) { + efree(MySG(connect_error)); + } + MySG(connect_error) = estrdup(mysql_error(mysql->conn)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", MySG(connect_error)); +#if defined(HAVE_MYSQL_ERRNO) + MySG(connect_errno) = mysql_errno(mysql->conn); +#endif + free(mysql); + efree(hashed_details); + MYSQL_DO_CONNECT_RETURN_FALSE(); + } + mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile)); + + /* hash it up */ + Z_TYPE(new_le) = le_plink; + new_le.ptr = mysql; + if (zend_hash_update(&EG(persistent_list), hashed_details, hashed_details_length+1, (void *) &new_le, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) { + free(mysql); + efree(hashed_details); + MYSQL_DO_CONNECT_RETURN_FALSE(); + } + MySG(num_persistent)++; + MySG(num_links)++; + } else { /* The link is in our list of persistent connections */ + if (Z_TYPE_P(le) != le_plink) { + MYSQL_DO_CONNECT_RETURN_FALSE(); + } + mysql = (php_mysql_conn *) le->ptr; + mysql->active_result_id = 0; +#ifdef CLIENT_MULTI_STATEMENTS + mysql->multi_query = client_flags & CLIENT_MULTI_STATEMENTS? 1:0; +#else + mysql->multi_query = 0; +#endif + /* ensure that the link did not die */ +#if defined(A0) && MYSQL_USE_MYSQLND + mysqlnd_end_psession(mysql->conn); +#endif + if (mysql_ping(mysql->conn)) { + if (mysql_errno(mysql->conn) == 2006) { +#ifndef MYSQL_USE_MYSQLND + if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL) +#else + if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags TSRMLS_CC) == NULL) +#endif + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Link to server lost, unable to reconnect"); + zend_hash_del(&EG(persistent_list), hashed_details, hashed_details_length+1); + efree(hashed_details); + MYSQL_DO_CONNECT_RETURN_FALSE(); + } + mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile)); + } + } else { +#ifdef MYSQL_USE_MYSQLND + mysqlnd_restart_psession(mysql->conn); +#endif + } + } + ZEND_REGISTER_RESOURCE(return_value, mysql, le_plink); + } else { /* non persistent */ + zend_rsrc_list_entry *index_ptr, new_index_ptr; + + /* first we check the hash for the hashed_details key. if it exists, + * it should point us to the right offset where the actual mysql link sits. + * if it doesn't, open a new mysql link, add it to the resource list, + * and add a pointer to it with hashed_details as the key. + */ + if (!new_link && zend_hash_find(&EG(regular_list), hashed_details, hashed_details_length+1,(void **) &index_ptr)==SUCCESS) { + int type; + long link; + void *ptr; + + if (Z_TYPE_P(index_ptr) != le_index_ptr) { + MYSQL_DO_CONNECT_RETURN_FALSE(); + } + link = (long) index_ptr->ptr; + ptr = zend_list_find(link,&type); /* check if the link is still there */ + if (ptr && (type==le_link || type==le_plink)) { + zend_list_addref(link); + Z_LVAL_P(return_value) = link; + php_mysql_set_default_link(link TSRMLS_CC); + Z_TYPE_P(return_value) = IS_RESOURCE; + efree(hashed_details); + MYSQL_DO_CONNECT_CLEANUP(); + return; + } else { + zend_hash_del(&EG(regular_list), hashed_details, hashed_details_length+1); + } + } + if (MySG(max_links) != -1 && MySG(num_links) >= MySG(max_links)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MySG(num_links)); + efree(hashed_details); + MYSQL_DO_CONNECT_RETURN_FALSE(); + } + + mysql = (php_mysql_conn *) emalloc(sizeof(php_mysql_conn)); + mysql->active_result_id = 0; +#ifdef CLIENT_MULTI_STATEMENTS + mysql->multi_query = 1; +#endif + +#ifndef MYSQL_USE_MYSQLND + mysql->conn = mysql_init(NULL); +#else + mysql->conn = mysql_init(persistent); +#endif + if (!mysql->conn) { + MySG(connect_error) = estrdup("OOM"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "OOM"); + efree(hashed_details); + efree(mysql); + MYSQL_DO_CONNECT_RETURN_FALSE(); + } + + if (connect_timeout != -1) { + mysql_options(mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout); + } + +#ifndef MYSQL_USE_MYSQLND + if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL) +#else + if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags TSRMLS_CC) == NULL) +#endif + { + /* Populate connect error globals so that the error functions can read them */ + if (MySG(connect_error) != NULL) { + efree(MySG(connect_error)); + } + MySG(connect_error) = estrdup(mysql_error(mysql->conn)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", MySG(connect_error)); +#if defined(HAVE_MYSQL_ERRNO) + MySG(connect_errno) = mysql_errno(mysql->conn); +#endif + /* free mysql structure */ +#ifdef MYSQL_USE_MYSQLND + mysqlnd_close(mysql->conn, MYSQLND_CLOSE_DISCONNECTED); +#endif + efree(hashed_details); + efree(mysql); + MYSQL_DO_CONNECT_RETURN_FALSE(); + } + mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile)); + + /* add it to the list */ + ZEND_REGISTER_RESOURCE(return_value, mysql, le_link); + + /* add it to the hash */ + new_index_ptr.ptr = (void *) Z_LVAL_P(return_value); + Z_TYPE(new_index_ptr) = le_index_ptr; + if (zend_hash_update(&EG(regular_list), hashed_details, hashed_details_length+1,(void *) &new_index_ptr, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) { + efree(hashed_details); + MYSQL_DO_CONNECT_RETURN_FALSE(); + } + MySG(num_links)++; + } + + efree(hashed_details); + php_mysql_set_default_link(Z_LVAL_P(return_value) TSRMLS_CC); + MYSQL_DO_CONNECT_CLEANUP(); +} +/* }}} */ + +/* {{{ php_mysql_get_default_link + */ +static int php_mysql_get_default_link(INTERNAL_FUNCTION_PARAMETERS) +{ + if (MySG(default_link)==-1) { /* no link opened yet, implicitly open one */ + ht = 0; + php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); + } + return MySG(default_link); +} +/* }}} */ + +/* {{{ proto resource mysql_connect([string hostname[:port][:/path/to/socket] [, string username [, string password [, bool new [, int flags]]]]]) + Opens a connection to a MySQL Server */ +PHP_FUNCTION(mysql_connect) +{ + php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ + +/* {{{ proto resource mysql_pconnect([string hostname[:port][:/path/to/socket] [, string username [, string password [, int flags]]]]) + Opens a persistent connection to a MySQL Server */ +PHP_FUNCTION(mysql_pconnect) +{ + php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +/* {{{ proto bool mysql_close([int link_identifier]) + Close a MySQL connection */ +PHP_FUNCTION(mysql_close) +{ + int resource_id; + zval *mysql_link=NULL; + php_mysql_conn *mysql; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) { + return; + } + + if (mysql_link) { + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, -1, "MySQL-Link", le_link, le_plink); + } else { + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, NULL, MySG(default_link), "MySQL-Link", le_link, le_plink); + } + + resource_id = mysql_link ? Z_RESVAL_P(mysql_link) : MySG(default_link); + PHPMY_UNBUFFERED_QUERY_CHECK(); +#ifdef MYSQL_USE_MYSQLND + { + int tmp; + if ((mysql = zend_list_find(resource_id, &tmp)) && tmp == le_plink) { + mysqlnd_end_psession(mysql->conn); + } + } +#endif + zend_list_delete(resource_id); + + if (!mysql_link + || (mysql_link && Z_RESVAL_P(mysql_link)==MySG(default_link))) { + MySG(default_link) = -1; + if (mysql_link) { + /* on an explicit close of the default connection it had a refcount of 2 so we need one more call */ + zend_list_delete(resource_id); + } + } + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto bool mysql_select_db(string database_name [, int link_identifier]) + Selects a MySQL database */ +PHP_FUNCTION(mysql_select_db) +{ + char *db; + int db_len; + zval *mysql_link = NULL; + int id = -1; + php_mysql_conn *mysql; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) { + return; + } + + if (!mysql_link) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + if (php_mysql_select_db(mysql, db TSRMLS_CC)) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ + +#ifdef HAVE_GETINFO_FUNCS + +/* {{{ proto string mysql_get_client_info(void) + Returns a string that represents the client library version */ +PHP_FUNCTION(mysql_get_client_info) +{ + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + RETURN_STRING((char *)mysql_get_client_info(),1); +} +/* }}} */ + +/* {{{ proto string mysql_get_host_info([int link_identifier]) + Returns a string describing the type of connection in use, including the server host name */ +PHP_FUNCTION(mysql_get_host_info) +{ + zval *mysql_link = NULL; + int id = -1; + php_mysql_conn *mysql; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) { + return; + } + + if (!mysql_link) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + RETURN_STRING((char *)mysql_get_host_info(mysql->conn),1); +} +/* }}} */ + +/* {{{ proto int mysql_get_proto_info([int link_identifier]) + Returns the protocol version used by current connection */ +PHP_FUNCTION(mysql_get_proto_info) +{ + zval *mysql_link = NULL; + int id = -1; + php_mysql_conn *mysql; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) { + return; + } + + if (!mysql_link) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + RETURN_LONG(mysql_get_proto_info(mysql->conn)); +} +/* }}} */ + +/* {{{ proto string mysql_get_server_info([int link_identifier]) + Returns a string that represents the server version number */ +PHP_FUNCTION(mysql_get_server_info) +{ + zval *mysql_link = NULL; + int id = -1; + php_mysql_conn *mysql; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) { + return; + } + + if (!mysql_link) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + RETURN_STRING((char *)mysql_get_server_info(mysql->conn),1); +} +/* }}} */ + +/* {{{ proto string mysql_info([int link_identifier]) + Returns a string containing information about the most recent query */ +PHP_FUNCTION(mysql_info) +{ + zval *mysql_link = NULL; + int id = -1; + char *str; + php_mysql_conn *mysql; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) { + return; + } + + if (ZEND_NUM_ARGS() == 0) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + if ((str = (char *)mysql_info(mysql->conn))) { + RETURN_STRING(str,1); + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto int mysql_thread_id([int link_identifier]) + Returns the thread id of current connection */ +PHP_FUNCTION(mysql_thread_id) +{ + zval *mysql_link = NULL; + int id = -1; + php_mysql_conn *mysql; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) { + return; + } + + if (ZEND_NUM_ARGS() == 0) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + RETURN_LONG((long) mysql_thread_id(mysql->conn)); +} +/* }}} */ + +/* {{{ proto string mysql_stat([int link_identifier]) + Returns a string containing status information */ +PHP_FUNCTION(mysql_stat) +{ + zval *mysql_link = NULL; + int id = -1; + php_mysql_conn *mysql; + char *stat; +#ifdef MYSQL_USE_MYSQLND + uint stat_len; +#endif + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) { + return; + } + + if (ZEND_NUM_ARGS() == 0) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + PHPMY_UNBUFFERED_QUERY_CHECK(); +#ifndef MYSQL_USE_MYSQLND + if ((stat = (char *)mysql_stat(mysql->conn))) { + RETURN_STRING(stat, 1); +#else + if (mysqlnd_stat(mysql->conn, &stat, &stat_len) == PASS) { + RETURN_STRINGL(stat, stat_len, 0); +#endif + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto string mysql_client_encoding([int link_identifier]) + Returns the default character set for the current connection */ +PHP_FUNCTION(mysql_client_encoding) +{ + zval *mysql_link = NULL; + int id = -1; + php_mysql_conn *mysql; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) { + return; + } + + if (ZEND_NUM_ARGS() == 0) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + RETURN_STRING((char *)mysql_character_set_name(mysql->conn), 1); +} +/* }}} */ +#endif + +#ifdef MYSQL_HAS_SET_CHARSET +/* {{{ proto bool mysql_set_charset(string csname [, int link_identifier]) + sets client character set */ +PHP_FUNCTION(mysql_set_charset) +{ + zval *mysql_link = NULL; + char *csname; + int id = -1, csname_len; + php_mysql_conn *mysql; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &csname, &csname_len, &mysql_link) == FAILURE) { + return; + } + + if (ZEND_NUM_ARGS() == 1) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + if (!mysql_set_character_set(mysql->conn, csname)) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ +#endif + +#ifndef NETWARE /* The below two functions not supported on NetWare */ +#if MYSQL_VERSION_ID < 40000 +/* {{{ proto bool mysql_create_db(string database_name [, int link_identifier]) + Create a MySQL database */ +PHP_FUNCTION(mysql_create_db) +{ + char *db; + int db_len; + zval *mysql_link = NULL; + int id = -1; + php_mysql_conn *mysql; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) { + return; + } + + if (!mysql_link) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + PHPMY_UNBUFFERED_QUERY_CHECK(); + + if (mysql_create_db(mysql->conn, db)==0) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto bool mysql_drop_db(string database_name [, int link_identifier]) + Drops (delete) a MySQL database */ +PHP_FUNCTION(mysql_drop_db) +{ + char *db; + int db_len; + zval *mysql_link = NULL; + int id = -1; + php_mysql_conn *mysql; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) { + return; + } + + if (!mysql_link) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + if (mysql_drop_db(mysql->conn, db)==0) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ +#endif +#endif /* NETWARE */ + +/* {{{ php_mysql_do_query_general + */ +static void php_mysql_do_query_general(char *query, int query_len, zval *mysql_link, int link_id, char *db, int use_store, zval *return_value TSRMLS_DC) +{ + php_mysql_conn *mysql; + MYSQL_RES *mysql_result; + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, link_id, "MySQL-Link", le_link, le_plink); + + if (db) { + if (!php_mysql_select_db(mysql, db TSRMLS_CC)) { + RETURN_FALSE; + } + } + + PHPMY_UNBUFFERED_QUERY_CHECK(); + + MYSQL_DISABLE_MQ; + +#ifndef MYSQL_USE_MYSQLND + /* check explain */ + if (MySG(trace_mode)) { + if (!strncasecmp("select", query, 6)){ + MYSQL_ROW row; + + char *newquery; + int newql = spprintf (&newquery, 0, "EXPLAIN %s", query); + mysql_real_query(mysql->conn, newquery, newql); + efree (newquery); + if (mysql_errno(mysql->conn)) { + php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn)); + RETURN_FALSE; + } + else { + mysql_result = mysql_use_result(mysql->conn); + while ((row = mysql_fetch_row(mysql_result))) { + if (!strcmp("ALL", row[1])) { + php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "Your query requires a full tablescan (table %s, %s rows affected). Use EXPLAIN to optimize your query.", row[0], row[6]); + } else if (!strcmp("INDEX", row[1])) { + php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "Your query requires a full indexscan (table %s, %s rows affected). Use EXPLAIN to optimize your query.", row[0], row[6]); + } + } + mysql_free_result(mysql_result); + } + } + } /* end explain */ +#endif + + /* mysql_query is binary unsafe, use mysql_real_query */ +#if MYSQL_VERSION_ID > 32199 + if (mysql_real_query(mysql->conn, query, query_len)!=0) { + /* check possible error */ + if (MySG(trace_mode)){ + if (mysql_errno(mysql->conn)){ + php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn)); + } + } + RETURN_FALSE; + } +#else + if (mysql_query(mysql->conn, query)!=0) { + /* check possible error */ + if (MySG(trace_mode)){ + if (mysql_errno(mysql->conn)){ + php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn)); + } + } + RETURN_FALSE; + } +#endif + if(use_store == MYSQL_USE_RESULT) { + mysql_result=mysql_use_result(mysql->conn); + } else { + mysql_result=mysql_store_result(mysql->conn); + } + if (!mysql_result) { + if (PHP_MYSQL_VALID_RESULT(mysql->conn)) { /* query should have returned rows */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save result set"); + RETURN_FALSE; + } else { + RETURN_TRUE; + } + } + MySG(result_allocated)++; + ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result); + if (use_store == MYSQL_USE_RESULT) { + mysql->active_result_id = Z_LVAL_P(return_value); + } +} +/* }}} */ + +/* {{{ php_mysql_do_query + */ +static void php_mysql_do_query(INTERNAL_FUNCTION_PARAMETERS, int use_store) +{ + char *query; + int query_len; + zval *mysql_link = NULL; + int id = -1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &query, &query_len, &mysql_link) == FAILURE) { + return; + } + + if (!mysql_link) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + + php_mysql_do_query_general(query, query_len, mysql_link, id, NULL, use_store, return_value TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto resource mysql_query(string query [, int link_identifier]) + Sends an SQL query to MySQL */ +PHP_FUNCTION(mysql_query) +{ + php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_STORE_RESULT); +} +/* }}} */ + + +/* {{{ proto resource mysql_unbuffered_query(string query [, int link_identifier]) + Sends an SQL query to MySQL, without fetching and buffering the result rows */ +PHP_FUNCTION(mysql_unbuffered_query) +{ + php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_USE_RESULT); +} +/* }}} */ + + +/* {{{ proto resource mysql_db_query(string database_name, string query [, int link_identifier]) + Sends an SQL query to MySQL */ +PHP_FUNCTION(mysql_db_query) +{ + char *db, *query; + int db_len, query_len; + zval *mysql_link = NULL; + int id = -1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &db, &db_len, &query, &query_len, &mysql_link) == FAILURE) { + return; + } + + if (!mysql_link) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + + php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "This function is deprecated; use mysql_query() instead"); + + php_mysql_do_query_general(query, query_len, mysql_link, id, db, MYSQL_STORE_RESULT, return_value TSRMLS_CC); +} +/* }}} */ + + +/* {{{ proto resource mysql_list_dbs([int link_identifier]) + List databases available on a MySQL server */ +PHP_FUNCTION(mysql_list_dbs) +{ + zval *mysql_link = NULL; + int id = -1; + php_mysql_conn *mysql; + MYSQL_RES *mysql_result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) { + return; + } + + if (!mysql_link) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "This function is deprecated; use mysql_query() with SHOW DATABASES instead"); + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + PHPMY_UNBUFFERED_QUERY_CHECK(); + + + if ((mysql_result=mysql_list_dbs(mysql->conn, NULL))==NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result"); + RETURN_FALSE; + } + MySG(result_allocated)++; + ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result); +} +/* }}} */ + + +/* {{{ proto resource mysql_list_tables(string database_name [, int link_identifier]) + List tables in a MySQL database */ +PHP_FUNCTION(mysql_list_tables) +{ + char *db; + int db_len; + zval *mysql_link = NULL; + int id = -1; + php_mysql_conn *mysql; + MYSQL_RES *mysql_result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) { + return; + } + + if (!mysql_link) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + if (!php_mysql_select_db(mysql, db TSRMLS_CC)) { + RETURN_FALSE; + } + + PHPMY_UNBUFFERED_QUERY_CHECK(); + + if ((mysql_result=mysql_list_tables(mysql->conn, NULL))==NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result"); + RETURN_FALSE; + } + MySG(result_allocated)++; + ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result); +} +/* }}} */ + + +/* {{{ proto resource mysql_list_fields(string database_name, string table_name [, int link_identifier]) + List MySQL result fields */ +PHP_FUNCTION(mysql_list_fields) +{ + char *db, *table; + int db_len, table_len; + zval *mysql_link = NULL; + int id = -1; + php_mysql_conn *mysql; + MYSQL_RES *mysql_result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &db, &db_len, &table, &table_len, &mysql_link) == FAILURE) { + return; + } + + if (!mysql_link) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + if (!php_mysql_select_db(mysql, db TSRMLS_CC)) { + RETURN_FALSE; + } + + PHPMY_UNBUFFERED_QUERY_CHECK(); + + if ((mysql_result=mysql_list_fields(mysql->conn, table, NULL))==NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result"); + RETURN_FALSE; + } + MySG(result_allocated)++; + ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result); +} +/* }}} */ + +/* {{{ proto resource mysql_list_processes([int link_identifier]) + Returns a result set describing the current server threads */ +PHP_FUNCTION(mysql_list_processes) +{ + zval *mysql_link = NULL; + int id = -1; + php_mysql_conn *mysql; + MYSQL_RES *mysql_result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) { + return; + } + + if (ZEND_NUM_ARGS() == 0) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + PHPMY_UNBUFFERED_QUERY_CHECK(); + + mysql_result = mysql_list_processes(mysql->conn); + if (mysql_result == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result"); + RETURN_FALSE; + } + + MySG(result_allocated)++; + ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result); +} +/* }}} */ + + +/* {{{ proto string mysql_error([int link_identifier]) + Returns the text of the error message from previous MySQL operation */ +PHP_FUNCTION(mysql_error) +{ + zval *mysql_link = NULL; + int id = -1; + php_mysql_conn *mysql; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) { + return; + } + + if (!mysql_link) { + id = MySG(default_link); + if (id==-1) { + if (MySG(connect_error)!=NULL){ + RETURN_STRING(MySG(connect_error),1); + } else { + RETURN_FALSE; + } + } + } + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + RETURN_STRING((char *)mysql_error(mysql->conn), 1); +} +/* }}} */ + + +/* {{{ proto int mysql_errno([int link_identifier]) + Returns the number of the error message from previous MySQL operation */ +#ifdef HAVE_MYSQL_ERRNO +PHP_FUNCTION(mysql_errno) +{ + zval *mysql_link = NULL; + int id = -1; + php_mysql_conn *mysql; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) { + return; + } + + if (!mysql_link) { + id = MySG(default_link); + if (id==-1) { + if (MySG(connect_errno)!=0){ + RETURN_LONG(MySG(connect_errno)); + } else { + RETURN_FALSE; + } + } + } + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + RETURN_LONG(mysql_errno(mysql->conn)); +} +#endif +/* }}} */ + + +/* {{{ proto int mysql_affected_rows([int link_identifier]) + Gets number of affected rows in previous MySQL operation */ +PHP_FUNCTION(mysql_affected_rows) +{ + zval *mysql_link = NULL; + int id = -1; + php_mysql_conn *mysql; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) { + return; + } + + if (!mysql_link) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + /* conversion from int64 to long happing here */ + Z_LVAL_P(return_value) = (long) mysql_affected_rows(mysql->conn); + Z_TYPE_P(return_value) = IS_LONG; +} +/* }}} */ + + +/* {{{ proto string mysql_escape_string(string to_be_escaped) + Escape string for mysql query */ +PHP_FUNCTION(mysql_escape_string) +{ + char *str; + int str_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) { + return; + } + + /* assume worst case situation, which is 2x of the original string. + * we don't realloc() down to the real size since it'd most probably not + * be worth it + */ + + Z_STRVAL_P(return_value) = (char *) safe_emalloc(str_len, 2, 1); + Z_STRLEN_P(return_value) = mysql_escape_string(Z_STRVAL_P(return_value), str, str_len); + Z_TYPE_P(return_value) = IS_STRING; + + php_error_docref("function.mysql-real-escape-string" TSRMLS_CC, E_DEPRECATED, "This function is deprecated; use mysql_real_escape_string() instead."); +} +/* }}} */ + +/* {{{ proto string mysql_real_escape_string(string to_be_escaped [, int link_identifier]) + Escape special characters in a string for use in a SQL statement, taking into account the current charset of the connection */ +PHP_FUNCTION(mysql_real_escape_string) +{ + zval *mysql_link = NULL; + char *str; + char *new_str; + int id = -1, str_len, new_str_len; + php_mysql_conn *mysql; + + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &str, &str_len, &mysql_link) == FAILURE) { + return; + } + + if (ZEND_NUM_ARGS() == 1) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + new_str = safe_emalloc(str_len, 2, 1); + new_str_len = mysql_real_escape_string(mysql->conn, new_str, str, str_len); + new_str = erealloc(new_str, new_str_len + 1); + + RETURN_STRINGL(new_str, new_str_len, 0); +} +/* }}} */ + +/* {{{ proto int mysql_insert_id([int link_identifier]) + Gets the ID generated from the previous INSERT operation */ +PHP_FUNCTION(mysql_insert_id) +{ + zval *mysql_link = NULL; + int id = -1; + php_mysql_conn *mysql; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) { + return; + } + + if (!mysql_link) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + /* conversion from int64 to long happing here */ + Z_LVAL_P(return_value) = (long) mysql_insert_id(mysql->conn); + Z_TYPE_P(return_value) = IS_LONG; +} +/* }}} */ + + +/* {{{ proto mixed mysql_result(resource result, int row [, mixed field]) + Gets result data */ +PHP_FUNCTION(mysql_result) +{ + zval *result, *field=NULL; + long row; + MYSQL_RES *mysql_result; +#ifndef MYSQL_USE_MYSQLND + MYSQL_ROW sql_row; + mysql_row_length_type *sql_row_lengths; +#endif + int field_offset=0; + +/* +johannes TODO: +Do 2 zend_parse_paramters calls instead of type "z" and switch below +Q: String or long first? +*/ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &result, &row, &field) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result); + + if (row<0 || row>=(int)mysql_num_rows(mysql_result)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to jump to row %ld on MySQL result index %ld", row, Z_LVAL_P(result)); + RETURN_FALSE; + } + mysql_data_seek(mysql_result, row); + + if (field) { + switch(Z_TYPE_P(field)) { + case IS_STRING: { + int i=0; + const MYSQL_FIELD *tmp_field; + char *table_name, *field_name, *tmp; + + if ((tmp=strchr(Z_STRVAL_P(field), '.'))) { + table_name = estrndup(Z_STRVAL_P(field), tmp-Z_STRVAL_P(field)); + field_name = estrdup(tmp+1); + } else { + table_name = NULL; + field_name = estrndup(Z_STRVAL_P(field),Z_STRLEN_P(field)); + } + mysql_field_seek(mysql_result, 0); + while ((tmp_field=mysql_fetch_field(mysql_result))) { + if ((!table_name || !strcasecmp(tmp_field->table, table_name)) && !strcasecmp(tmp_field->name, field_name)) { + field_offset = i; + break; + } + i++; + } + if (!tmp_field) { /* no match found */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s%s%s not found in MySQL result index %ld", + (table_name?table_name:""), (table_name?".":""), field_name, Z_LVAL_P(result)); + efree(field_name); + if (table_name) { + efree(table_name); + } + RETURN_FALSE; + } + efree(field_name); + if (table_name) { + efree(table_name); + } + } + break; + default: + convert_to_long_ex(&field); + field_offset = Z_LVAL_P(field); + if (field_offset<0 || field_offset>=(int)mysql_num_fields(mysql_result)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad column offset specified"); + RETURN_FALSE; + } + break; + } + } + +#ifndef MYSQL_USE_MYSQLND + if ((sql_row=mysql_fetch_row(mysql_result))==NULL + || (sql_row_lengths=mysql_fetch_lengths(mysql_result))==NULL) { /* shouldn't happen? */ + RETURN_FALSE; + } + if (sql_row[field_offset]) { + Z_TYPE_P(return_value) = IS_STRING; + +#if PHP_API_VERSION < 20100412 + if (PG(magic_quotes_runtime)) { + Z_STRVAL_P(return_value) = php_addslashes(sql_row[field_offset], sql_row_lengths[field_offset],&Z_STRLEN_P(return_value), 0 TSRMLS_CC); + } else { +#endif + Z_STRLEN_P(return_value) = sql_row_lengths[field_offset]; + Z_STRVAL_P(return_value) = (char *) safe_estrndup(sql_row[field_offset], Z_STRLEN_P(return_value)); +#if PHP_API_VERSION < 20100412 + } +#endif + } else { + Z_TYPE_P(return_value) = IS_NULL; + } +#else + mysqlnd_result_fetch_field_data(mysql_result, field_offset, return_value); +#endif +} +/* }}} */ + + +/* {{{ proto int mysql_num_rows(resource result) + Gets number of rows in a result */ +PHP_FUNCTION(mysql_num_rows) +{ + zval *result; + MYSQL_RES *mysql_result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result); + + /* conversion from int64 to long happing here */ + Z_LVAL_P(return_value) = (long) mysql_num_rows(mysql_result); + Z_TYPE_P(return_value) = IS_LONG; +} +/* }}} */ + +/* {{{ proto int mysql_num_fields(resource result) + Gets number of fields in a result */ +PHP_FUNCTION(mysql_num_fields) +{ + zval *result; + MYSQL_RES *mysql_result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result); + + Z_LVAL_P(return_value) = mysql_num_fields(mysql_result); + Z_TYPE_P(return_value) = IS_LONG; +} +/* }}} */ + +/* {{{ php_mysql_fetch_hash + */ +static void php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, int expected_args, int into_object) +{ + MYSQL_RES *mysql_result; + zval *res, *ctor_params = NULL; + zend_class_entry *ce = NULL; +#ifndef MYSQL_USE_MYSQLND + int i; + MYSQL_FIELD *mysql_field; + MYSQL_ROW mysql_row; + mysql_row_length_type *mysql_row_lengths; +#endif + +#ifdef ZEND_ENGINE_2 + if (into_object) { + char *class_name = NULL; + int class_name_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|sz", &res, &class_name, &class_name_len, &ctor_params) == FAILURE) { + return; + } + + if (ZEND_NUM_ARGS() < 2) { + ce = zend_standard_class_def; + } else { + ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC); + } + if (!ce) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name); + return; + } + result_type = MYSQL_ASSOC; + } else +#endif + { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &res, &result_type) == FAILURE) { + return; + } + if (!result_type) { + /* result_type might have been set outside, so only overwrite when not set */ + result_type = MYSQL_BOTH; + } + } + + if (result_type & ~MYSQL_BOTH) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQL_NUM, MYSQL_ASSOC or MYSQL_BOTH"); + result_type = MYSQL_BOTH; + } + + ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &res, -1, "MySQL result", le_result); + +#ifndef MYSQL_USE_MYSQLND + if ((mysql_row = mysql_fetch_row(mysql_result)) == NULL || + (mysql_row_lengths = mysql_fetch_lengths(mysql_result)) == NULL) { + RETURN_FALSE; + } + + array_init(return_value); + + mysql_field_seek(mysql_result, 0); + for (mysql_field = mysql_fetch_field(mysql_result), i = 0; + mysql_field; + mysql_field = mysql_fetch_field(mysql_result), i++) + { + if (mysql_row[i]) { + zval *data; + + MAKE_STD_ZVAL(data); + +#if PHP_API_VERSION < 20100412 + if (PG(magic_quotes_runtime)) { + Z_TYPE_P(data) = IS_STRING; + Z_STRVAL_P(data) = php_addslashes(mysql_row[i], mysql_row_lengths[i], &Z_STRLEN_P(data), 0 TSRMLS_CC); + } else { +#endif + ZVAL_STRINGL(data, mysql_row[i], mysql_row_lengths[i], 1); +#if PHP_API_VERSION < 20100412 + } +#endif + + if (result_type & MYSQL_NUM) { + add_index_zval(return_value, i, data); + } + if (result_type & MYSQL_ASSOC) { + if (result_type & MYSQL_NUM) { + Z_ADDREF_P(data); + } + add_assoc_zval(return_value, mysql_field->name, data); + } + } else { + /* NULL value. */ + if (result_type & MYSQL_NUM) { + add_index_null(return_value, i); + } + + if (result_type & MYSQL_ASSOC) { + add_assoc_null(return_value, mysql_field->name); + } + } + } +#else + mysqlnd_fetch_into(mysql_result, ((result_type & MYSQL_NUM)? MYSQLND_FETCH_NUM:0) | ((result_type & MYSQL_ASSOC)? MYSQLND_FETCH_ASSOC:0), return_value, MYSQLND_MYSQL); +#endif + +#ifdef ZEND_ENGINE_2 + /* mysqlnd might return FALSE if no more rows */ + if (into_object && Z_TYPE_P(return_value) != IS_BOOL) { + zval dataset = *return_value; + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval *retval_ptr; + + object_and_properties_init(return_value, ce, NULL); + zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC); + + if (ce->constructor) { + fci.size = sizeof(fci); + fci.function_table = &ce->function_table; + fci.function_name = NULL; + fci.symbol_table = NULL; + fci.object_ptr = return_value; + fci.retval_ptr_ptr = &retval_ptr; + if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) { + if (Z_TYPE_P(ctor_params) == IS_ARRAY) { + HashTable *htl = Z_ARRVAL_P(ctor_params); + Bucket *p; + + fci.param_count = 0; + fci.params = safe_emalloc(sizeof(zval*), htl->nNumOfElements, 0); + p = htl->pListHead; + while (p != NULL) { + fci.params[fci.param_count++] = (zval**)p->pData; + p = p->pListNext; + } + } else { + /* Two problems why we throw exceptions here: PHP is typeless + * and hence passing one argument that's not an array could be + * by mistake and the other way round is possible, too. The + * single value is an array. Also we'd have to make that one + * argument passed by reference. + */ + zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Parameter ctor_params must be an array", 0 TSRMLS_CC); + return; + } + } else { + fci.param_count = 0; + fci.params = NULL; + } + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = ce->constructor; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(return_value); + fcc.object_ptr = return_value; + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) { + zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name); + } else { + if (retval_ptr) { + zval_ptr_dtor(&retval_ptr); + } + } + if (fci.params) { + efree(fci.params); + } + } else if (ctor_params) { + zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Class %s does not have a constructor hence you cannot use ctor_params", ce->name); + } + } +#endif + +} +/* }}} */ + +/* {{{ proto array mysql_fetch_row(resource result) + Gets a result row as an enumerated array */ +PHP_FUNCTION(mysql_fetch_row) +{ + php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_NUM, 1, 0); +} +/* }}} */ + + +/* {{{ proto object mysql_fetch_object(resource result [, string class_name [, NULL|array ctor_params]]) + Fetch a result row as an object */ +PHP_FUNCTION(mysql_fetch_object) +{ + php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_ASSOC, 2, 1); + + if (Z_TYPE_P(return_value) == IS_ARRAY) { + object_and_properties_init(return_value, ZEND_STANDARD_CLASS_DEF_PTR, Z_ARRVAL_P(return_value)); + } +} +/* }}} */ + + +/* {{{ proto array mysql_fetch_array(resource result [, int result_type]) + Fetch a result row as an array (associative, numeric or both) */ +PHP_FUNCTION(mysql_fetch_array) +{ + php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 2, 0); +} +/* }}} */ + + +/* {{{ proto array mysql_fetch_assoc(resource result) + Fetch a result row as an associative array */ +PHP_FUNCTION(mysql_fetch_assoc) +{ + php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_ASSOC, 1, 0); +} +/* }}} */ + +/* {{{ proto bool mysql_data_seek(resource result, int row_number) + Move internal result pointer */ +PHP_FUNCTION(mysql_data_seek) +{ + zval *result; + long offset; + MYSQL_RES *mysql_result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &offset)) { + return; + } + + ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result); + + if (offset<0 || offset>=(int)mysql_num_rows(mysql_result)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset %ld is invalid for MySQL result index %ld (or the query data is unbuffered)", offset, Z_LVAL_P(result)); + RETURN_FALSE; + } + mysql_data_seek(mysql_result, offset); + RETURN_TRUE; +} +/* }}} */ + + +/* {{{ proto array mysql_fetch_lengths(resource result) + Gets max data size of each column in a result */ +PHP_FUNCTION(mysql_fetch_lengths) +{ + zval *result; + MYSQL_RES *mysql_result; + mysql_row_length_type *lengths; + int num_fields; + int i; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result); + + if ((lengths=mysql_fetch_lengths(mysql_result))==NULL) { + RETURN_FALSE; + } + array_init(return_value); + num_fields = mysql_num_fields(mysql_result); + + for (i=0; i<num_fields; i++) { + add_index_long(return_value, i, lengths[i]); + } +} +/* }}} */ + +/* {{{ php_mysql_get_field_name + */ +static char *php_mysql_get_field_name(int field_type) +{ + switch(field_type) { + case FIELD_TYPE_STRING: + case FIELD_TYPE_VAR_STRING: + return "string"; + break; +#if MYSQL_VERSION_ID > 50002 || defined(MYSQL_USE_MYSQLND) + case MYSQL_TYPE_BIT: +#endif +#ifdef MYSQL_HAS_TINY + case FIELD_TYPE_TINY: +#endif + case FIELD_TYPE_SHORT: + case FIELD_TYPE_LONG: + case FIELD_TYPE_LONGLONG: + case FIELD_TYPE_INT24: + return "int"; + break; + case FIELD_TYPE_FLOAT: + case FIELD_TYPE_DOUBLE: + case FIELD_TYPE_DECIMAL: +#ifdef FIELD_TYPE_NEWDECIMAL + case FIELD_TYPE_NEWDECIMAL: +#endif + return "real"; + break; + case FIELD_TYPE_TIMESTAMP: + return "timestamp"; + break; +#ifdef MYSQL_HAS_YEAR + case FIELD_TYPE_YEAR: + return "year"; + break; +#endif + case FIELD_TYPE_DATE: +#ifdef FIELD_TYPE_NEWDATE + case FIELD_TYPE_NEWDATE: +#endif + return "date"; + break; + case FIELD_TYPE_TIME: + return "time"; + break; + case FIELD_TYPE_SET: + return "set"; + break; + case FIELD_TYPE_ENUM: + return "enum"; + break; +#ifdef FIELD_TYPE_GEOMETRY + case FIELD_TYPE_GEOMETRY: + return "geometry"; + break; +#endif + case FIELD_TYPE_DATETIME: + return "datetime"; + break; + case FIELD_TYPE_TINY_BLOB: + case FIELD_TYPE_MEDIUM_BLOB: + case FIELD_TYPE_LONG_BLOB: + case FIELD_TYPE_BLOB: + return "blob"; + break; + case FIELD_TYPE_NULL: + return "null"; + break; + default: + return "unknown"; + break; + } +} +/* }}} */ + +/* {{{ proto object mysql_fetch_field(resource result [, int field_offset]) + Gets column information from a result and return as an object */ +PHP_FUNCTION(mysql_fetch_field) +{ + zval *result; + long field=0; + MYSQL_RES *mysql_result; + const MYSQL_FIELD *mysql_field; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &result, &field) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result); + + if (ZEND_NUM_ARGS() > 1) { + if (field<0 || field>=(int)mysql_num_fields(mysql_result)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad field offset"); + RETURN_FALSE; + } + mysql_field_seek(mysql_result, field); + } + if ((mysql_field=mysql_fetch_field(mysql_result))==NULL) { + RETURN_FALSE; + } + object_init(return_value); + + add_property_string(return_value, "name",(mysql_field->name?mysql_field->name:""), 1); + add_property_string(return_value, "table",(mysql_field->table?mysql_field->table:""), 1); + add_property_string(return_value, "def",(mysql_field->def?mysql_field->def:""), 1); + add_property_long(return_value, "max_length", mysql_field->max_length); + add_property_long(return_value, "not_null", IS_NOT_NULL(mysql_field->flags)?1:0); + add_property_long(return_value, "primary_key", IS_PRI_KEY(mysql_field->flags)?1:0); + add_property_long(return_value, "multiple_key",(mysql_field->flags&MULTIPLE_KEY_FLAG?1:0)); + add_property_long(return_value, "unique_key",(mysql_field->flags&UNIQUE_KEY_FLAG?1:0)); + add_property_long(return_value, "numeric", IS_NUM(Z_TYPE_P(mysql_field))?1:0); + add_property_long(return_value, "blob", IS_BLOB(mysql_field->flags)?1:0); + add_property_string(return_value, "type", php_mysql_get_field_name(Z_TYPE_P(mysql_field)), 1); + add_property_long(return_value, "unsigned",(mysql_field->flags&UNSIGNED_FLAG?1:0)); + add_property_long(return_value, "zerofill",(mysql_field->flags&ZEROFILL_FLAG?1:0)); +} +/* }}} */ + + +/* {{{ proto bool mysql_field_seek(resource result, int field_offset) + Sets result pointer to a specific field offset */ +PHP_FUNCTION(mysql_field_seek) +{ + zval *result; + long offset; + MYSQL_RES *mysql_result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &offset) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result); + + if (offset<0 || offset>=(int)mysql_num_fields(mysql_result)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field %ld is invalid for MySQL result index %ld", offset, Z_LVAL_P(result)); + RETURN_FALSE; + } + mysql_field_seek(mysql_result, offset); + RETURN_TRUE; +} +/* }}} */ + + +#define PHP_MYSQL_FIELD_NAME 1 +#define PHP_MYSQL_FIELD_TABLE 2 +#define PHP_MYSQL_FIELD_LEN 3 +#define PHP_MYSQL_FIELD_TYPE 4 +#define PHP_MYSQL_FIELD_FLAGS 5 + +/* {{{ php_mysql_field_info + */ +static void php_mysql_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) +{ + zval *result; + long field; + MYSQL_RES *mysql_result; + const MYSQL_FIELD *mysql_field = {0}; + char buf[512]; + int len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &field) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result); + + if (field<0 || field>=(int)mysql_num_fields(mysql_result)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field %ld is invalid for MySQL result index %ld", field, Z_LVAL_P(result)); + RETURN_FALSE; + } + mysql_field_seek(mysql_result, field); + if ((mysql_field=mysql_fetch_field(mysql_result))==NULL) { + RETURN_FALSE; + } + + switch (entry_type) { + case PHP_MYSQL_FIELD_NAME: + Z_STRLEN_P(return_value) = strlen(mysql_field->name); + Z_STRVAL_P(return_value) = estrndup(mysql_field->name, Z_STRLEN_P(return_value)); + Z_TYPE_P(return_value) = IS_STRING; + break; + case PHP_MYSQL_FIELD_TABLE: + Z_STRLEN_P(return_value) = strlen(mysql_field->table); + Z_STRVAL_P(return_value) = estrndup(mysql_field->table, Z_STRLEN_P(return_value)); + Z_TYPE_P(return_value) = IS_STRING; + break; + case PHP_MYSQL_FIELD_LEN: + Z_LVAL_P(return_value) = mysql_field->length; + Z_TYPE_P(return_value) = IS_LONG; + break; + case PHP_MYSQL_FIELD_TYPE: + Z_STRVAL_P(return_value) = php_mysql_get_field_name(Z_TYPE_P(mysql_field)); + Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); + Z_STRVAL_P(return_value) = estrndup(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value)); + Z_TYPE_P(return_value) = IS_STRING; + break; + case PHP_MYSQL_FIELD_FLAGS: + memcpy(buf, "", sizeof("")); +#ifdef IS_NOT_NULL + if (IS_NOT_NULL(mysql_field->flags)) { + strcat(buf, "not_null "); + } +#endif +#ifdef IS_PRI_KEY + if (IS_PRI_KEY(mysql_field->flags)) { + strcat(buf, "primary_key "); + } +#endif +#ifdef UNIQUE_KEY_FLAG + if (mysql_field->flags&UNIQUE_KEY_FLAG) { + strcat(buf, "unique_key "); + } +#endif +#ifdef MULTIPLE_KEY_FLAG + if (mysql_field->flags&MULTIPLE_KEY_FLAG) { + strcat(buf, "multiple_key "); + } +#endif +#ifdef IS_BLOB + if (IS_BLOB(mysql_field->flags)) { + strcat(buf, "blob "); + } +#endif +#ifdef UNSIGNED_FLAG + if (mysql_field->flags&UNSIGNED_FLAG) { + strcat(buf, "unsigned "); + } +#endif +#ifdef ZEROFILL_FLAG + if (mysql_field->flags&ZEROFILL_FLAG) { + strcat(buf, "zerofill "); + } +#endif +#ifdef BINARY_FLAG + if (mysql_field->flags&BINARY_FLAG) { + strcat(buf, "binary "); + } +#endif +#ifdef ENUM_FLAG + if (mysql_field->flags&ENUM_FLAG) { + strcat(buf, "enum "); + } +#endif +#ifdef SET_FLAG + if (mysql_field->flags&SET_FLAG) { + strcat(buf, "set "); + } +#endif +#ifdef AUTO_INCREMENT_FLAG + if (mysql_field->flags&AUTO_INCREMENT_FLAG) { + strcat(buf, "auto_increment "); + } +#endif +#ifdef TIMESTAMP_FLAG + if (mysql_field->flags&TIMESTAMP_FLAG) { + strcat(buf, "timestamp "); + } +#endif + len = strlen(buf); + /* remove trailing space, if present */ + if (len && buf[len-1] == ' ') { + buf[len-1] = 0; + len--; + } + + Z_STRLEN_P(return_value) = len; + Z_STRVAL_P(return_value) = estrndup(buf, len); + Z_TYPE_P(return_value) = IS_STRING; + break; + + default: + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto string mysql_field_name(resource result, int field_index) + Gets the name of the specified field in a result */ +PHP_FUNCTION(mysql_field_name) +{ + php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_NAME); +} +/* }}} */ + + +/* {{{ proto string mysql_field_table(resource result, int field_offset) + Gets name of the table the specified field is in */ +PHP_FUNCTION(mysql_field_table) +{ + php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_TABLE); +} +/* }}} */ + + +/* {{{ proto int mysql_field_len(resource result, int field_offset) + Returns the length of the specified field */ +PHP_FUNCTION(mysql_field_len) +{ + php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_LEN); +} +/* }}} */ + + +/* {{{ proto string mysql_field_type(resource result, int field_offset) + Gets the type of the specified field in a result */ +PHP_FUNCTION(mysql_field_type) +{ + php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_TYPE); +} +/* }}} */ + + +/* {{{ proto string mysql_field_flags(resource result, int field_offset) + Gets the flags associated with the specified field in a result */ +PHP_FUNCTION(mysql_field_flags) +{ + php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_FLAGS); +} +/* }}} */ + + +/* {{{ proto bool mysql_free_result(resource result) + Free result memory */ +PHP_FUNCTION(mysql_free_result) +{ + zval *result; + MYSQL_RES *mysql_result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) { + return; + } + + if (Z_LVAL_P(result)==0) { + RETURN_FALSE; + } + + ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result); + + zend_list_delete(Z_LVAL_P(result)); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto bool mysql_ping([int link_identifier]) + Ping a server connection. If no connection then reconnect. */ +PHP_FUNCTION(mysql_ping) +{ + zval *mysql_link = NULL; + int id = -1; + php_mysql_conn *mysql; + + if (0 == ZEND_NUM_ARGS()) { + id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); + CHECK_LINK(id); + } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &mysql_link)==FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); + + PHPMY_UNBUFFERED_QUERY_CHECK(); + + RETURN_BOOL(! mysql_ping(mysql->conn)); +} +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/ext/mysql/php_mysql.h b/ext/mysql/php_mysql.h new file mode 100644 index 0000000..7b9ab8d --- /dev/null +++ b/ext/mysql/php_mysql.h @@ -0,0 +1,36 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Zeev Suraski <zeev@zend.com> | + +----------------------------------------------------------------------+ +*/ + + +/* $Id$ */ + +#ifndef PHP_MYSQL_H +#define PHP_MYSQL_H + +#if HAVE_MYSQL + +extern zend_module_entry mysql_module_entry; +#define mysql_module_ptr &mysql_module_entry + +#else +#define mysql_module_ptr NULL +#endif + +#define phpext_mysql_ptr mysql_module_ptr + +#endif /* PHP_MYSQL_H */ diff --git a/ext/mysql/php_mysql_structs.h b/ext/mysql/php_mysql_structs.h new file mode 100644 index 0000000..bf09b24 --- /dev/null +++ b/ext/mysql/php_mysql_structs.h @@ -0,0 +1,136 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Zeev Suraski <zeev@zend.com> | + | Andrey Hristov <andrey@php.net> | + +----------------------------------------------------------------------+ +*/ + + +/* $Id$ */ + +#ifndef PHP_MYSQL_STRUCTS_H +#define PHP_MYSQL_STRUCTS_H + +#ifdef ZTS +#include "TSRM.h" +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#if defined(MYSQL_USE_MYSQLND) +#include "ext/mysqlnd/mysqlnd.h" +#include "mysql_mysqlnd.h" +#else +#include <mysql.h> +#endif + +#ifdef PHP_MYSQL_UNIX_SOCK_ADDR +#ifdef MYSQL_UNIX_ADDR +#undef MYSQL_UNIX_ADDR +#endif +#define MYSQL_UNIX_ADDR PHP_MYSQL_UNIX_SOCK_ADDR +#endif + +#if (MYSQL_VERSION_ID >= 40113 && MYSQL_VERSION_ID < 50000) || MYSQL_VERSION_ID >= 50007 || defined(MYSQL_USE_MYSQLND) +#define MYSQL_HAS_SET_CHARSET +#endif + +PHP_MINIT_FUNCTION(mysql); +PHP_RINIT_FUNCTION(mysql); +PHP_MSHUTDOWN_FUNCTION(mysql); +PHP_RSHUTDOWN_FUNCTION(mysql); +PHP_MINFO_FUNCTION(mysql); + +PHP_FUNCTION(mysql_connect); +PHP_FUNCTION(mysql_pconnect); +PHP_FUNCTION(mysql_close); +PHP_FUNCTION(mysql_select_db); +#if MYSQL_VERSION_ID < 40000 +PHP_FUNCTION(mysql_create_db); +PHP_FUNCTION(mysql_drop_db); +#endif +PHP_FUNCTION(mysql_query); +PHP_FUNCTION(mysql_unbuffered_query); +PHP_FUNCTION(mysql_db_query); +PHP_FUNCTION(mysql_list_dbs); +PHP_FUNCTION(mysql_list_tables); +PHP_FUNCTION(mysql_list_fields); +PHP_FUNCTION(mysql_list_processes); +PHP_FUNCTION(mysql_error); +PHP_FUNCTION(mysql_errno); +PHP_FUNCTION(mysql_affected_rows); +PHP_FUNCTION(mysql_insert_id); +PHP_FUNCTION(mysql_result); +PHP_FUNCTION(mysql_num_rows); +PHP_FUNCTION(mysql_num_fields); +PHP_FUNCTION(mysql_fetch_row); +PHP_FUNCTION(mysql_fetch_array); +PHP_FUNCTION(mysql_fetch_assoc); +PHP_FUNCTION(mysql_fetch_object); +PHP_FUNCTION(mysql_data_seek); +PHP_FUNCTION(mysql_fetch_lengths); +PHP_FUNCTION(mysql_fetch_field); +PHP_FUNCTION(mysql_field_seek); +PHP_FUNCTION(mysql_free_result); +PHP_FUNCTION(mysql_field_name); +PHP_FUNCTION(mysql_field_table); +PHP_FUNCTION(mysql_field_len); +PHP_FUNCTION(mysql_field_type); +PHP_FUNCTION(mysql_field_flags); +PHP_FUNCTION(mysql_escape_string); +PHP_FUNCTION(mysql_real_escape_string); +PHP_FUNCTION(mysql_get_client_info); +PHP_FUNCTION(mysql_get_host_info); +PHP_FUNCTION(mysql_get_proto_info); +PHP_FUNCTION(mysql_get_server_info); +PHP_FUNCTION(mysql_info); +PHP_FUNCTION(mysql_stat); +PHP_FUNCTION(mysql_thread_id); +PHP_FUNCTION(mysql_client_encoding); +PHP_FUNCTION(mysql_ping); +#ifdef MYSQL_HAS_SET_CHARSET +PHP_FUNCTION(mysql_set_charset); +#endif + +ZEND_BEGIN_MODULE_GLOBALS(mysql) + long default_link; + long num_links,num_persistent; + long max_links,max_persistent; + long allow_persistent; + long default_port; + char *default_host, *default_user, *default_password; + char *default_socket; + char *connect_error; + long connect_errno; + long connect_timeout; + long result_allocated; + long trace_mode; + long allow_local_infile; +ZEND_END_MODULE_GLOBALS(mysql) + +#ifdef ZTS +# define MySG(v) TSRMG(mysql_globals_id, zend_mysql_globals *, v) +#else +# define MySG(v) (mysql_globals.v) +#endif + + +#endif /* PHP_MYSQL_STRUCTS_H */ diff --git a/ext/mysql/tests/001.phpt b/ext/mysql/tests/001.phpt new file mode 100644 index 0000000..72b6614 --- /dev/null +++ b/ext/mysql/tests/001.phpt @@ -0,0 +1,33 @@ +--TEST-- +mysql connect +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +require_once('connect.inc'); +$test = ''; + +if ($socket) + $host = sprintf("%s:%s", $host, $socket); +else if ($port) + $host = sprintf("%s:%s", $host, $port); + +/*** test mysql_connect localhost ***/ +$db = mysql_connect($host, $user, $passwd); +$test .= ($db) ? '1' : '0'; +mysql_close($db); + +/*** test mysql_connect localhost:port ***/ +$db = mysql_connect($host, $user, $passwd, true); +$test .= ($db) ? '1' : '0'; +mysql_close($db); + +var_dump($test); +print "done!"; +?> +--EXPECTF-- +%unicode|string%(2) "11" +done! diff --git a/ext/mysql/tests/002.phpt b/ext/mysql/tests/002.phpt new file mode 100644 index 0000000..8355c5f --- /dev/null +++ b/ext/mysql/tests/002.phpt @@ -0,0 +1,61 @@ +--TEST-- +mysql_fetch_array +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +require_once('connect.inc'); + +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + +var_dump($link); + +var_dump(mysql_query('DROP TABLE IF EXISTS test')); + +var_dump(mysql_query('CREATE TABLE test(col1 int PRIMARY KEY, col2 varchar(50), col3 char(5))')); + +var_dump(mysql_query("INSERT INTO test(col1, col2, col3) VALUES(1, 'foo', 'bar'),(2, 'foo', 'bar')")); + +var_dump($res = mysql_query('SELECT col1, col2, col3 FROM test ORDER BY col1 ASC')); + +while ($data = mysql_fetch_array($res, MYSQL_ASSOC)) { + var_dump($data); +} + +mysql_free_result($res); +mysql_close($link); + +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +resource(%d) of type (mysql link) +bool(true) +bool(true) +bool(true) +resource(%d) of type (mysql result) +array(3) { + [%u|b%"col1"]=> + %unicode|string%(1) "1" + [%u|b%"col2"]=> + %unicode|string%(3) "foo" + [%u|b%"col3"]=> + %unicode|string%(3) "bar" +} +array(3) { + [%u|b%"col1"]=> + %unicode|string%(1) "2" + [%u|b%"col2"]=> + %unicode|string%(3) "foo" + [%u|b%"col3"]=> + %unicode|string%(3) "bar" +} +done! diff --git a/ext/mysql/tests/003.phpt b/ext/mysql/tests/003.phpt new file mode 100644 index 0000000..2d0b68b --- /dev/null +++ b/ext/mysql/tests/003.phpt @@ -0,0 +1,89 @@ +--TEST-- +mysql_fetch_object +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include_once('connect.inc'); + +class class24 { + function __construct() { + echo __METHOD__ . "\n"; + } +} + +$data = array("one", "two", "three"); + +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + +if (!mysql_query('DROP TABLE IF EXISTS test', $link)) + printf("[002] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (!mysql_query("CREATE TABLE test(a varchar(10))", $link)) + printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +foreach ($data as $str) { + if (!mysql_query(sprintf("INSERT INTO test VALUES('%s')", $str), $link)) + printf("[004 - %s] [%d] %s\n", $str, mysql_errno($link), mysql_error($link)); +} + +echo "==stdClass==\n"; +if (!$res = mysql_query("SELECT a FROM test", $link)) + printf("[005] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +while ($obj = mysql_fetch_object($res)) { + var_dump($obj); +} +mysql_free_result($res); + +echo "==class24==\n"; +if (!$res = mysql_query("SELECT a FROM test", $link)) + printf("[006] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +while ($obj = mysql_fetch_object($res, 'class24')) { + var_dump($obj); +} +mysql_free_result($res); +mysql_close($link); +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +==stdClass== +object(stdClass)#%d (1) { + [%u|b%"a"]=> + %unicode|string%(3) "one" +} +object(stdClass)#%d (1) { + [%u|b%"a"]=> + %unicode|string%(3) "two" +} +object(stdClass)#%d (1) { + [%u|b%"a"]=> + %unicode|string%(5) "three" +} +==class24== +class24::__construct +object(class24)#%d (1) { + [%u|b%"a"]=> + %unicode|string%(3) "one" +} +class24::__construct +object(class24)#%d (1) { + [%u|b%"a"]=> + %unicode|string%(3) "two" +} +class24::__construct +object(class24)#%d (1) { + [%u|b%"a"]=> + %unicode|string%(5) "three" +} +done! diff --git a/ext/mysql/tests/bug47438.phpt b/ext/mysql/tests/bug47438.phpt new file mode 100644 index 0000000..11f0ff3 --- /dev/null +++ b/ext/mysql/tests/bug47438.phpt @@ -0,0 +1,52 @@ +--TEST-- +Bug #47438 (mysql_fetch_field ignores zero offset) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +require_once('connect.inc'); + +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + +mysql_select_db($db, $link); +mysql_query("DROP TABLE IF EXISTS test_47438", $link); +mysql_query("CREATE TABLE test_47438 (a INT, b INT, c INT)", $link); +mysql_query("INSERT INTO test_47438 VALUES (10, 11, 12), (20, 21, 22)", $link); +$result = mysql_query("SELECT * FROM test_47438", $link); +mysql_field_seek($result, 1); + +$i = 0; + +while($i<mysql_num_fields($result)) +{ + $meta=mysql_fetch_field($result,$i); + echo $i . "." . $meta->name . "\n"; + $i++; +} + +mysql_query("DROP TABLE IF EXISTS test_47438", $link); + +?> +--CLEAN-- +<?php +require_once('connect.inc'); + +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + +if (!mysql_select_db($db, $link) || + !mysql_query("DROP TABLE IF EXISTS test_47438", $link)) + printf("[c002] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +mysql_close($link); +?> +--EXPECT-- +0.a +1.b +2.c diff --git a/ext/mysql/tests/bug48754.phpt b/ext/mysql/tests/bug48754.phpt new file mode 100644 index 0000000..fb322f4 --- /dev/null +++ b/ext/mysql/tests/bug48754.phpt @@ -0,0 +1,92 @@ +--TEST-- +Bug #48754 (mysql_close() crash php when no handle specified) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +require_once('connect.inc'); + +function my_mysql_pconnect($host, $user, $passwd, $db, $port, $socket) { + if ($socket) + $host = sprintf("%s:%s", $host, $socket); + else if ($port) + $host = sprintf("%s:%s", $host, $port); + + if (!$link = mysql_pconnect($host, $user, $passwd, true)) { + printf("[000-a] Cannot connect using host '%s', user '%s', password '****', [%d] %s\n", + $host, $user, $passwd, + mysql_errno(), mysql_error()); + return false; + } + return $link; +} + +echo "Explicit connection on close\n"; +$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket); +$link1_thread_id = mysql_thread_id($link); +$default1_thread_id = mysql_thread_id(); +echo 'Expect same thread id for $link and default conn: '; +var_dump($link1_thread_id == $default1_thread_id); +var_dump($link); +mysql_close($link); +var_dump($link); + +// we sohuld have no default link anymore +mysql_close(); + +echo "\nClosing default link\n"; +$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket); +$link2_thread_id = mysql_thread_id($link); +$default2_thread_id = mysql_thread_id(); +echo 'Expect same thread id for $link and default conn but not the previous: '; +var_dump($link1_thread_id == $default1_thread_id && $link1_thread_id != $link2_thread_id); +var_dump($link); +mysql_close(); +var_dump($link); +mysql_close($link); +var_dump($link); + +echo "\nExplicit resource and pconnect\n"; +$link = my_mysql_pconnect($host, $user, $passwd, $db, $port, $socket); +var_dump($link); +mysql_close($link); +var_dump($link); + +// we sohuld have no default link +mysql_close(); + +echo "\nDefault link and pconnect\n"; +$link = my_mysql_pconnect($host, $user, $passwd, $db, $port, $socket); +var_dump($link); +mysql_close(); +var_dump($link); +mysql_close($link); +var_dump($link); +?> +--EXPECTF-- +Explicit connection on close +Expect same thread id for $link and default conn: bool(true) +resource(%d) of type (mysql link) +resource(%d) of type (Unknown) + +Warning: mysql_close(): no MySQL-Link resource supplied in %s on line %d + +Closing default link +Expect same thread id for $link and default conn but not the previous: bool(true) +resource(%d) of type (mysql link) +resource(%d) of type (mysql link) +resource(%d) of type (Unknown) + +Explicit resource and pconnect +resource(%d) of type (mysql link persistent) +resource(%d) of type (Unknown) + +Warning: mysql_close(): no MySQL-Link resource supplied in %s on line %d + +Default link and pconnect +resource(%d) of type (mysql link persistent) +resource(%d) of type (mysql link persistent) +resource(%d) of type (Unknown) diff --git a/ext/mysql/tests/bug51242.phpt b/ext/mysql/tests/bug51242.phpt new file mode 100644 index 0000000..9b62cdb --- /dev/null +++ b/ext/mysql/tests/bug51242.phpt @@ -0,0 +1,38 @@ +--TEST-- +Bug #51242 (Empty mysql.default_port does not default to 3306 anymore, but 0) +--INI-- +mysql.default_port= +mysql.default_socket=/this/does/not/really/need/to/exist +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifnotmysqlnd.inc'); + +// Specific to this bug: we need to be able to connect via TCP. We'll use +// 127.0.0.1:3306 as a (hopefully) moderately sensible default if the hostname +// is actually specified as localhost. +if ($host == 'localhost') { + $host = '127.0.0.1'; +} + +if (!@mysql_connect("$host:3306", $user, $passwd)) { + die("skip mysql not available at $host:3306"); +} +?> +--FILE-- +<?php +require_once('connect.inc'); + +if ($host == 'localhost') { + $host = '127.0.0.1'; +} + +if ($link = my_mysql_connect($host, $user, $passwd, $db, null, $socket)) { + var_dump($link); +} else { + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, null, $socket); +} +?> +--EXPECTF-- +resource(%d) of type (mysql link) diff --git a/ext/mysql/tests/bug53649.phpt b/ext/mysql/tests/bug53649.phpt new file mode 100644 index 0000000..70bf9be --- /dev/null +++ b/ext/mysql/tests/bug53649.phpt @@ -0,0 +1,71 @@ +--TEST--
+Bug #53649 (mysql_query with "load data" unable to save result set)
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifconnectfailure.inc');
+
+if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) {
+ die(sprintf("skip Connect failed, [%d] %s\n", mysqlerrno(), mysqli_error()));
+}
+
+if (!mysql_query("DROP TABLE IF EXISTS test", $link) ||
+ !mysql_query("CREATE TABLE test (dump1 INT UNSIGNED NOT NULL PRIMARY KEY) ENGINE=" . $engine, $link))
+ die(sprintf("skip [%d] %s\n", mysql_errno($link), mysql_error($link)));
+
+if (false === file_put_contents('bug53649.data', "1\n2\n3\n"))
+ die(sprintf("skip Failed to create data file\n"));
+
+if (!mysql_query("LOAD DATA LOCAL INFILE 'bug53649.data' INTO TABLE test", $link) &&
+ 1148 == mysql_errno($link))
+ die("skip LOAD DATA LOAD INFILE not allowed\n");
+?>
+--FILE--
+<?php
+ require_once("connect.inc");
+
+ if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) {
+ printf("[001] Connect failed, [%d] %s\n", mysqlerrno(), mysqli_error());
+ }
+
+ if (!mysql_query("DROP TABLE IF EXISTS test", $link)) {
+ printf("[002] [%d] %s\n", mysql_errno($link), mysql_error($link));
+ }
+
+ if (!mysql_query("CREATE TABLE test (dump1 INT UNSIGNED NOT NULL PRIMARY KEY) ENGINE=" . $engine, $link)) {
+ printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link));
+ }
+
+ if (false === file_put_contents('bug53649.data', "1\n2\n3\n"))
+ printf("[004] Failed to create data file\n");
+
+ if (!mysql_query("SELECT 1 FROM DUAL", $link))
+ printf("[005] [%d] %s\n", mysql_errno($link), mysql_error($link));
+
+ if (!mysql_query("LOAD DATA LOCAL INFILE 'bug53649.data' INTO TABLE test", $link)) {
+ printf("[006] [%d] %s\n", mysql_errno($link), mysql_error($link));
+ echo "bug";
+ } else {
+ echo "done";
+ }
+ mysql_close($link);
+?>
+--CLEAN--
+<?php
+require_once('connect.inc');
+
+if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) {
+ printf("[clean] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+ $host, $user, $db, $port, $socket);
+}
+
+if (!mysql_query($link, 'DROP TABLE IF EXISTS test', $link)) {
+ printf("[clean] Failed to drop old test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+}
+
+mysql_close($link);
+
+unlink('bug53649.data');
+?>
+--EXPECT--
+done
\ No newline at end of file diff --git a/ext/mysql/tests/bug55473.phpt b/ext/mysql/tests/bug55473.phpt new file mode 100644 index 0000000..befecef --- /dev/null +++ b/ext/mysql/tests/bug55473.phpt @@ -0,0 +1,79 @@ +--TEST-- +Bug #55473 (mysql_pconnect leaks file descriptors on reconnect) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +if (defined('PHP_WINDOWS_VERSION_MAJOR')) { + die("skip Test doesn't work on Windows"); +} + +if (!($output = @exec("lsof -nwp " . getmypid()))) + die("skip Test can't find command line tool lsof"); +?> +--INI-- +mysql.max_persistent=30 +mysql.allow_persistent=1 +--FILE-- +<?php + include "connect.inc"; + + $tmp = NULL; + $link = NULL; + + if ($socket) + $host = sprintf("%s:%s", $host, $socket); + else if ($port) + $host = sprintf("%s:%s", $host, $port); + + function connect($host, $user, $passwd) { + $conn = mysql_pconnect($host, $user, $passwd); + + if (!$conn) + die(sprintf("[001] %s\n", mysql_error())); + + if (!mysql_query("set wait_timeout=1", $conn)) + printf("[002] [%d] %s\n", mysql_errno($conn), mysql_error($conn)); + + return $conn; + } + + $conn = connect($host, $user, $passwd); + $opened_files = -1; + + for ($i = 0; $i < 4; $i++) { + /* wait while mysql closes connection */ + sleep(3); + + if (!mysql_ping($conn)) { + printf("[003] reconnect %d\n", $i); + $conn = connect($host, $user, $passwd); + } + + $r = mysql_query('select 1', $conn); + if (!$r) + printf("[004] [%d] %s\n", mysql_errno($conn), mysql_error($conn)); + + + if ($opened_files == -1) { + $opened_files = trim(exec("lsof -nwp " . getmypid() . " | wc -l")); + printf("[005] Setting openened files...\n"); + } else if (($tmp = trim(exec("lsof -nwp " . getmypid() . " | wc -l"))) != $opened_files) { + printf("[006] [%d] different number of opened_files : expected %d, got %d", $i, $opened_files, $tmp); + } else { + printf("[007] Opened files as expected\n"); + } + } + + print "done!"; +?> +--EXPECTF-- +[003] reconnect 0 +[005] Setting openened files... +[003] reconnect 1 +[007] Opened files as expected +[003] reconnect 2 +[007] Opened files as expected +[003] reconnect 3 +[007] Opened files as expected +done! diff --git a/ext/mysql/tests/clean_table.inc b/ext/mysql/tests/clean_table.inc new file mode 100644 index 0000000..e53245b --- /dev/null +++ b/ext/mysql/tests/clean_table.inc @@ -0,0 +1,15 @@ +<?PHP +require_once('connect.inc'); + +// connect + select_db +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[clean] Cannot connect to the server using host=%s/%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $myhost, $user, $db, $port, $socket); +} + +if (!mysql_query('DROP TABLE IF EXISTS test', $link)) { + printf("[clean] Failed to drop test table: [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +mysql_close($link); +?>
\ No newline at end of file diff --git a/ext/mysql/tests/connect.inc b/ext/mysql/tests/connect.inc new file mode 100644 index 0000000..0df5bc3 --- /dev/null +++ b/ext/mysql/tests/connect.inc @@ -0,0 +1,82 @@ +<?php +if (!function_exists('sys_get_temp_dir')) { + function sys_get_temp_dir() { + + if (!empty($_ENV['TMP'])) + return realpath( $_ENV['TMP'] ); + if (!empty($_ENV['TMPDIR'])) + return realpath( $_ENV['TMPDIR'] ); + if (!empty($_ENV['TEMP'])) + return realpath( $_ENV['TEMP'] ); + + $temp_file = tempnam(md5(uniqid(rand(), TRUE)), ''); + if ($temp_file) { + $temp_dir = realpath(dirname($temp_file)); + unlink($temp_file); + return $temp_dir; + } + return FALSE; + } +} + +if (!function_exists('my_mysql_connect')) { + /* wrapper to simplify test porting */ + function my_mysql_connect($host, $user, $passwd, $db, $port, $socket, $flags = NULL, $persistent = false) { + global $connect_flags; + + $flags = ($flags === NULL) ? $connect_flags : $flags; + + if ($socket) + $host = sprintf("%s:%s", $host, $socket); + else if ($port) + $host = sprintf("%s:%s", $host, $port); + + if ($persistent) { + $link = mysql_pconnect($host, $user, $passwd, $flags); + } else { + $link = mysql_connect($host, $user, $passwd, true, $flags); + } + + if (!$link) { + printf("[000-a] Cannot connect using host '%s', user '%s', password '****', persistent = %d, [%d] %s\n", + $host, $user, ($persistent) ? 1 : 0, + mysql_errno(), mysql_error()); + return false; + } + + if (!mysql_select_db($db, $link)) { + printf("[000-b] [%d] %s\n", mysql_errno($link), mysql_error($link)); + return false; + } + + return $link; + } +} else { + printf("skip Eeeek/BUG/FIXME - connect.inc included twice! skipif bug?\n"); +} + +/* +Default values are "localhost", "root", database "test" and empty password. +Change the MYSQL_TEST_* environment values if you want to use another configuration. +*/ + +$host = getenv("MYSQL_TEST_HOST") ? getenv("MYSQL_TEST_HOST") : "localhost"; +$port = getenv("MYSQL_TEST_PORT") ? getenv("MYSQL_TEST_PORT") : 3306; +$user = getenv("MYSQL_TEST_USER") ? getenv("MYSQL_TEST_USER") : "root"; +$passwd = getenv("MYSQL_TEST_PASSWD") ? getenv("MYSQL_TEST_PASSWD") : ""; + +$db = getenv("MYSQL_TEST_DB") ? getenv("MYSQL_TEST_DB") : "test"; +$engine = getenv("MYSQL_TEST_ENGINE") ? getenv("MYSQL_TEST_ENGINE") : "MyISAM"; +$socket = getenv("MYSQL_TEST_SOCKET") ? getenv("MYSQL_TEST_SOCKET") : null; +$skip_on_connect_failure = getenv("MYSQL_TEST_SKIP_CONNECT_FAILURE") ? getenv("MYSQL_TEST_SKIP_CONNECT_FAILURE") : true; +$connect_flags = getenv("MYSQL_TEST_CONNECT_FLAGS") ? (int)getenv("MYSQL_TEST_CONNECT_FLAGS") : 0; +if ($socket) { + ini_set('mysql.default_socket', $socket); +} +/* Development setting: test experimal features and/or feature requests that never worked before? */ +$TEST_EXPERIMENTAL = (in_array(getenv("MYSQL_TEST_EXPERIMENTAL"), array(0, 1))) ? + ((1 == getenv("MYSQL_TEST_EXPERIMENTAL")) ? true : false) : + false; + +$IS_MYSQLND = stristr(mysql_get_client_info(), "mysqlnd"); +?> diff --git a/ext/mysql/tests/mysql_affected_rows.phpt b/ext/mysql/tests/mysql_affected_rows.phpt new file mode 100644 index 0000000..145e1f5 --- /dev/null +++ b/ext/mysql/tests/mysql_affected_rows.phpt @@ -0,0 +1,125 @@ +--TEST-- +mysql_affected_rows() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include_once("connect.inc"); +include_once('setupdefault.inc'); + +$tmp = NULL; +$link = NULL; + +if (0 !== ($tmp = @mysql_affected_rows())) + printf("[001] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + +if (null !== ($tmp = @mysql_affected_rows($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (!is_null($tmp = @mysql_affected_rows($link, $link))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[004] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + +if (-1 !== ($tmp = mysql_affected_rows($link))) + printf("[005] Expecting int/-1, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysql_errno($link), mysql_error($link)); + +if (!mysql_query('DROP TABLE IF EXISTS test', $link)) + printf("[006] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (!mysql_query('CREATE TABLE test(id INT, label CHAR(1), PRIMARY KEY(id)) ENGINE = ' . $engine, $link)) + printf("[007] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (!mysql_query("INSERT INTO test(id, label) VALUES (1, 'a')", $link)) + printf("[008] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (1 !== ($tmp = mysql_affected_rows($link))) + printf("[010] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + +// ignore INSERT error, NOTE: command line returns 0, affected_rows returns -1 as documented +@mysql_query("INSERT INTO test(id, label) VALUES (1, 'a')", $link); +if (-1 !== ($tmp = mysql_affected_rows($link))) + printf("[011] Expecting int/-1, got %s/%s\n", gettype($tmp), $tmp); + +if (!mysql_query("INSERT INTO test(id, label) VALUES (1, 'a') ON DUPLICATE KEY UPDATE id = 4", $link)) + printf("[012] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (2 !== ($tmp = mysql_affected_rows($link))) + printf("[013] Expecting int/2, got %s/%s\n", gettype($tmp), $tmp); + +if (!mysql_query("INSERT INTO test(id, label) VALUES (2, 'b'), (3, 'c')", $link)) + printf("[014] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (2 !== ($tmp = mysql_affected_rows($link))) + printf("[015] Expecting int/2, got %s/%s\n", gettype($tmp), $tmp); + +if (!mysql_query("INSERT IGNORE INTO test(id, label) VALUES (1, 'a')", $link)) { + printf("[016] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +if (1 !== ($tmp = mysql_affected_rows($link))) + printf("[017] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + +if (!mysql_query("INSERT INTO test(id, label) SELECT id + 10, label FROM test", $link)) + printf("[018] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (4 !== ($tmp = mysql_affected_rows($link))) + printf("[019] Expecting int/4, got %s/%s\n", gettype($tmp), $tmp); + +if (!mysql_query("REPLACE INTO test(id, label) values (4, 'd')", $link)) + printf("[020] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (2 !== ($tmp = mysql_affected_rows($link))) + printf("[021] Expecting int/2, got %s/%s\n", gettype($tmp), $tmp); + +if (!mysql_query("REPLACE INTO test(id, label) values (5, 'e')", $link)) + printf("[022] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (1 !== ($tmp = mysql_affected_rows($link))) + printf("[023] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + +if (!mysql_query("UPDATE test SET label = 'a' WHERE id = 2", $link)) + printf("[024] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (1 !== ($tmp = mysql_affected_rows($link))) + printf("[025] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); + +if (!mysql_query("UPDATE test SET label = 'a' WHERE id = 2", $link)) { + printf("[025] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +if (0 !== ($tmp = mysql_affected_rows($link))) + printf("[026] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + +if (!mysql_query("UPDATE test SET label = 'a' WHERE id = 100", $link)) { + printf("[025] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +if (0 !== ($tmp = mysql_affected_rows($link))) + printf("[026] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + +if (0 !== ($tmp = mysql_affected_rows())) + printf("[027] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + +if (!mysql_query('DROP TABLE IF EXISTS test', $link)) + printf("[028] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +mysql_close($link); + +if (false !== ($tmp = @mysql_affected_rows($link))) + printf("[029] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +done! diff --git a/ext/mysql/tests/mysql_client_encoding.phpt b/ext/mysql/tests/mysql_client_encoding.phpt new file mode 100644 index 0000000..8aa67a0 --- /dev/null +++ b/ext/mysql/tests/mysql_client_encoding.phpt @@ -0,0 +1,70 @@ +--TEST-- +mysql_client_encoding() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include_once "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + +$default_link_enc = mysql_client_encoding(); +$link_enc = mysql_client_encoding($link); + +if ($default_link_enc !== $link_enc) + printf("[003] %s != %s, [%d] %s\n", $default_link_enc, $link_enc, mysql_errno($link), mysql_error($link)); + +if (!$res = mysql_query('SELECT version() AS server_version', $link)) + printf("[004] [%d] %s\n", mysql_errno($link), mysql_error($link)); +$tmp = mysql_fetch_assoc($res); +mysql_free_result($res); +$version = explode('.', $tmp['server_version']); +if (empty($version)) + printf("[005] Cannot determine server version, need MySQL Server 4.1+ for the test!\n"); + +if ($version[0] <= 4 && $version[1] < 1) + printf("[006] Need MySQL Server 4.1+ for the test!\n"); + +if (!$res = mysql_query('SELECT @@character_set_connection AS charset, @@collation_connection AS collation', $link)) + printf("[007] [%d] %s\n", mysql_errno($link), mysql_error($link)); +$tmp = mysql_fetch_assoc($res); +mysql_free_result($res); +if (!$tmp['charset']) + printf("[008] Cannot determine current character set and collation\n"); + +if ($link_enc !== $tmp['charset']) { + if ($link_enc === $tmp['collation']) { + printf("[009] Known bug, collation instead of chatset returned, http://bugs.mysql.com/bug.php?id=7923\n"); + } else { + printf("[009] Check manually, watch out for unicode and others\n"); + var_dump($link_enc); + var_dump($tmp); + } +} + +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && function_exists('is_unicode')) { +// unicode mode + if (!is_unicode($default_link_enc) || !is_unicode($link_enc)) { + printf("[010] No unicode returned!\n"); + var_dump($default_link_enc); + var_dump($link_enc); + } +} + +mysql_close($link); + +if (false !== ($tmp = @mysql_client_encoding($link))) + printf("[012] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +print "done!"; +?> +--EXPECTF-- +done! diff --git a/ext/mysql/tests/mysql_close.phpt b/ext/mysql/tests/mysql_close.phpt new file mode 100644 index 0000000..8f305ba --- /dev/null +++ b/ext/mysql/tests/mysql_close.phpt @@ -0,0 +1,39 @@ +--TEST-- +mysql_close() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (false !== ($tmp = @mysql_close())) + printf("[001] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +if (NULL !== ($tmp = @mysql_close($link, $link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + +$tmp = @mysql_close(NULL); +if (null !== $tmp) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +$tmp = mysql_close($link); +if (true !== $tmp) + printf("[005] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + +if (false !== ($tmp = @mysql_query("SELECT 1", $link))) + printf("[006] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +print "done!\n"; +?> +--EXPECTF-- +done! diff --git a/ext/mysql/tests/mysql_connect.phpt b/ext/mysql/tests/mysql_connect.phpt new file mode 100644 index 0000000..7158248 --- /dev/null +++ b/ext/mysql/tests/mysql_connect.phpt @@ -0,0 +1,108 @@ +--TEST-- +mysql_connect() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include_once "connect.inc"; + +$tmp = NULL; +$link = NULL; + +// mysql_connect ( [string server [, string username [, string password [, bool new_link [, int client_flags]]]]] ) +if (NULL !== ($tmp = @mysql_connect($link, $link, $link, $link, $link, $link))) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +$myhost = (is_null($socket)) ? ((is_null($port)) ? $host : $host . ':' . $port) : $host . ':' . $socket; +if (!$link = mysql_connect($myhost, $user, $passwd, true)) + printf("[002] Cannot connect to the server using host=%s/%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $myhost, $user, $db, $port, $socket); + +mysql_close($link); + +if (!$link = mysql_connect($myhost, $user, $passwd, true)) + printf("[003] Cannot connect to the server using host=%s/%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $myhost, $user, $db, $port, $socket); + +mysql_close(); + +if ($link = mysql_connect($myhost, $user . 'unknown_really', $passwd . 'non_empty', true)) + printf("[004] Can connect to the server using host=%s/%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", + $host, $myhost, $user . 'unknown_really', $db, $port, $socket); + +if (false !== $link) +printf("[005] Expecting boolean/false, got %s/%s\n", gettype($link), $link); + +// Run the following tests without an anoynmous MySQL user and use a password for the test user! +ini_set('mysql.default_socket', $socket); +if (!is_null($socket)) { + if (!is_resource($link = mysql_connect($host, $user, $passwd, true))) { + printf("[006] Usage of mysql.default_socket failed\n"); + } else { + mysql_close($link); + } +} + +if (!ini_get('sql.safe_mode')) { + + ini_set('mysql.default_port', $port); + if (!is_null($port)) { + if (!is_resource($link = mysql_connect($host, $user, $passwd, true))) { + printf("[007] Usage of mysql.default_port failed\n"); + } else { + mysql_close($link); + } + } + + ini_set('mysql.default_password', $passwd); + if (!is_resource($link = mysql_connect($myhost, $user))) { + printf("[008] Usage of mysql.default_password failed\n"); + } else { + mysql_close($link); + } + ini_set('mysql.default_user', $user); + if (!is_resource($link = mysql_connect($myhost))) { + printf("[009] Usage of mysql.default_user failed\n"); + } else { + mysql_close($link); + } + + ini_set('mysql.default_host', $myhost); + if (!is_resource($link = mysql_connect())) { + printf("[010] Usage of mysql.default_host failed\n") ; + } else { + mysql_close($link); + } + + if (!is_resource($link = mysql_connect()) || !is_resource($link2 = mysql_connect())) { + printf("[011] Usage of mysql.default_host failed\n") ; + } else { + mysql_close(); + mysql_close($link2); + } + + if (!stristr(PHP_OS, 'win') && !stristr(PHP_OS, 'netware')) { + ini_set('mysql.default_port', -1); + if (putenv(sprintf('MYSQL_TCP_PORT=%d', $port))) { + if (!is_resource($link = mysql_connect())) { + printf("[012] Usage of env MYSQL_TCP_PORT failed\n") ; + } else { + mysql_close($link); + } + } else if (putenv(sprintf('MYSQL_TCP_PORT=%d', $port + 1))) { + if (!is_resource($link = mysql_connect())) { + printf("[013] Usage of env MYSQL_TCP_PORT=%d should have failed\n", $port + 1) ; + mysql_close($link); + } + } + } +} + +print "done!"; +?> +--EXPECTF-- +Warning: mysql_connect(): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d +done! diff --git a/ext/mysql/tests/mysql_constants.phpt b/ext/mysql/tests/mysql_constants.phpt new file mode 100644 index 0000000..1346100 --- /dev/null +++ b/ext/mysql/tests/mysql_constants.phpt @@ -0,0 +1,65 @@ +--TEST-- +Constants exported by ext/mysql +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +require("connect.inc"); +require("table.inc"); + +$constants = get_defined_constants(true); +sort($constants); + +$expected_constants = array( + 'MYSQL_ASSOC' => true, + 'MYSQL_NUM' => true, + 'MYSQL_BOTH' => true, + 'MYSQL_CLIENT_COMPRESS' => true, + 'MYSQL_CLIENT_INTERACTIVE' => true, + 'MYSQL_CLIENT_IGNORE_SPACE' => true, +); + +$version = mysql_get_server_info($link); +if (!preg_match('@(\d+)\.(\d+)\.(\d+)@ism', $version, $matches)) + printf("[001] Cannot get server version\n"); +$version = ($matches[1] * 100) + ($matches[2] * 10) + $matches[3]; + +if ($version > 400) { + $expected_constants = array_merge($expected_constants, array( + "MYSQL_CLIENT_SSL" => true, + )); +} + + +$unexpected_constants = array(); + +foreach ($constants as $group => $consts) { + foreach ($consts as $name => $value) { + if (stristr($name, 'mysql') && !preg_match("/^mysql([^_]+)_/iu", $name)) { + $name = strtoupper($name); + if (isset($expected_constants[$name])) { + unset($expected_constants[$name]); + } else { + $unexpected_constants[$name] = $name; + } + } + } +} + +if (!empty($unexpected_constants)) { + printf("Dumping list of unexpected constants\n"); + var_dump($unexpected_constants); +} + +if (!empty($expected_constants)) { + printf("Dumping list of missing constants\n"); + var_dump($expected_constants); +} + +print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysql/tests/mysql_create_db.phpt b/ext/mysql/tests/mysql_create_db.phpt new file mode 100644 index 0000000..bc91964 --- /dev/null +++ b/ext/mysql/tests/mysql_create_db.phpt @@ -0,0 +1,56 @@ +--TEST-- +mysql_create_db() +--SKIPIF-- +<?php +require_once('skipif.inc'); +if (!function_exists('mysql_create_db')) + die("Skip mysql_create_db() exists only in old versions of the libmysql."); +?> +--FILE-- +<?php +include "connect.inc"; + +$link = NULL; +$tmp = null; + +if (false !== ($tmp = mysql_create_db())) + printf("[001] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +if (false !== ($tmp = mysql_create_db($link, $link, $link))) + printf("[002] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +if ($link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[003] Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", + $host, $user . 'unknown_really', $db, $port, $socket); + +if (!mysql_query("CREATE DATABASE mysqlcreatedb", $link)) + die(sprintf("[004] Cannot create database, aborting test, [%d] %s\n", mysql_errno($link), mysql_error($link))); + +if (!mysql_query("DROP DATABASE mysqlcreatedb", $link)) + printf("[005] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (true !== ($tmp = mysql_create_db("mysqlcreatedb", $link))) + printf("[006] Expecting boolean/true, got %s/%s, [%d] %s\n", gettype($tmp), $tmp, mysql_errno($link), mysql_error($link)); + +if (false !== ($tmp = mysql_create_db("mysqlcreatedb", $link))) + printf("[007] Expecting boolean/false, got %s/%s, [%d] %s\n", gettype($tmp), $tmp, mysql_errno($link), mysql_error($link)); + +if (!mysql_query("DROP DATABASE mysqlcreatedb", $link)) + printf("[008] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +print "done!"; +?> +--CLEAN-- +<?php +require_once('connect.inc'); +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + +if (!mysql_query("DROP DATABASE IF EXISTS mysqlcreatedb", $link)) + printf("[c002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysql_close($link); +?> +--EXPECTF-- +done! diff --git a/ext/mysql/tests/mysql_data_seek.phpt b/ext/mysql/tests/mysql_data_seek.phpt new file mode 100644 index 0000000..46a0f86 --- /dev/null +++ b/ext/mysql/tests/mysql_data_seek.phpt @@ -0,0 +1,77 @@ +--TEST-- +mysql_data_seek() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (NULL !== ($tmp = @mysql_data_seek())) + printf("[001] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +if (NULL !== ($tmp = @mysql_data_seek($link))) + printf("[002] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +if (NULL !== ($tmp = @mysql_data_seek($link, $link))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); +if (!$res = mysql_query('SELECT * FROM test ORDER BY id LIMIT 4', $link)) + printf("[004] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (true !== ($tmp = mysql_data_seek($res, 3))) + printf("[005] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + +$row = mysql_fetch_assoc($res); +if (4 != $row['id']) + printf("[006] Expecting record 4/d, got record %s/%s\n", $row['id'], $row['label']); + +if (true !== ($tmp = mysql_data_seek($res, 0))) + printf("[007] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + +$row = mysql_fetch_assoc($res); +if (1 != $row['id']) + printf("[008] Expecting record 1/a, got record %s/%s\n", $row['id'], $row['label']); + +if (false !== ($tmp = mysql_data_seek($res, 4))) + printf("[009] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +if (false !== ($tmp = mysql_data_seek($res, -1))) + printf("[010] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +mysql_free_result($res); + +if (!$res = mysql_unbuffered_query('SELECT * FROM test ORDER BY id', $link)) + printf("[011] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (false !== ($tmp = mysql_data_seek($res, 3))) + printf("[012] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +mysql_free_result($res); + +if (false !== ($tmp = mysql_data_seek($res, 1))) + printf("[013] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +mysql_close($link); + +print "done!\n"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysql_data_seek(): Offset 4 is invalid for MySQL result index %d (or the query data is unbuffered) in %s on line %d + +Warning: mysql_data_seek(): Offset -1 is invalid for MySQL result index %d (or the query data is unbuffered) in %s on line %d + +Warning: mysql_data_seek(): Offset 3 is invalid for MySQL result index %d (or the query data is unbuffered) in %s on line %d + +Warning: mysql_data_seek(): %d is not a valid MySQL result resource in %s on line %d +done! diff --git a/ext/mysql/tests/mysql_db_name.phpt b/ext/mysql/tests/mysql_db_name.phpt new file mode 100644 index 0000000..b7f9042 --- /dev/null +++ b/ext/mysql/tests/mysql_db_name.phpt @@ -0,0 +1,66 @@ +--TEST-- +mysql_db_name() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (NULL !== ($tmp = @mysql_db_name())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (NULL !== ($tmp = @mysql_db_name($link, $link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); + +if (!$res = @mysql_list_dbs($link)) + printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (!$num = mysql_num_rows($res)) + printf("[004] Empty database list? [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (false !== ($tmp = mysql_db_name($res, -1))) + printf("[005] Expecting boolean/false, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysql_errno($link), mysql_error($link)); + +if (false !== ($tmp = mysql_db_name($res, $num + 1))) + printf("[006] Expecting boolean/false, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysql_errno($link), mysql_error($link)); + +$unicode = (boolean)(version_compare(PHP_VERSION, '5.9.9', '>') == 1); +for ($i = 0; $i < $num; $i++) { + if ('' === ($dbname = mysql_db_name($res, $i))) + printf("[%03d] Got empty database name! [%d] %s\n", + (($i * 2) + 1) + 6, mysql_errno($link), mysql_error($link)); + + if ($unicode && !is_unicode($dbname)) { + printf("[%03d] Expecting unicode string! [%d] %s\n", + (($i * 2) + 2) + 6, mysql_errno($link), mysql_error($link)); + var_inspect($dbname); + } +} + +mysql_free_result($res); + +if (false !== ($tmp = mysql_db_name($res, $num))) + printf("[999] Expecting boolean/false, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysql_errno($link), mysql_error($link)); + +mysql_close($link); + +print "done!\n"; +?> +--EXPECTF-- +Warning: mysql_db_name(): Unable to jump to row -1 on MySQL result index %d in %s on line %d + +Warning: mysql_db_name(): Unable to jump to row %d on MySQL result index %d in %s on line %d + +Warning: mysql_db_name(): %d is not a valid MySQL result resource in %s on line %d +done! diff --git a/ext/mysql/tests/mysql_db_query.phpt b/ext/mysql/tests/mysql_db_query.phpt new file mode 100644 index 0000000..bb837dd --- /dev/null +++ b/ext/mysql/tests/mysql_db_query.phpt @@ -0,0 +1,65 @@ +--TEST-- +mysql_db_query() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +// NOTE: this function is deprecated. We do only the most necessary +// to test it. We don't test all aspects of the documented behaviour. + +$tmp = NULL; +$link = NULL; + +if (NULL !== ($tmp = @mysql_db_query())) + printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (NULL !== ($tmp = @mysql_db_query($link))) + printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (NULL !== ($tmp = @mysql_db_query($link))) + printf("[003] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); +if (!$res = @mysql_db_query($db, 'SELECT id, label FROM test ORDER BY id LIMIT 1', $link)) + printf("[004] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +$row = mysql_fetch_assoc($res); +if (1 != $row['id']) + printf("[005] Expecting record 1/a, got record %s/%s\n", $row['id'], $row['label']); + +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($row['label'])) { + printf("[006] No unicode returned! [%d] %s\n", mysql_errno($link), mysql_error($link)); + var_inspect($row); +} + +mysql_free_result($res); + + +if (!$res = @mysql_db_query($db, 'SELECT id, label FROM test ORDER BY id LIMIT 1')) + printf("[007] [%d] %s\n", mysql_errno(), mysql_error()); + +$row = mysql_fetch_assoc($res); +if (1 != $row['id']) + printf("[008] Expecting record 1/a, got record %s/%s\n", $row['id'], $row['label']); + +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($row['label'])) { + printf("[009] No unicode returned! [%d] %s\n", mysql_errno(), mysql_error()); + var_inspect($row); +} + +mysql_free_result($res); +mysql_close($link); + +print "done!\n"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +done! diff --git a/ext/mysql/tests/mysql_deprecated_api.phpt b/ext/mysql/tests/mysql_deprecated_api.phpt new file mode 100644 index 0000000..d54307c --- /dev/null +++ b/ext/mysql/tests/mysql_deprecated_api.phpt @@ -0,0 +1,78 @@ +--TEST-- +Check if deprecated API calls bail out +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +mysql.trace_mode=1 +error_reporting=E_ALL | E_NOTICE | E_STRICT +--FILE-- +<?php +/* + We use an extra test to cover deprecation warning. + Due to this extra test we can silence deprecation warnings + in have other test using @ operator without loosing the information + which function is deprecated and, without reducing test portability. +*/ +include "table.inc"; + +if (version_compare(PHP_VERSION, '5.3.0') >= 0) { + $error = NULL; + ob_start(); + if (!$res = mysql_db_query($db, "SELECT * FROM test", $link)) + $error .= sprintf("[001] [%d] %s\n", mysql_errno($link), mysql_error($link)); + else + mysql_free_result($res); + $output = ob_get_contents(); + ob_end_clean(); + + if (!stristr($output, 'deprecated')) { + printf("[002] mysql_db_query has been deprecated in 5.3.0\n"); + } + + /* + Deprecated since 2002 or the like but documented to be deprecated since 5.3. + In 5.3 and before the deprecation message was bound to mysql.trace_mode=1. + In 5.3.99 the warning will always be thrown, independent of the mysql.trace_mode + setting. + */ + $error = NULL; + ob_start(); + if (!$query = mysql_escape_string("charsets will be ignored")) + $error .= sprintf("[005] [%d] %s\n", mysql_errno($link), mysql_error($link)); + $output = ob_get_contents(); + ob_end_clean(); + + if (!stristr($output, 'deprecated')) { + printf("[006] mysql_escape_string has been deprecated in 5.3.0\n"); + } + +} + +if (version_compare(PHP_VERSION, '5.3.99') >= 0) { + $error = NULL; + ob_start(); + if (!$res = mysql_list_dbs($link)) + $error .= sprintf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); + else + mysql_free_result($res); + $output = ob_get_contents(); + ob_end_clean(); + + if (!stristr($output, 'deprecated')) { + printf("[004] mysql_db_query has been deprecated in 5.3.0\n"); + } +} + + + +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysql/tests/mysql_drop_db.phpt b/ext/mysql/tests/mysql_drop_db.phpt new file mode 100644 index 0000000..bd729e7 --- /dev/null +++ b/ext/mysql/tests/mysql_drop_db.phpt @@ -0,0 +1,55 @@ +--TEST-- +mysql_drop_db() +--SKIPIF-- +<?php +require_once('skipif.inc'); +if (!function_exists('mysql_drop_db')) + die("Skip function is deprecated and not available"); +?> +--FILE-- +<?php +include_once "connect.inc"; + +$tmp = NULL; +$link = NULL; + +// NOTE: again this test does not test all of the behaviour of the function + +if (NULL !== ($tmp = mysql_drop_db())) + printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); +if (!mysql_query('DROP DATABASE IF EXISTS mysqldropdb')) + printf("[004] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (!mysql_query('CREATE DATABASE mysqldropdb')) + die(sprintf("[005] Skipping, can't create test database. [%d] %s\n", mysql_errno($link), mysql_error($link))); + +if (true !== ($tmp = mysql_drop_db('mysqldropdb', $link))) + printf("[006] Can't drop, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, + mysql_errno($link), mysql_error($link)); + +if (false !== ($tmp = mysql_drop_db('mysqldropdb', $link))) + printf("[007] Expecting boolean/false, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, + mysql_errno($link), mysql_error($link)); + +mysql_close($link); + +print "done!\n"; +?> +--CLEAN-- +<?php +require_once('connect.inc'); +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + +if (!mysql_query("DROP DATABASE IF EXISTS mysqldropdb", $link)) + printf("[c002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysql_close($link); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysql/tests/mysql_errno.phpt b/ext/mysql/tests/mysql_errno.phpt new file mode 100644 index 0000000..8cfa7bd --- /dev/null +++ b/ext/mysql/tests/mysql_errno.phpt @@ -0,0 +1,63 @@ +--TEST-- +mysql_errno() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (false !== ($tmp = @mysql_errno())) + printf("[001] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +if (null !== ($tmp = @mysql_errno($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (!is_null($tmp = @mysql_errno($link, 'too many args'))) + printf("[002b] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); +} +var_dump(mysql_errno($link)); + +if (!mysql_query('DROP TABLE IF EXISTS test', $link)) { + printf("[004] Failed to drop old test table: [%d] %s\n", mysql_errno($link), mysql_errno($link)); +} + +mysql_query('SELECT * FROM test', $link); +var_dump(mysql_errno($link)); + +mysql_close($link); + +var_dump(mysql_errno($link)); + +if ($link = @mysql_connect($host . '_unknown', $user . '_unknown', $passwd, true)) { + printf("[005] Can connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host . '_unknown', $user . '_unknown', $db, $port, $socket); +} else { + $errno = mysql_errno(); + if (!is_int($errno)) + printf("[006] Expecting int/any (e.g 1046, 2005) got %s/%s\n", gettype($errno), $errno); + +} + +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +int(0) +int(%d) + +Warning: mysql_errno(): %d is not a valid MySQL-Link resource in %s on line %d +bool(false) +done! diff --git a/ext/mysql/tests/mysql_error.phpt b/ext/mysql/tests/mysql_error.phpt new file mode 100644 index 0000000..aae4480 --- /dev/null +++ b/ext/mysql/tests/mysql_error.phpt @@ -0,0 +1,67 @@ +--TEST-- +mysql_error() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (false !== ($tmp = @mysql_error())) + printf("[001] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +if (NULL !== ($tmp = @mysql_error($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (!is_null($tmp = @mysql_error($link, 'too many args'))) + printf("[002b] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); +} + +$tmp = mysql_error($link); +if (!is_string($tmp) || ('' !== $tmp)) + printf("[004] Expecting string/empty, got %s/%s. [%d] %s\n", gettype($tmp), $tmp, mysql_errno($link), mysql_error($link)); + +if (!mysql_query('DROP TABLE IF EXISTS test', $link)) { + printf("[005] Failed to drop old test table: [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +mysql_query('SELECT * FROM test', $link); +$tmp = mysql_error($link); +if (!is_string($tmp) || !preg_match("/Table '\w*\.test' doesn't exist/su", $tmp)) + printf("[006] Expecting string/[Table... doesn't exit], got %s/%s. [%d] %s\n", gettype($tmp), $tmp, mysql_errno($link), mysql_error($link)); + +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($tmp)) { + printf("[007] Expecting Unicode error message!\n"); + var_inspect($tmp); +} + +mysql_close($link); + +var_dump(mysql_error($link)); + +if ($link = @mysql_connect($host . '_unknown', $user . '_unknown', $passwd, true)) { + printf("[008] Can connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host . '_unknown', $user . '_unknown', $db, $port, $socket); +} +if ('' == mysql_error()) + printf("[009] Connect error should have been set\n"); + +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysql_error(): %d is not a valid MySQL-Link resource in %s on line %d +bool(false) +done! diff --git a/ext/mysql/tests/mysql_escape_string.phpt b/ext/mysql/tests/mysql_escape_string.phpt new file mode 100644 index 0000000..8e70da6 --- /dev/null +++ b/ext/mysql/tests/mysql_escape_string.phpt @@ -0,0 +1,33 @@ +--TEST-- +mysql_escape_string() +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (NULL !== ($tmp = @mysql_escape_string())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +var_dump(@mysql_escape_string("Am I a unicode string in PHP 6?")); +var_dump(@mysql_escape_string('\\')); +var_dump(@mysql_escape_string('"')); +var_dump(@mysql_escape_string("'")); +var_dump(@mysql_escape_string("\n")); +var_dump(@mysql_escape_string("\r")); +var_dump(@mysql_escape_string("foo" . chr(0) . "bar")); + +print "done!"; +?> +--EXPECTF-- +%unicode|string%(31) "Am I a unicode string in PHP 6?" +%unicode|string%(2) "\\" +%unicode|string%(2) "\"" +%unicode|string%(2) "\'" +%unicode|string%(2) "\n" +%unicode|string%(2) "\r" +%unicode|string%(8) "foo\0bar" +done! diff --git a/ext/mysql/tests/mysql_fetch_array.phpt b/ext/mysql/tests/mysql_fetch_array.phpt new file mode 100644 index 0000000..362cf99 --- /dev/null +++ b/ext/mysql/tests/mysql_fetch_array.phpt @@ -0,0 +1,360 @@ +--TEST-- +mysql_fetch_array() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include_once "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (NULL !== ($tmp = @mysql_fetch_array())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (NULL != ($tmp = @mysql_fetch_array($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); +if (!$res = mysql_query("SELECT * FROM test ORDER BY id LIMIT 5", $link)) { + printf("[004] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +print "[005]\n"; +var_dump(mysql_fetch_array($res)); + +print "[006]\n"; +var_dump(mysql_fetch_array($res, MYSQL_NUM)); + +print "[007]\n"; +var_dump(mysql_fetch_array($res, MYSQL_BOTH)); + +print "[008]\n"; +var_dump(mysql_fetch_array($res, MYSQL_ASSOC)); + +print "[009]\n"; +var_dump(mysql_fetch_array($res)); + +mysql_free_result($res); + +if (!$res = mysql_query("SELECT 1 AS a, 2 AS a, 3 AS c, 4 AS C, NULL AS d, true AS e", $link)) { + printf("[010] Cannot run query, [%d] %s\n", mysql_errno($link), mysql_error($link)); +} +print "[011]\n"; +var_dump(mysql_fetch_array($res, MYSQL_BOTH)); + +mysql_free_result($res); +if (!$res = mysql_query("SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS C", $link)) { + printf("[012] Cannot run query, [%d] %s\n", + mysql_errno($link), $mysql_error($link)); + exit(1); +} + +do { + $illegal_mode = mt_rand(0, 10000); +} while (in_array($illegal_mode, array(MYSQL_ASSOC, MYSQL_NUM, MYSQL_BOTH))); +$tmp = mysql_fetch_array($res, $illegal_mode); +if (!is_array($tmp)) + printf("[013] Expecting array, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysql_errno($link), mysql_error($link)); + +$tmp = @mysql_fetch_array($res, $illegal_mode); +if (false !== $tmp) + printf("[014] Expecting boolean/false, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, mysql_errno($link), mysql_error($link)); + +mysql_free_result($res); + +function func_mysql_fetch_array($link, $engine, $sql_type, $sql_value, $php_value, $offset, $regexp_comparison = NULL, $binary_type = false) { + + if (!mysql_query("DROP TABLE IF EXISTS test", $link)) { + printf("[%04d] [%d] %s\n", $offset, mysql_errno($link), mysql_error($link)); + return false; + } + + if (!mysql_query($sql = sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine), $link)) { + // don't bail, engine might not support the datatype + return false; + } + + if (is_null($php_value) && !mysql_query($sql = sprintf("INSERT INTO test(id, label) VALUES (1, NULL)"), $link)) { + printf("[%04d] [%d] %s\n", $offset + 1, mysql_errno($link), mysql_error($link)); + return false; + } + + if (!is_null($php_value)) { + if (is_int($sql_value) && !mysql_query(sprintf("INSERT INTO test(id, label) VALUES (1, '%d')", $sql_value), $link)) { + printf("[%04d] [%d] %s\n", $offset + 1, mysql_errno($link), mysql_error($link)); + return false; + } else if (!is_int($sql_value) && !mysql_query(sprintf("INSERT INTO test(id, label) VALUES (1, '%s')", $sql_value), $link)) { + printf("[%04d] [%d] %s\n", $offset + 1, mysql_errno($link), mysql_error($link)); + return false; + } + } + + if (!$res = mysql_query("SELECT id, label FROM test", $link)) { + printf("[%04d] [%d] %s\n", $offset + 2, mysql_errno($link), mysql_error($link)); + return false; + } + + if (!$row = mysql_fetch_array($res, MYSQL_BOTH)) { + printf("[%04d] [%d] %s\n", $offset + 3, mysql_errno($link), mysql_error($link)); + return false; + } + + if ($regexp_comparison) { + if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) { + printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4, + gettype($php_value), $php_value, $regexp_comparison, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], mysql_errno($link), mysql_error($link)); + return false; + } + } else if ((gettype($php_value) == 'unicode') && $binary_type) { + // Unicode is on and we are told that the MySQL column type is a binary type. + // Don't expect a unicode value from the database, you'll get binary string + if (($row['label'] != $php_value) || ($row[1] != $php_value)) { + printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 5, + gettype($php_value), $php_value, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], mysql_errno($link), mysql_error($link)); + return false; + } + if (gettype($row['label']) == 'unicode') { + printf("[%04d] SQL Type: '%s', binary columns are supposed to return binary string and not unicode\n", + $offset + 6, $sql_type); + return false; + } + } else { + if (($row['label'] !== $php_value) || ($row[1] != $php_value)) { + printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 7, + gettype($php_value), $php_value, + gettype($row[1]), $row[1], + gettype($row['label']), $row['label'], mysql_errno($link), mysql_error($link)); + return false; + } + } + + return true; +} + +function func_mysql_fetch_array_make_string($len) { + + $ret = ''; + for ($i = 0; $i < $len; $i++) + $ret .= chr(mt_rand(65, 90)); + + return $ret; +} + +func_mysql_fetch_array($link, $engine, "TINYINT", -11, "-11", 20); +func_mysql_fetch_array($link, $engine, "TINYINT", NULL, NULL, 30); +func_mysql_fetch_array($link, $engine, "TINYINT UNSIGNED", 1, "1", 40); +func_mysql_fetch_array($link, $engine, "TINYINT UNSIGNED", NULL, NULL, 50); + +func_mysql_fetch_array($link, $engine, "BOOL", 1, "1", 60); +func_mysql_fetch_array($link, $engine, "BOOL", NULL, NULL, 70); +func_mysql_fetch_array($link, $engine, "BOOLEAN", 0, "0", 80); +func_mysql_fetch_array($link, $engine, "BOOLEAN", NULL, NULL, 90); + +func_mysql_fetch_array($link, $engine, "SMALLINT", -32768, "-32768", 100); +func_mysql_fetch_array($link, $engine, "SMALLINT", 32767, "32767", 110); +func_mysql_fetch_array($link, $engine, "SMALLINT", NULL, NULL, 120); +func_mysql_fetch_array($link, $engine, "SMALLINT UNSIGNED", 65535, "65535", 130); +func_mysql_fetch_array($link, $engine, "SMALLINT UNSIGNED", NULL, NULL, 140); + +func_mysql_fetch_array($link, $engine, "MEDIUMINT", -8388608, "-8388608", 150); +func_mysql_fetch_array($link, $engine, "MEDIUMINT", 8388607, "8388607", 160); +func_mysql_fetch_array($link, $engine, "MEDIUMINT", NULL, NULL, 170); +func_mysql_fetch_array($link, $engine, "MEDIUMINT UNSIGNED", 16777215, "16777215", 180); +func_mysql_fetch_array($link, $engine, "MEDIUMINT UNSIGNED", NULL, NULL, 190); + +func_mysql_fetch_array($link, $engine, "INTEGER", -2147483648, "-2147483648", 200); +func_mysql_fetch_array($link, $engine, "INTEGER", 2147483647, "2147483647", 210); +func_mysql_fetch_array($link, $engine, "INTEGER", NULL, NULL, 220); +func_mysql_fetch_array($link, $engine, "INTEGER UNSIGNED", 4294967295, "4294967295", 230); +func_mysql_fetch_array($link, $engine, "INTEGER UNSIGNED", NULL, NULL, 240); + +// func_mysql_fetch_array($link, $engine, "BIGINT", -9223372036854775808, "-9.22337e+018", 250, "/-9\.22337e\+[0]?18/iu"); +func_mysql_fetch_array($link, $engine, "BIGINT", NULL, NULL, 260); +// func_mysql_fetch_array($link, $engine, "BIGINT UNSIGNED", 18446744073709551615, "1.84467e+019", 270, "/1\.84467e\+[0]?19/iu"); +func_mysql_fetch_array($link, $engine, "BIGINT UNSIGNED", NULL, NULL, 280); + +func_mysql_fetch_array($link, $engine, "FLOAT", -9223372036854775808 - 1.1, "-9.22337e+18", 290, "/-9\.22337e\+?[0]?18/iu"); +func_mysql_fetch_array($link, $engine, "FLOAT", NULL, NULL, 300); +func_mysql_fetch_array($link, $engine, "FLOAT UNSIGNED", 18446744073709551615 + 1.1, "1.84467e+19", 310, "/1\.84467e\+?[0]?19/iu"); +func_mysql_fetch_array($link, $engine, "FLOAT UNSIGNED ", NULL, NULL, 320); + +func_mysql_fetch_array($link, $engine, "DOUBLE(10,2)", -99999999.99, "-99999999.99", 330); +func_mysql_fetch_array($link, $engine, "DOUBLE(10,2)", NULL, NULL, 340); +func_mysql_fetch_array($link, $engine, "DOUBLE(10,2) UNSIGNED", 99999999.99, "99999999.99", 350); +func_mysql_fetch_array($link, $engine, "DOUBLE(10,2) UNSIGNED", NULL, NULL, 360); + +func_mysql_fetch_array($link, $engine, "DECIMAL(10,2)", -99999999.99, "-99999999.99", 370); +func_mysql_fetch_array($link, $engine, "DECIMAL(10,2)", NULL, NULL, 380); +func_mysql_fetch_array($link, $engine, "DECIMAL(10,2)", 99999999.99, "99999999.99", 390); +func_mysql_fetch_array($link, $engine, "DECIMAL(10,2)", NULL, NULL, 400); + +// don't care about date() strict TZ warnings... +func_mysql_fetch_array($link, $engine, "DATE", @date('Y-m-d'), @date('Y-m-d'), 410); +func_mysql_fetch_array($link, $engine, "DATE NOT NULL", @date('Y-m-d'), @date('Y-m-d'), 420); +func_mysql_fetch_array($link, $engine, "DATE", NULL, NULL, 430); + +func_mysql_fetch_array($link, $engine, "DATETIME", @date('Y-m-d H:i:s'), @date('Y-m-d H:i:s'), 440); +func_mysql_fetch_array($link, $engine, "DATETIME NOT NULL", @date('Y-m-d H:i:s'), @date('Y-m-d H:i:s'), 450); +func_mysql_fetch_array($link, $engine, "DATETIME", NULL, NULL, 460); + +func_mysql_fetch_array($link, $engine, "TIMESTAMP", @date('Y-m-d H:i:s'), @date('Y-m-d H:i:s'), 470); + +func_mysql_fetch_array($link, $engine, "TIME", @date('H:i:s'), @date('H:i:s'), 480); +func_mysql_fetch_array($link, $engine, "TIME NOT NULL", @date('H:i:s'), @date('H:i:s'), 490); +func_mysql_fetch_array($link, $engine, "TIME", NULL, NULL, 500); + +func_mysql_fetch_array($link, $engine, "YEAR", @date('Y'), @date('Y'), 510); +func_mysql_fetch_array($link, $engine, "YEAR NOT NULL", @date('Y'), @date('Y'), 520); +func_mysql_fetch_array($link, $engine, "YEAR", NULL, NULL, 530); + +$string255 = func_mysql_fetch_array_make_string(255); + +func_mysql_fetch_array($link, $engine, "CHAR(1)", "a", "a", 540); +func_mysql_fetch_array($link, $engine, "CHAR(255)", $string255, $string255, 550); +func_mysql_fetch_array($link, $engine, "CHAR(1) NOT NULL", "a", "a", 560); +func_mysql_fetch_array($link, $engine, "CHAR(1)", NULL, NULL, 570); + +$string65k = func_mysql_fetch_array_make_string(65400); + +func_mysql_fetch_array($link, $engine, "VARCHAR(1)", "a", "a", 580); +func_mysql_fetch_array($link, $engine, "VARCHAR(255)", $string255, $string255, 590); +func_mysql_fetch_array($link, $engine, "VARCHAR(65400)", $string65k, $string65k, 600); +func_mysql_fetch_array($link, $engine, "VARCHAR(1) NOT NULL", "a", "a", 610); +func_mysql_fetch_array($link, $engine, "VARCHAR(1)", NULL, NULL, 620); + +func_mysql_fetch_array($link, $engine, "BINARY(1)", "a", "a", 630, null , true); +func_mysql_fetch_array($link, $engine, "BINARY(1) NOT NULL", "b", "b", 650, null , true); +func_mysql_fetch_array($link, $engine, "BINARY(1)", NULL, NULL, 660, null , true); + +func_mysql_fetch_array($link, $engine, "VARBINARY(1)", "a", "a", 670, null , true); +func_mysql_fetch_array($link, $engine, "VARBINARY(1) NOT NULL", "b", "b", 690, null , true); +func_mysql_fetch_array($link, $engine, "VARBINARY(1)", NULL, NULL, 700, null , true); + +func_mysql_fetch_array($link, $engine, "TINYBLOB", "a", "a", 710, null , true); +func_mysql_fetch_array($link, $engine, "TINYBLOB NOT NULL", "b", "b", 730, null , true); +func_mysql_fetch_array($link, $engine, "TINYBLOB", NULL, NULL, 740, null , true); + +func_mysql_fetch_array($link, $engine, "TINYTEXT", "a", "a", 750); +func_mysql_fetch_array($link, $engine, "TINYTEXT NOT NULL", "a", "a", 760); +func_mysql_fetch_array($link, $engine, "TINYTEXT", NULL, NULL, 770); + +func_mysql_fetch_array($link, $engine, "BLOB", "a", "a", 780, null , true); +func_mysql_fetch_array($link, $engine, "BLOB", NULL, NULL, 790, null , true); + +func_mysql_fetch_array($link, $engine, "TEXT", "a", "a", 800); +func_mysql_fetch_array($link, $engine, "TEXT", NULL, NULL, 820); + +func_mysql_fetch_array($link, $engine, "MEDIUMBLOB", "a", "a", 830, null , true); +func_mysql_fetch_array($link, $engine, "MEDIUMBLOB", NULL, NULL, 850, null , true); + +func_mysql_fetch_array($link, $engine, "MEDIUMTEXT", "a", "a", 860); +func_mysql_fetch_array($link, $engine, "MEDIUMTEXT", NULL, NULL, 880); + +func_mysql_fetch_array($link, $engine, "LONGBLOB", "a", "a", 890, null , true); +func_mysql_fetch_array($link, $engine, "LONGBLOB", NULL, NULL, 910, null , true); + +func_mysql_fetch_array($link, $engine, "ENUM('a', 'b')", "a", "a", 920); +func_mysql_fetch_array($link, $engine, "ENUM('a', 'b')", NULL, NULL, 930); + +func_mysql_fetch_array($link, $engine, "SET('a', 'b')", "a", "a", 940); +func_mysql_fetch_array($link, $engine, "SET('a', 'b')", NULL, NULL, 950); + +mysql_close($link); + +if (false !== ($tmp = mysql_fetch_array($res, MYSQL_ASSOC))) +printf("[015] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +[005] +array(4) { + [0]=> + %unicode|string%(1) "1" + [%u|b%"id"]=> + %unicode|string%(1) "1" + [1]=> + %unicode|string%(1) "a" + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +[006] +array(2) { + [0]=> + %unicode|string%(1) "2" + [1]=> + %unicode|string%(1) "b" +} +[007] +array(4) { + [0]=> + %unicode|string%(1) "3" + [%u|b%"id"]=> + %unicode|string%(1) "3" + [1]=> + %unicode|string%(1) "c" + [%u|b%"label"]=> + %unicode|string%(1) "c" +} +[008] +array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "4" + [%u|b%"label"]=> + %unicode|string%(1) "d" +} +[009] +array(4) { + [0]=> + %unicode|string%(1) "5" + [%u|b%"id"]=> + %unicode|string%(1) "5" + [1]=> + %unicode|string%(1) "e" + [%u|b%"label"]=> + %unicode|string%(1) "e" +} +[011] +array(11) { + [0]=> + %unicode|string%(1) "1" + [%u|b%"a"]=> + %unicode|string%(1) "2" + [1]=> + %unicode|string%(1) "2" + [2]=> + %unicode|string%(1) "3" + [%u|b%"c"]=> + %unicode|string%(1) "3" + [3]=> + %unicode|string%(1) "4" + [%u|b%"C"]=> + %unicode|string%(1) "4" + [4]=> + NULL + [%u|b%"d"]=> + NULL + [5]=> + %unicode|string%(1) "1" + [%u|b%"e"]=> + %unicode|string%(1) "1" +} + +Warning: mysql_fetch_array(): The result type should be either MYSQL_NUM, MYSQL_ASSOC or MYSQL_BOTH in %s on line %d + +Warning: mysql_fetch_array(): %d is not a valid MySQL result resource in %s on line %d +done! diff --git a/ext/mysql/tests/mysql_fetch_assoc.phpt b/ext/mysql/tests/mysql_fetch_assoc.phpt new file mode 100644 index 0000000..3c5ca79 --- /dev/null +++ b/ext/mysql/tests/mysql_fetch_assoc.phpt @@ -0,0 +1,103 @@ +--TEST-- +mysql_fetch_assoc() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +// Note: no SQL type tests, internally the same function gets used as for mysql_fetch_array() which does a lot of SQL type test + +if (!is_null($tmp = @mysql_fetch_assoc())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (NULL !== ($tmp = @mysql_fetch_assoc($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); +if (!$res = mysql_query("SELECT id, label FROM test ORDER BY id LIMIT 1", $link)) { + printf("[004] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +print "[005]\n"; +var_dump(mysql_fetch_assoc($res)); + +print "[006]\n"; +var_dump(mysql_fetch_assoc($res)); + +mysql_free_result($res); + +if (!$res = mysql_query("SELECT 1 AS a, 2 AS a, 3 AS c, 4 AS C, NULL AS d, true AS e", $link)) { + printf("[007] Cannot run query, [%d] %s\n", mysql_errno($link), $mysql_error($link)); +} +print "[008]\n"; +var_dump(mysql_fetch_assoc($res)); + +mysql_free_result($res); + +if (false !== ($tmp = mysql_fetch_assoc($res))) + printf("[008] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +mysql_close($link); + +include('table.inc'); +if (!$res = mysql_query("SELECT id, label, id AS _id, CONCAT(label, 'a') _label, NULL as _foo FROM test _test ORDER BY id ASC LIMIT 1", $link)) { + printf("[009] [%d] %s\n", mysql_errno($link), $mysql_error($link)); +} +print "[010]\n"; +var_dump(mysql_fetch_assoc($res)); +mysql_free_result($res); + +mysql_close($link); + +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +[005] +array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +[006] +bool(false) +[008] +array(5) { + [%u|b%"a"]=> + %unicode|string%(1) "2" + [%u|b%"c"]=> + %unicode|string%(1) "3" + [%u|b%"C"]=> + %unicode|string%(1) "4" + [%u|b%"d"]=> + NULL + [%u|b%"e"]=> + %unicode|string%(1) "1" +} + +Warning: mysql_fetch_assoc(): %d is not a valid MySQL result resource in %s on line %d +[010] +array(5) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" + [%u|b%"_id"]=> + %unicode|string%(1) "1" + [%u|b%"_label"]=> + %unicode|string%(2) "aa" + [%u|b%"_foo"]=> + NULL +} +done! diff --git a/ext/mysql/tests/mysql_fetch_field.phpt b/ext/mysql/tests/mysql_fetch_field.phpt new file mode 100644 index 0000000..ef03279 --- /dev/null +++ b/ext/mysql/tests/mysql_fetch_field.phpt @@ -0,0 +1,277 @@ +--TEST-- +mysql_fetch_field() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + include "connect.inc"; + + $tmp = NULL; + $link = NULL; + + // Note: no SQL type tests, internally the same function gets used as for mysql_fetch_array() which does a lot of SQL type test + if (!is_null($tmp = @mysql_fetch_field())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + if (NULL !== ($tmp = @mysql_fetch_field($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + require('table.inc'); + + $version = mysql_get_server_info($link); + if (!preg_match('@(\d+)\.(\d+)\.(\d+)@ism', $version, $matches)) + printf("[003] Cannot get server version\n"); + $version = ($matches[1] * 100) + ($matches[2] * 10) + $matches[3]; + + if (!$res = mysql_query("SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1", $link)) { + printf("[004] [%d] %s\n", mysql_errno($link), mysql_error($link)); + } + + while ($tmp = mysql_fetch_field($res)) + var_dump($tmp); + var_dump($tmp); + + mysql_free_result($res); + + if (!$res = mysql_query("SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1", $link)) { + printf("[005] [%d] %s\n", mysql_errno($link), mysql_error($link)); + } + if (false !== ($tmp = mysql_fetch_field($res, PHP_INT_MAX - 1))) + printf("[006] Expecting boolean/false got %s/%s\n", gettype($tmp), var_export($tmp, true)); + + mysql_free_result($res); + + if (false !== ($tmp = mysql_fetch_field($res))) + printf("[007] Expecting boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); + + $types = array( + 'BIT' => array(1, 'int'), + 'TINYINT' => array(1, 'int'), + 'BOOL' => array('true', 'int'), + 'BOOL' => array(1, 'int'), + 'SMALLINT' => array(32767, 'int'), + 'MEDIUMINT' => array(8388607, 'int'), + 'INT' => array(100, 'int'), + 'BIGINT' => array(100, 'int'), + 'FLOAT' => array(100, 'real'), + 'DOUBLE' => array(100, 'real'), + 'DECIMAL' => array(100, 'real'), + 'DATE' => array(@date('Y-m-d'), 'date'), + 'DATETIME' => array(@date('Y-m-d H:i:s'), 'datetime'), + 'TIMESTAMP' => array(@date('Y-m-d H:i:s'), 'timestamp'), + 'TIME' => array(@date('H:i:s'), 'time'), + 'YEAR' => array(@date('Y'), 'year'), + 'CHAR(1)' => array('a', 'string'), + 'VARCHAR(1)' => array('a', 'string'), + 'BINARY(1)' => array('a', 'string'), + 'VARBINARY(1)' => array('a', 'string'), + 'TINYBLOB' => array('a', 'blob'), + 'TINYTEXT' => array('a', 'blob'), + 'BLOB' => array('a', 'blob'), + 'TEXT' => array('a', 'blob'), + 'MEDIUMBLOB' => array('a', 'blob'), + 'MEDIUMTEXT' => array('a', 'blob'), + 'LONGBLOB' => array('a', 'blob'), + 'LONGTEXT' => array('a', 'blob'), + 'ENUM("a", "b")' => array('a', 'string'), /* !!! */ + 'SET("a", "b")' => array('a', 'string'), /* !!! */ + ); + + foreach ($types as $type_name => $type_desc) { + if (!mysql_query("DROP TABLE IF EXISTS test", $link)) + printf("[008/%s] [%d] %s\n", $type_name, mysql_errno($link), mysql_error($link)); + if (!mysql_query(sprintf("CREATE TABLE test(id INT, label %s) ENGINE = %s", $type_name, $engine), $link)) { + // server and/or engine might not support the data type + continue; + } + + if (is_string($type_desc[0])) + $insert = sprintf("INSERT INTO test(id, label) VALUES (1, '%s')", $type_desc[0]); + else + $insert = sprintf("INSERT INTO test(id, label) VALUES (1, %s)", $type_desc[0]); + + if (!mysql_query($insert, $link)) { + if (1366 == mysql_errno($link)) { + /* Strict SQL mode - 1366, Incorrect integer value: 'true' for column 'label' at row 1 */ + continue; + } + printf("[009/%s] [%d] %s\n", $type_name, mysql_errno($link), mysql_error($link)); + continue; + } + if (!$res = mysql_query("SELECT id, label FROM test", $link)) { + printf("[010/%s] [%d] %s\n", $type_name, mysql_errno($link), mysql_error($link)); + continue; + } + if (!$tmp = mysql_fetch_field($res, 1)) { + printf("[011/%s] [%d] %s\n", $type_name, mysql_errno($link), mysql_error($link)); + } + + if ($type_desc[1] != $tmp->type) { + printf("[012/%s] Expecting type '%s' got '%s'\n", $type_name, $type_desc[1], $tmp->type); + } + mysql_free_result($res); + } + + if (!mysql_query("DROP TABLE IF EXISTS test", $link)) + printf("[013] [%d] %s\n", mysql_errno($link), mysql_error($link)); + + if (!mysql_query("CREATE TABLE test(id INT DEFAULT 1)")) + printf("[014] [%d] %s\n", mysql_errno($link), mysql_error($link)); + + if (!mysql_query("INSERT INTO test(id) VALUES (2)")) + printf("[015] [%d] %s\n", mysql_errno($link), mysql_error($link)); + + if (!$res = mysql_query("SELECT id FROM test", $link)) { + printf("[016] [%d] %s\n", mysql_errno($link), mysql_error($link)); + } + + var_dump(mysql_fetch_field($res)); + mysql_free_result($res); + + if (!$res = mysql_query("SELECT id FROM test", $link)) { + printf("[017] [%d] %s\n", mysql_errno($link), mysql_error($link)); + } + $res = mysql_list_fields($db, 'test'); + $found = false; + while ($tmp = mysql_fetch_field($res)) { + if ($tmp->name == 'id') { + printf("Fetch field from mysql_list_fields result set.\n"); + $found = true; + var_dump($tmp); + } + } + if (!$found) + printf("[018] mysqli_list_fields result set processing has failed.\n"); + + mysql_free_result($res); + + mysql_close($link); + print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(2) "ID" + [%u|b%"table"]=> + %unicode|string%(4) "TEST" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"max_length"]=> + int(1) + [%u|b%"not_null"]=> + int(1) + [%u|b%"primary_key"]=> + int(1) + [%u|b%"multiple_key"]=> + int(0) + [%u|b%"unique_key"]=> + int(0) + [%u|b%"numeric"]=> + int(1) + [%u|b%"blob"]=> + int(0) + [%u|b%"type"]=> + %unicode|string%(3) "int" + [%u|b%"unsigned"]=> + int(0) + [%u|b%"zerofill"]=> + int(0) +} +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(5) "label" + [%u|b%"table"]=> + %unicode|string%(4) "TEST" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"max_length"]=> + int(1) + [%u|b%"not_null"]=> + int(0) + [%u|b%"primary_key"]=> + int(0) + [%u|b%"multiple_key"]=> + int(0) + [%u|b%"unique_key"]=> + int(0) + [%u|b%"numeric"]=> + int(0) + [%u|b%"blob"]=> + int(0) + [%u|b%"type"]=> + %unicode|string%(6) "string" + [%u|b%"unsigned"]=> + int(0) + [%u|b%"zerofill"]=> + int(0) +} +bool(false) + +Warning: mysql_fetch_field(): Bad field offset in %s on line %d + +Warning: mysql_fetch_field(): %d is not a valid MySQL result resource in %s on line %d +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"max_length"]=> + int(1) + [%u|b%"not_null"]=> + int(0) + [%u|b%"primary_key"]=> + int(0) + [%u|b%"multiple_key"]=> + int(0) + [%u|b%"unique_key"]=> + int(0) + [%u|b%"numeric"]=> + int(1) + [%u|b%"blob"]=> + int(0) + [%u|b%"type"]=> + %unicode|string%(3) "int" + [%u|b%"unsigned"]=> + int(0) + [%u|b%"zerofill"]=> + int(0) +} +Fetch field from mysql_list_fields result set. +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(1) "1" + [%u|b%"max_length"]=> + int(0) + [%u|b%"not_null"]=> + int(0) + [%u|b%"primary_key"]=> + int(0) + [%u|b%"multiple_key"]=> + int(0) + [%u|b%"unique_key"]=> + int(0) + [%u|b%"numeric"]=> + int(1) + [%u|b%"blob"]=> + int(0) + [%u|b%"type"]=> + %unicode|string%(3) "int" + [%u|b%"unsigned"]=> + int(0) + [%u|b%"zerofill"]=> + int(0) +} +done! diff --git a/ext/mysql/tests/mysql_fetch_lengths.phpt b/ext/mysql/tests/mysql_fetch_lengths.phpt new file mode 100644 index 0000000..4793e26 --- /dev/null +++ b/ext/mysql/tests/mysql_fetch_lengths.phpt @@ -0,0 +1,52 @@ +--TEST-- +mysql_fetch_lengths() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (!is_null($tmp = @mysql_fetch_lengths())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (NULL !== ($tmp = @mysql_fetch_lengths($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); +if (!$res = mysql_query("SELECT id, label FROM test ORDER BY id LIMIT 1", $link)) { + printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +while ($row = mysql_fetch_assoc($res)) + var_dump(mysql_fetch_lengths($res)); +var_dump(mysql_fetch_lengths($res)); + +mysql_free_result($res); + +var_dump(mysql_fetch_lengths($res)); + +mysql_close($link); +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +array(2) { + [0]=> + int(1) + [1]=> + int(1) +} +bool(false) + +Warning: mysql_fetch_lengths(): %d is not a valid MySQL result resource in %s on line %d +bool(false) +done! diff --git a/ext/mysql/tests/mysql_fetch_object.phpt b/ext/mysql/tests/mysql_fetch_object.phpt new file mode 100644 index 0000000..c11631e --- /dev/null +++ b/ext/mysql/tests/mysql_fetch_object.phpt @@ -0,0 +1,152 @@ +--TEST-- +mysql_fetch_object() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (!is_null($tmp = @mysql_fetch_object())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (false !== ($tmp = @mysql_fetch_object($link))) + printf("[002] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); +if (!$res = mysql_query("SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 5", $link)) { + printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +var_dump(mysql_fetch_object($res)); + +class mysql_fetch_object_test { + + public $a = null; + public $b = null; + + public function toString() { + var_dump($this); + } +} + +var_dump(mysql_fetch_object($res, 'mysql_fetch_object_test')); + +class mysql_fetch_object_construct extends mysql_fetch_object_test { + + public function __construct($a, $b) { + $this->a = $a; + $this->b = $b; + } + +} + +var_dump(mysql_fetch_object($res, 'mysql_fetch_object_construct', null)); +var_dump(mysql_fetch_object($res, 'mysql_fetch_object_construct', array('a'))); +var_dump(mysql_fetch_object($res, 'mysql_fetch_object_construct', array('a', 'b'))); +var_dump(mysql_fetch_object($res, 'mysql_fetch_object_construct', array('a', 'b', 'c'))); +var_dump(mysql_fetch_object($res, 'mysql_fetch_object_construct', "no array and not null")); +var_dump(mysql_fetch_object($res)); +var_dump(mysql_fetch_object($res, 'mysql_fetch_object_construct', array('a', 'b'))); + +class mysql_fetch_object_private_construct { + private function __construct($a, $b) { + var_dump($a); + } +} +var_dump(mysql_fetch_object($res, 'mysql_fetch_object_private_construct', array('a', 'b'))); + +mysql_free_result($res); + +if (!$res = mysql_query("SELECT id AS ID, label FROM test AS TEST", $link)) { + printf("[009] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +mysql_free_result($res); + +var_dump(mysql_fetch_object($res)); + +// Fatal error, script execution will end +var_dump(mysql_fetch_object($res, 'this_class_does_not_exist')); + +mysql_close($link); +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +object(stdClass)#%d (2) { + [%u|b%"ID"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +object(mysql_fetch_object_test)#%d (4) { + [%u|b%"a"]=> + NULL + [%u|b%"b"]=> + NULL + [%u|b%"ID"]=> + %unicode|string%(1) "2" + [%u|b%"label"]=> + %unicode|string%(1) "b" +} + +Warning: Missing argument 1 for mysql_fetch_object_construct::__construct() in %s on line %d + +Warning: Missing argument 2 for mysql_fetch_object_construct::__construct() in %s on line %d + +Notice: Undefined variable: a in %s on line %d + +Notice: Undefined variable: b in %s on line %d +object(mysql_fetch_object_construct)#%d (4) { + [%u|b%"a"]=> + NULL + [%u|b%"b"]=> + NULL + [%u|b%"ID"]=> + %unicode|string%(1) "3" + [%u|b%"label"]=> + %unicode|string%(1) "c" +} + +Warning: Missing argument 2 for mysql_fetch_object_construct::__construct() in %s on line %d + +Notice: Undefined variable: b in %s on line %d +object(mysql_fetch_object_construct)#%d (4) { + [%u|b%"a"]=> + %unicode|string%(1) "a" + [%u|b%"b"]=> + NULL + [%u|b%"ID"]=> + %unicode|string%(1) "4" + [%u|b%"label"]=> + %unicode|string%(1) "d" +} +object(mysql_fetch_object_construct)#%d (4) { + [%u|b%"a"]=> + %unicode|string%(1) "a" + [%u|b%"b"]=> + %unicode|string%(1) "b" + [%u|b%"ID"]=> + %unicode|string%(1) "5" + [%u|b%"label"]=> + %unicode|string%(1) "e" +} +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) + +Warning: mysql_fetch_object(): %d is not a valid MySQL result resource in %s on line %d +bool(false) + +Fatal error: Class 'this_class_does_not_exist' not found in %s on line %d diff --git a/ext/mysql/tests/mysql_fetch_row.phpt b/ext/mysql/tests/mysql_fetch_row.phpt new file mode 100644 index 0000000..8d6b958 --- /dev/null +++ b/ext/mysql/tests/mysql_fetch_row.phpt @@ -0,0 +1,56 @@ +--TEST-- +mysql_fetch_row() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (!is_null($tmp = @mysql_fetch_row())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (NULL !== ($tmp = @mysql_fetch_row($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); +if (!$res = mysql_query("SELECT id, label FROM test ORDER BY id LIMIT 1", $link)) { + printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +print "[004]\n"; +var_dump(mysql_fetch_row($res)); + +print "[005]\n"; +var_dump(mysql_fetch_row($res)); + +mysql_free_result($res); + +var_dump(mysql_fetch_row($res)); + +mysql_close($link); +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +[004] +array(2) { + [0]=> + %unicode|string%(1) "1" + [1]=> + %unicode|string%(1) "a" +} +[005] +bool(false) + +Warning: mysql_fetch_row(): %d is not a valid MySQL result resource in %s on line %d +bool(false) +done!
\ No newline at end of file diff --git a/ext/mysql/tests/mysql_field_flags.phpt b/ext/mysql/tests/mysql_field_flags.phpt new file mode 100644 index 0000000..e07e041 --- /dev/null +++ b/ext/mysql/tests/mysql_field_flags.phpt @@ -0,0 +1,155 @@ +--TEST-- +mysql_field_flags() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (!is_null($tmp = @mysql_field_flags())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (null !== ($tmp = @mysql_field_flags($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); +if (!$res = mysql_query("SELECT id, label FROM test ORDER BY id LIMIT 2", $link)) { + printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +if (NULL !== ($tmp = mysql_field_flags($res))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (false !== ($tmp = mysql_field_flags($res, -1))) + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +if (!is_string($tmp = mysql_field_flags($res, 0)) || empty($tmp)) + printf("[006] Expecting non empty string, got %s/%s\n", gettype($tmp), $tmp); + +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($tmp)) { + printf("[007] Check the unicode support!\n"); + var_inspect($tmp); +} + +if (false !== ($tmp = mysql_field_flags($res, 2))) + printf("[008] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +mysql_free_result($res); + +$version = mysql_get_server_info($link); +if (!preg_match('@(\d+)\.(\d+)\.(\d+)@ism', $version, $matches)) + printf("[009] Cannot get server version\n"); +$version = ($matches[1] * 100) + ($matches[2] * 10) + $matches[3]; + +$tables = array( + 'label INT, UNIQUE KEY (label)' => array( + array('label', '1'), + 'label' => array(($version < 500) ? 'multiple_key' : 'unique_key') + ), + 'labela INT, label2 CHAR(1), KEY keyname (labela, label2)' => array( + array('labela, label2', "1, 'a'"), + 'labela' => array('multiple_key'), + ), + 'label1 BLOB' => array( + array('label1', "'blob'"), + 'label1' => array('blob', 'binary'), + ), + 'label1 INT UNSIGNED' => array( + array('label1', '100'), + 'label1' => array('unsigned'), + ), + 'label1 INT UNSIGNED NOT NULL AUTO INCREMENT' => array( + array('label1', '100'), + 'label1' => array('auto_increment', + 'unsigned'), + ), + 'label1 ENUM("a", "b")' => array( + array('label1', "'a'"), + 'label1' => array('enum'), + ), + 'label1 SET("a", "b")' => array( + array('label1', "'a'"), + 'label1' => array('set'), + ), + 'label1 TIMESTAMP' => array( + array('label1', sprintf("'%s'", @date("Y-m-d H:i:s"))), + 'label1' => array( + 'timestamp', + 'binary', + 'not_null'), + ), +); + +if ($version < 560) { + $tables['label1 TIMESTAMP']['label1'][] = 'zerofill'; + $tables['label1 TIMESTAMP']['label1'][] = 'unsigned'; +} + + +foreach ($tables as $columns => $expected) { + if (!mysql_query("DROP TABLE IF EXISTS test", $link)) { + printf("[010/%s] [%d] %s\n", $columns, mysql_errno($link), mysql_error($link)); + continue; + } + $sql = sprintf("CREATE TABLE test(id INT, %s) ENGINE = %s", $columns, $engine); + if (!@mysql_query($sql, $link)) { + // server or engine might not support this + continue; + } + + reset($expected); + list($k, $values) = each($expected); + $sql = sprintf("INSERT INTO test(id, %s) VALUES (1, %s)", $values[0], $values[1]); + if (!mysql_query($sql, $link)) { + printf("[011/%s] '%s', [%d] %s\n", $columns, $sql, mysql_errno($link), mysql_error($link)); + continue; + } + + if (!$res = mysql_query(sprintf("SELECT id, %s FROM test", $values[0]), $link)) { + printf("[012/%s] [%d] %s\n", $columns, mysql_errno($link), mysql_error($link)); + continue; + } + + $i = 1; + while (list($field, $flags) = each($expected)) { + $tmp = mysql_field_flags($res, $i++); + + foreach ($flags as $k => $flag) { + if (!preg_match(sprintf('@\s*%s\s*@ismU', $flag), $tmp)) { + printf("[013/%s] Field '%s', flag '%s' not found, [%d] %s\n", $columns, $field, $flag, mysql_errno($link), mysql_error($link)); + } + } + foreach ($flags as $k => $flag) { + $tmp = preg_replace(sprintf('@\s*%s\s*@ismU', $flag), '', $tmp); + } + if ('' != $tmp) + printf("[014/%s] Field '%s', unexpected flags '%s' found, [%d] %s\n", $columns, $field, $tmp, mysql_errno($link), mysql_error($link)); + } + mysql_free_result($res); +} + +var_dump(mysql_field_flags($res, 0)); + +mysql_close($link); +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysql_field_flags() expects exactly 2 parameters, 1 given in %s on line %d + +Warning: mysql_field_flags(): Field -1 is invalid for MySQL result index %d in %s on line %d + +Warning: mysql_field_flags(): Field 2 is invalid for MySQL result index %d in %s on line %d + +Warning: mysql_field_flags(): %d is not a valid MySQL result resource in %s on line %d +bool(false) +done! diff --git a/ext/mysql/tests/mysql_field_len.phpt b/ext/mysql/tests/mysql_field_len.phpt new file mode 100644 index 0000000..a740c62 --- /dev/null +++ b/ext/mysql/tests/mysql_field_len.phpt @@ -0,0 +1,58 @@ +--TEST-- +mysql_field_len() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (!is_null($tmp = @mysql_field_len())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (null !== ($tmp = @mysql_field_len($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); +if (!$res = mysql_query("SELECT id, label FROM test ORDER BY id LIMIT 2", $link)) { + printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +if (NULL !== ($tmp = mysql_field_len($res))) +printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (false !== ($tmp = mysql_field_len($res, -1))) + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +if (!is_int($tmp = mysql_field_len($res, 0)) || empty($tmp)) + printf("[006] Expecting non empty integer, got %s/%s\n", gettype($tmp), $tmp); + +if (false !== ($tmp = mysql_field_len($res, 2))) + printf("[008] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +mysql_free_result($res); + +var_dump(mysql_field_len($res, 0)); + +mysql_close($link); +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysql_field_len() expects exactly 2 parameters, 1 given in %s on line %d + +Warning: mysql_field_len(): Field -1 is invalid for MySQL result index %d in %s on line %d + +Warning: mysql_field_len(): Field 2 is invalid for MySQL result index %d in %s on line %d + +Warning: mysql_field_len(): %d is not a valid MySQL result resource in %s on line %d +bool(false) +done! diff --git a/ext/mysql/tests/mysql_field_name.phpt b/ext/mysql/tests/mysql_field_name.phpt new file mode 100644 index 0000000..c87ac18 --- /dev/null +++ b/ext/mysql/tests/mysql_field_name.phpt @@ -0,0 +1,58 @@ +--TEST-- +mysql_field_name() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (!is_null($tmp = @mysql_field_name())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (null !== ($tmp = @mysql_field_name($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); +if (!$res = mysql_query("SELECT id, label FROM test ORDER BY id LIMIT 2", $link)) { + printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +if (NULL !== ($tmp = mysql_field_name($res))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (false !== ($tmp = mysql_field_name($res, -1))) + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +var_dump(mysql_field_name($res, 0)); + +if (false !== ($tmp = mysql_field_name($res, 2))) + printf("[008] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +mysql_free_result($res); + +var_dump(mysql_field_name($res, 0)); + +mysql_close($link); +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysql_field_name() expects exactly 2 parameters, 1 given in %s on line %d + +Warning: mysql_field_name(): Field -1 is invalid for MySQL result index %d in %s on line %d +%unicode|string%(2) "id" + +Warning: mysql_field_name(): Field 2 is invalid for MySQL result index %d in %s on line %d + +Warning: mysql_field_name(): %d is not a valid MySQL result resource in %s on line %d +bool(false) +done! diff --git a/ext/mysql/tests/mysql_field_seek.phpt b/ext/mysql/tests/mysql_field_seek.phpt new file mode 100644 index 0000000..7e8b313 --- /dev/null +++ b/ext/mysql/tests/mysql_field_seek.phpt @@ -0,0 +1,142 @@ +--TEST-- +mysql_field_seek() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (!is_null($tmp = @mysql_field_seek())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (!is_null($tmp = @mysql_field_seek($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); +if (!$res = mysql_query("SELECT id, label FROM test ORDER BY id LIMIT 1", $link)) { + printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +var_dump(mysql_field_seek($res, -1)); +var_dump(mysql_fetch_field($res)); +var_dump(mysql_field_seek($res, 0)); +var_dump(mysql_fetch_field($res)); +var_dump(mysql_field_seek($res, 1)); +var_dump(mysql_fetch_field($res)); +var_dump(mysql_field_seek($res, 2)); +var_dump(mysql_fetch_field($res)); + +mysql_free_result($res); + +var_dump(mysql_field_seek($res, 0)); + +mysql_close($link); +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysql_field_seek(): Field -1 is invalid for MySQL result index %d in %s on line %d +bool(false) +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"max_length"]=> + int(1) + [%u|b%"not_null"]=> + int(1) + [%u|b%"primary_key"]=> + int(1) + [%u|b%"multiple_key"]=> + int(0) + [%u|b%"unique_key"]=> + int(0) + [%u|b%"numeric"]=> + int(1) + [%u|b%"blob"]=> + int(0) + [%u|b%"type"]=> + %unicode|string%(3) "int" + [%u|b%"unsigned"]=> + int(0) + [%u|b%"zerofill"]=> + int(0) +} +bool(true) +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"max_length"]=> + int(1) + [%u|b%"not_null"]=> + int(1) + [%u|b%"primary_key"]=> + int(1) + [%u|b%"multiple_key"]=> + int(0) + [%u|b%"unique_key"]=> + int(0) + [%u|b%"numeric"]=> + int(1) + [%u|b%"blob"]=> + int(0) + [%u|b%"type"]=> + %unicode|string%(3) "int" + [%u|b%"unsigned"]=> + int(0) + [%u|b%"zerofill"]=> + int(0) +} +bool(true) +object(stdClass)#%d (13) { + [%u|b%"name"]=> + %unicode|string%(5) "label" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"max_length"]=> + int(1) + [%u|b%"not_null"]=> + int(0) + [%u|b%"primary_key"]=> + int(0) + [%u|b%"multiple_key"]=> + int(0) + [%u|b%"unique_key"]=> + int(0) + [%u|b%"numeric"]=> + int(0) + [%u|b%"blob"]=> + int(0) + [%u|b%"type"]=> + %unicode|string%(6) "string" + [%u|b%"unsigned"]=> + int(0) + [%u|b%"zerofill"]=> + int(0) +} + +Warning: mysql_field_seek(): Field %d is invalid for MySQL result index %d in %s on line %d +bool(false) +bool(false) + +Warning: mysql_field_seek(): %d is not a valid MySQL result resource in %s on line %d +bool(false) +done! diff --git a/ext/mysql/tests/mysql_field_table.phpt b/ext/mysql/tests/mysql_field_table.phpt new file mode 100644 index 0000000..707d1df --- /dev/null +++ b/ext/mysql/tests/mysql_field_table.phpt @@ -0,0 +1,58 @@ +--TEST-- +mysql_field_table() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (!is_null($tmp = @mysql_field_table())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (null !== ($tmp = @mysql_field_table($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); +if (!$res = mysql_query("SELECT id, label FROM test ORDER BY id LIMIT 2", $link)) { + printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +if (NULL !== ($tmp = mysql_field_table($res))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (false !== ($tmp = mysql_field_table($res, -1))) + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +var_dump(mysql_field_table($res, 0)); + +if (false !== ($tmp = mysql_field_table($res, 2))) + printf("[008] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +mysql_free_result($res); + +var_dump(mysql_field_table($res, 0)); + +mysql_close($link); +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysql_field_table() expects exactly 2 parameters, 1 given in %s on line %d + +Warning: mysql_field_table(): Field -1 is invalid for MySQL result index %d in %s on line %d +%unicode|string%(4) "test" + +Warning: mysql_field_table(): Field 2 is invalid for MySQL result index %d in %s on line %d + +Warning: mysql_field_table(): %d is not a valid MySQL result resource in %s on line %d +bool(false) +done! diff --git a/ext/mysql/tests/mysql_field_type.phpt b/ext/mysql/tests/mysql_field_type.phpt new file mode 100644 index 0000000..c737b4e --- /dev/null +++ b/ext/mysql/tests/mysql_field_type.phpt @@ -0,0 +1,58 @@ +--TEST-- +mysql_field_type() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (!is_null($tmp = @mysql_field_type())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (null !== ($tmp = @mysql_field_type($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); +if (!$res = mysql_query("SELECT id, label FROM test ORDER BY id LIMIT 2", $link)) { + printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +if (NULL !== ($tmp = mysql_field_type($res))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (false !== ($tmp = mysql_field_type($res, -1))) + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +var_dump(mysql_field_type($res, 0)); + +if (false !== ($tmp = mysql_field_type($res, 2))) + printf("[008] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +mysql_free_result($res); + +var_dump(mysql_field_type($res, 0)); + +mysql_close($link); +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysql_field_type() expects exactly 2 parameters, 1 given in %s on line %d + +Warning: mysql_field_type(): Field -1 is invalid for MySQL result index %d in %s on line %d +%unicode|string%(3) "int" + +Warning: mysql_field_type(): Field 2 is invalid for MySQL result index %d in %s on line %d + +Warning: mysql_field_type(): %d is not a valid MySQL result resource in %s on line %d +bool(false) +done! diff --git a/ext/mysql/tests/mysql_free_result.phpt b/ext/mysql/tests/mysql_free_result.phpt new file mode 100644 index 0000000..fe132d8 --- /dev/null +++ b/ext/mysql/tests/mysql_free_result.phpt @@ -0,0 +1,51 @@ +--TEST-- +mysql_free_result() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (!is_null($tmp = @mysql_free_result())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (null !== ($tmp = @mysql_free_result($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); +if (!$res = mysql_query("SELECT id FROM test ORDER BY id LIMIT 1", $link)) { + printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +var_dump(mysql_free_result($res)); +var_dump(mysql_free_result($res)); + +if ($tmp = sys_get_temp_dir()) { + $tmpname = tempnam($tmp, 'free_result'); + if ($fp = fopen($tmpname, 'w')) { + if (false !== ($tmp = @mysql_free_result($fp))) + printf("[004] Expecting boolean/false got %s/%s\n", gettype($tmp), $tmp); + fclose($fp); + @unlink($tmpname); + } +} + +mysql_close($link); +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +bool(true) + +Warning: mysql_free_result(): %d is not a valid MySQL result resource in %s on line %d +bool(false) +done! diff --git a/ext/mysql/tests/mysql_get_client_info.phpt b/ext/mysql/tests/mysql_get_client_info.phpt new file mode 100644 index 0000000..95de0ad --- /dev/null +++ b/ext/mysql/tests/mysql_get_client_info.phpt @@ -0,0 +1,23 @@ +--TEST-- +mysql_get_client_info() +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +include "connect.inc"; +if (!is_string($info = mysql_get_client_info()) || ('' === $info)) + printf("[001] Expecting string/any_non_empty, got %s/%s\n", gettype($info), $info); + +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($info)) { + printf("[002] Expecting Unicode!\n"); + var_inspect($info); +} + +if (!is_null($tmp = @mysql_get_client_info("too many arguments"))) { + printf("[003] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp)); +} + +print "done!"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysql/tests/mysql_get_host_info.phpt b/ext/mysql/tests/mysql_get_host_info.phpt new file mode 100644 index 0000000..443910c --- /dev/null +++ b/ext/mysql/tests/mysql_get_host_info.phpt @@ -0,0 +1,44 @@ +--TEST-- +mysql_get_host_info() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include_once "connect.inc"; + +if (NULL !== ($tmp = @mysql_get_host_info(NULL))) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require "table.inc"; +if (!is_string($info = mysql_get_host_info($link)) || ('' === $info)) + printf("[003] Expecting string/any_non_empty, got %s/%s\n", gettype($info), $info); + +$def_info = mysql_get_host_info(); +if ($def_info !== $info) { + printf("[004] Host info for the default link and the specified link differ, [%d] %s\n", + mysql_errno(), mysql_error()); + + var_dump($def_info); + var_dump($info); +} + +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($info)) { + printf("[005] Expecting Unicode error message!\n"); + var_inspect($info); +} + +if (!is_null($tmp = @mysql_get_host_info($link, "too many arguments"))) { + printf("[006] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp)); +} + +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +done! diff --git a/ext/mysql/tests/mysql_get_proto_info.phpt b/ext/mysql/tests/mysql_get_proto_info.phpt new file mode 100644 index 0000000..043fb62 --- /dev/null +++ b/ext/mysql/tests/mysql_get_proto_info.phpt @@ -0,0 +1,34 @@ +--TEST-- +mysql_get_proto_info() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include_once "connect.inc"; + +if (NULL !== ($tmp = @mysql_get_proto_info(NULL))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require "table.inc"; +if (!is_int($info = mysql_get_proto_info($link)) || (0 === $info)) + printf("[003] Expecting int/any_non_empty, got %s/%s\n", gettype($info), $info); + +if (!is_int($info2 = mysql_get_proto_info()) || (0 === $info2)) + printf("[004] Expecting int/any_non_empty, got %s/%s\n", gettype($info2), $info2); + +assert($info === $info2); + +if (NULL !== ($tmp = @mysql_get_proto_info('too many', 'arguments'))) + printf("[005] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +done! diff --git a/ext/mysql/tests/mysql_get_server_info.phpt b/ext/mysql/tests/mysql_get_server_info.phpt new file mode 100644 index 0000000..e806335 --- /dev/null +++ b/ext/mysql/tests/mysql_get_server_info.phpt @@ -0,0 +1,39 @@ +--TEST-- +mysql_get_server_info() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +if (null !== ($tmp = @mysql_get_server_info(NULL))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require "table.inc"; +if (!is_string($info = mysql_get_server_info($link)) || ('' === $info)) + printf("[003] Expecting string/any_non_empty, got %s/%s\n", gettype($info), $info); + +$def_info = mysql_get_server_info(); +if ($def_info !== $info) { + printf("[004] Server info for the default link and the specified link differ, [%d] %s\n", + mysql_errno(), mysql_error()); + + var_dump($def_info); + var_dump($info); +} + +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($info)) { + printf("[005] Expecting Unicode error message!\n"); + var_inspect($info); +} + +if (NULL !== ($tmp = @mysql_get_server_info('too many', 'just too many'))) + printf("[006] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + +print "done!"; +?> +--EXPECTF-- +done! diff --git a/ext/mysql/tests/mysql_info.phpt b/ext/mysql/tests/mysql_info.phpt new file mode 100644 index 0000000..464578c --- /dev/null +++ b/ext/mysql/tests/mysql_info.phpt @@ -0,0 +1,73 @@ +--TEST-- +mysql_info() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +if (false !== ($tmp = @mysql_info())) + printf("[001] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +if (NULL !== ($tmp = @mysql_info(NULL))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require "table.inc"; +if (!$res = mysql_query("INSERT INTO test(id, label) VALUES (100, 'a')", $link)) + printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (false !== ($tmp = mysql_info($link))) + printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +if (!$res = mysql_query("INSERT INTO test(id, label) VALUES (101, 'a'), (102, 'b')", $link)) + printf("[005] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (!is_string($tmp = mysql_info($link)) || ('' == $tmp)) + printf("[006] Expecting string/any_non_empty, got %s/%s\n", gettype($tmp), $tmp); + +if (!$res = mysql_query('INSERT INTO test(id, label) SELECT id + 200, label FROM test', $link)) + printf("[007] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (!is_string($tmp = mysql_info($link)) || ('' == $tmp)) + printf("[008] Expecting string/any_non_empty, got %s/%s\n", gettype($tmp), $tmp); + +if (!$res = mysql_query('ALTER TABLE test MODIFY label CHAR(2)', $link)) + printf("[009] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (!is_string($tmp = mysql_info($link)) || ('' == $tmp)) + printf("[010] Expecting string/any_non_empty, got %s/%s\n", gettype($tmp), $tmp); + +if (!$res = mysql_query("UPDATE test SET label = 'b' WHERE id >= 100", $link)) + printf("[011] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (!is_string($tmp = mysql_info($link)) || ('' == $tmp)) + printf("[012] Expecting string/any_non_empty, got %s/%s\n", gettype($tmp), $tmp); + +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($tmp)) { + printf("[013] Expecting Unicode!\n"); + var_inspect($info); +} + +if (!is_string($def_tmp = mysql_info()) || ('' == $def_tmp)) + printf("[014] Expecting string/any_non_empty, got %s/%s\n", gettype($def_tmp), $def_tmp); + +if ($def_tmp !== $tmp) { + printf("[015] Results differ for default link and specified link, [%d] %s\n", + mysql_errno(), mysql_error()); + var_inspect($tmp); + var_inspect($def_tmp); +} + +// NOTE: no LOAD DATA INFILE test + +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysql/tests/mysql_insert_id.phpt b/ext/mysql/tests/mysql_insert_id.phpt new file mode 100644 index 0000000..460d9f3 --- /dev/null +++ b/ext/mysql/tests/mysql_insert_id.phpt @@ -0,0 +1,71 @@ +--TEST-- +mysql_insert_id() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; +include 'setupdefault.inc'; + +$tmp = NULL; +$link = NULL; + +if (0 !== ($tmp = @mysql_insert_id())) + printf("[001] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + +if (NULL !== ($tmp = @mysql_insert_id($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (!is_null($tmp = @mysql_insert_id($link, 'too many args'))) + printf("[002a] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); + +if (0 !== ($tmp = mysql_insert_id($link))) + printf("[003] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + +if (!$res = mysql_query("SELECT id, label FROM test ORDER BY id LIMIT 1", $link)) { + printf("[004] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} +if (0 !== ($tmp = mysql_insert_id($link))) + printf("[005] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); +mysql_free_result($res); + +// no auto_increment column +if (!$res = mysql_query("INSERT INTO test(id, label) VALUES (100, 'a')", $link)) { + printf("[006] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} +if (0 !== ($tmp = mysql_insert_id($link))) + printf("[007] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp); + +if (!$res = mysql_query("ALTER TABLE test MODIFY id INT NOT NULL AUTO_INCREMENT", $link)) { + printf("[008] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} +if (!$res = mysql_query("INSERT INTO test(label) VALUES ('a')", $link)) { + printf("[009] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} +if (0 === ($tmp = mysql_insert_id($link))) + printf("[010] Expecting int/not zero, got %s/%s\n", gettype($tmp), $tmp); + +if ($tmp !== ($tmp2 = mysql_insert_id())) + printf("[011] Expecting %s/%s, got %s/%s\n", + gettype($tmp), $tmp, + gettype($tmp2), $tmp2); + +mysql_close($link); + +var_dump(mysql_insert_id($link)); + +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysql_insert_id(): %d is not a valid MySQL-Link resource in %s on line %d +bool(false) +done! diff --git a/ext/mysql/tests/mysql_list_dbs.phpt b/ext/mysql/tests/mysql_list_dbs.phpt new file mode 100644 index 0000000..054e02e --- /dev/null +++ b/ext/mysql/tests/mysql_list_dbs.phpt @@ -0,0 +1,54 @@ +--TEST-- +mysql_list_dbs() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include_once "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (NULL !== ($tmp = @mysql_list_dbs(NULL))) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (NULL !== ($tmp = @mysql_list_dbs($link, $link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); + +if (!$res = @mysql_list_dbs($link)) + printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (!$num = mysql_num_rows($res)) + printf("[004] Empty database list? [%d] %s\n", mysql_errno($link), mysql_error($link)); + +$row = mysql_fetch_array($res, MYSQL_NUM); +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($row[0])) { + printf("[005] Check for unicode support\n"); + var_inspect($row); +} + +mysql_free_result($res); + +if (!$res2 = @mysql_list_dbs()) + printf("[006] [%d] %s\n", mysql_errno(), mysql_error()); + +$row2 = mysql_fetch_array($res2, MYSQL_NUM); +mysql_free_result($res2); + +assert($row === $row2); + +mysql_close($link); + +print "done!\n"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysql/tests/mysql_list_fields.phpt b/ext/mysql/tests/mysql_list_fields.phpt new file mode 100644 index 0000000..e0b3fd5 --- /dev/null +++ b/ext/mysql/tests/mysql_list_fields.phpt @@ -0,0 +1,79 @@ +--TEST-- +mysql_list_fields() +--SKIPIF-- +<?php +require_once 'skipif.inc'; +require_once 'skipifconnectfailure.inc'; +?> +--FILE-- +<?php +require_once 'connect.inc'; + +$tmp = NULL; +$link = NULL; + +require 'table.inc'; + +if (!$res = mysql_list_fields($db, 'test', $link)) + printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (2 !== ($num = mysql_num_fields($res))) + printf("[004] Expecting two fields from 'test', got %d. [%d] %s\n", $num, mysql_errno($link), mysql_error($link)); + +mysql_free_result($res); + +if (!mysql_query("DROP TABLE IF EXISTS test2", $link)) + printf("[005] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (!$res = @mysql_list_fields($db, 'test2', $link)) + printf("[006] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (!$res = mysql_list_fields($db, 'test', $link)) + printf("[007] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (2 !== ($num = mysql_num_fields($res))) + printf("[008] Expecting 2 fields from 'test', got %d. [%d] %s\n", $num, mysql_errno($link), mysql_error($link)); + +var_dump(mysql_fetch_assoc($res)); +for ($field_offset = 0; $field_offset < mysql_num_fields($res); $field_offset++) { + printf("Field Offset %d\n", $field_offset); + printf("mysql_field_flags(): %s\n", mysql_field_flags($res, $field_offset)); + printf("mysql_field_len(): %s\n", mysql_field_len($res, $field_offset)); + printf("mysql_field_name(): %s\n", mysql_field_name($res, $field_offset)); + printf("mysql_field_type(): %s\n", mysql_field_type($res, $field_offset)); +} + +mysql_free_result($res); +mysql_close($link); + +print "done!"; +?> +--CLEAN-- +<?php +require_once 'connect.inc'; +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[c001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + +if (!mysql_query("DROP TABLE IF EXISTS test", $link)) + printf("[c002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +if (!mysql_query("DROP TABLE IF EXISTS test2", $link)) + printf("[c002] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + +mysql_close($link); +?> +--EXPECTF-- +[006] [%d] %s +bool(false) +Field Offset 0 +mysql_field_flags()%s +mysql_field_len(): 11 +mysql_field_name(): id +mysql_field_type(): int +Field Offset 1 +mysql_field_flags()%s +mysql_field_len(): 1 +mysql_field_name(): label +mysql_field_type(): string +done! diff --git a/ext/mysql/tests/mysql_list_processes.phpt b/ext/mysql/tests/mysql_list_processes.phpt new file mode 100644 index 0000000..b0c71ad --- /dev/null +++ b/ext/mysql/tests/mysql_list_processes.phpt @@ -0,0 +1,52 @@ +--TEST-- +mysql_list_processes() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (NULL !== ($tmp = @mysql_list_processes($link, $link))) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); + +if (!$res = mysql_list_processes($link)) + printf("[002] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (!$num = mysql_num_rows($res)) + printf("[003] Empty process list? [%d] %s\n", mysql_errno($link), mysql_error($link)); + +$row = mysql_fetch_array($res, MYSQL_NUM); +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($row[0])) { + printf("[004] Check for unicode support\n"); + var_inspect($row); +} + +mysql_free_result($res); + +if (!$res = mysql_list_processes()) + printf("[005] [%d] %s\n", mysql_errno(), mysql_error()); + +if (!$num = mysql_num_rows($res)) + printf("[006] Empty process list? [%d] %s\n", mysql_errno(), mysql_error()); + +$row = mysql_fetch_array($res, MYSQL_NUM); +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($row[0])) { + printf("[007] Check for unicode support\n"); + var_inspect($row); +} + +mysql_free_result($res); +mysql_close($link); + +print "done!\n"; +?> +--EXPECTF-- +done!
\ No newline at end of file diff --git a/ext/mysql/tests/mysql_list_tables.phpt b/ext/mysql/tests/mysql_list_tables.phpt new file mode 100644 index 0000000..cf0b1a6 --- /dev/null +++ b/ext/mysql/tests/mysql_list_tables.phpt @@ -0,0 +1,85 @@ +--TEST-- +mysql_list_tables() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include_once "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (NULL !== ($tmp = @mysql_list_tables())) + printf("[001] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + +if (NULL !== ($tmp = @mysql_list_tables('too', 'many', 'arguments'))) + printf("[002] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + +if (false !== ($tmp = @mysql_list_tables(NULL))) + printf("[003] Expecting boolean/false got %s/%s\n", gettype($tmp), $tmp); + +if (NULL !== ($tmp = @mysql_list_tables($db, NULL))) + printf("[004] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + +require_once('table.inc'); + +if (!$res_def = @mysql_list_tables($db)) + printf("[005] [%d] %s\n", mysql_errno(), mysql_error()); + +if (!$res = @mysql_list_tables($db, $link)) + printf("[006] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (!$res_query = mysql_query("SHOW TABLES", $link)) + printf("[007] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +$tables_def = $tables = $tables_query = array(); + +while ($row = mysql_fetch_assoc($res_def)) + $tables_def[] = $row; +mysql_free_result($res_def); + +while ($row = mysql_fetch_assoc($res)) + $tables[] = $row; +mysql_free_result($res); + +while ($row = mysql_fetch_assoc($res_query)) + $tables_query[] = $row; +mysql_free_result($res_query); + +if ($tables_def !== $tables) { + printf("[008] Got different table lists for default link and specified link\n"); + var_dump($tables_def); + var_dump($tables); +} + +$list1 = $list2 = array(); +foreach ($tables as $k => $tlist) + foreach ($tlist as $k => $table) + $list1[] = $table; + +foreach ($tables_query as $k => $tlist) + foreach ($tlist as $k => $table) + $list2[] = $table; + +if ($list1 !== $list2) { + printf("[009] Got different results for mysql_list_tables() and SHOW TABLES\n"); + var_dump($list1); + var_dump($list2); +} + +if (!in_array('test', $list1)) + printf("[010] Table lists seem to be wrong. Check manually.\n"); + +mysql_close($link); + +print "done!\n"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +done! diff --git a/ext/mysql/tests/mysql_max_links.phpt b/ext/mysql/tests/mysql_max_links.phpt new file mode 100644 index 0000000..52ecd0a --- /dev/null +++ b/ext/mysql/tests/mysql_max_links.phpt @@ -0,0 +1,70 @@ +--TEST-- +mysql_[p]connect() - max_links/max_persistent +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +mysql.max_links=2 +--FILE-- +<?php +require_once('connect.inc'); + +function my_connect($offset, $host, $user, $passwd, $db, $port, $socket) { + if ($socket) + $host = sprintf("%s:%s", $host, $socket); + else if ($port) + $host = sprintf("%s:%s", $host, $port); + + $link = mysql_connect($host, $user, $passwd, true); + + if (!$link) { + printf("[%03d] Cannot connect using host '%s', user '%s', password '****', [%d] %s\n", + $offset, $host, $user, $passwd, + mysql_errno(), mysql_error()); + return false; + } + + return $link; +} + +$links = array(); + +// try to open 3 links +$links[0] = my_connect(10, $host, $user, $passwd, $db, $port, $socket); +$links[1] = my_connect(20, $host, $user, $passwd, $db, $port, $socket); +$links[2] = my_connect(30, $host, $user, $passwd, $db, $port, $socket); +if (false !== $links[2]) + printf("[040] Last connection should not have been allowed!\n"); + +// free some links but let index 1 remain +unset($links[2]); +mysql_close($links[0]); +unset($links[0]); + +// should be allowed -> second open connection +$links[0] = my_connect(50, $host, $user, $passwd, $db, $port, $socket); +$links[2] = my_connect(60, $host, $user, $passwd, $db, $port, $socket); +ksort($links); +var_dump($links); + +mysql_close($links[0]); +mysql_close($links[1]); +print "done!\n"; +?> +--EXPECTF-- +Warning: mysql_connect(): Too many open links (2) in %s on line %s +[030] Cannot connect using host '%s', user '%s', password '****', [0] 0 + +Warning: mysql_connect(): Too many open links (2) in %s on line %s +[060] Cannot connect using host '%s', user '%s', password '****', [0] 0 +array(3) { + [0]=> + resource(%d) of type (mysql link) + [1]=> + resource(%d) of type (mysql link) + [2]=> + bool(false) +} +done!
\ No newline at end of file diff --git a/ext/mysql/tests/mysql_max_persistent.phpt b/ext/mysql/tests/mysql_max_persistent.phpt new file mode 100644 index 0000000..ac35cd1 --- /dev/null +++ b/ext/mysql/tests/mysql_max_persistent.phpt @@ -0,0 +1,99 @@ +--TEST-- +mysql_[p]connect() - max_links/max_persistent +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +require_once('table.inc'); + +mysql_query('DROP USER pcontest', $link); +if (!mysql_query('CREATE USER pcontest IDENTIFIED BY "pcontest"', $link)) { + printf("skip Cannot create second DB user [%d] %s", mysql_errno($link), mysql_error($link)); + mysql_close($link); + die(); +} + +// we might be able to specify the host using CURRENT_USER(), but... +if (!mysql_query(sprintf("GRANT SELECT ON TABLE %s.test TO pcontest@'%%'", $db), $link)) { + printf("skip Cannot GRANT SELECT to second DB user [%d] %s", mysql_errno($link), mysql_error($link)); + mysql_query('REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest', $link); + mysql_query('DROP USER pcontest', $link); + mysql_close($link); + die(); +} +mysql_close($link); +?> +--INI-- +mysql.max_links=2 +mysql.allow_persistent=1 +mysql.max_persistent=1 +--FILE-- +<?php +require_once('connect.inc'); + +function my_connect($offset, $host, $user, $passwd, $db, $port, $socket) { + if ($socket) + $host = sprintf("%s:%s", $host, $socket); + else if ($port) + $host = sprintf("%s:%s", $host, $port); + + + $link = mysql_pconnect($host, $user, $passwd); + if (!$link) { + printf("[%03d] Cannot connect using host '%s', user '%s', password '****', [%d] %s\n", + $offset, $host, $user, $passwd, + mysql_errno(), mysql_error()); + return false; + } + + if (!mysql_select_db($db, $link)) + return false; + + return $link; +} + +$links = array(); + +// try to open 2 links +$links[0] = my_connect(10, $host, $user, $passwd, $db, $port, $socket); +$links[1] = my_connect(20, $host, 'pcontest', 'pcontest', $db, $port, $socket); +if (false !== $links[1]) + printf("[030] Last connection should not have been allowed!\n"); + +// free some links but let index 1 remain +unset($links[1]); +mysql_close($links[0]); +unset($links[0]); + +// should be allowed -> only open connection +$links[0] = my_connect(40, $host, $user, $passwd, $db, $port, $socket); +var_dump($links); + +mysql_query('REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest', $links[0]); +mysql_query('DROP USER pcontest', $links[0]); + +mysql_close($links[0]); +print "done!\n"; +?> +--CLEAN-- +<?php +// connect + select_db +require_once("connect.inc"); +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[c001] Cannot connect to the server using host=%s/%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $myhost, $user, $db, $port, $socket); +} + +@mysql_query('REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest', $link); +@mysql_query('DROP USER pcontest', $link); + +mysql_close($link); +?> +--EXPECTF-- +Warning: mysql_pconnect(): Too many open persistent links (1) in %s on line %d +[020] Cannot connect using host '%s', user '%s', password '****', [0] 0 +array(1) { + [0]=> + resource(%d) of type (mysql link persistent) +} +done!
\ No newline at end of file diff --git a/ext/mysql/tests/mysql_mysqlnd_read_timeout_long.phpt b/ext/mysql/tests/mysql_mysqlnd_read_timeout_long.phpt new file mode 100644 index 0000000..d54cb50 --- /dev/null +++ b/ext/mysql/tests/mysql_mysqlnd_read_timeout_long.phpt @@ -0,0 +1,37 @@ +--TEST-- +mysqlnd.net_read_timeout > default_socket_timeout +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +require_once('connect.inc'); +?> +--INI-- +default_socket_timeout=1 +mysqlnd.net_read_timeout=12 +max_execution_time=12 +--FILE-- +<?php + set_time_limit(12); + include ("connect.inc"); + + if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[001] Connect failed, [%d] %s\n", mysql_errno(), mysqlerror()); + } + + if (!$res = mysql_query("SELECT SLEEP(6)", $link)) + printf("[002] [%d] %s\n", mysql_errno($link), mysql_error($link)); + + var_dump(mysql_fetch_assoc($res)); + + mysql_free_result($res); + mysql_close($link); + + print "done!"; +?> +--EXPECTF-- +array(1) { + [%u|b%"SLEEP(6)"]=> + %unicode|string%(1) "0" +} +done!
\ No newline at end of file diff --git a/ext/mysql/tests/mysql_num_fields.phpt b/ext/mysql/tests/mysql_num_fields.phpt new file mode 100644 index 0000000..0dad5f7 --- /dev/null +++ b/ext/mysql/tests/mysql_num_fields.phpt @@ -0,0 +1,56 @@ +--TEST-- +mysql_num_fields() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (!is_null($tmp = @mysql_num_fields())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (NULL !== ($tmp = @mysql_num_fields($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); + +function func_test_mysql_num_fields($link, $query, $expected, $offset, $test_free = false) { + +if (!($res = mysql_query($query, $link))) { + printf("[%03d] [%d] %s\n", $offset, mysql_errno($link), mysql_error($link)); + return; +} + +if ($expected !== ($tmp = mysql_num_fields($res))) + printf("[%03d] Expecting %s/%d, got %s/%d\n", $offset + 1, + gettype($expected), $expected, + gettype($tmp), $tmp); + +mysql_free_result($res); + +if ($test_free && (false !== ($tmp = mysql_num_fields($res)))) + printf("[%03d] Expecting boolean/false, got %s/%s\n", $offset + 2, gettype($tmp), $tmp); +} + +func_test_mysql_num_fields($link, "SELECT 1 AS a", 1, 5); +func_test_mysql_num_fields($link, "SELECT id, label FROM test", 2, 10); +func_test_mysql_num_fields($link, "SELECT 1 AS a, NULL AS b, 'foo' AS c", 3, 15); +func_test_mysql_num_fields($link, "SELECT id FROM test", 1, 20, true); + +mysql_close($link); + +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysql_num_fields(): %d is not a valid MySQL result resource in %s on line %d +done! diff --git a/ext/mysql/tests/mysql_num_rows.phpt b/ext/mysql/tests/mysql_num_rows.phpt new file mode 100644 index 0000000..0f538c4 --- /dev/null +++ b/ext/mysql/tests/mysql_num_rows.phpt @@ -0,0 +1,87 @@ +--TEST-- +mysql_num_rows() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (!is_null($tmp = @mysql_num_rows())) +printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (NULL !== ($tmp = @mysql_num_rows($link))) +printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); + +function func_test_mysql_num_rows($link, $query, $expected, $offset, $test_free = false) { + + if (!$res = mysql_query($query, $link)) { + printf("[%03d] [%d] %s\n", $offset, mysql_errno($link), mysql_error($link)); + return; + } + + if ($expected !== ($tmp = mysql_num_rows($res))) + printf("[%03d] Expecting %s/%d, got %s/%d\n", $offset + 1, + gettype($expected), $expected, + gettype($tmp), $tmp); + + mysql_free_result($res); + + if ($test_free && (false !== ($tmp = mysql_num_rows($res)))) + printf("[%03d] Expecting boolean/false, got %s/%s\n", $offset + 2, gettype($tmp), $tmp); +} + +func_test_mysql_num_rows($link, "SELECT 1 AS a", 1, 5); +func_test_mysql_num_rows($link, "SHOW VARIABLES LIKE '%nixnutz%'", 0, 10); +func_test_mysql_num_rows($link, "INSERT INTO test(id, label) VALUES (100, 'z')", NULL, 15); +func_test_mysql_num_rows($link, "SELECT id FROM test LIMIT 2", 2, 20, true); + +if ($res = mysql_query('SELECT COUNT(id) AS num FROM test', $link)) { + + $row = mysql_fetch_assoc($res); + mysql_free_result($res); + + func_test_mysql_num_rows($link, "SELECT id, label FROM test", (int)$row['num'], 25); + +} else { + printf("[030] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +if ($res = mysql_unbuffered_query('SELECT id, label FROM test')) { + + if (0 != mysql_num_rows($res)) + printf("[032] Expecting 0 rows got %d\n", mysql_num_rows($res)); + + $rows = 0; + while ($row = mysql_fetch_assoc($res)) + $rows++; + + if ($rows != mysql_num_rows($res)) + printf("[033] Expecting %d rows got %d\n", $rows, mysql_num_rows($res)); + + mysql_free_result($res); +} else { + printf("[034] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +mysql_close($link); +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysql_num_rows() expects parameter 1 to be resource, boolean given in %s on line %d + +Warning: mysql_free_result() expects parameter 1 to be resource, boolean given in %s on line %d + +Warning: mysql_num_rows(): %d is not a valid MySQL result resource in %s on line %d +done! diff --git a/ext/mysql/tests/mysql_pconn_disable.phpt b/ext/mysql/tests/mysql_pconn_disable.phpt new file mode 100644 index 0000000..532e2e5 --- /dev/null +++ b/ext/mysql/tests/mysql_pconn_disable.phpt @@ -0,0 +1,54 @@ +--TEST-- +mysql_pconnect() - disabling feature +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +mysql.allow_persistent=0 +mysql.max_persistent=1 +mysql.max_links=2 +--FILE-- +<?php + require_once("connect.inc"); + require_once("table.inc"); + + if (($plink = my_mysql_connect($host, $user, $passwd, $db, $port, $socket, NULL, true))) + printf("[001] Can connect to the server.\n"); + + if (($res = mysql_query('SELECT id FROM test ORDER BY id ASC', $plink)) && + ($row = mysql_fetch_assoc($res)) && + (mysql_free_result($res))) { + printf("[002] Can fetch data using persistent connection! Data = '%s'\n", + $row['id']); + } + + $thread_id = mysql_thread_id($plink); + mysql_close($plink); + + if (!($plink = my_mysql_connect($host, $user, $passwd, $db, $port, $socket, NULL, true))) + printf("[003] Cannot connect, [%d] %s\n", mysql_errno(), mysql_error()); + + if (mysql_thread_id($plink) != $thread_id) + printf("[004] Looks like the second call to pconnect() did not give us the same connection.\n"); + + $thread_id = mysql_thread_id($plink); + mysql_close($plink); + + if (!($plink = my_mysql_connect($host, $user, $passwd, $db, $port, $socket))) + printf("[005] Cannot connect, [%d] %s\n", mysql_errno(), mysql_error()); + + if (mysql_thread_id($plink) == $thread_id) + printf("[006] Looks like connect() did not return a new connection.\n"); + + print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +[001] Can connect to the server. +[002] Can fetch data using persistent connection! Data = '1' +done!
\ No newline at end of file diff --git a/ext/mysql/tests/mysql_pconn_kill.phpt b/ext/mysql/tests/mysql_pconn_kill.phpt new file mode 100644 index 0000000..efef421 --- /dev/null +++ b/ext/mysql/tests/mysql_pconn_kill.phpt @@ -0,0 +1,110 @@ +--TEST-- +mysql_pconnect() - killing persitent connection +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +mysql.allow_persistent=1 +mysql.max_persistent=2 +--FILE-- +<?php + include "connect.inc"; + include "table.inc"; + + if ($socket) + $myhost = sprintf("%s:%s", $host, $socket); + else if ($port) + $myhost = sprintf("%s:%s", $host, $port); + else + $myhost = $host; + + if (!($plink = mysql_pconnect($myhost, $user, $passwd))) + printf("[001] Cannot connect to the server using host=%s/%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $myhost, $user, $db, $port, $socket); + mysql_select_db($db, $plink); + + $pthread_id = mysql_thread_id($plink); + $thread_id = mysql_thread_id($link); + + if (!($res = mysql_query("SHOW FULL PROCESSLIST", $link))) + printf("[002] Cannot get processlist, [%d] %s\n", mysql_errno($link), mysql_error($link)); + + $processlist = array(); + while ($row = mysql_fetch_assoc($res)) + $processlist[$row['Id']] = $row; + mysql_free_result($res); + + if (!isset($processlist[$thread_id])) + printf("[003] Cannot find regular connection thread in process list, [%d] %s\n", mysql_errno($link), mysql_error($link)); + if (!isset($processlist[$pthread_id])) + printf("[004] Cannot find persistent connection thread in process list, [%d] %s\n", mysql_errno($link), mysql_error($link)); + + if (!mysql_query(sprintf("KILL %d", $pthread_id), $link)) + printf("[005] Cannot kill persistent connection thread, [%d] %s\n", mysql_errno($link), mysql_error($link)); + + while (1) { + if (!($res = mysql_query("SHOW FULL PROCESSLIST", $link))) + printf("[006] Cannot get processlist, [%d] %s\n", mysql_errno($link), mysql_error($link)); + + $processlist2 = array(); + while ($row = mysql_fetch_assoc($res)) + $processlist2[$row['Id']] = $row; + mysql_free_result($res); + if (isset($processlist2[$pthread_id])) { + sleep(1); + } else { + break; + } + } + + if (!isset($processlist2[$thread_id])) + printf("[007] Cannot find regular connection thread in process list, [%d] %s\n", mysql_errno($link), mysql_error($link)); + + mysql_close($plink); + + if (!($plink = @mysql_pconnect($myhost, $user, $passwd))) + printf("[009] Cannot create new persistent connection, [%d] %s\n", mysql_errno(), mysql_error()); + mysql_select_db($db, $plink); + + if (!($res = mysql_query("SELECT 1", $plink))) + printf("[010] Cannot run query on new persistent connection, [%d] %s\n", @mysql_errno($plink), @mysql_error($plink)); + mysql_free_result($res); + + var_dump(mysql_ping($plink)); + + if (!($res = mysql_query("SELECT 1", $plink))) + printf("[011] Cannot run query on new persistent connection, [%d] %s\n", @mysql_errno($plink), @mysql_error($plink)); + mysql_free_result($res); + + if (!($link2 = mysql_connect($myhost, $user, $passwd, true))) + printf("[012] Cannot connect to the server using host=%s/%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $myhost, $user, $db, $port, $socket); + mysql_select_db($db, $link2); + if (!mysql_query(sprintf("KILL %d", $thread_id), $link2)) + printf("[013] Cannot kill regular connection thread, [%d] %s\n", mysql_errno($link2), mysql_error($link2)); + + if (!($link = mysql_connect($myhost, $user, $passwd, true))) + printf("[014] Cannot connect to the server using host=%s/%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $myhost, $user, $db, $port, $socket); + mysql_select_db($db, $link); + if (!($res = mysql_query("SELECT * FROM test", $link))) + printf("[015] Cannot run query on new regular connection, [%d] %s\n", @mysql_errno($link), @mysql_error($link)); + + if (!($res = mysql_query("SELECT * FROM test", $link2))) + printf("[016] Cannot run query on other regular connection, [%d] %s\n", @mysql_errno($link2), @mysql_error($link2)); + + mysql_free_result($res); + mysql_close($plink); + mysql_close($link); + mysql_close($link2); + print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +bool(true) +done! diff --git a/ext/mysql/tests/mysql_pconn_max_links.phpt b/ext/mysql/tests/mysql_pconn_max_links.phpt new file mode 100644 index 0000000..3eca0e5 --- /dev/null +++ b/ext/mysql/tests/mysql_pconn_max_links.phpt @@ -0,0 +1,206 @@ +--TEST-- +Persistent connections and mysql.max_persistent +--SKIPIF-- +<?php + require_once('skipif.inc'); + require_once('skipifconnectfailure.inc'); + require_once('table.inc'); + + if ($socket) + $host = sprintf("%s:%s", $host, $socket); + else if ($port) + $host = sprintf("%s:%s", $host, $port); + + // we need a second DB user to test for a possible flaw in the ext/mysql[i] code + if (!$link = mysql_connect($host, $user, $passwd, true)) + die(sprintf("skip Cannot connect [%d] %s", mysql_errno(), mysql_error())); + + if (!mysql_select_db($db, $link)) + die(sprintf("skip [%d] %s", mysql_errno($link), mysql_error($link))); + + if (!$res = mysql_query('SHOW VARIABLES LIKE "old_passwords"', $link)) { + die(sprintf("skip [%d] %s", mysql_errno($link), mysql_error($link))); + } + + if (mysql_num_rows($res) != 1) { + die(sprintf("skip Can't check if old_passwords = ON")); + } + + $row = mysql_fetch_assoc($res); + mysql_free_result($res); + if ($row['Value'] == "ON") + die(sprintf("skip Test will fail because old_passwords = ON. Hint: old passwords are insecure!")); + + if (!$res = mysql_query("SELECT CURRENT_USER() AS _user", $link)) + die(sprintf("skip [%d] %s", mysql_errno($link), mysql_error($link))); + + $row = mysql_fetch_assoc($res); + mysql_free_result($res); + $host = substr($row['_user'], strrpos($row['_user'], "@") + 1, strlen($row['_user'])); + + mysql_query('DROP USER pcontest', $link); + mysql_query(sprintf('DROP USER pcontest@"%s"', mysql_real_escape_string($host, $link)), $link); + if (!mysql_query(sprintf('CREATE USER pcontest@"%s" IDENTIFIED BY "pcontest"', mysql_real_escape_string($host, $link)), $link)) { + printf("skip Cannot create second DB user [%d] %s", mysql_errno($link), mysql_error($link)); + mysql_close($link); + die(); + } + + // we might be able to specify the host using CURRENT_USER(), but... + if (!mysql_query(sprintf('GRANT SELECT ON TABLE %s.test TO pcontest@"%s"', $db, mysql_real_escape_string($host, $link)), $link)) { + printf("skip Cannot GRANT SELECT to second DB user [%d] %s", mysql_errno($link), mysql_error($link)); + mysql_query(sprintf('REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest@"%s"', mysql_real_escape_string($host, $link)), $link); + mysql_query(sprintf('DROP USER pcontest@"%s"', mysql_real_escape_string($host, $link)), $link); + mysql_close($link); + die(); + } + + mysql_close($link); +?> +--INI-- +mysql.max_links=3 +mysql.max_persistent=2 +mysql.allow_persistent=1 +--FILE-- +<?php + require_once("connect.inc"); + require_once('table.inc'); + + if ($socket) + $host = sprintf("%s:%s", $host, $socket); + else if ($port) + $host = sprintf("%s:%s", $host, $port); + + if (!$plink = mysql_pconnect($host, $user, $passwd)) + printf("[001] Cannot connect using the second DB user created during SKIPIF, [%d] %s\n", + mysql_errno(), mysql_error()); + + if (!mysql_select_db($db, $plink)) + printf("[002] [%d] %s\n", mysql_errno($plink), mysql_error($plink)); + + ob_start(); + phpinfo(); + $phpinfo = strip_tags(ob_get_contents()); + ob_end_clean(); + $phpinfo = substr($phpinfo, strpos($phpinfo, 'MySQL Support => enabled'), 500); + if (!preg_match('@Active Persistent Links\s+=>\s+(\d+)@ismU', $phpinfo, $matches)) + printf("[003] Cannot get # active persistent links from phpinfo()"); + $num_plinks = $matches[1]; + + if (!$res = mysql_query('SELECT id, label FROM test WHERE id = 1', $plink)) + printf("[004] Cannot run query on persistent connection of second DB user, [%d] %s\n", + mysql_errno($plink), mysql_error($plink)); + + if (!$row = mysql_fetch_assoc($res)) + printf("[005] Cannot run fetch result, [%d] %s\n", + mysql_errno($plink), mysql_error($plink)); + mysql_free_result($res); + var_dump($row); + + // change the password for the second DB user and kill the persistent connection + if (!$res = mysql_query("SELECT CURRENT_USER() AS _user", $link)) + printf("[006] [%d] %s", mysql_errno($link), mysql_error($link)); + + $row = mysql_fetch_assoc($res); + mysql_free_result($res); + $host = substr($row['_user'], strrpos($row['_user'], "@") + 1, strlen($row['_user'])); + + $sql = sprintf('SET PASSWORD FOR pcontest@"%s" = PASSWORD("newpass")', mysql_real_escape_string($host, $link)); + if (!mysql_query($sql, $link)) + printf("[007] Cannot change PW of second DB user, [%d] %s\n", mysql_errno($link), mysql_error($link)); + + // persistent connections cannot be closed but only be killed + $pthread_id = mysql_thread_id($plink); + if (!mysql_query(sprintf('KILL %d', $pthread_id), $link)) + printf("[008] Cannot KILL persistent connection of second DB user, [%d] %s\n", mysql_errno($link), mysql_error($link)); + // give the server a second to really kill the thread + sleep(1); + + if (!$res = mysql_query("SHOW FULL PROCESSLIST", $link)) + printf("[009] [%d] %s\n", mysql_errno($link), mysql_error($link)); + + $running_threads = array(); + while ($row = mysql_fetch_assoc($res)) + $running_threads[$row['Id']] = $row; + mysql_free_result($res); + + if (isset($running_threads[$pthread_id])) + printf("[010] Persistent connection has not been killed\n"); + + // we might get the old handle + if ($plink = @mysql_pconnect($host, 'pcontest', 'pcontest')) + printf("[011] Can connect using the old password, [%d] %s\n", + mysql_errno(), mysql_error()); + + ob_start(); + phpinfo(); + $phpinfo = strip_tags(ob_get_contents()); + ob_end_clean(); + $phpinfo = substr($phpinfo, strpos($phpinfo, 'MySQL Support => enabled'), 500); + if (!preg_match('@Active Persistent Links\s+=>\s+(\d+)@ismU', $phpinfo, $matches)) + printf("[012] Cannot get # active persistent links from phpinfo()\n"); + + $num_plinks_kill = $matches[1]; + if ($num_plinks_kill > $num_plinks) + printf("[013] Statistics seems to be wrong, got %d active persistent links, expecting < %d links\n", + $num_plinks_kill, $num_plinks); + + // The first connection has been closed, the last pconnect() was unable to connect -> no connection open + // We must be able to connect because max_persistent limit has not been reached + if (!$plink = mysql_pconnect($host, 'pcontest', 'newpass')) + die(sprintf("[014] Cannot connect using the second DB, [%d] %s\n", + mysql_errno(), mysql_error())); + + if (!mysql_select_db($db, $plink)) + printf("[015] [%d] %s\n", mysql_errno($plink), mysql_error($plink)); + + if (!$res = mysql_query('SELECT id, label FROM test WHERE id = 1', $plink)) + printf("[016] Cannot run query on persistent connection of second DB user, [%d] %s\n", + mysql_errno($plink), mysql_error($plink)); + + if (!$row = mysql_fetch_assoc($res)) + printf("[017] Cannot run fetch result, [%d] %s\n", + mysql_errno($plink), mysql_error($plink)); + mysql_free_result($res); + var_dump($row); + + mysql_query(sprintf('REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest@"%s"', mysql_real_escape_string($host, $link)), $link); + mysql_query(sprintf('DROP USER pcontest@"%s"', mysql_real_escape_string($host, $link)), $link); + mysql_close($link); + print "done!"; +?> +--CLEAN-- +<?php +// connect + select_db +require_once("connect.inc"); +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[c001] Cannot connect to the server using host=%s/%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $myhost, $user, $db, $port, $socket); +} + +if (!$res = mysql_query("SELECT CURRENT_USER() AS _user", $link)) + printf("[c002] [%d] %s", mysql_errno($link), mysql_error($link)); + +$row = mysql_fetch_assoc($res); +mysql_free_result($res); +$host = substr($row['_user'], strrpos($row['_user'], "@") + 1, strlen($row['_user'])); + +@mysql_query(sprintf('REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest@"%s"', mysql_real_escape_string($host, $link)), $link); +@mysql_query(sprintf('DROP USER pcontest@"%s"', mysql_real_escape_string($host, $link)), $link); + +mysql_close($link); +?> +--EXPECTF-- +array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +array(2) { + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" +} +done! diff --git a/ext/mysql/tests/mysql_pconn_reuse.phpt b/ext/mysql/tests/mysql_pconn_reuse.phpt new file mode 100644 index 0000000..ffa5f75 --- /dev/null +++ b/ext/mysql/tests/mysql_pconn_reuse.phpt @@ -0,0 +1,66 @@ +--TEST-- +mysql_pconnect() - disabling feature +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +mysql.allow_persistent=1 +mysql.max_persistent=1 +mysql.max_links=2 +--FILE-- +<?php + require_once("connect.inc"); + require_once("table.inc"); + mysql_close($link); + + if ($socket) + $myhost = sprintf("%s:%s", $host, $socket); + else if ($port) + $myhost = sprintf("%s:%s", $host, $port); + else + $myhost = $host; + + if (($plink = mysql_pconnect($myhost, $user, $passwd))) + printf("[001] Can connect to the server.\n"); + + if ((mysql_select_db($db, $plink)) && + ($res = mysql_query('SELECT id FROM test', $plink)) && + ($row = mysql_fetch_assoc($res)) && + (mysql_free_result($res))) { + printf("[002] Can fetch data using persistent connection! Data = '%s'\n", + $row['id']); + } else { + printf("[002] [%d] %s\n", mysql_errno($plink), mysql_error($plink)); + } + + $thread_id = mysql_thread_id($plink); + mysql_close($plink); + + if (!($plink = mysql_pconnect($myhost, $user, $passwd))) + printf("[003] Cannot connect, [%d] %s\n", mysql_errno(), mysql_error()); + + if (mysql_thread_id($plink) != $thread_id) + printf("[004] Looks like the second call to pconnect() did not give us the same connection.\n"); + + $thread_id = mysql_thread_id($plink); + mysql_close($plink); + + if (!($plink = mysql_connect($myhost, $user, $passwd, true))) + printf("[005] Cannot connect, [%d] %s\n", mysql_errno(), mysql_error()); + + if (mysql_thread_id($plink) == $thread_id) + printf("[006] Looks like connect() did not return a new connection.\n"); + + if (($link = mysql_connect($myhost, $user, $passwd, true))) + printf("[007] Can connect although limit has been reached, [%d] %s\n", mysql_errno(), mysql_error()); + + print "done!"; +?> +--EXPECTF-- +[001] Can connect to the server. +[002] Can fetch data using persistent connection! Data = '1' + +Warning: mysql_connect(): Too many open links (2) in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysql/tests/mysql_pconnect.phpt b/ext/mysql/tests/mysql_pconnect.phpt new file mode 100644 index 0000000..5a7db93 --- /dev/null +++ b/ext/mysql/tests/mysql_pconnect.phpt @@ -0,0 +1,85 @@ +--TEST-- +mysql_pconnect() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +mysql.max_persistent=10 +mysql.allow_persistent=1 +--FILE-- +<?php + include "connect.inc"; + + $tmp = NULL; + $link = NULL; + + // mysql_pconnect ( [string server [, string username [, string password [, bool new_link [, int client_flags]]]]] ) + if (NULL !== ($tmp = @mysql_pconnect($link, $link, $link, $link, $link, $link))) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + + $myhost = (is_null($socket)) ? ((is_null($port)) ? $host : $host . ':' . $port) : $host . ':' . $socket; + if (!$link = mysql_pconnect($myhost, $user, $passwd, true)) + printf("[002] Cannot connect to the server using host=%s/%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $myhost, $user, $db, $port, $socket); + + mysql_close($link); + + if ($link = mysql_pconnect($myhost, $user . 'unknown_really', $passwd . 'non_empty', true)) + printf("[003] Can connect to the server using host=%s/%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", + $host, $myhost, $user . 'unknown_really', $db, $port, $socket); + + if (false !== $link) + printf("[004] Expecting boolean/false, got %s/%s\n", gettype($link), $link); + + // Run the following tests without an anoynmous MySQL user and use a password for the test user! + + + if (!ini_get('sql.safe_mode')) { + + if ($socket) { + ini_set('mysql.default_socket', $socket); + if (!is_resource($link = mysql_pconnect($host, $user, $passwd, true))) { + printf("[005] Usage of mysql.default_socket failed\n") ; + } else { + mysql_close($link); + } + } else { + ini_set('mysql.default_socket', null); + } + + ini_set('mysql.default_port', $port); + if (!is_resource($link = mysql_pconnect($host, $user, $passwd, true))) { + printf("[006] Usage of mysql.default_port failed\n") ; + } else { + mysql_close($link); + } + + ini_set('mysql.default_password', $passwd); + if (!is_resource($link = mysql_pconnect($myhost, $user))) { + printf("[007] Usage of mysql.default_password failed\n") ; + } else { + mysql_close($link); + } + + ini_set('mysql.default_user', $user); + if (!is_resource($link = mysql_pconnect($myhost))) { + printf("[008] Usage of mysql.default_user failed\n"); + } else { + mysql_close($link); + } + + ini_set('mysql.default_host', $myhost); + if (!is_resource($link = mysql_pconnect())) { + printf("[009] Usage of mysql.default_host failed\n") ; + } else { + mysql_close($link); + } + } + + print "done!"; +?> +--EXPECTF-- +Warning: mysql_pconnect(): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d +done! diff --git a/ext/mysql/tests/mysql_phpinfo.phpt b/ext/mysql/tests/mysql_phpinfo.phpt new file mode 100644 index 0000000..79de939 --- /dev/null +++ b/ext/mysql/tests/mysql_phpinfo.phpt @@ -0,0 +1,75 @@ +--TEST-- +phpinfo() mysql section +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include_once("connect.inc"); + +@ob_clean(); +ob_start(); +phpinfo(); +$phpinfo = ob_get_contents(); +ob_end_clean(); + +/* all versions should at least dump this minimum information */ +if (!stristr($phpinfo, "mysql support")) + printf("[001] ext/mysql should have exposed itself.\n"); + +if (!stristr($phpinfo, "client api version")) + printf("[002] ext/mysql should have exposed the library version.\n"); + +if (!stristr($phpinfo, "mysql.default_host")) + printf("[003] php.ini setting mysql.default_host not shown.\n"); + +if (!stristr($phpinfo, "mysql.default_port")) + printf("[004] php.ini setting mysql.default_port not shown.\n"); + +if (!stristr($phpinfo, "mysql.default_password")) + printf("[005] php.ini setting mysql.default_password not shown.\n"); + +if (!stristr($phpinfo, "mysql.default_socket")) + printf("[006] php.ini setting mysql.default_socket not shown.\n"); + +if (!stristr($phpinfo, "mysql.default_user")) + printf("[007] php.ini setting mysql.default_user not shown.\n"); + +if (!stristr($phpinfo, "mysql.max_links")) + printf("[008] php.ini setting mysql.max_links not shown.\n"); + +if (!stristr($phpinfo, "mysql.max_persistent")) + printf("[009] php.ini setting mysql.max_persistent not shown.\n"); + +if (!stristr($phpinfo, "mysql.connect_timeout")) + printf("[010] php.ini setting mysql.connect_timeout not shown.\n"); + +if (!stristr($phpinfo, "mysql.allow_persistent")) + printf("[011] php.ini setting mysql.allow_persistent not shown.\n"); + +if ($IS_MYSQLND) { + $expected = array( + 'mysqlnd statistics', + 'bytes_sent', 'bytes_received', 'packets_sent', 'packets_received', + 'protocol_overhead_in', 'protocol_overhead_out', 'result_set_queries', + 'non_result_set_queries', 'no_index_used', 'bad_index_used', + 'buffered_sets', 'unbuffered_sets', 'ps_buffered_sets', 'ps_unbuffered_sets', + 'flushed_normal_sets', 'flushed_ps_sets', 'rows_fetched_from_server', + 'rows_fetched_from_client', 'rows_skipped', 'copy_on_write_saved', + 'copy_on_write_performed', 'command_buffer_too_small', 'connect_success', + 'connect_failure', 'connection_reused', 'explicit_close', 'implicit_close', + 'disconnect_close', 'in_middle_of_command_close', 'explicit_free_result', + 'implicit_free_result', 'explicit_stmt_close', 'implicit_stmt_close', + 'size', + ); + foreach ($expected as $k => $entry) + if (!stristr($phpinfo, $entry)) + printf("[012] Could not find entry for '%s'\n", $entry); +} + +print "done!"; +?> +--EXPECTF-- +done! diff --git a/ext/mysql/tests/mysql_ping.phpt b/ext/mysql/tests/mysql_ping.phpt new file mode 100644 index 0000000..edf18c4 --- /dev/null +++ b/ext/mysql/tests/mysql_ping.phpt @@ -0,0 +1,50 @@ +--TEST-- +mysql_ping() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include_once "connect.inc"; + +$tmp = NULL; +$link = NULL; + +require('table.inc'); + +if (!is_null($tmp = @mysql_ping($link, $link))) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +var_dump(mysql_ping($link)); + +// provoke an error to check if mysql_ping resets it +$res = mysql_query('SELECT * FROM unknown_table', $link); +if (!($errno = mysql_errno($link))) + printf("[002] Statement should have caused an error\n"); + +var_dump(mysql_ping($link)); + +if ($errno === mysql_errno($link)) + printf("[003] Error codes should have been reset\n"); + +var_dump(mysql_ping()); +mysql_close($link); + +if (false !== ($tmp = mysql_ping($link))) + printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +bool(true) +bool(true) +bool(true) + +Warning: mysql_ping(): %d is not a valid MySQL-Link resource in %s on line %d +done! diff --git a/ext/mysql/tests/mysql_query.phpt b/ext/mysql/tests/mysql_query.phpt new file mode 100644 index 0000000..a5978a6 --- /dev/null +++ b/ext/mysql/tests/mysql_query.phpt @@ -0,0 +1,127 @@ +--TEST-- +mysql_query() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include_once("connect.inc"); + +$tmp = NULL; +$link = NULL; + +if (!is_null($tmp = @mysql_query())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (false !== ($tmp = @mysql_query($link))) + printf("[002] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); + +if (NULL !== ($tmp = @mysql_query("SELECT 1 AS a", $link, "foo"))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (false !== ($tmp = mysql_query('THIS IS NOT SQL', $link))) + printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +if (false !== ($tmp = mysql_query("SELECT 'this is sql but with backslash g'\g", $link))) + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +if ((0 === mysql_errno($link)) || ('' == mysql_error($link))) + printf("[006] mysql_errno()/mysql_error should return some error\n"); + +if (!$res = mysql_query("SELECT 'this is sql but with semicolon' AS valid ; ", $link)) + printf("[007] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +var_dump(mysql_fetch_assoc($res)); +mysql_free_result($res); + +if (!$res = mysql_query("SELECT 'a' AS ''", $link)) + printf("[007a] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +var_dump($tmp = mysql_fetch_assoc($res)); +var_dump($tmp[""]); +mysql_free_result($res); + +if (false !== ($res = mysql_query("SELECT 'this is sql but with semicolon' AS valid ; SHOW VARIABLES", $link))) + printf("[008] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (mysql_query('DROP PROCEDURE IF EXISTS p', $link)) { + // let's try to play with stored procedures + if (mysql_query('CREATE PROCEDURE p(OUT ver_param VARCHAR(25)) BEGIN SELECT VERSION() INTO ver_param; END;', $link)) { + $res = mysql_query('CALL p(@version)', $link); + $res = mysql_query('SELECT @version AS p_version', $link); + $tmp = mysql_fetch_assoc($res); + if (!isset($tmp['p_version']) || ('' == $tmp['p_version'])) { + printf("[009] Result seems wrong, dumping\n"); + var_dump($tmp); + } + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($tmp['p_version'])) { + printf("[010] Expecting unicode string, dumping\n"); + var_dump($tmp); + } + mysql_free_result($res); + } else { + printf("[011] [%d] %s\n", mysql_errno($link), mysql_error($link)); + } + + mysql_query('DROP FUNCTION IF EXISTS f', $link); + if (mysql_query('CREATE FUNCTION f( ver_param VARCHAR(25)) RETURNS VARCHAR(25) DETERMINISTIC RETURN ver_param;', $link)) { + $res = mysql_query('SELECT f(VERSION()) AS f_version', $link); + $tmp = mysql_fetch_assoc($res); + if (!isset($tmp['f_version']) || ('' == $tmp['f_version'])) { + printf("[012] Result seems wrong, dumping\n"); + var_dump($tmp); + } + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($tmp['f_version'])) { + printf("[013] Expecting unicode string, dumping\n"); + var_dump($tmp); + } + mysql_free_result($res); + } else { + printf("[014] [%d] %s\n", mysql_errno($link), mysql_error($link)); + } +} + +mysql_close($link); + +if (false !== ($tmp = mysql_query("SELECT id FROM test", $link))) + printf("[011] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +print "done!"; +?> +--CLEAN-- +<?php +require_once('connect.inc'); + +// connect + select_db +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[clean] Cannot connect to the server using host=%s/%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $myhost, $user, $db, $port, $socket); +} + +if (!mysql_query('DROP TABLE IF EXISTS test', $link)) { + printf("[clean] Failed to drop test table: [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +/* MySQL server may not support this - ignore errors */ +@mysql_query('DROP PROCEDURE IF EXISTS p', $link); +@mysql_query('DROP FUNCTION IF EXISTS f', $link); + +mysql_close($link); +?> +--EXPECTF-- +array(1) { + [%u|b%"valid"]=> + %unicode|string%(30) "this is sql but with semicolon" +} +array(1) { + [%u|b%""]=> + %unicode|string%(1) "a" +} +%unicode|string%(1) "a" + +Warning: mysql_query(): %d is not a valid MySQL-Link resource in %s on line %d +done! diff --git a/ext/mysql/tests/mysql_query_load_data_openbasedir.phpt b/ext/mysql/tests/mysql_query_load_data_openbasedir.phpt new file mode 100644 index 0000000..aa15f5c --- /dev/null +++ b/ext/mysql/tests/mysql_query_load_data_openbasedir.phpt @@ -0,0 +1,118 @@ +--TEST-- +LOAD DATA INFILE - open_basedir +--SKIPIF-- +<?php +include_once('skipif.inc'); +include_once('skipifconnectfailure.inc'); + + +if (!$IS_MYSQLND) + die("skip mysqlnd only, libmysql does not know about open_basedir restrictions"); + +if (file_exists('./simple.csv') && !unlink('./simple.csv')) + die("skip Cannot remove previous CSV file"); + +if (!$fp = fopen('./simple.csv', 'w')) + die("skip Cannot create test CSV file"); + +fclose($fp); +@unlink('./simple.csv'); + +if ($socket == "" && $host != NULL && $host != 'localhost' && $host != '.') { + /* could be a remote TCP/IP connection. LOCAL INFILE may not work */ + if (gethostbyaddr($host) != gethostname()) { + die("skip LOAD DATA LOCAL INFILE will fail if connecting to remote MySQL"); + } +} +?> +--FILE-- +<?php +@include_once("connect.inc"); +ini_set("open_basedir", __DIR__); +chdir(__DIR__); +if (!isset($db)) { + // run-tests, I love you for not allowing me to set ini settings dynamically + print "[006] [1148] The used command is not allowed with this MySQL version +[007] [0] +[008] LOAD DATA not run? +[010] [1148] The used command is not allowed with this MySQL version +done!"; + die(); +} +require('table.inc'); +mysql_close($link); +if ($socket) + $host = sprintf("%s:%s", $host, $socket); +else if ($port) + $host = sprintf("%s:%s", $host, $port); + +if (!$link = mysql_connect($host, $user, $passwd, true, 128)) { + printf("[001] Cannot connect using host '%s', user '%s', password '****', [%d] %s\n", + $host, $user, $passwd, + mysql_errno(), mysql_error()); +} + +if (!mysql_select_db($db, $link)) { + printf("[002] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +if (file_exists('./simple.csv')) + unlink('./simple.csv'); + +if (!$fp = fopen('./simple.csv', 'w')) + printf("[003] Cannot open CSV file\n"); + +if (version_compare(PHP_VERSION, '5.9.9', '>') >= 0) { + if (!fwrite($fp, (binary)"'97';'x';\n") || + !fwrite($fp, (binary)"'98';'y';\n") || + !fwrite($fp, (binary)"99;'z';\n")) { + printf("[004] Cannot write CVS file '%s'\n", $file); + } +} else { + if (!fwrite($fp, "97;'x';\n") || + !fwrite($fp, "98;'y';\n") || + !fwrite($fp, "99;'z';\n")) { + printf("[005] Cannot write CVS file '%s'\n", $file); + } +} +fclose($fp); + +$sql = sprintf("LOAD DATA LOCAL INFILE '%s' + INTO TABLE test + FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '\'' + LINES TERMINATED BY '\n'", + mysql_real_escape_string(realpath('./simple.csv'), $link)); + +if (!mysql_query($sql, $link)) + printf("[006] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (!($res = mysql_query('SELECT label FROM test WHERE id = 97', $link)) || + !($row = mysql_fetch_assoc($res)) || + !mysql_free_result($res)) + printf("[007] [%d] '%s'\n", mysql_errno($link), mysql_error($link)); + +if ($row['label'] != "x") + printf("[008] LOAD DATA not run?\n"); + +if (!mysql_query('DELETE FROM test', $link)) + printf("[009] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +$sql = "LOAD DATA LOCAL INFILE '/tmp/idonotexist' + INTO TABLE test + FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '\'' + LINES TERMINATED BY '\n'"; + +if (!mysql_query($sql, $link)) + printf("[010] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +mysql_close($link); +unlink("./simple.csv"); + +print "done!"; +?> +--EXPECTF-- +[006] [1148] %s +[007] [0] '' +[008] LOAD DATA not run? +[010] [1148] %s +done! diff --git a/ext/mysql/tests/mysql_real_escape_string.phpt b/ext/mysql/tests/mysql_real_escape_string.phpt new file mode 100644 index 0000000..2789ad2 --- /dev/null +++ b/ext/mysql/tests/mysql_real_escape_string.phpt @@ -0,0 +1,43 @@ +--TEST-- +mysql_real_escape_string() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (NULL !== ($tmp = @mysql_real_escape_string())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); + +if (NULL !== ($tmp = @mysql_real_escape_string('foo', $link, $link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +var_dump(mysql_real_escape_string("Am I a unicode string in PHP 6?", $link)); +var_dump(mysql_real_escape_string('\\', $link)); +var_dump(mysql_real_escape_string('"', $link)); +var_dump(mysql_real_escape_string("'", $link)); +var_dump(mysql_real_escape_string("\n", $link)); +var_dump(mysql_real_escape_string("\r", $link)); +var_dump($tmp = mysql_real_escape_string("foo" . chr(0) . "bar", $link)); + +assert($tmp === mysql_real_escape_string("foo" . chr(0) . "bar")); + +print "done!"; +?> +--EXPECTF-- +%unicode|string%(31) "Am I a unicode string in PHP 6?" +%unicode|string%(2) "\\" +%unicode|string%(2) "\"" +%unicode|string%(2) "\'" +%unicode|string%(2) "\n" +%unicode|string%(2) "\r" +%unicode|string%(8) "foo\0bar" +done! diff --git a/ext/mysql/tests/mysql_result.phpt b/ext/mysql/tests/mysql_result.phpt new file mode 100644 index 0000000..2c7c618 --- /dev/null +++ b/ext/mysql/tests/mysql_result.phpt @@ -0,0 +1,114 @@ +--TEST-- +mysql_result() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +require_once("connect.inc"); + +$tmp = NULL; +$link = NULL; + +// string mysql_result ( resource result, int row [, mixed field] ) + +if (!is_null($tmp = @mysql_result())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (!is_null($tmp = @mysql_result($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require_once('table.inc'); +if (!$res = mysql_query("SELECT id, label, id AS _id, CONCAT(label, 'a') _label, NULL as _foo FROM test _test ORDER BY id ASC LIMIT 1", $link)) { + printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +var_dump(mysql_result($res, -1)); +var_dump(mysql_result($res, 2)); + +var_dump(mysql_result($res, 0, -1)); +var_dump(mysql_result($res, 0, 500)); + +print "valid fields\n"; +var_dump(mysql_result($res, 0)); +var_dump(mysql_result($res, 0, 1)); + +var_dump(mysql_result($res, 0, 'id')); +var_dump(mysql_result($res, 0, '_test.id')); +var_dump(mysql_result($res, 0, 'label')); +var_dump(mysql_result($res, 0, '_test.label')); +print "some invalid fields\n"; +var_dump(mysql_result($res, 0, 'unknown')); +var_dump(mysql_result($res, 0, '_test.')); +var_dump(mysql_result($res, 0, chr(0))); +var_dump(mysql_result($res, 0, '_test.' . chr(0))); +print "_id\n"; +var_dump(mysql_result($res, 0, '_id')); +print "_label\n"; +var_dump(mysql_result($res, 0, '_label')); +print "_foo\n"; +var_dump(mysql_result($res, 0, '_foo')); +var_dump(mysql_result($res, 0, 'test.id')); +var_dump(mysql_result($res, 0, 'test.label')); + +mysql_free_result($res); + +var_dump(mysql_result($res, 0)); + +mysql_close($link); +print "done!"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +Warning: mysql_result(): Unable to jump to row -1 on MySQL result index %d in %s on line %d +bool(false) + +Warning: mysql_result(): Unable to jump to row 2 on MySQL result index %d in %s on line %d +bool(false) + +Warning: mysql_result(): Bad column offset specified in %s on line %d +bool(false) + +Warning: mysql_result(): Bad column offset specified in %s on line %d +bool(false) +valid fields +%unicode|string%(1) "1" +%unicode|string%(1) "a" +%unicode|string%(1) "1" +%unicode|string%(1) "1" +%unicode|string%(1) "a" +%unicode|string%(1) "a" +some invalid fields + +Warning: mysql_result(): unknown not found in MySQL result index %d in %s on line %d +bool(false) + +Warning: mysql_result(): _test. not found in MySQL result index %d in %s on line %d +bool(false) + +Warning: mysql_result(): not found in MySQL result index %d in %s on line %d +bool(false) + +Warning: mysql_result(): _test. not found in MySQL result index %d in %s on line %d +bool(false) +_id +%unicode|string%(1) "1" +_label +string(2) "aa" +_foo +NULL + +Warning: mysql_result(): test.id not found in MySQL result index %d in %s on line %d +bool(false) + +Warning: mysql_result(): test.label not found in MySQL result index %d in %s on line %d +bool(false) + +Warning: mysql_result(): %d is not a valid MySQL result resource in %s on line %d +bool(false) +done! diff --git a/ext/mysql/tests/mysql_select_db.phpt b/ext/mysql/tests/mysql_select_db.phpt new file mode 100644 index 0000000..211e342 --- /dev/null +++ b/ext/mysql/tests/mysql_select_db.phpt @@ -0,0 +1,73 @@ +--TEST-- +mysql_select_db() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include_once "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (false !== ($tmp = @mysql_select_db($link))) + printf("[001] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + +if (!is_null($tmp = @mysql_select_db($db, $link, "foo"))) + printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +/* does not make too much sense, unless we have access to at least one more database than $db */ +if (!mysql_select_db($db, $link)) + printf("[004] Cannot select DB %s, [%d] %s\n", $db, mysql_errno($link), mysql_error($link)); + +if (!$res = mysql_query("SELECT DATABASE() AS dbname", $link)) + printf("[005] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (!$row = mysql_fetch_assoc($res)) + printf("[006] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if ($row['dbname'] !== (string)$db) + printf("[007] Expecting database '%s', found '%s'\n", $db, $row['dbname']); + +var_dump($row['dbname']); + +mysql_free_result($res); + +if (mysql_select_db('mysql', $link)) { + // Yippie, a second database to play with - that's great because mysql_select_db + // ($db) was done by mysql__connect() already and the previous test + // was quite useless + if (!$res = mysql_query("SELECT DATABASE() AS dbname", $link)) + printf("[008] [%d] %s\n", mysql_errno($link), mysql_error($link)); + + if (!$row = mysql_fetch_assoc($res)) + printf("[009] [%d] %s\n", mysql_errno($link), mysql_error($link)); + + if (strtolower($row['dbname']) !== 'mysql') + printf("[010] Expecting database 'mysql', found '%s'\n", $row['dbname']); + + mysql_free_result($res); +} + + +var_dump(mysql_select_db('I can not imagine that this database exists', $link)); + +mysql_close($link); + +if (false !== ($tmp = mysql_select_db($db, $link))) + printf("[012] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +print "done!\n"; +?> +--EXPECTF-- +%unicode|string%(%d) "%s" +bool(false) + +Warning: mysql_select_db(): %d is not a valid MySQL-Link resource in %s on line %d +done! diff --git a/ext/mysql/tests/mysql_set_charset.phpt b/ext/mysql/tests/mysql_set_charset.phpt new file mode 100644 index 0000000..953323b --- /dev/null +++ b/ext/mysql/tests/mysql_set_charset.phpt @@ -0,0 +1,61 @@ +--TEST-- +mysql_set_charset() - STUB, function usage not recommended +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); + +if (version_compare(PHP_VERSION, '5.9.9', '>') == 1) { + die('skip set character set not functional with PHP 6 (fomerly PHP 6 && unicode.semantics=On)'); +} + +if (!function_exists('mysql_set_charset')) + die("skip Function not available"); +?> +--FILE-- +<?php +include_once "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (!is_null($tmp = @mysql_set_charset())) + printf("[001] Expecting NULL got %s/%s\n", $tmp, gettype($tmp)); + +if (false !== ($tmp = @mysql_set_charset($link))) + printf("[002] Expecting boolean/false got %s/%s\n", $tmp, gettype($tmp)); + +if (false !== ($tmp = @mysql_set_charset(-1))) + printf("[003] Expecting boolean/false got %s/%s\n", $tmp, gettype($tmp)); + +if (!is_null($tmp = @mysql_set_charset('somecharset', $link))) + printf("[004] Expecting NULL got %s/%s\n", $tmp, gettype($tmp)); + +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) + printf("[005] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + +/* unicode mode should throw a warning */ +$tmp = mysql_set_charset('uFt8', $link); + +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1)) + $expect = false; +else + $expect = true; + +$charsets = array('latin1', 'latin2'); +foreach ($charsets as $k => $charset) { + if (!($res = mysql_query(sprintf('SHOW CHARACTER SET LIKE "%s"', $charset), $link))) + continue; + mysql_free_result($res); + if ($expect !== ($tmp = @mysql_set_charset($charset, $link))) + printf("[006] Expecting %s/%s got %s/%s\n", + gettype($expect), $expect, + gettype($tmp), $tmp); +} + +mysql_close($link); +print "done!"; +?> +--EXPECTF-- +done! diff --git a/ext/mysql/tests/mysql_sql_safe_mode.phpt b/ext/mysql/tests/mysql_sql_safe_mode.phpt new file mode 100644 index 0000000..4d8ca92 --- /dev/null +++ b/ext/mysql/tests/mysql_sql_safe_mode.phpt @@ -0,0 +1,40 @@ +--TEST-- +mysql_[p]connect() - safe_mode +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +$link = @mysql_connect("", "", "", true); +if ($link) + die("skip Test cannot be run if annonymous connections are allowed"); +?> +--INI-- +sql.safe_mode=1 +--FILE-- +<?php +require_once('connect.inc'); +if ($socket) + $host = sprintf("%s:%s", $host, $socket); +else if ($port) + $host = sprintf("%s:%s", $host, $port); + +if ($link = mysql_connect($host, $user, $passwd, true)) { + printf("[001] Safe mode not working properly?\n"); + mysql_close($link); +} + +if ($link = mysql_pconnect($host, $user, $passwd)) { + printf("[002] Safe mode not working properly?\n"); + mysql_close($link); +} +print "done!\n"; +?> +--EXPECTF-- +Notice: mysql_connect(): SQL safe mode in effect - ignoring host/user/password information in %s on line %d + +Warning: mysql_connect(): Access denied for user '%s'@'%s' (using password: NO) in %s on line %d + +Notice: mysql_pconnect(): SQL safe mode in effect - ignoring host/user/password information in %s on line %d + +Warning: mysql_pconnect(): Access denied for user '%s'@'%s' (using password: NO) in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysql/tests/mysql_stat.phpt b/ext/mysql/tests/mysql_stat.phpt new file mode 100644 index 0000000..30a840a --- /dev/null +++ b/ext/mysql/tests/mysql_stat.phpt @@ -0,0 +1,48 @@ +--TEST-- +mysql_stat() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include_once "connect.inc"; + +$dbname = 'test'; +$tmp = NULL; +$link = NULL; + +if (!is_null($tmp = @mysql_stat($link))) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); + +if (!is_null($tmp = @mysql_stat($link, "foo"))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if ((!is_string($stat = mysql_stat($link))) || ('' === $stat)) + printf("[003] Expecting non empty string, got %s/'%s', [%d] %s\n", + gettype($stat), $stat, mysql_errno($link), mysql_error($link)); + +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($stat)) { + printf("[004] Expecting Unicode error message!\n"); + var_inspect($stat); +} + +if ((!is_string($stat_def = mysql_stat())) || ('' === $stat_def)) + printf("[003] Expecting non empty string, got %s/'%s', [%d] %s\n", + gettype($stat_def), $stat_def, mysql_errno(), mysql_error()); + +assert(soundex($stat) === soundex($stat_def)); + +mysql_close($link); + +if (false !== ($tmp = mysql_stat($link))) + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +print "done!"; +?> +--EXPECTF-- +Warning: mysql_stat(): %d is not a valid MySQL-Link resource in %s on line %d +done! diff --git a/ext/mysql/tests/mysql_tablename.phpt b/ext/mysql/tests/mysql_tablename.phpt new file mode 100644 index 0000000..2415e4f --- /dev/null +++ b/ext/mysql/tests/mysql_tablename.phpt @@ -0,0 +1,54 @@ +--TEST-- +mysql_tablename() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (!is_null($tmp = @mysql_tablename())) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (null !== ($tmp = @mysql_tablename($link))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); +if (!$res = mysql_query("SELECT id, label FROM test ORDER BY id LIMIT 2", $link)) { + printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +if (NULL !== ($tmp = mysql_tablename($res))) + printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (false !== ($tmp = mysql_tablename($res, -1))) + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +var_dump(mysql_tablename($res, 0)); + +if (false !== ($tmp = mysql_tablename($res, 2))) + printf("[00%d] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +mysql_free_result($res); + +var_dump(mysql_tablename($res, 0)); + +mysql_close($link); +print "done!"; +?> +--EXPECTF-- +Warning: mysql_tablename() expects at least 2 parameters, 1 given in %s on line %d + +Warning: mysql_tablename(): Unable to jump to row -1 on MySQL result index %d in %s on line %d +%unicode|string%(1) "1" + +Warning: mysql_tablename(): Unable to jump to row 2 on MySQL result index %d in %s on line %d + +Warning: mysql_tablename(): %d is not a valid MySQL result resource in %s on line %d +bool(false) +done! diff --git a/ext/mysql/tests/mysql_thread_id.phpt b/ext/mysql/tests/mysql_thread_id.phpt new file mode 100644 index 0000000..b05bb3e --- /dev/null +++ b/ext/mysql/tests/mysql_thread_id.phpt @@ -0,0 +1,39 @@ +--TEST-- +mysql_thread_id() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include_once "connect.inc"; + +$tmp = NULL; +$link = NULL; + +if (!is_null($tmp = @mysql_thread_id($link))) + printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); + +if (!is_int($id = mysql_thread_id($link)) || (0 === $id)) + printf("[002] Expecting int/any but zero, got %s/%s. [%d] %s\n", + gettype($id), $id, mysql_errno($link), mysql_error($link)); + +if (!is_int($id_def = mysql_thread_id()) || (0 === $id_def)) + printf("[003] Expecting int/any but zero, got %s/%s. [%d] %s\n", + gettype($id_def), $id_def, mysql_errno(), mysql_error()); + +assert($id === $id_def); + +mysql_close($link); + +if (false !== ($tmp = mysql_thread_id($link))) + printf("[003] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +print "done!"; +?> +--EXPECTF-- +Warning: mysql_thread_id(): %d is not a valid MySQL-Link resource in %s on line %d +done!
\ No newline at end of file diff --git a/ext/mysql/tests/mysql_trace_mode.phpt b/ext/mysql/tests/mysql_trace_mode.phpt new file mode 100644 index 0000000..2b6c61d --- /dev/null +++ b/ext/mysql/tests/mysql_trace_mode.phpt @@ -0,0 +1,36 @@ +--TEST-- +mysql.trace_mode=1 +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--INI-- +mysql.trace_mode=1 +error_reporting=E_ALL | E_NOTICE | E_STRICT +--FILE-- +<?php +require_once('table.inc'); + +$res1 = mysql_query('SELECT id FROM test', $link); + +if (!$res2 = @mysql_db_query($db, 'SELECT id FROM test', $link)) + printf("[001] [%d] %s\n", mysql_errno($link), mysql_error($link)); +mysql_free_result($res2); +print @mysql_escape_string("I don't mind character sets, do I?\n"); + +$res3 = mysql_query('BOGUS_SQL', $link); +mysql_close($link); + +print "done!\n"; +?> +--CLEAN-- +<?php +require_once("clean_table.inc"); +?> +--EXPECTF-- +I don\'t mind character sets, do I?\n +Warning: mysql_query(): 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 'BOGUS_SQL' at line 1 in %s on line %d +done! + +Warning: Unknown: 1 result set(s) not freed. Use mysql_free_result to free result sets which were requested using mysql_query() in %s on line %d diff --git a/ext/mysql/tests/mysql_unbuffered_query.phpt b/ext/mysql/tests/mysql_unbuffered_query.phpt new file mode 100644 index 0000000..ad9b4fb --- /dev/null +++ b/ext/mysql/tests/mysql_unbuffered_query.phpt @@ -0,0 +1,121 @@ +--TEST-- +mysql_unbuffered_query() +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php +include_once("connect.inc"); + +$tmp = NULL; +$link = NULL; + +if (false !== ($tmp = @mysql_unbuffered_query($link))) + printf("[001] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +require('table.inc'); + +if (NULL !== ($tmp = @mysql_unbuffered_query("SELECT 1 AS a", $link, "foo"))) + printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + +if (false !== ($tmp = mysql_unbuffered_query('THIS IS NOT SQL', $link))) + printf("[003] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +if (false !== ($tmp = mysql_unbuffered_query("SELECT 'this is sql but with backslash g'\g", $link))) + printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +if ((0 === mysql_errno($link)) || ('' == mysql_error($link))) + printf("[005] mysql_errno()/mysql_error should return some error\n"); + +if (!$res = mysql_unbuffered_query("SELECT 'this is sql but with semicolon' AS valid ; ", $link)) + printf("[006] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +var_dump(mysql_fetch_assoc($res)); +mysql_free_result($res); + +if (false !== ($res = mysql_unbuffered_query("SELECT 'this is sql but with semicolon' AS valid ; SHOW VARIABLES", $link))) + printf("[007] [%d] %s\n", mysql_errno($link), mysql_error($link)); + +if (mysql_unbuffered_query('DROP PROCEDURE IF EXISTS p', $link)) { + // let's try to play with stored procedures + if (mysql_unbuffered_query('CREATE PROCEDURE p(OUT ver_param VARCHAR(25)) BEGIN SELECT VERSION() INTO ver_param; END;', $link)) { + $res = mysql_unbuffered_query('CALL p(@version)', $link); + $res = mysql_unbuffered_query('SELECT @version AS p_version', $link); + $tmp = mysql_fetch_assoc($res); + if (!isset($tmp['p_version']) || ('' == $tmp['p_version'])) { + printf("[008] Result seems wrong, dumping\n"); + var_dump($tmp); + } + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($tmp['p_version'])) { + printf("[009] Expecting unicode string, dumping\n"); + var_dump($tmp); + } + mysql_free_result($res); + } else { + printf("[010] [%d] %s\n", mysql_errno($link), mysql_error($link)); + } + + mysql_unbuffered_query('DROP FUNCTION IF EXISTS f', $link); + if (mysql_unbuffered_query('CREATE FUNCTION f( ver_param VARCHAR(25)) RETURNS VARCHAR(25) DETERMINISTIC RETURN ver_param;', $link)) { + $res = mysql_unbuffered_query('SELECT f(VERSION()) AS f_version', $link); + $tmp = mysql_fetch_assoc($res); + if (!isset($tmp['f_version']) || ('' == $tmp['f_version'])) { + printf("[011] Result seems wrong, dumping\n"); + var_dump($tmp); + } + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($tmp['f_version'])) { + printf("[012] Expecting unicode string, dumping\n"); + var_dump($tmp); + } + mysql_free_result($res); + } else { + printf("[012] [%d] %s\n", mysql_errno($link), mysql_error($link)); + } +} + +var_dump(mysql_unbuffered_query('INSERT INTO test(id) VALUES (100)', $link)); +var_dump($res = mysql_unbuffered_query('SELECT id FROM test', $link)); +var_dump(mysql_num_rows($res)); + +mysql_close($link); + +if (false !== ($tmp = mysql_unbuffered_query("SELECT id FROM test", $link))) + printf("[010] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + +print "done!"; +?> +--CLEAN-- +<?php +require_once('connect.inc'); + +// connect + select_db +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("[clean] Cannot connect to the server using host=%s/%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $myhost, $user, $db, $port, $socket); +} + +if (!mysql_query('DROP TABLE IF EXISTS test', $link)) { + printf("[clean] Failed to drop test table: [%d] %s\n", mysql_errno($link), mysql_error($link)); +} + +/* MySQL server may not support this - ignore errors */ +@mysql_query('DROP PROCEDURE IF EXISTS p', $link); +@mysql_query('DROP FUNCTION IF EXISTS f', $link); + +mysql_close($link); +?> +--EXPECTF-- +array(1) { + [%u|b%"valid"]=> + %unicode|string%(30) "this is sql but with semicolon" +} +bool(true) +resource(%d) of type (mysql result) +int(0) + +Notice: mysql_close(): Function called without first fetching all rows from a previous unbuffered query in %s on line %d + +Warning: mysql_unbuffered_query(): %d is not a valid MySQL-Link resource in %s on line %d +done! diff --git a/ext/mysql/tests/setupdefault.inc b/ext/mysql/tests/setupdefault.inc new file mode 100644 index 0000000..6d25c20 --- /dev/null +++ b/ext/mysql/tests/setupdefault.inc @@ -0,0 +1,10 @@ +<?php + +// copy variables from connect.inc into mysql default connection ini settings, so that implicit mysql_connect() behaviour can be tested where needed +// must be loaded AFTER connect.inc + +ini_set('mysql.default_host', $host); +ini_set('mysql.default_user', $user); +ini_set('mysql.default_password', $passwd); + +?> diff --git a/ext/mysql/tests/skipif.inc b/ext/mysql/tests/skipif.inc new file mode 100644 index 0000000..0f93289 --- /dev/null +++ b/ext/mysql/tests/skipif.inc @@ -0,0 +1,6 @@ +<?php +if (!extension_loaded("mysql")) { + die('skip mysql extension not available'); +} +require_once('connect.inc'); +?> diff --git a/ext/mysql/tests/skipifconnectfailure.inc b/ext/mysql/tests/skipifconnectfailure.inc new file mode 100644 index 0000000..a57c7db --- /dev/null +++ b/ext/mysql/tests/skipifconnectfailure.inc @@ -0,0 +1,17 @@ +<?php +require_once('connect.inc'); +if ($skip_on_connect_failure) { + if ($socket) + $myhost = sprintf("%s:%s", $host, $socket); + else if ($port) + $myhost = sprintf("%s:%s", $host, $port); + + if (!$link = @mysql_connect($myhost, $user, $passwd, true, $connect_flags)) + die(sprintf("skip Can't connect to MySQL Server - [%d] %s", mysql_errno(), mysql_error())); + + if (!@mysql_select_db($db, $link)) + die(sprintf("skip Can't connect to MySQL Server - [%d] %s", mysql_errno(), mysql_error())); + + mysql_close($link); +} +?>
\ No newline at end of file diff --git a/ext/mysql/tests/skipifnotmysqlnd.inc b/ext/mysql/tests/skipifnotmysqlnd.inc new file mode 100644 index 0000000..9cccdc7 --- /dev/null +++ b/ext/mysql/tests/skipifnotmysqlnd.inc @@ -0,0 +1,5 @@ +<?php +if (strpos(mysql_get_client_info(), 'mysqlnd') === false) { + die('skip mysqlnd extension not available'); +} +?> diff --git a/ext/mysql/tests/table.inc b/ext/mysql/tests/table.inc new file mode 100644 index 0000000..18c858d --- /dev/null +++ b/ext/mysql/tests/table.inc @@ -0,0 +1,24 @@ +<?PHP +require_once 'connect.inc'; + +// connect + select_db +if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) { + printf("Cannot connect to the server using host=%s/%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $myhost, $user, $db, $port, $socket); + exit(1); +} + +if (!mysql_query('DROP TABLE IF EXISTS test', $link)) { + printf("Failed to drop old test table: [%d] %s\n", mysql_errno($link), mysql_error($link)); + exit(1); +} + +if (!mysql_query('CREATE TABLE test(id INT, label CHAR(1), PRIMARY KEY(id)) ENGINE=' . $engine, $link)) { + printf("Failed to create test table: [%d] %s\n", mysql_errno($link), mysql_error($link)); + exit(1); +} + +if (!mysql_query("INSERT INTO test(id, label) VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'), (6, 'f')", $link)) { + printf("[%d] %s\n", mysql_errno($link), mysql_error($link)); +} +?> |