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/dba | |
download | php2-c4dd7a1a684490673e25aaf4fabec5df138854c4.tar.gz |
Imported from /home/lorry/working-area/delta_php2/php-5.4.13.tar.bz2.HEADphp-5.4.13master
Diffstat (limited to 'ext/dba')
107 files changed, 9594 insertions, 0 deletions
diff --git a/ext/dba/CREDITS b/ext/dba/CREDITS new file mode 100644 index 0000000..370b3ea --- /dev/null +++ b/ext/dba/CREDITS @@ -0,0 +1,2 @@ +DBA +Sascha Schumann, Marcus Boerger
\ No newline at end of file diff --git a/ext/dba/README b/ext/dba/README new file mode 100755 index 0000000..0c22830 --- /dev/null +++ b/ext/dba/README @@ -0,0 +1,54 @@ +These functions build the foundation for accessing Berkeley DB style +databases. + +This is a general abstraction layer for several file-based databases. As +such, functionality is limited to a common subset of features supported +by modern databases such as Sleepycat Software's DB2. (This is not to be +confused with IBM's DB2 software, which is supported through the ODBC +functions.) + +This extensions allows to work with the following databases: +dbm DBM is the oldest (original) type of Berkeley DB style databases. + You should avoid it, if possible. We do not support the + compatibility functions built into DB2 and gdbm, because they are + only compatible on the source code level, but cannot handle the + original dbm format. +ndbm NDBM is a newer type and more flexible than dbm. It still has + most of the arbitrary limits of dbm (therefore it is deprecated). +gdbm GDBM is the GNU database manager. +db2 DB2 is Sleepycat Software's DB2. It's described as "a programmatic + toolkit that provides high-performance built-in database support + for both standalone and client/server applications. +db3 DB3 is Sleepycat Software's DB3. +db4 DB4 is Sleepycat Software's DB4. This is available since PHP 5.0. +cdb CDB is "a fast, reliable, lightweight package for creating and + reading constant databases." It is from the author of qmail and + can be found at http://cr.yp.to/cdb.html. Since it is constant, + we support only reading operations. And since PHP 4.3.0 we support + writing (not updating) through the internal cdb library. +cdb_make Since PHP 4.3.0 we support creation (not updating) of cdb files + when the bundled cdb library is used. +flatfile This is available since PHP 4.3.0 for compatibility with the + deprecated dbm extension only and should be avoided. However you + may use this where files were created in this format. That happens + when configure could not find any external library. +inifile This is available since PHP 4.3.3 to be able to modify php.ini + files from within PHP scripts. When working with ini files you + can pass arrays of the form array(0=>group,1=>value_name) or + strings of the form "[group]value_name" where group is optional. + As the functions dba_firstkey() and dba_nextkey() return string + representations of the key there is a new function dba_key_split() + available since PHP 5 which allows to convert the string keys into + array keys without loosing FALSE. +qdbm This is available since PHP 5.0.0. The qdbm library can be loaded + from http://qdbm.sourceforge.net. + + +After configuring and compiling PHP you must execute the following test +from commandline: + php run-tests.php ext/dba. +This shows whether your combination of handlers works. Most problematic +are dbm and ndbm which conflict with many installations. The reason for +this is that on several systems these libraries are part of more than one +other library. The configuration test only prevents you from configuring +malfaunctioning single handlers but not combinations.
\ No newline at end of file diff --git a/ext/dba/config.m4 b/ext/dba/config.m4 new file mode 100644 index 0000000..4b12351 --- /dev/null +++ b/ext/dba/config.m4 @@ -0,0 +1,635 @@ +dnl +dnl $Id$ +dnl + +dnl Suppose we need FlatFile if no support or only CDB is used. + +AC_DEFUN([PHP_DBA_STD_BEGIN],[ + unset THIS_INCLUDE THIS_LIBS THIS_LFLAGS THIS_PREFIX THIS_RESULT +]) + +AC_DEFUN([PHP_TEMP_LDFLAGS],[ + old_LDFLAGS=$LDFLAGS + LDFLAGS="$1 $LDFLAGS" + old_LIBS=$LIBS + LIBS="$2 $LIBS" + $3 + LDFLAGS=$old_LDFLAGS + LIBS=$old_LIBS +]) + +dnl Assign INCLUDE/LFLAGS from PREFIX +AC_DEFUN([PHP_DBA_STD_ASSIGN],[ + if test -n "$THIS_PREFIX" && test "$THIS_PREFIX" != "/usr"; then + THIS_LFLAGS=$THIS_PREFIX/$PHP_LIBDIR + fi +]) + +dnl Standard check +AC_DEFUN([PHP_DBA_STD_CHECK],[ + THIS_RESULT=yes + if test -z "$THIS_INCLUDE"; then + AC_MSG_ERROR([DBA: Could not find necessary header file(s).]) + fi + if test -z "$THIS_LIBS"; then + AC_MSG_ERROR([DBA: Could not find necessary library.]) + fi +]) + +dnl Attach THIS_x to DBA_x +AC_DEFUN([PHP_DBA_STD_ATTACH],[ + PHP_ADD_LIBRARY_WITH_PATH($THIS_LIBS, $THIS_LFLAGS, DBA_SHARED_LIBADD) + unset THIS_INCLUDE THIS_LIBS THIS_LFLAGS THIS_PREFIX +]) + +dnl Print the result message +dnl parameters(name [, full name [, empty or error message]]) +AC_DEFUN([PHP_DBA_STD_RESULT],[ + THIS_NAME=[]translit($1,a-z0-9-,A-Z0-9_) + if test -n "$2"; then + THIS_FULL_NAME="$2" + else + THIS_FULL_NAME="$THIS_NAME" + fi + AC_MSG_CHECKING([for $THIS_FULL_NAME support]) + if test -n "$3"; then + AC_MSG_ERROR($3) + fi + if test "$THIS_RESULT" = "yes" || test "$THIS_RESULT" = "builtin"; then + HAVE_DBA=1 + eval HAVE_$THIS_NAME=1 + AC_MSG_RESULT([$THIS_RESULT]) + else + AC_MSG_RESULT(no) + fi + unset THIS_RESULT THIS_NAME THIS_FULL_NAME +]) + +dnl +dnl Options +dnl + +PHP_ARG_ENABLE(dba,, +[ --enable-dba Build DBA with bundled modules. To build shared DBA + extension use --enable-dba=shared]) + +PHP_ARG_WITH(qdbm,, +[ --with-qdbm[=DIR] DBA: QDBM support], no, no) + +PHP_ARG_WITH(gdbm,, +[ --with-gdbm[=DIR] DBA: GDBM support], no, no) + +PHP_ARG_WITH(ndbm,, +[ --with-ndbm[=DIR] DBA: NDBM support], no, no) + +PHP_ARG_WITH(db4,, +[ --with-db4[=DIR] DBA: Oracle Berkeley DB 4.x or 5.x support], no, no) + +PHP_ARG_WITH(db3,, +[ --with-db3[=DIR] DBA: Oracle Berkeley DB 3.x support], no, no) + +PHP_ARG_WITH(db2,, +[ --with-db2[=DIR] DBA: Oracle Berkeley DB 2.x support], no, no) + +PHP_ARG_WITH(db1,, +[ --with-db1[=DIR] DBA: Oracle Berkeley DB 1.x support/emulation], no, no) + +PHP_ARG_WITH(dbm,, +[ --with-dbm[=DIR] DBA: DBM support], no, no) + +PHP_ARG_WITH(tcadb,, +[ --with-tcadb[=DIR] DBA: Tokyo Cabinet abstract DB support], no, no) + + +dnl +dnl Library checks +dnl + +# QDBM +if test "$PHP_QDBM" != "no"; then + PHP_DBA_STD_BEGIN + for i in $PHP_QDBM /usr/local /usr; do + if test -f "$i/include/depot.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/depot.h + break + fi + done + + if test -n "$THIS_INCLUDE"; then + for LIB in qdbm; do + PHP_CHECK_LIBRARY($LIB, dpopen, [ + AC_DEFINE_UNQUOTED(QDBM_INCLUDE_FILE, "$THIS_INCLUDE", [ ]) + AC_DEFINE(DBA_QDBM, 1, [ ]) + THIS_LIBS=$LIB + ], [], [-L$THIS_PREFIX/$PHP_LIBDIR]) + if test -n "$THIS_LIBS"; then + break + fi + done + fi + + PHP_DBA_STD_ASSIGN + PHP_DBA_STD_CHECK + PHP_DBA_STD_ATTACH +fi +PHP_DBA_STD_RESULT(qdbm) + +# GDBM +if test "$PHP_GDBM" != "no"; then + PHP_DBA_STD_BEGIN + if test "$HAVE_QDBM" = "1"; then + PHP_DBA_STD_RESULT(gdbm, gdbm, [You cannot combine --with-gdbm with --with-qdbm]) + fi + for i in $PHP_GDBM /usr/local /usr; do + if test -f "$i/include/gdbm.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/gdbm.h + break + fi + done + + if test -n "$THIS_INCLUDE"; then + PHP_CHECK_LIBRARY(gdbm, gdbm_open, [ + AC_DEFINE_UNQUOTED(GDBM_INCLUDE_FILE, "$THIS_INCLUDE", [ ]) + AC_DEFINE(DBA_GDBM, 1, [ ]) + THIS_LIBS=gdbm + ], [], [-L$THIS_PREFIX/$PHP_LIBDIR]) + fi + + PHP_DBA_STD_ASSIGN + PHP_DBA_STD_CHECK + PHP_DBA_STD_ATTACH +fi +PHP_DBA_STD_RESULT(gdbm) + +# NDBM +if test "$PHP_NDBM" != "no"; then + PHP_DBA_STD_BEGIN + for i in $PHP_NDBM /usr/local /usr; do + if test -f "$i/include/ndbm.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/ndbm.h + break + elif test -f "$i/include/db1/ndbm.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db1/ndbm.h + break + fi + done + + if test -n "$THIS_INCLUDE"; then + for LIB in ndbm db1 c; do + PHP_CHECK_LIBRARY($LIB, dbm_open, [ + AC_DEFINE_UNQUOTED(NDBM_INCLUDE_FILE, "$THIS_INCLUDE", [ ]) + AC_DEFINE(DBA_NDBM, 1, [ ]) + THIS_LIBS=$LIB + ], [], [-L$THIS_PREFIX/$PHP_LIBDIR]) + if test -n "$THIS_LIBS"; then + break + fi + done + fi + + PHP_DBA_STD_ASSIGN + PHP_DBA_STD_CHECK + PHP_DBA_STD_ATTACH +fi +PHP_DBA_STD_RESULT(ndbm) + +dnl TCADB +if test "$PHP_TCADB" != "no"; then + PHP_DBA_STD_BEGIN + for i in $PHP_TCADB /usr/local /usr; do + if test -f "$i/include/tcadb.h"; then + THIS_PREFIX=$i + PHP_ADD_INCLUDE($THIS_PREFIX/include) + THIS_INCLUDE=$i/include/tcadb.h + break + fi + done + + if test -n "$THIS_INCLUDE"; then + for LIB in tokyocabinet; do + PHP_CHECK_LIBRARY($LIB, tcadbopen, [ + AC_DEFINE_UNQUOTED(TCADB_INCLUDE_FILE, "$THIS_INCLUDE", [ ]) + AC_DEFINE(DBA_TCADB, 1, [ ]) + THIS_LIBS=$LIB + ], [], [-L$THIS_PREFIX/$PHP_LIBDIR]) + if test -n "$THIS_LIBS"; then + break + fi + done + fi + + PHP_DBA_STD_ASSIGN + PHP_DBA_STD_CHECK + PHP_DBA_STD_ATTACH +fi +PHP_DBA_STD_RESULT(tcadb) + +dnl Berkeley specific (library and version test) +dnl parameters(version, library list, function) +AC_DEFUN([PHP_DBA_DB_CHECK],[ + if test -z "$THIS_INCLUDE"; then + AC_MSG_ERROR([DBA: Could not find necessary header file(s).]) + fi + for LIB in $2; do + if test -f $THIS_PREFIX/$PHP_LIBDIR/lib$LIB.a || test -f $THIS_PREFIX/$PHP_LIBDIR/lib$LIB.$SHLIB_SUFFIX_NAME; then + lib_found=""; + PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/$PHP_LIBDIR, -l$LIB,[ + AC_TRY_LINK([ +#include "$THIS_INCLUDE" + ],[ + $3; + ],[ + AC_EGREP_CPP(yes,[ +#include "$THIS_INCLUDE" +#if DB_VERSION_MAJOR == $1 || ($1 == 4 && DB_VERSION_MAJOR == 5) + yes +#endif + ],[ + THIS_LIBS=$LIB + lib_found=1 + ]) + ]) + ]) + if test -n "$lib_found"; then + lib_found=""; + break; + fi + fi + done + if test -z "$THIS_LIBS"; then + AC_MSG_CHECKING([for DB$1 major version]) + AC_MSG_ERROR([Header contains different version]) + fi + if test "$1" = "4"; then + AC_MSG_CHECKING([for DB4 minor version and patch level]) + AC_EGREP_CPP(yes,[ +#include "$THIS_INCLUDE" +#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR != 1) || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 1 && DB_VERSION_PATCH >= 25) + yes +#endif + ],[ + AC_MSG_RESULT(ok) + ],[ + AC_MSG_ERROR([Version 4.1 requires patch level 25]) + ]) + fi + if test "$ext_shared" = "yes"; then + AC_MSG_CHECKING([if dba can be used as shared extension]) + AC_EGREP_CPP(yes,[ +#include "$THIS_INCLUDE" +#if DB_VERSION_MAJOR > 3 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR > 2) + yes +#endif + ],[ + AC_MSG_RESULT(yes) + ],[ + AC_MSG_ERROR([At least version 3.3 is required]) + ]) + fi + if test -n "$THIS_LIBS"; then + AC_DEFINE(DBA_DB$1, 1, [ ]) + if test -n "$THIS_INCLUDE"; then + AC_DEFINE_UNQUOTED(DB$1_INCLUDE_FILE, "$THIS_INCLUDE", [ ]) + fi + else + AC_MSG_ERROR([DBA: Could not find necessary library.]) + fi + THIS_RESULT=yes + DB$1_LIBS=$THIS_LIBS + DB$1_PREFIX=$THIS_PREFIX + DB$1_INCLUDE=$THIS_INCLUDE + PHP_DBA_STD_ASSIGN + PHP_DBA_STD_ATTACH +]) + +# DB4 +if test "$PHP_DB4" != "no"; then + PHP_DBA_STD_BEGIN + dbdp4="/usr/local/BerkeleyDB.4." + dbdp5="/usr/local/BerkeleyDB.5." + for i in $PHP_DB4 ${dbdp5}1 ${dbdp5}0 ${dbdp4}8 ${dbdp4}7 ${dbdp4}6 ${dbdp4}5 ${dbdp4}4 ${dbdp4}3 ${dbdp4}2 ${dbdp4}1 ${dbdp}0 /usr/local /usr; do + if test -f "$i/db5/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/db5/db.h + break + elif test -f "$i/db4/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/db4/db.h + break + elif test -f "$i/include/db5.1/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db5.1/db.h + break + elif test -f "$i/include/db5.0/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db5.0/db.h + break + elif test -f "$i/include/db4.8/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db4.8/db.h + break + elif test -f "$i/include/db4.7/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db4.7/db.h + break + elif test -f "$i/include/db4.6/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db4.6/db.h + break + elif test -f "$i/include/db4.5/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db4.5/db.h + break + elif test -f "$i/include/db4/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db4/db.h + break + elif test -f "$i/include/db/db4.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db/db4.h + break + elif test -f "$i/include/db4.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db4.h + break + elif test -f "$i/include/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db.h + break + fi + done + PHP_DBA_DB_CHECK(4, db-5.1 db-5.0 db-4.8 db-4.7 db-4.6 db-4.5 db-4.4 db-4.3 db-4.2 db-4.1 db-4.0 db-4 db4 db, [(void)db_create((DB**)0, (DB_ENV*)0, 0)]) +fi +PHP_DBA_STD_RESULT(db4,Berkeley DB4) + +# DB3 +if test "$PHP_DB3" != "no"; then + PHP_DBA_STD_BEGIN + if test "$HAVE_DB4" = "1"; then + PHP_DBA_STD_RESULT(db3, Berkeley DB3, [You cannot combine --with-db3 with --with-db4]) + fi + for i in $PHP_DB3 /usr/local/BerkeleyDB.3.3 /usr/local/BerkeleyDB.3.2 /usr/local/BerkeleyDB.3.1 /usr/local/BerkeleyDB.3.0 /usr/local /usr; do + if test -f "$i/db3/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db3/db.h + break + elif test -f "$i/include/db3/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db3/db.h + break + elif test -f "$i/include/db/db3.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db/db3.h + break + elif test -f "$i/include/db3.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db3.h + break + elif test -f "$i/include/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db.h + break + fi + done + PHP_DBA_DB_CHECK(3, db-3.3 db-3.2 db-3.1 db-3.0 db-3 db3 db, [(void)db_create((DB**)0, (DB_ENV*)0, 0)]) +fi +PHP_DBA_STD_RESULT(db3,Berkeley DB3) + +# DB2 +if test "$PHP_DB2" != "no"; then + PHP_DBA_STD_BEGIN + if test "$HAVE_DB3" = "1" || test "$HAVE_DB4" = "1"; then + PHP_DBA_STD_RESULT(db2, Berkeley DB2, [You cannot combine --with-db2 with --with-db3 or --with-db4]) + fi + for i in $PHP_DB2 $PHP_DB2/BerkeleyDB /usr/BerkeleyDB /usr/local /usr; do + if test -f "$i/db2/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/db2/db.h + break + elif test -f "$i/include/db2/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db2/db.h + break + elif test -f "$i/include/db/db2.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db/db2.h + break + elif test -f "$i/include/db2.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db2.h + break + elif test -f "$i/include/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db.h + break + fi + done + PHP_DBA_DB_CHECK(2, db-2 db2 db, [(void)db_appinit("", NULL, (DB_ENV*)0, 0)]) +fi +PHP_DBA_STD_RESULT(db2, Berkeley DB2) + +# DB1 +if test "$PHP_DB1" != "no"; then + PHP_DBA_STD_BEGIN + AC_MSG_CHECKING([for DB1 in library]) + if test "$HAVE_DB4" = "1"; then + THIS_VERSION=4 + THIS_LIBS=$DB4_LIBS + THIS_PREFIX=$DB4_PREFIX + elif test "$HAVE_DB3" = "1"; then + THIS_LIBS=$DB3_LIBS + THIS_PREFIX=$DB3_PREFIX + elif test "$HAVE_DB2" = "1"; then + THIS_VERSION=2 + THIS_LIBS=$DB2_LIBS + THIS_PREFIX=$DB2_PREFIX + fi + if test "$HAVE_DB4" = "1" || test "$HAVE_DB3" = "1" || test "$HAVE_DB2" = "1"; then + AC_DEFINE_UNQUOTED(DB1_VERSION, "Berkeley DB 1.85 emulation in DB$THIS_VERSION", [ ]) + for i in db$THIS_VERSION/db_185.h include/db$THIS_VERSION/db_185.h include/db/db_185.h; do + if test -f "$THIS_PREFIX/$i"; then + THIS_INCLUDE=$THIS_PREFIX/$i + break + fi + done + else + AC_DEFINE_UNQUOTED(DB1_VERSION, "Unknown DB1", [ ]) + for i in $PHP_DB1 /usr/local /usr; do + if test -f "$i/db1/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/db1/db.h + break + elif test -f "$i/include/db1/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db1/db.h + break + elif test -f "$i/include/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db.h + break + fi + done + THIS_LIBS=db + fi + AC_MSG_RESULT([$THIS_LIBS]) + AC_MSG_CHECKING([for DB1 in header]) + AC_MSG_RESULT([$THIS_INCLUDE]) + if test -n "$THIS_INCLUDE"; then + PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/$PHP_LIBDIR, -l$THIS_LIBS,[ + AC_TRY_LINK([ +#include "$THIS_INCLUDE" + ],[ + DB * dbp = dbopen("", 0, 0, DB_HASH, 0); + ],[ + AC_DEFINE_UNQUOTED(DB1_INCLUDE_FILE, "$THIS_INCLUDE", [ ]) + AC_DEFINE(DBA_DB1, 1, [ ]) + THIS_RESULT=yes + ],[ + THIS_RESULT=no + ]) + ]) + fi + PHP_DBA_STD_ASSIGN + PHP_DBA_STD_CHECK + PHP_DBA_STD_ATTACH +fi +PHP_DBA_STD_RESULT(db1, DB1) + +# DBM +if test "$PHP_DBM" != "no"; then + PHP_DBA_STD_BEGIN + if test "$HAVE_QDBM" = "1"; then + PHP_DBA_STD_RESULT(dbm, dbm, [You cannot combine --with-dbm with --with-qdbm]) + fi + for i in $PHP_DBM /usr/local /usr; do + if test -f "$i/include/dbm.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/dbm.h + break + elif test -f "$i/include/gdbm/dbm.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/gdbm/dbm.h + break + fi + done + + if test -n "$THIS_INCLUDE"; then + for LIB in dbm c gdbm; do + PHP_CHECK_LIBRARY($LIB, dbminit, [ + AC_MSG_CHECKING(for DBM using GDBM) + AC_DEFINE_UNQUOTED(DBM_INCLUDE_FILE, "$THIS_INCLUDE", [ ]) + if test "$LIB" = "gdbm"; then + AC_DEFINE_UNQUOTED(DBM_VERSION, "GDBM", [ ]) + AC_MSG_RESULT(yes) + else + AC_DEFINE_UNQUOTED(DBM_VERSION, "DBM", [ ]) + AC_MSG_RESULT(no) + fi + AC_DEFINE(DBA_DBM, 1, [ ]) + THIS_LIBS=$LIB + ], [], [-L$THIS_PREFIX/$PHP_LIBDIR]) + if test -n "$THIS_LIBS"; then + break + fi + done + fi + + PHP_DBA_STD_ASSIGN + PHP_DBA_STD_CHECK + PHP_DBA_STD_ATTACH +fi +PHP_DBA_STD_RESULT(dbm) + +dnl +dnl Bundled modules that should be enabled by default if any other option is enabled +dnl +if test "$PHP_DBA" != "no" || test "$HAVE_DBA" = "1" || test "$with_cdb" = "yes" || test "$enable_inifile" = "yes" || test "$enable_flatfile" = "yes"; then + php_dba_enable=yes +else + php_dba_enable=no +fi + +PHP_ARG_WITH(cdb,, +[ --without-cdb[=DIR] DBA: CDB support (bundled)], $php_dba_enable, no) + +PHP_ARG_ENABLE(inifile,, +[ --disable-inifile DBA: INI support (bundled)], $php_dba_enable, no) + +PHP_ARG_ENABLE(flatfile,, +[ --disable-flatfile DBA: FlatFile support (bundled)], $php_dba_enable, no) + +# CDB +if test "$PHP_CDB" = "yes"; then + AC_DEFINE(DBA_CDB_BUILTIN, 1, [ ]) + AC_DEFINE(DBA_CDB_MAKE, 1, [ ]) + AC_DEFINE(DBA_CDB, 1, [ ]) + cdb_sources="libcdb/cdb.c libcdb/cdb_make.c libcdb/uint32.c" + THIS_RESULT="builtin" +elif test "$PHP_CDB" != "no"; then + PHP_DBA_STD_BEGIN + for i in $PHP_CDB /usr/local /usr; do + if test -f "$i/include/cdb.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/cdb.h + break + fi + done + + if test -n "$THIS_INCLUDE"; then + for LIB in cdb c; do + PHP_CHECK_LIBRARY($LIB, cdb_read, [ + AC_DEFINE_UNQUOTED(CDB_INCLUDE_FILE, "$THIS_INCLUDE", [ ]) + AC_DEFINE(DBA_CDB, 1, [ ]) + THIS_LIBS=$LIB + ], [], [-L$THIS_PREFIX/$PHP_LIBDIR]) + if test -n "$THIS_LIBS"; then + break + fi + done + fi + + PHP_DBA_STD_ASSIGN + PHP_DBA_STD_CHECK + PHP_DBA_STD_ATTACH +fi +PHP_DBA_STD_RESULT(cdb) + +# INIFILE +if test "$PHP_INIFILE" != "no"; then + AC_DEFINE(DBA_INIFILE, 1, [ ]) + ini_sources="libinifile/inifile.c" + THIS_RESULT="builtin" +fi +PHP_DBA_STD_RESULT(inifile, [INI File]) + +# FLATFILE +if test "$PHP_FLATFILE" != "no"; then + AC_DEFINE(DBA_FLATFILE, 1, [ ]) + flat_sources="libflatfile/flatfile.c" + THIS_RESULT="builtin" +fi +PHP_DBA_STD_RESULT(FlatFile, FlatFile) + +dnl +dnl Extension setup +dnl +AC_MSG_CHECKING([whether to enable DBA interface]) +if test "$HAVE_DBA" = "1"; then + if test "$ext_shared" = "yes"; then + AC_MSG_RESULT([yes, shared]) + else + AC_MSG_RESULT([yes]) + fi + AC_DEFINE(HAVE_DBA, 1, [ ]) + PHP_NEW_EXTENSION(dba, dba.c dba_cdb.c dba_dbm.c dba_gdbm.c dba_ndbm.c dba_db1.c dba_db2.c dba_db3.c dba_db4.c dba_flatfile.c dba_inifile.c dba_qdbm.c dba_tcadb.c $cdb_sources $flat_sources $ini_sources, $ext_shared) + PHP_ADD_BUILD_DIR($ext_builddir/libinifile) + PHP_ADD_BUILD_DIR($ext_builddir/libcdb) + PHP_ADD_BUILD_DIR($ext_builddir/libflatfile) + PHP_SUBST(DBA_SHARED_LIBADD) +else + AC_MSG_RESULT(no) +fi diff --git a/ext/dba/config.w32 b/ext/dba/config.w32 new file mode 100644 index 0000000..4f3514e --- /dev/null +++ b/ext/dba/config.w32 @@ -0,0 +1,18 @@ +// $Id$ +// vim:ft=javascript + +ARG_WITH("dba", "DBA support", "no"); + +if (PHP_DBA != "no") { + if (CHECK_LIB("libdb31s.lib", "dba", PHP_DBA) && + CHECK_HEADER_ADD_INCLUDE("db.h", "CFLAGS_DBA")) { + EXTENSION("dba", "dba.c dba_cdb.c dba_db1.c dba_db2.c dba_db3.c dba_dbm.c dba_flatfile.c dba_gdbm.c dba_ndbm.c dba_inifile.c"); + ADD_SOURCES("ext/dba/libcdb", "cdb.c cdb_make.c uint32.c", "dba"); + ADD_SOURCES("ext/dba/libflatfile", "flatfile.c", "dba"); + ADD_SOURCES("ext/dba/libinifile", "inifile.c", "dba"); + AC_DEFINE('HAVE_DBA', 1, 'DBA support'); + ADD_FLAG("CFLAGS_DBA", "/D DBA_DB1=0 /D DB1_VERSION=\"\\\"Berkeley DB 1.85 emulation in DB3\\\"\" /D DB1_INCLUDE_FILE=\"\\\"db_185.h\\\"\" /D DBA_DB3=1 /D DB3_INCLUDE_FILE=\"\\\"db.h\\\"\" /D DBA_FLATFILE=1 /D DBA_CDB=1 /D DBA_CDB_MAKE=1 /D DBA_CDB_BUILTIN=1 /D DBA_INIFILE=1"); + } else { + WARNING("dba not enabled; libraries and headers not found"); + } +} diff --git a/ext/dba/dba.c b/ext/dba/dba.c new file mode 100644 index 0000000..303d65c --- /dev/null +++ b/ext/dba/dba.c @@ -0,0 +1,1247 @@ +/* + +----------------------------------------------------------------------+ + | 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: Sascha Schumann <sascha@schumann.cx> | + | Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if HAVE_DBA + +#include "php_ini.h" +#include <stdio.h> +#include <fcntl.h> +#ifdef HAVE_SYS_FILE_H +#include <sys/file.h> +#endif + +#include "php_dba.h" +#include "ext/standard/info.h" +#include "ext/standard/php_string.h" +#include "ext/standard/flock_compat.h" + +#include "php_gdbm.h" +#include "php_ndbm.h" +#include "php_dbm.h" +#include "php_cdb.h" +#include "php_db1.h" +#include "php_db2.h" +#include "php_db3.h" +#include "php_db4.h" +#include "php_flatfile.h" +#include "php_inifile.h" +#include "php_qdbm.h" +#include "php_tcadb.h" + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dba_popen, 0, 0, 2) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, mode) + ZEND_ARG_INFO(0, handlername) + ZEND_ARG_INFO(0, ...) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dba_open, 0, 0, 2) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, mode) + ZEND_ARG_INFO(0, handlername) + ZEND_ARG_INFO(0, ...) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_dba_close, 0) + ZEND_ARG_INFO(0, handle) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_dba_exists, 0) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, handle) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dba_fetch, 0, 0, 2) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, skip) + ZEND_ARG_INFO(0, handle) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_dba_key_split, 0) + ZEND_ARG_INFO(0, key) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_dba_firstkey, 0) + ZEND_ARG_INFO(0, handle) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_dba_nextkey, 0) + ZEND_ARG_INFO(0, handle) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_dba_delete, 0) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, handle) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_dba_insert, 0) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, handle) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_dba_replace, 0) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, handle) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_dba_optimize, 0) + ZEND_ARG_INFO(0, handle) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_dba_sync, 0) + ZEND_ARG_INFO(0, handle) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dba_handlers, 0, 0, 0) + ZEND_ARG_INFO(0, full_info) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_dba_list, 0) +ZEND_END_ARG_INFO() + +/* }}} */ + +/* {{{ dba_functions[] + */ +const zend_function_entry dba_functions[] = { + PHP_FE(dba_open, arginfo_dba_open) + PHP_FE(dba_popen, arginfo_dba_popen) + PHP_FE(dba_close, arginfo_dba_close) + PHP_FE(dba_delete, arginfo_dba_delete) + PHP_FE(dba_exists, arginfo_dba_exists) + PHP_FE(dba_fetch, arginfo_dba_fetch) + PHP_FE(dba_insert, arginfo_dba_insert) + PHP_FE(dba_replace, arginfo_dba_replace) + PHP_FE(dba_firstkey, arginfo_dba_firstkey) + PHP_FE(dba_nextkey, arginfo_dba_nextkey) + PHP_FE(dba_optimize, arginfo_dba_optimize) + PHP_FE(dba_sync, arginfo_dba_sync) + PHP_FE(dba_handlers, arginfo_dba_handlers) + PHP_FE(dba_list, arginfo_dba_list) + PHP_FE(dba_key_split, arginfo_dba_key_split) + PHP_FE_END +}; +/* }}} */ + +PHP_MINIT_FUNCTION(dba); +PHP_MSHUTDOWN_FUNCTION(dba); +PHP_MINFO_FUNCTION(dba); + +ZEND_BEGIN_MODULE_GLOBALS(dba) + char *default_handler; + dba_handler *default_hptr; +ZEND_END_MODULE_GLOBALS(dba) + +ZEND_DECLARE_MODULE_GLOBALS(dba) + +#ifdef ZTS +#define DBA_G(v) TSRMG(dba_globals_id, zend_dba_globals *, v) +#else +#define DBA_G(v) (dba_globals.v) +#endif + +static PHP_GINIT_FUNCTION(dba); + +zend_module_entry dba_module_entry = { + STANDARD_MODULE_HEADER, + "dba", + dba_functions, + PHP_MINIT(dba), + PHP_MSHUTDOWN(dba), + NULL, + NULL, + PHP_MINFO(dba), + NO_VERSION_YET, + PHP_MODULE_GLOBALS(dba), + PHP_GINIT(dba), + NULL, + NULL, + STANDARD_MODULE_PROPERTIES_EX +}; + +#ifdef COMPILE_DL_DBA +ZEND_GET_MODULE(dba) +#endif + +/* {{{ macromania */ + +#define DBA_ID_PARS \ + zval *id; \ + dba_info *info = NULL; \ + int ac = ZEND_NUM_ARGS() + +/* these are used to get the standard arguments */ + +/* {{{ php_dba_myke_key */ +static size_t php_dba_make_key(zval *key, char **key_str, char **key_free TSRMLS_DC) +{ + if (Z_TYPE_P(key) == IS_ARRAY) { + zval **group, **name; + HashPosition pos; + size_t len; + + if (zend_hash_num_elements(Z_ARRVAL_P(key)) != 2) { + php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "Key does not have exactly two elements: (key, name)"); + return -1; + } + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(key), &pos); + zend_hash_get_current_data_ex(Z_ARRVAL_P(key), (void **) &group, &pos); + zend_hash_move_forward_ex(Z_ARRVAL_P(key), &pos); + zend_hash_get_current_data_ex(Z_ARRVAL_P(key), (void **) &name, &pos); + convert_to_string_ex(group); + convert_to_string_ex(name); + if (Z_STRLEN_PP(group) == 0) { + *key_str = Z_STRVAL_PP(name); + *key_free = NULL; + return Z_STRLEN_PP(name); + } + len = spprintf(key_str, 0, "[%s]%s", Z_STRVAL_PP(group), Z_STRVAL_PP(name)); + *key_free = *key_str; + return len; + } else { + *key_free = NULL; + + convert_to_string(key); + *key_str = Z_STRVAL_P(key); + + return Z_STRLEN_P(key); + } +} +/* }}} */ + +#define DBA_GET2 \ + zval *key; \ + char *key_str, *key_free; \ + size_t key_len; \ + if (zend_parse_parameters(ac TSRMLS_CC, "zr", &key, &id) == FAILURE) { \ + return; \ + } \ + if ((key_len = php_dba_make_key(key, &key_str, &key_free TSRMLS_CC)) == 0) {\ + RETURN_FALSE; \ + } + +#define DBA_GET2_3 \ + zval *key; \ + char *key_str, *key_free; \ + size_t key_len; \ + long skip = 0; \ + switch(ac) { \ + case 2: \ + if (zend_parse_parameters(ac TSRMLS_CC, "zr", &key, &id) == FAILURE) { \ + return; \ + } \ + break; \ + case 3: \ + if (zend_parse_parameters(ac TSRMLS_CC, "zlr", &key, &skip, &id) == FAILURE) { \ + return; \ + } \ + break; \ + default: \ + WRONG_PARAM_COUNT; \ + } \ + if ((key_len = php_dba_make_key(key, &key_str, &key_free TSRMLS_CC)) == 0) {\ + RETURN_FALSE; \ + } + + +#define DBA_FETCH_RESOURCE(info, id) \ + ZEND_FETCH_RESOURCE2(info, dba_info *, id, -1, "DBA identifier", le_db, le_pdb); + +#define DBA_ID_GET2 DBA_ID_PARS; DBA_GET2; DBA_FETCH_RESOURCE(info, &id) +#define DBA_ID_GET2_3 DBA_ID_PARS; DBA_GET2_3; DBA_FETCH_RESOURCE(info, &id) + +#define DBA_ID_DONE \ + if (key_free) efree(key_free) +/* a DBA handler must have specific routines */ + +#define DBA_NAMED_HND(alias, name, flags) \ +{\ + #alias, flags, dba_open_##name, dba_close_##name, dba_fetch_##name, dba_update_##name, \ + dba_exists_##name, dba_delete_##name, dba_firstkey_##name, dba_nextkey_##name, \ + dba_optimize_##name, dba_sync_##name, dba_info_##name \ +}, + +#define DBA_HND(name, flags) DBA_NAMED_HND(name, name, flags) + +/* check whether the user has write access */ +#define DBA_WRITE_CHECK \ + if(info->mode != DBA_WRITER && info->mode != DBA_TRUNC && info->mode != DBA_CREAT) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "You cannot perform a modification to a database without proper access"); \ + RETURN_FALSE; \ + } + +/* }}} */ + +/* {{{ globals */ + +static dba_handler handler[] = { +#if DBA_GDBM + DBA_HND(gdbm, DBA_LOCK_EXT) /* Locking done in library if set */ +#endif +#if DBA_DBM + DBA_HND(dbm, DBA_LOCK_ALL) /* No lock in lib */ +#endif +#if DBA_NDBM + DBA_HND(ndbm, DBA_LOCK_ALL) /* Could be done in library: filemode = 0644 + S_ENFMT */ +#endif +#if DBA_CDB + DBA_HND(cdb, DBA_STREAM_OPEN|DBA_LOCK_ALL) /* No lock in lib */ +#endif +#if DBA_CDB_BUILTIN + DBA_NAMED_HND(cdb_make, cdb, DBA_STREAM_OPEN|DBA_LOCK_ALL) /* No lock in lib */ +#endif +#if DBA_DB1 + DBA_HND(db1, DBA_LOCK_ALL) /* No lock in lib */ +#endif +#if DBA_DB2 + DBA_HND(db2, DBA_LOCK_ALL) /* No lock in lib */ +#endif +#if DBA_DB3 + DBA_HND(db3, DBA_LOCK_ALL) /* No lock in lib */ +#endif +#if DBA_DB4 + DBA_HND(db4, DBA_LOCK_ALL) /* No lock in lib */ +#endif +#if DBA_INIFILE + DBA_HND(inifile, DBA_STREAM_OPEN|DBA_LOCK_ALL|DBA_CAST_AS_FD) /* No lock in lib */ +#endif +#if DBA_FLATFILE + DBA_HND(flatfile, DBA_STREAM_OPEN|DBA_LOCK_ALL|DBA_NO_APPEND) /* No lock in lib */ +#endif +#if DBA_QDBM + DBA_HND(qdbm, DBA_LOCK_EXT) +#endif +#if DBA_TCADB + DBA_HND(tcadb, DBA_LOCK_ALL) +#endif + { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } +}; + +#if DBA_FLATFILE +#define DBA_DEFAULT "flatfile" +#elif DBA_DB4 +#define DBA_DEFAULT "db4" +#elif DBA_DB3 +#define DBA_DEFAULT "db3" +#elif DBA_DB2 +#define DBA_DEFAULT "db2" +#elif DBA_DB1 +#define DBA_DEFAULT "db1" +#elif DBA_GDBM +#define DBA_DEFAULT "gdbm" +#elif DBA_NBBM +#define DBA_DEFAULT "ndbm" +#elif DBA_DBM +#define DBA_DEFAULT "dbm" +#elif DBA_QDBM +#define DBA_DEFAULT "qdbm" +#elif DBA_TCADB +#define DBA_DEFAULT "tcadb" +#else +#define DBA_DEFAULT "" +#endif +/* cdb/cdb_make and ini are no option here */ + +static int le_db; +static int le_pdb; +/* }}} */ + +/* {{{ dba_fetch_resource +PHPAPI void dba_fetch_resource(dba_info **pinfo, zval **id TSRMLS_DC) +{ + dba_info *info; + DBA_ID_FETCH + *pinfo = info; +} +*/ +/* }}} */ + +/* {{{ dba_get_handler +PHPAPI dba_handler *dba_get_handler(const char* handler_name) +{ + dba_handler *hptr; + for (hptr = handler; hptr->name && strcasecmp(hptr->name, handler_name); hptr++); + return hptr; +} +*/ +/* }}} */ + +/* {{{ dba_close + */ +static void dba_close(dba_info *info TSRMLS_DC) +{ + if (info->hnd) { + info->hnd->close(info TSRMLS_CC); + } + if (info->path) { + pefree(info->path, info->flags&DBA_PERSISTENT); + } + if (info->fp && info->fp!=info->lock.fp) { + if(info->flags&DBA_PERSISTENT) { + php_stream_pclose(info->fp); + } else { + php_stream_close(info->fp); + } + } + if (info->lock.fp) { + if(info->flags&DBA_PERSISTENT) { + php_stream_pclose(info->lock.fp); + } else { + php_stream_close(info->lock.fp); + } + } + if (info->lock.name) { + pefree(info->lock.name, info->flags&DBA_PERSISTENT); + } + pefree(info, info->flags&DBA_PERSISTENT); +} +/* }}} */ + +/* {{{ dba_close_rsrc + */ +static void dba_close_rsrc(zend_rsrc_list_entry *rsrc TSRMLS_DC) +{ + dba_info *info = (dba_info *)rsrc->ptr; + + dba_close(info TSRMLS_CC); +} +/* }}} */ + +/* {{{ dba_close_pe_rsrc_deleter */ +int dba_close_pe_rsrc_deleter(zend_rsrc_list_entry *le, void *pDba TSRMLS_DC) +{ + return le->ptr == pDba; +} +/* }}} */ + +/* {{{ dba_close_pe_rsrc */ +static void dba_close_pe_rsrc(zend_rsrc_list_entry *rsrc TSRMLS_DC) +{ + dba_info *info = (dba_info *)rsrc->ptr; + + /* closes the resource by calling dba_close_rsrc() */ + zend_hash_apply_with_argument(&EG(persistent_list), (apply_func_arg_t) dba_close_pe_rsrc_deleter, info TSRMLS_CC); +} +/* }}} */ + +/* {{{ PHP_INI + */ +ZEND_INI_MH(OnUpdateDefaultHandler) +{ + dba_handler *hptr; + + if (!strlen(new_value)) { + DBA_G(default_hptr) = NULL; + return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); + } + + for (hptr = handler; hptr->name && strcasecmp(hptr->name, new_value); hptr++); + + if (!hptr->name) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such handler: %s", new_value); + return FAILURE; + } + DBA_G(default_hptr) = hptr; + return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); +} + +PHP_INI_BEGIN() + STD_PHP_INI_ENTRY("dba.default_handler", DBA_DEFAULT, PHP_INI_ALL, OnUpdateDefaultHandler, default_handler, zend_dba_globals, dba_globals) +PHP_INI_END() +/* }}} */ + +/* {{{ PHP_GINIT_FUNCTION + */ +static PHP_GINIT_FUNCTION(dba) +{ + dba_globals->default_handler = ""; + dba_globals->default_hptr = NULL; +} +/* }}} */ + +/* {{{ PHP_MINIT_FUNCTION + */ +PHP_MINIT_FUNCTION(dba) +{ + REGISTER_INI_ENTRIES(); + le_db = zend_register_list_destructors_ex(dba_close_rsrc, NULL, "dba", module_number); + le_pdb = zend_register_list_destructors_ex(dba_close_pe_rsrc, dba_close_rsrc, "dba persistent", module_number); + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MSHUTDOWN_FUNCTION + */ +PHP_MSHUTDOWN_FUNCTION(dba) +{ + UNREGISTER_INI_ENTRIES(); + return SUCCESS; +} +/* }}} */ + +#include "ext/standard/php_smart_str.h" + +/* {{{ PHP_MINFO_FUNCTION + */ +PHP_MINFO_FUNCTION(dba) +{ + dba_handler *hptr; + smart_str handlers = {0}; + + for(hptr = handler; hptr->name; hptr++) { + smart_str_appends(&handlers, hptr->name); + smart_str_appendc(&handlers, ' '); + } + + php_info_print_table_start(); + php_info_print_table_row(2, "DBA support", "enabled"); + if (handlers.c) { + smart_str_0(&handlers); + php_info_print_table_row(2, "Supported handlers", handlers.c); + smart_str_free(&handlers); + } else { + php_info_print_table_row(2, "Supported handlers", "none"); + } + php_info_print_table_end(); + DISPLAY_INI_ENTRIES(); +} +/* }}} */ + +/* {{{ php_dba_update + */ +static void php_dba_update(INTERNAL_FUNCTION_PARAMETERS, int mode) +{ + char *v; + int val_len; + zval *id; + dba_info *info = NULL; + int ac = ZEND_NUM_ARGS(); + zval *key; + char *val; + char *key_str, *key_free; + size_t key_len; + + if (zend_parse_parameters(ac TSRMLS_CC, "zsr", &key, &val, &val_len, &id) == FAILURE) { + return; + } + + if ((key_len = php_dba_make_key(key, &key_str, &key_free TSRMLS_CC)) == 0) { + RETURN_FALSE; + } + + DBA_FETCH_RESOURCE(info, &id); + + DBA_WRITE_CHECK; + + if (info->hnd->update(info, key_str, key_len, val, val_len, mode TSRMLS_CC) == SUCCESS) { + DBA_ID_DONE; + RETURN_TRUE; + } + + DBA_ID_DONE; + RETURN_FALSE; +} +/* }}} */ + +#define FREENOW if(args) efree(args); if(key) efree(key) + +/* {{{ php_find_dbm + */ +dba_info *php_dba_find(const char* path TSRMLS_DC) +{ + zend_rsrc_list_entry *le; + dba_info *info; + int numitems, i; + + numitems = zend_hash_next_free_element(&EG(regular_list)); + for (i=1; i<numitems; i++) { + if (zend_hash_index_find(&EG(regular_list), i, (void **) &le)==FAILURE) { + continue; + } + if (Z_TYPE_P(le) == le_db || Z_TYPE_P(le) == le_pdb) { + info = (dba_info *)(le->ptr); + if (!strcmp(info->path, path)) { + return (dba_info *)(le->ptr); + } + } + } + + return NULL; +} +/* }}} */ + +/* {{{ php_dba_open + */ +static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent) +{ + zval ***args = (zval ***) NULL; + int ac = ZEND_NUM_ARGS(); + dba_mode_t modenr; + dba_info *info, *other; + dba_handler *hptr; + char *key = NULL, *error = NULL; + int keylen = 0; + int i; + int lock_mode, lock_flag, lock_dbf = 0; + char *file_mode; + char mode[4], *pmode, *lock_file_mode = NULL; + int persistent_flag = persistent ? STREAM_OPEN_PERSISTENT : 0; + char *opened_path, *lock_name; + + if(ac < 2) { + WRONG_PARAM_COUNT; + } + + /* we pass additional args to the respective handler */ + args = safe_emalloc(ac, sizeof(zval *), 0); + if (zend_get_parameters_array_ex(ac, args) != SUCCESS) { + FREENOW; + WRONG_PARAM_COUNT; + } + + /* we only take string arguments */ + for (i = 0; i < ac; i++) { + convert_to_string_ex(args[i]); + keylen += Z_STRLEN_PP(args[i]); + } + + if (persistent) { + zend_rsrc_list_entry *le; + + /* calculate hash */ + key = safe_emalloc(keylen, 1, 1); + key[keylen] = '\0'; + keylen = 0; + + for(i = 0; i < ac; i++) { + memcpy(key+keylen, Z_STRVAL_PP(args[i]), Z_STRLEN_PP(args[i])); + keylen += Z_STRLEN_PP(args[i]); + } + + /* try to find if we already have this link in our persistent list */ + if (zend_hash_find(&EG(persistent_list), key, keylen+1, (void **) &le) == SUCCESS) { + FREENOW; + + if (Z_TYPE_P(le) != le_pdb) { + RETURN_FALSE; + } + + info = (dba_info *)le->ptr; + + ZEND_REGISTER_RESOURCE(return_value, info, le_pdb); + return; + } + } + + if (ac==2) { + hptr = DBA_G(default_hptr); + if (!hptr) { + php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "No default handler selected"); + FREENOW; + RETURN_FALSE; + } + } else { + for (hptr = handler; hptr->name && strcasecmp(hptr->name, Z_STRVAL_PP(args[2])); hptr++); + } + + if (!hptr->name) { + php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "No such handler: %s", Z_STRVAL_PP(args[2])); + FREENOW; + RETURN_FALSE; + } + + /* Check mode: [rwnc][fl]?t? + * r: Read + * w: Write + * n: Create/Truncate + * c: Create + * + * d: force lock on database file + * l: force lock on lck file + * -: ignore locking + * + * t: test open database, warning if locked + */ + strlcpy(mode, Z_STRVAL_PP(args[1]), sizeof(mode)); + pmode = &mode[0]; + if (pmode[0] && (pmode[1]=='d' || pmode[1]=='l' || pmode[1]=='-')) { /* force lock on db file or lck file or disable locking */ + switch (pmode[1]) { + case 'd': + lock_dbf = 1; + if ((hptr->flags & DBA_LOCK_ALL) == 0) { + lock_flag = (hptr->flags & DBA_LOCK_ALL); + break; + } + /* no break */ + case 'l': + lock_flag = DBA_LOCK_ALL; + if ((hptr->flags & DBA_LOCK_ALL) == 0) { + php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_NOTICE, "Handler %s does locking internally", hptr->name); + } + break; + default: + case '-': + if ((hptr->flags & DBA_LOCK_ALL) == 0) { + php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "Locking cannot be disabled for handler %s", hptr->name); + FREENOW; + RETURN_FALSE; + } + lock_flag = 0; + break; + } + } else { + lock_flag = (hptr->flags&DBA_LOCK_ALL); + lock_dbf = 1; + } + switch (*pmode++) { + case 'r': + modenr = DBA_READER; + lock_mode = (lock_flag & DBA_LOCK_READER) ? LOCK_SH : 0; + file_mode = "r"; + break; + case 'w': + modenr = DBA_WRITER; + lock_mode = (lock_flag & DBA_LOCK_WRITER) ? LOCK_EX : 0; + file_mode = "r+b"; + break; + case 'c': + modenr = DBA_CREAT; + lock_mode = (lock_flag & DBA_LOCK_CREAT) ? LOCK_EX : 0; + if (lock_mode) { + if (lock_dbf) { + /* the create/append check will be done on the lock + * when the lib opens the file it is already created + */ + file_mode = "r+b"; /* read & write, seek 0 */ + lock_file_mode = "a+b"; /* append */ + } else { + file_mode = "a+b"; /* append */ + lock_file_mode = "w+b"; /* create/truncate */ + } + } else { + file_mode = "a+b"; + } + /* In case of the 'a+b' append mode, the handler is responsible + * to handle any rewind problems (see flatfile handler). + */ + break; + case 'n': + modenr = DBA_TRUNC; + lock_mode = (lock_flag & DBA_LOCK_TRUNC) ? LOCK_EX : 0; + file_mode = "w+b"; + break; + default: + php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "Illegal DBA mode"); + FREENOW; + RETURN_FALSE; + } + if (!lock_file_mode) { + lock_file_mode = file_mode; + } + if (*pmode=='d' || *pmode=='l' || *pmode=='-') { + pmode++; /* done already - skip here */ + } + if (*pmode=='t') { + pmode++; + if (!lock_flag) { + php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "You cannot combine modifiers - (no lock) and t (test lock)"); + FREENOW; + RETURN_FALSE; + } + if (!lock_mode) { + if ((hptr->flags & DBA_LOCK_ALL) == 0) { + php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "Handler %s uses its own locking which doesn't support mode modifier t (test lock)", hptr->name); + FREENOW; + RETURN_FALSE; + } else { + php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "Handler %s doesn't uses locking for this mode which makes modifier t (test lock) obsolete", hptr->name); + FREENOW; + RETURN_FALSE; + } + } else { + lock_mode |= LOCK_NB; /* test =: non blocking */ + } + } + if (*pmode) { + php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "Illegal DBA mode"); + FREENOW; + RETURN_FALSE; + } + + info = pemalloc(sizeof(dba_info), persistent); + memset(info, 0, sizeof(dba_info)); + info->path = pestrdup(Z_STRVAL_PP(args[0]), persistent); + info->mode = modenr; + info->argc = ac - 3; + info->argv = args + 3; + info->flags = (hptr->flags & ~DBA_LOCK_ALL) | (lock_flag & DBA_LOCK_ALL) | (persistent ? DBA_PERSISTENT : 0); + info->lock.mode = lock_mode; + + /* if any open call is a locking call: + * check if we already habe a locking call open that should block this call + * the problem is some systems would allow read during write + */ + if (hptr->flags & DBA_LOCK_ALL) { + if ((other = php_dba_find(info->path TSRMLS_CC)) != NULL) { + if ( ( (lock_mode&LOCK_EX) && (other->lock.mode&(LOCK_EX|LOCK_SH)) ) + || ( (other->lock.mode&LOCK_EX) && (lock_mode&(LOCK_EX|LOCK_SH)) ) + ) { + error = "Unable to establish lock (database file already open)"; /* force failure exit */ + } + } + } + + if (!error && lock_mode) { + if (lock_dbf) { + lock_name = Z_STRVAL_PP(args[0]); + } else { + spprintf(&lock_name, 0, "%s.lck", info->path); + if (!strcmp(file_mode, "r")) { + /* when in read only mode try to use existing .lck file first */ + /* do not log errors for .lck file while in read ony mode on .lck file */ + lock_file_mode = "rb"; + info->lock.fp = php_stream_open_wrapper(lock_name, lock_file_mode, STREAM_MUST_SEEK|IGNORE_PATH|persistent_flag, &opened_path); + } + if (!info->lock.fp) { + /* when not in read mode or failed to open .lck file read only. now try again in create(write) mode and log errors */ + lock_file_mode = "a+b"; + } else { + if (!persistent) { + info->lock.name = opened_path; + } else { + info->lock.name = pestrdup(opened_path, persistent); + efree(opened_path); + } + } + } + if (!info->lock.fp) { + info->lock.fp = php_stream_open_wrapper(lock_name, lock_file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|persistent_flag, &opened_path); + if (info->lock.fp) { + if (lock_dbf) { + /* replace the path info with the real path of the opened file */ + pefree(info->path, persistent); + info->path = pestrdup(opened_path, persistent); + } + /* now store the name of the lock */ + if (!persistent) { + info->lock.name = opened_path; + } else { + info->lock.name = pestrdup(opened_path, persistent); + efree(opened_path); + } + } + } + if (!lock_dbf) { + efree(lock_name); + } + if (!info->lock.fp) { + dba_close(info TSRMLS_CC); + /* stream operation already wrote an error message */ + FREENOW; + RETURN_FALSE; + } + if (!php_stream_supports_lock(info->lock.fp)) { + error = "Stream does not support locking"; + } + if (php_stream_lock(info->lock.fp, lock_mode)) { + error = "Unable to establish lock"; /* force failure exit */ + } + } + + /* centralised open stream for builtin */ + if (!error && (hptr->flags&DBA_STREAM_OPEN)==DBA_STREAM_OPEN) { + if (info->lock.fp && lock_dbf) { + info->fp = info->lock.fp; /* use the same stream for locking and database access */ + } else { + info->fp = php_stream_open_wrapper(info->path, file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|persistent_flag, NULL); + } + if (!info->fp) { + dba_close(info TSRMLS_CC); + /* stream operation already wrote an error message */ + FREENOW; + RETURN_FALSE; + } + if (hptr->flags & (DBA_NO_APPEND|DBA_CAST_AS_FD)) { + /* Needed becasue some systems do not allow to write to the original + * file contents with O_APPEND being set. + */ + if (SUCCESS != php_stream_cast(info->fp, PHP_STREAM_AS_FD, (void*)&info->fd, 1)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not cast stream"); + dba_close(info TSRMLS_CC); + FREENOW; + RETURN_FALSE; +#ifdef F_SETFL + } else if (modenr == DBA_CREAT) { + int flags = fcntl(info->fd, F_SETFL); + fcntl(info->fd, F_SETFL, flags & ~O_APPEND); +#endif + } + + } + } + + if (error || hptr->open(info, &error TSRMLS_CC) != SUCCESS) { + dba_close(info TSRMLS_CC); + php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "Driver initialization failed for handler: %s%s%s", hptr->name, error?": ":"", error?error:""); + FREENOW; + RETURN_FALSE; + } + + info->hnd = hptr; + info->argc = 0; + info->argv = NULL; + + if (persistent) { + zend_rsrc_list_entry new_le; + + Z_TYPE(new_le) = le_pdb; + new_le.ptr = info; + if (zend_hash_update(&EG(persistent_list), key, keylen+1, &new_le, sizeof(zend_rsrc_list_entry), NULL) == FAILURE) { + dba_close(info TSRMLS_CC); + php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "Could not register persistent resource"); + FREENOW; + RETURN_FALSE; + } + } + + ZEND_REGISTER_RESOURCE(return_value, info, (persistent ? le_pdb : le_db)); + FREENOW; +} +/* }}} */ +#undef FREENOW + +/* {{{ proto resource dba_popen(string path, string mode [, string handlername, string ...]) + Opens path using the specified handler in mode persistently */ +PHP_FUNCTION(dba_popen) +{ + php_dba_open(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +/* {{{ proto resource dba_open(string path, string mode [, string handlername, string ...]) + Opens path using the specified handler in mode*/ +PHP_FUNCTION(dba_open) +{ + php_dba_open(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ + +/* {{{ proto void dba_close(resource handle) + Closes database */ +PHP_FUNCTION(dba_close) +{ + zval *id; + dba_info *info = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &id) == FAILURE) { + return; + } + + DBA_FETCH_RESOURCE(info, &id); + + zend_list_delete(Z_RESVAL_P(id)); +} +/* }}} */ + +/* {{{ proto bool dba_exists(string key, resource handle) + Checks, if the specified key exists */ +PHP_FUNCTION(dba_exists) +{ + DBA_ID_GET2; + + if(info->hnd->exists(info, key_str, key_len TSRMLS_CC) == SUCCESS) { + DBA_ID_DONE; + RETURN_TRUE; + } + DBA_ID_DONE; + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto string dba_fetch(string key, [int skip ,] resource handle) + Fetches the data associated with key */ +PHP_FUNCTION(dba_fetch) +{ + char *val; + int len = 0; + DBA_ID_GET2_3; + + if (ac==3) { + if (!strcmp(info->hnd->name, "cdb")) { + if (skip < 0) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Handler %s accepts only skip values greater than or equal to zero, using skip=0", info->hnd->name); + skip = 0; + } + } else if (!strcmp(info->hnd->name, "inifile")) { + /* "-1" is compareable to 0 but allows a non restrictive + * access which is fater. For example 'inifile' uses this + * to allow faster access when the key was already found + * using firstkey/nextkey. However explicitly setting the + * value to 0 ensures the first value. + */ + if (skip < -1) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Handler %s accepts only skip value -1 and greater, using skip=0", info->hnd->name); + skip = 0; + } + } else { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Handler %s does not support optional skip parameter, the value will be ignored", info->hnd->name); + skip = 0; + } + } else { + skip = 0; + } + if((val = info->hnd->fetch(info, key_str, key_len, skip, &len TSRMLS_CC)) != NULL) { + DBA_ID_DONE; + RETURN_STRINGL(val, len, 0); + } + DBA_ID_DONE; + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto array|false dba_key_split(string key) + Splits an inifile key into an array of the form array(0=>group,1=>value_name) but returns false if input is false or null */ +PHP_FUNCTION(dba_key_split) +{ + zval *zkey; + char *key, *name; + int key_len; + + if (ZEND_NUM_ARGS() != 1) { + WRONG_PARAM_COUNT; + } + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "z", &zkey) == SUCCESS) { + if (Z_TYPE_P(zkey) == IS_NULL || (Z_TYPE_P(zkey) == IS_BOOL && !Z_LVAL_P(zkey))) { + RETURN_BOOL(0); + } + } + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &key, &key_len) == FAILURE) { + RETURN_BOOL(0); + } + array_init(return_value); + if (key[0] == '[' && (name = strchr(key, ']')) != NULL) { + add_next_index_stringl(return_value, key+1, name - (key + 1), 1); + add_next_index_stringl(return_value, name+1, key_len - (name - key + 1), 1); + } else { + add_next_index_stringl(return_value, "", 0, 1); + add_next_index_stringl(return_value, key, key_len, 1); + } +} +/* }}} */ + +/* {{{ proto string dba_firstkey(resource handle) + Resets the internal key pointer and returns the first key */ +PHP_FUNCTION(dba_firstkey) +{ + char *fkey; + int len; + zval *id; + dba_info *info = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &id) == FAILURE) { + return; + } + + DBA_FETCH_RESOURCE(info, &id); + + fkey = info->hnd->firstkey(info, &len TSRMLS_CC); + + if (fkey) + RETURN_STRINGL(fkey, len, 0); + + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto string dba_nextkey(resource handle) + Returns the next key */ +PHP_FUNCTION(dba_nextkey) +{ + char *nkey; + int len; + zval *id; + dba_info *info = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &id) == FAILURE) { + return; + } + + DBA_FETCH_RESOURCE(info, &id); + + nkey = info->hnd->nextkey(info, &len TSRMLS_CC); + + if (nkey) + RETURN_STRINGL(nkey, len, 0); + + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto bool dba_delete(string key, resource handle) + Deletes the entry associated with key + If inifile: remove all other key lines */ +PHP_FUNCTION(dba_delete) +{ + DBA_ID_GET2; + + DBA_WRITE_CHECK; + + if(info->hnd->delete(info, key_str, key_len TSRMLS_CC) == SUCCESS) + { + DBA_ID_DONE; + RETURN_TRUE; + } + DBA_ID_DONE; + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto bool dba_insert(string key, string value, resource handle) + If not inifile: Insert value as key, return false, if key exists already + If inifile: Add vakue as key (next instance of key) */ +PHP_FUNCTION(dba_insert) +{ + php_dba_update(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +/* {{{ proto bool dba_replace(string key, string value, resource handle) + Inserts value as key, replaces key, if key exists already + If inifile: remove all other key lines */ +PHP_FUNCTION(dba_replace) +{ + php_dba_update(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ + +/* {{{ proto bool dba_optimize(resource handle) + Optimizes (e.g. clean up, vacuum) database */ +PHP_FUNCTION(dba_optimize) +{ + zval *id; + dba_info *info = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &id) == FAILURE) { + return; + } + + DBA_FETCH_RESOURCE(info, &id); + + DBA_WRITE_CHECK; + + if (info->hnd->optimize(info TSRMLS_CC) == SUCCESS) { + RETURN_TRUE; + } + + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto bool dba_sync(resource handle) + Synchronizes database */ +PHP_FUNCTION(dba_sync) +{ + zval *id; + dba_info *info = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &id) == FAILURE) { + return; + } + + DBA_FETCH_RESOURCE(info, &id); + + if (info->hnd->sync(info TSRMLS_CC) == SUCCESS) { + RETURN_TRUE; + } + + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto array dba_handlers([bool full_info]) + List configured database handlers */ +PHP_FUNCTION(dba_handlers) +{ + dba_handler *hptr; + zend_bool full_info = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &full_info) == FAILURE) { + RETURN_FALSE; + } + + array_init(return_value); + + for(hptr = handler; hptr->name; hptr++) { + if (full_info) { + add_assoc_string(return_value, hptr->name, hptr->info(hptr, NULL TSRMLS_CC), 0); + } else { + add_next_index_string(return_value, hptr->name, 1); + } + } +} +/* }}} */ + +/* {{{ proto array dba_list() + List opened databases */ +PHP_FUNCTION(dba_list) +{ + ulong numitems, i; + zend_rsrc_list_entry *le; + dba_info *info; + + if (zend_parse_parameters_none() == FAILURE) { + RETURN_FALSE; + } + + array_init(return_value); + + numitems = zend_hash_next_free_element(&EG(regular_list)); + for (i=1; i<numitems; i++) { + if (zend_hash_index_find(&EG(regular_list), i, (void **) &le)==FAILURE) { + continue; + } + if (Z_TYPE_P(le) == le_db || Z_TYPE_P(le) == le_pdb) { + info = (dba_info *)(le->ptr); + add_index_string(return_value, i, info->path, 1); + } + } +} +/* }}} */ + +#endif /* HAVE_DBA */ + +/* + * 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/dba/dba.dsp b/ext/dba/dba.dsp new file mode 100644 index 0000000..ddfd148 --- /dev/null +++ b/ext/dba/dba.dsp @@ -0,0 +1,213 @@ +# Microsoft Developer Studio Project File - Name="dba" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=dba - Win32 Debug_TS Berkeley DB3
+!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 "dba.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 "dba.mak" CFG="dba - Win32 Debug_TS Berkeley DB3"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "dba - Win32 Release_TS Berkeley DB3" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "dba - Win32 Debug_TS Berkeley DB3" (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)" == "dba - Win32 Release_TS Berkeley DB3"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release_TS"
+# PROP BASE Intermediate_Dir "Release_TS"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_TS"
+# PROP Intermediate_Dir "Release_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /D ZEND_DEBUG=0 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "COMPILE_DL_DBA" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_DBA=1 /D DBA_DB3=1 /D DB3_INCLUDE_FILE="db.h" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /D ZEND_DEBUG=0 /D DBA_DB3=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "COMPILE_DL_DBA" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_DBA=1 /D DBA_FLATFILE=1 /D DBA_CDB=1 /D DBA_CDB_MAKE=1 /D DBA_CDB_BUILTIN=1 /D DBA_INIFILE=1 /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x407 /d "NDEBUG"
+# ADD RSC /l 0x407 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 php5ts.lib libdb31s.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_dba.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline"
+# ADD LINK32 php5ts.lib libdb31s.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_dba.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline"
+
+!ELSEIF "$(CFG)" == "dba - Win32 Debug_TS Berkeley DB3"
+
+# 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 Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug_TS"
+# PROP Intermediate_Dir "Debug_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "COMPILE_DL_DBA" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_DBA=1 /D "DBA_DB3" /D DB3_INCLUDE_FILE="db.h" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /D ZEND_DEBUG=1 /D "DBA_DB3" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "COMPILE_DL_DBA" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_DBA=1 /D DBA_FLATFILE=1 /D DBA_CDB=1 /D DBA_CDB_MAKE=1 /D DBA_CDB_BUILTIN=1 /D DBA_INIFILE=1 /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x407 /d "_DEBUG"
+# ADD RSC /l 0x407 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 php5ts_debug.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_dba.dll" /pdbtype:sept /libpath:"..\..\Debug_TS"
+# ADD LINK32 php5ts_debug.lib libdb31s.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_dba.dll" /pdbtype:sept /libpath:"..\..\Debug_TS"
+
+!ENDIF
+
+# Begin Target
+
+# Name "dba - Win32 Release_TS Berkeley DB3"
+# Name "dba - Win32 Debug_TS Berkeley DB3"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\libcdb\cdb.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\libcdb\cdb_make.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dba.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dba_cdb.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dba_db2.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dba_db3.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dba_dbm.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dba_flatfile.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dba_gdbm.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dba_inifile.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dba_ndbm.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\libflatfile\flatfile.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\libinifile\inifile.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\libcdb\uint32.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\libcdb\cdb.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\libcdb\cdb_make.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\libflatfile\flatfile.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\php_cdb.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\php_db2.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\php_db3.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\php_dba.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\php_dbm.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\php_flatfile.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\php_gdbm.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\php_inifile.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\php_ndbm.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\libcdb\uint32.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\libinifile\inifile.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/ext/dba/dba_cdb.c b/ext/dba/dba_cdb.c new file mode 100644 index 0000000..a4a7314 --- /dev/null +++ b/ext/dba/dba_cdb.c @@ -0,0 +1,350 @@ +/* + +----------------------------------------------------------------------+ + | 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: Sascha Schumann <sascha@schumann.cx> | + | Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if DBA_CDB +#include "php_cdb.h" + +#include <sys/types.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <fcntl.h> + +#if DBA_CDB_BUILTIN +# include "libcdb/cdb.h" +# include "libcdb/cdb_make.h" +# include "libcdb/uint32.h" +#else +# ifdef CDB_INCLUDE_FILE +# include CDB_INCLUDE_FILE +# endif +#endif + +#define CDB_INFO \ + dba_cdb *cdb = (dba_cdb *) info->dbf + +typedef struct { + struct cdb c; +#if DBA_CDB_BUILTIN + struct cdb_make m; + php_stream *file; + int make; +#else + int file; +#endif + uint32 eod; /* size of constant database */ + uint32 pos; /* current position for traversing */ +} dba_cdb; + +DBA_OPEN_FUNC(cdb) +{ +#if DBA_CDB_BUILTIN + php_stream* file = 0; + int make; +#else + int file = 0; +#endif + dba_cdb *cdb; + dba_info *pinfo = (dba_info *) info; + + switch (info->mode) { + case DBA_READER: +#if DBA_CDB_BUILTIN + make = 0; + file = info->fp; +#else + file = VCWD_OPEN(info->path, O_RDONLY); + if (file < 0) { + *error = "Unable to open file"; + return FAILURE; + } +#endif + break; +#if DBA_CDB_BUILTIN + case DBA_TRUNC: + make = 1; + file = info->fp; + break; + case DBA_CREAT: + case DBA_WRITER: + *error = "Update operations are not supported"; + return FAILURE; /* not supported */ +#endif + default: + *error = "Currently not supported"; + return FAILURE; + } + + cdb = pemalloc(sizeof(dba_cdb), info->flags&DBA_PERSISTENT); + memset(cdb, 0, sizeof(dba_cdb)); + +#if DBA_CDB_BUILTIN + if (make) { + cdb_make_start(&cdb->m, file TSRMLS_CC); + } else { + cdb_init(&cdb->c, file TSRMLS_CC); + } + cdb->make = make; +#else + cdb_init(&cdb->c, file); +#endif + cdb->file = file; + + pinfo->dbf = cdb; + return SUCCESS; +} + +DBA_CLOSE_FUNC(cdb) +{ + CDB_INFO; + + /* cdb_free does not close associated file */ +#if DBA_CDB_BUILTIN + if (cdb->make) { + cdb_make_finish(&cdb->m TSRMLS_CC); + } else { + cdb_free(&cdb->c TSRMLS_CC); + } +#else + cdb_free(&cdb->c); + close(cdb->file); +#endif + pefree(cdb, info->flags&DBA_PERSISTENT); +} + +#if DBA_CDB_BUILTIN +# define php_cdb_read(cdb, buf, len, pos) cdb_read(cdb, buf, len, pos TSRMLS_CC) +# define php_cdb_findnext(cdb, key, len) cdb_findnext(cdb, key, len TSRMLS_CC) +# define php_cdb_find(cdb, key, len) cdb_find(cdb, key, len TSRMLS_CC) +#else +# define php_cdb_read(cdb, buf, len, pos) cdb_read(cdb, buf, len, pos) +# define php_cdb_findnext(cdb, key, len) cdb_findnext(cdb, key, len) +# define php_cdb_find(cdb, key, len) cdb_find(cdb, key, len) +#endif + +DBA_FETCH_FUNC(cdb) +{ + CDB_INFO; + unsigned int len; + char *new_entry = NULL; + +#if DBA_CDB_BUILTIN + if (cdb->make) + return NULL; /* database was opened writeonly */ +#endif + if (php_cdb_find(&cdb->c, key, keylen) == 1) { + while(skip--) { + if (php_cdb_findnext(&cdb->c, key, keylen) != 1) { + return NULL; + } + } + len = cdb_datalen(&cdb->c); + new_entry = safe_emalloc(len, 1, 1); + + if (php_cdb_read(&cdb->c, new_entry, len, cdb_datapos(&cdb->c)) == -1) { + efree(new_entry); + return NULL; + } + new_entry[len] = 0; + if (newlen) + *newlen = len; + } + + return new_entry; +} + +DBA_UPDATE_FUNC(cdb) +{ +#if DBA_CDB_BUILTIN + CDB_INFO; + + if (!cdb->make) + return FAILURE; /* database was opened readonly */ + if (!mode) + return FAILURE; /* cdb_make dosn't know replace */ + if (cdb_make_add(&cdb->m, key, keylen, val, vallen TSRMLS_CC) != -1) + return SUCCESS; +#endif + return FAILURE; +} + +DBA_EXISTS_FUNC(cdb) +{ + CDB_INFO; + +#if DBA_CDB_BUILTIN + if (cdb->make) + return FAILURE; /* database was opened writeonly */ +#endif + if (php_cdb_find(&cdb->c, key, keylen) == 1) + return SUCCESS; + return FAILURE; +} + +DBA_DELETE_FUNC(cdb) +{ + return FAILURE; /* cdb doesn't support delete */ +} + +/* {{{ cdb_file_read */ +#if DBA_CDB_BUILTIN +# define cdb_file_read(fildes, buf, size) php_stream_read(fildes, buf, size) +#else +# define cdb_file_read(fildes, buf, size) read(fildes, buf, size) +#endif +/* }}} */ + +#define CREAD(n) do { \ + if (cdb_file_read(cdb->file, buf, n) < n) return NULL; \ +} while (0) + +/* {{{ cdb_file_lseek + php_stream_seek does not return actual position */ +#if DBA_CDB_BUILTIN +int cdb_file_lseek(php_stream *fp, off_t offset, int whence TSRMLS_DC) { + php_stream_seek(fp, offset, whence); + return php_stream_tell(fp); +} +#else +int cdb_file_lseek(int fd, off_t offset, int whence TSRMLS_DC) { + return lseek(fd, offset, whence); +} +#endif +/* }}} */ + +#define CSEEK(n) do { \ + if (n >= cdb->eod) return NULL; \ + if (cdb_file_lseek(cdb->file, (off_t)n, SEEK_SET TSRMLS_CC) != (off_t) n) return NULL; \ +} while (0) + + +DBA_FIRSTKEY_FUNC(cdb) +{ + CDB_INFO; + uint32 klen, dlen; + char buf[8]; + char *key; + +#if DBA_CDB_BUILTIN + if (cdb->make) + return NULL; /* database was opened writeonly */ +#endif + + cdb->eod = -1; + CSEEK(0); + CREAD(4); + + /* Total length of file in bytes */ + uint32_unpack(buf, &cdb->eod); + + CSEEK(2048); + CREAD(8); + + /* The first four bytes contain the length of the key */ + uint32_unpack(buf, &klen); + uint32_unpack(buf + 4, &dlen); + + key = safe_emalloc(klen, 1, 1); + if (cdb_file_read(cdb->file, key, klen) < klen) { + efree(key); + key = NULL; + } else { + key[klen] = '\0'; + if (newlen) *newlen = klen; + } + + /* header + klenlen + dlenlen + klen + dlen */ + cdb->pos = 2048 + 4 + 4 + klen + dlen; + + return key; +} + +DBA_NEXTKEY_FUNC(cdb) +{ + CDB_INFO; + uint32 klen, dlen; + char buf[8]; + char *key; + +#if DBA_CDB_BUILTIN + if (cdb->make) + return NULL; /* database was opened writeonly */ +#endif + + CSEEK(cdb->pos); + CREAD(8); + uint32_unpack(buf, &klen); + uint32_unpack(buf + 4, &dlen); + + key = safe_emalloc(klen, 1, 1); + if (cdb_file_read(cdb->file, key, klen) < klen) { + efree(key); + key = NULL; + } else { + key[klen] = '\0'; + if (newlen) *newlen = klen; + } + + cdb->pos += 8 + klen + dlen; + + return key; +} + +DBA_OPTIMIZE_FUNC(cdb) +{ + return SUCCESS; +} + +DBA_SYNC_FUNC(cdb) +{ + /* this is read-only */ + return SUCCESS; +} + +DBA_INFO_FUNC(cdb) +{ +#if DBA_CDB_BUILTIN + if (!strcmp(hnd->name, "cdb")) { + return estrdup(cdb_version()); + } else { + return estrdup(cdb_make_version()); + } +#else + return estrdup("External"); +#endif +} + +#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/dba/dba_db1.c b/ext/dba/dba_db1.c new file mode 100644 index 0000000..fbb24d2 --- /dev/null +++ b/ext/dba/dba_db1.c @@ -0,0 +1,197 @@ +/* + +----------------------------------------------------------------------+ + | 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: Shen Cheng-Da <cdsheen@gmail.com> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if DBA_DB1 +#include "php_db1.h" + +#ifdef DB1_INCLUDE_FILE +#include DB1_INCLUDE_FILE +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#define DB1_DATA dba_db1_data *dba = info->dbf +#define DB1_GKEY DBT gkey; gkey.data = (char *) key; gkey.size = keylen + +typedef struct { + DB *dbp; +} dba_db1_data; + +DBA_OPEN_FUNC(db1) +{ + dba_db1_data *dba; + DB *db; + + int gmode; + int filemode = 0644; + + if (info->argc > 0) { + convert_to_long_ex(info->argv[0]); + filemode = Z_LVAL_PP(info->argv[0]); + } + + gmode = 0; + switch (info->mode) { + case DBA_READER: + gmode = O_RDONLY; + break; + case DBA_WRITER: + gmode = O_RDWR; + break; + case DBA_CREAT: + gmode = O_RDWR | O_CREAT; + break; + case DBA_TRUNC: + gmode = O_RDWR | O_CREAT | O_TRUNC; + break; + default: + return FAILURE; /* not possible */ + } + + db = dbopen((char *)info->path, gmode, filemode, DB_HASH, NULL); + + if (db == NULL) { + return FAILURE; + } + + dba = pemalloc(sizeof(*dba), info->flags&DBA_PERSISTENT); + dba->dbp = db; + + info->dbf = dba; + + return SUCCESS; +} + +DBA_CLOSE_FUNC(db1) +{ + DB1_DATA; + dba->dbp->close(dba->dbp); + pefree(info->dbf, info->flags&DBA_PERSISTENT); +} + +DBA_FETCH_FUNC(db1) +{ + DBT gval; + DB1_DATA; + DB1_GKEY; + + memset(&gval, 0, sizeof(gval)); + if (dba->dbp->get(dba->dbp, &gkey, &gval, 0) == RET_SUCCESS) { + if (newlen) *newlen = gval.size; + return estrndup(gval.data, gval.size); + } + return NULL; +} + +DBA_UPDATE_FUNC(db1) +{ + DBT gval; + DB1_DATA; + DB1_GKEY; + + gval.data = (char *) val; + gval.size = vallen; + + return dba->dbp->put(dba->dbp, &gkey, &gval, mode == 1 ? R_NOOVERWRITE : 0) != RET_SUCCESS ? FAILURE : SUCCESS; +} + +DBA_EXISTS_FUNC(db1) +{ + DBT gval; + DB1_DATA; + DB1_GKEY; + + return dba->dbp->get(dba->dbp, &gkey, &gval, 0) != RET_SUCCESS ? FAILURE : SUCCESS; +} + +DBA_DELETE_FUNC(db1) +{ + DB1_DATA; + DB1_GKEY; + + return dba->dbp->del(dba->dbp, &gkey, 0) != RET_SUCCESS ? FAILURE : SUCCESS; +} + +DBA_FIRSTKEY_FUNC(db1) +{ + DBT gkey; + DBT gval; + DB1_DATA; + + memset(&gkey, 0, sizeof(gkey)); + memset(&gval, 0, sizeof(gval)); + + if (dba->dbp->seq(dba->dbp, &gkey, &gval, R_FIRST) == RET_SUCCESS) { + if (newlen) *newlen = gkey.size; + return estrndup(gkey.data, gkey.size); + } + return NULL; +} + +DBA_NEXTKEY_FUNC(db1) +{ + DBT gkey; + DBT gval; + DB1_DATA; + + memset(&gkey, 0, sizeof(gkey)); + memset(&gval, 0, sizeof(gval)); + + if (dba->dbp->seq(dba->dbp, &gkey, &gval, R_NEXT) == RET_SUCCESS) { + if (newlen) *newlen = gkey.size; + return estrndup(gkey.data, gkey.size); + } + return NULL; +} + +DBA_OPTIMIZE_FUNC(db1) +{ + /* dummy */ + return SUCCESS; +} + +DBA_SYNC_FUNC(db1) +{ + return SUCCESS; +} + +DBA_INFO_FUNC(db1) +{ + return estrdup(DB1_VERSION); +} + +#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/dba/dba_db2.c b/ext/dba/dba_db2.c new file mode 100644 index 0000000..d92613a --- /dev/null +++ b/ext/dba/dba_db2.c @@ -0,0 +1,209 @@ +/* + +----------------------------------------------------------------------+ + | 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: Sascha Schumann <sascha@schumann.cx> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if DBA_DB2 +#include "php_db2.h" +#include <sys/stat.h> + +#include <string.h> +#ifdef DB2_INCLUDE_FILE +#include DB2_INCLUDE_FILE +#endif + +#define DB2_DATA dba_db2_data *dba = info->dbf +#define DB2_GKEY \ + DBT gkey = {0}; \ + gkey.data = (char *) key; \ + gkey.size = keylen + +typedef struct { + DB *dbp; + DBC *cursor; +} dba_db2_data; + +DBA_OPEN_FUNC(db2) +{ + DB *dbp; + DBTYPE type; + int gmode = 0; + int filemode = 0644; + struct stat check_stat; + int s = VCWD_STAT(info->path, &check_stat); + + if (!s && !check_stat.st_size) { + info->mode = DBA_TRUNC; /* force truncate */ + } + + type = info->mode == DBA_READER ? DB_UNKNOWN : + info->mode == DBA_TRUNC ? DB_BTREE : + s ? DB_BTREE : DB_UNKNOWN; + + gmode = info->mode == DBA_READER ? DB_RDONLY : + (info->mode == DBA_CREAT && s) ? DB_CREATE : + (info->mode == DBA_CREAT && !s) ? 0 : + info->mode == DBA_WRITER ? 0 : + info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1; + + if (gmode == -1) { + return FAILURE;/* not possible */ + } + + if (info->argc > 0) { + convert_to_long_ex(info->argv[0]); + filemode = Z_LVAL_PP(info->argv[0]); + } + + if (db_open(info->path, type, gmode, filemode, NULL, NULL, &dbp)) { + return FAILURE; + } + + info->dbf = pemalloc(sizeof(dba_db2_data), info->flags&DBA_PERSISTENT); + memset(info->dbf, 0, sizeof(dba_db2_data)); + ((dba_db2_data *) info->dbf)->dbp = dbp; + return SUCCESS; +} + +DBA_CLOSE_FUNC(db2) +{ + DB2_DATA; + + if (dba->cursor) + dba->cursor->c_close(dba->cursor); + dba->dbp->close(dba->dbp, 0); + pefree(dba, info->flags&DBA_PERSISTENT); +} + +DBA_FETCH_FUNC(db2) +{ + DBT gval = {0}; + DB2_DATA; + DB2_GKEY; + + if (dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) { + return NULL; + } + + if (newlen) *newlen = gval.size; + return estrndup(gval.data, gval.size); +} + +DBA_UPDATE_FUNC(db2) +{ + DBT gval = {0}; + DB2_DATA; + DB2_GKEY; + + gval.data = (char *) val; + gval.size = vallen; + + if (dba->dbp->put(dba->dbp, NULL, &gkey, &gval, + mode == 1 ? DB_NOOVERWRITE : 0)) { + return FAILURE; + } + return SUCCESS; +} + +DBA_EXISTS_FUNC(db2) +{ + DBT gval = {0}; + DB2_DATA; + DB2_GKEY; + + if (dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) { + return FAILURE; + } + return SUCCESS; +} + +DBA_DELETE_FUNC(db2) +{ + DB2_DATA; + DB2_GKEY; + + return dba->dbp->del(dba->dbp, NULL, &gkey, 0) ? FAILURE : SUCCESS; +} + +DBA_FIRSTKEY_FUNC(db2) +{ + DB2_DATA; + + if (dba->cursor) { + dba->cursor->c_close(dba->cursor); + dba->cursor = NULL; + } + +#if (DB_VERSION_MAJOR > 2) || (DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR > 6) || (DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR == 6 && DB_VERSION_PATCH >= 4) + if (dba->dbp->cursor(dba->dbp, NULL, &dba->cursor, 0)) { +#else + if (dba->dbp->cursor(dba->dbp, NULL, &dba->cursor)) { +#endif + return NULL; + } + + /* we should introduce something like PARAM_PASSTHRU... */ + return dba_nextkey_db2(info, newlen TSRMLS_CC); +} + +DBA_NEXTKEY_FUNC(db2) +{ + DB2_DATA; + DBT gkey = {0}, gval = {0}; + + if (dba->cursor->c_get(dba->cursor, &gkey, &gval, DB_NEXT) + || !gkey.data) + return NULL; + + if (newlen) *newlen = gkey.size; + return estrndup(gkey.data, gkey.size); +} + +DBA_OPTIMIZE_FUNC(db2) +{ + return SUCCESS; +} + +DBA_SYNC_FUNC(db2) +{ + DB2_DATA; + + return dba->dbp->sync(dba->dbp, 0) ? FAILURE : SUCCESS; +} + +DBA_INFO_FUNC(db2) +{ + return estrdup(DB_VERSION_STRING); +} + +#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/dba/dba_db3.c b/ext/dba/dba_db3.c new file mode 100644 index 0000000..b236865 --- /dev/null +++ b/ext/dba/dba_db3.c @@ -0,0 +1,238 @@ +/* + +----------------------------------------------------------------------+ + | 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: Sascha Schumann <sascha@schumann.cx> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if DBA_DB3 +#include "php_db3.h" +#include <sys/stat.h> + +#include <string.h> +#ifdef DB3_INCLUDE_FILE +#include DB3_INCLUDE_FILE +#else +#include <db.h> +#endif + +static void php_dba_db3_errcall_fcn(const char *errpfx, char *msg) +{ + TSRMLS_FETCH(); + + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s%s", errpfx?errpfx:"", msg); +} + +#define DB3_DATA dba_db3_data *dba = info->dbf +#define DB3_GKEY \ + DBT gkey; \ + memset(&gkey, 0, sizeof(gkey)); \ + gkey.data = (char *) key; gkey.size = keylen + +typedef struct { + DB *dbp; + DBC *cursor; +} dba_db3_data; + +DBA_OPEN_FUNC(db3) +{ + DB *dbp = NULL; + DBTYPE type; + int gmode = 0, err; + int filemode = 0644; + struct stat check_stat; + int s = VCWD_STAT(info->path, &check_stat); + + if (!s && !check_stat.st_size) { + info->mode = DBA_TRUNC; /* force truncate */ + } + + type = info->mode == DBA_READER ? DB_UNKNOWN : + info->mode == DBA_TRUNC ? DB_BTREE : + s ? DB_BTREE : DB_UNKNOWN; + + gmode = info->mode == DBA_READER ? DB_RDONLY : + (info->mode == DBA_CREAT && s) ? DB_CREATE : + (info->mode == DBA_CREAT && !s) ? 0 : + info->mode == DBA_WRITER ? 0 : + info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1; + + if (gmode == -1) { + return FAILURE; /* not possible */ + } + + if (info->argc > 0) { + convert_to_long_ex(info->argv[0]); + filemode = Z_LVAL_PP(info->argv[0]); + } + +#ifdef DB_FCNTL_LOCKING + gmode |= DB_FCNTL_LOCKING; +#endif + + if ((err=db_create(&dbp, NULL, 0)) == 0) { + dbp->set_errcall(dbp, php_dba_db3_errcall_fcn); + if ((err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) { + dba_db3_data *data; + + data = pemalloc(sizeof(*data), info->flags&DBA_PERSISTENT); + data->dbp = dbp; + data->cursor = NULL; + info->dbf = data; + + return SUCCESS; + } else { + dbp->close(dbp, 0); + *error = db_strerror(err); + } + } else { + *error = db_strerror(err); + } + + return FAILURE; +} + +DBA_CLOSE_FUNC(db3) +{ + DB3_DATA; + + if (dba->cursor) dba->cursor->c_close(dba->cursor); + dba->dbp->close(dba->dbp, 0); + pefree(dba, info->flags&DBA_PERSISTENT); +} + +DBA_FETCH_FUNC(db3) +{ + DBT gval; + char *new = NULL; + DB3_DATA; + DB3_GKEY; + + memset(&gval, 0, sizeof(gval)); + if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) { + if (newlen) *newlen = gval.size; + new = estrndup(gval.data, gval.size); + } + return new; +} + +DBA_UPDATE_FUNC(db3) +{ + DBT gval; + DB3_DATA; + DB3_GKEY; + + memset(&gval, 0, sizeof(gval)); + gval.data = (char *) val; + gval.size = vallen; + + if (!dba->dbp->put(dba->dbp, NULL, &gkey, &gval, + mode == 1 ? DB_NOOVERWRITE : 0)) { + return SUCCESS; + } + return FAILURE; +} + +DBA_EXISTS_FUNC(db3) +{ + DBT gval; + DB3_DATA; + DB3_GKEY; + + memset(&gval, 0, sizeof(gval)); + if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) { + return SUCCESS; + } + return FAILURE; +} + +DBA_DELETE_FUNC(db3) +{ + DB3_DATA; + DB3_GKEY; + + return dba->dbp->del(dba->dbp, NULL, &gkey, 0) ? FAILURE : SUCCESS; +} + +DBA_FIRSTKEY_FUNC(db3) +{ + DB3_DATA; + + if (dba->cursor) { + dba->cursor->c_close(dba->cursor); + } + + dba->cursor = NULL; + if (dba->dbp->cursor(dba->dbp, NULL, &dba->cursor, 0) != 0) { + return NULL; + } + + /* we should introduce something like PARAM_PASSTHRU... */ + return dba_nextkey_db3(info, newlen TSRMLS_CC); +} + +DBA_NEXTKEY_FUNC(db3) +{ + DB3_DATA; + DBT gkey, gval; + char *nkey = NULL; + + memset(&gkey, 0, sizeof(gkey)); + memset(&gval, 0, sizeof(gval)); + + if (dba->cursor->c_get(dba->cursor, &gkey, &gval, DB_NEXT) == 0) { + if (gkey.data) { + nkey = estrndup(gkey.data, gkey.size); + if (newlen) *newlen = gkey.size; + } + } + + return nkey; +} + +DBA_OPTIMIZE_FUNC(db3) +{ + return SUCCESS; +} + +DBA_SYNC_FUNC(db3) +{ + DB3_DATA; + + return dba->dbp->sync(dba->dbp, 0) ? FAILURE : SUCCESS; +} + +DBA_INFO_FUNC(db3) +{ + return estrdup(DB_VERSION_STRING); +} + +#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/dba/dba_db4.c b/ext/dba/dba_db4.c new file mode 100644 index 0000000..8987f1a --- /dev/null +++ b/ext/dba/dba_db4.c @@ -0,0 +1,302 @@ +/* + +----------------------------------------------------------------------+ + | 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: Marcus Boerger <helly@php.net> | + | Sascha Schumann <sascha@schumann.cx> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if DBA_DB4 +#include "php_db4.h" +#include <sys/stat.h> + +#include <string.h> +#ifdef DB4_INCLUDE_FILE +#include DB4_INCLUDE_FILE +#else +#include <db.h> +#endif + +static void php_dba_db4_errcall_fcn( +#if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3)) + const DB_ENV *dbenv, +#endif + const char *errpfx, const char *msg) +{ + TSRMLS_FETCH(); + +#if (DB_VERSION_MAJOR == 5 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 8)) +/* Bug 51086, Berkeley DB 4.8.26 */ +/* This code suppresses a BDB 4.8+ error message, thus keeping PHP test compatibility */ + { + const char *function = get_active_function_name(TSRMLS_C); + if (function && (!strcmp(function,"dba_popen") || !strcmp(function,"dba_open")) + && (!strncmp(msg, "fop_read_meta", sizeof("fop_read_meta")-1) + || !strncmp(msg, "BDB0004 fop_read_meta", sizeof("BDB0004 fop_read_meta")-1))) { + return; + } + } +#endif + + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s%s", errpfx?errpfx:"", msg); +} + +#define DB4_DATA dba_db4_data *dba = info->dbf +#define DB4_GKEY \ + DBT gkey; \ + memset(&gkey, 0, sizeof(gkey)); \ + gkey.data = (char *) key; gkey.size = keylen + +typedef struct { + DB *dbp; + DBC *cursor; +} dba_db4_data; + +DBA_OPEN_FUNC(db4) +{ + DB *dbp = NULL; + DBTYPE type; + int gmode = 0, err; + int filemode = 0644; + struct stat check_stat; + int s = VCWD_STAT(info->path, &check_stat); + +#if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR <= 7) /* Bug 51086 */ + if (!s && !check_stat.st_size) { + info->mode = DBA_TRUNC; /* force truncate */ + } + + type = info->mode == DBA_READER ? DB_UNKNOWN : + info->mode == DBA_TRUNC ? DB_BTREE : + s ? DB_BTREE : DB_UNKNOWN; + + gmode = info->mode == DBA_READER ? DB_RDONLY : + (info->mode == DBA_CREAT && s) ? DB_CREATE : + (info->mode == DBA_CREAT && !s) ? 0 : + info->mode == DBA_WRITER ? 0 : + info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1; +#else + if (!s && !check_stat.st_size) { + info->mode = DBA_CREAT; /* force creation */ + } + + type = info->mode == DBA_READER ? DB_UNKNOWN : + (info->mode == DBA_TRUNC || info->mode == DBA_CREAT) ? DB_BTREE : + s ? DB_BTREE : DB_UNKNOWN; + + gmode = info->mode == DBA_READER ? DB_RDONLY : + info->mode == DBA_CREAT ? DB_CREATE : + info->mode == DBA_WRITER ? 0 : + info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1; +#endif + + if (gmode == -1) { + return FAILURE; /* not possible */ + } + + if (info->flags & DBA_PERSISTENT) { + gmode |= DB_THREAD; + } + + if (info->argc > 0) { + convert_to_long_ex(info->argv[0]); + filemode = Z_LVAL_PP(info->argv[0]); + } + + if ((err=db_create(&dbp, NULL, 0)) == 0) { + dbp->set_errcall(dbp, php_dba_db4_errcall_fcn); + if ( +#if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)) + (err=dbp->open(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) { +#else + (err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) { +#endif + dba_db4_data *data; + + data = pemalloc(sizeof(*data), info->flags&DBA_PERSISTENT); + data->dbp = dbp; + data->cursor = NULL; + info->dbf = data; + + return SUCCESS; + } else { + dbp->close(dbp, 0); + *error = db_strerror(err); + } + } else { + *error = db_strerror(err); + } + + return FAILURE; +} + +DBA_CLOSE_FUNC(db4) +{ + DB4_DATA; + + if (dba->cursor) dba->cursor->c_close(dba->cursor); + dba->dbp->close(dba->dbp, 0); + pefree(dba, info->flags&DBA_PERSISTENT); +} + +DBA_FETCH_FUNC(db4) +{ + DBT gval; + char *new = NULL; + DB4_DATA; + DB4_GKEY; + + memset(&gval, 0, sizeof(gval)); + if (info->flags & DBA_PERSISTENT) { + gval.flags |= DB_DBT_MALLOC; + } + if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) { + if (newlen) *newlen = gval.size; + new = estrndup(gval.data, gval.size); + if (info->flags & DBA_PERSISTENT) { + free(gval.data); + } + } + return new; +} + +DBA_UPDATE_FUNC(db4) +{ + DBT gval; + DB4_DATA; + DB4_GKEY; + + memset(&gval, 0, sizeof(gval)); + gval.data = (char *) val; + gval.size = vallen; + + if (!dba->dbp->put(dba->dbp, NULL, &gkey, &gval, + mode == 1 ? DB_NOOVERWRITE : 0)) { + return SUCCESS; + } + return FAILURE; +} + +DBA_EXISTS_FUNC(db4) +{ + DBT gval; + DB4_DATA; + DB4_GKEY; + + memset(&gval, 0, sizeof(gval)); + + if (info->flags & DBA_PERSISTENT) { + gval.flags |= DB_DBT_MALLOC; + } + + if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) { + if (info->flags & DBA_PERSISTENT) { + free(gval.data); + } + return SUCCESS; + } + return FAILURE; +} + +DBA_DELETE_FUNC(db4) +{ + DB4_DATA; + DB4_GKEY; + + return dba->dbp->del(dba->dbp, NULL, &gkey, 0) ? FAILURE : SUCCESS; +} + +DBA_FIRSTKEY_FUNC(db4) +{ + DB4_DATA; + + if (dba->cursor) { + dba->cursor->c_close(dba->cursor); + } + + dba->cursor = NULL; + if (dba->dbp->cursor(dba->dbp, NULL, &dba->cursor, 0) != 0) { + return NULL; + } + + /* we should introduce something like PARAM_PASSTHRU... */ + return dba_nextkey_db4(info, newlen TSRMLS_CC); +} + +DBA_NEXTKEY_FUNC(db4) +{ + DB4_DATA; + DBT gkey, gval; + char *nkey = NULL; + + memset(&gkey, 0, sizeof(gkey)); + memset(&gval, 0, sizeof(gval)); + + if (info->flags & DBA_PERSISTENT) { + gkey.flags |= DB_DBT_MALLOC; + gval.flags |= DB_DBT_MALLOC; + } + if (dba->cursor && dba->cursor->c_get(dba->cursor, &gkey, &gval, DB_NEXT) == 0) { + if (gkey.data) { + nkey = estrndup(gkey.data, gkey.size); + if (newlen) *newlen = gkey.size; + } + if (info->flags & DBA_PERSISTENT) { + if (gkey.data) { + free(gkey.data); + } + if (gval.data) { + free(gval.data); + } + } + } + + return nkey; +} + +DBA_OPTIMIZE_FUNC(db4) +{ + return SUCCESS; +} + +DBA_SYNC_FUNC(db4) +{ + DB4_DATA; + + return dba->dbp->sync(dba->dbp, 0) ? FAILURE : SUCCESS; +} + +DBA_INFO_FUNC(db4) +{ + return estrdup(DB_VERSION_STRING); +} + +#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/dba/dba_dbm.c b/ext/dba/dba_dbm.c new file mode 100644 index 0000000..2f3b800 --- /dev/null +++ b/ext/dba/dba_dbm.c @@ -0,0 +1,213 @@ +/* + +----------------------------------------------------------------------+ + | 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: Sascha Schumann <sascha@schumann.cx> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if DBA_DBM +#include "php_dbm.h" + +#ifdef DBM_INCLUDE_FILE +#include DBM_INCLUDE_FILE +#endif +#if DBA_GDBM +#include "php_gdbm.h" +#endif + +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#define DBM_DATA dba_dbm_data *dba = info->dbf +#define DBM_GKEY datum gkey; gkey.dptr = (char *) key; gkey.dsize = keylen + +#define TRUNC_IT(extension, mode) \ + snprintf(buf, MAXPATHLEN, "%s" extension, info->path); \ + buf[MAXPATHLEN-1] = '\0'; \ + if((fd = VCWD_OPEN_MODE(buf, O_CREAT | mode | O_WRONLY, filemode)) == -1) \ + return FAILURE; \ + close(fd); + + +typedef struct { + datum nextkey; +} dba_dbm_data; + +DBA_OPEN_FUNC(dbm) +{ + int fd; + int filemode = 0644; + + if(info->argc > 0) { + convert_to_long_ex(info->argv[0]); + filemode = Z_LVAL_PP(info->argv[0]); + } + + if(info->mode == DBA_TRUNC) { + char buf[MAXPATHLEN]; + + /* dbm/ndbm original */ + TRUNC_IT(".pag", O_TRUNC); + TRUNC_IT(".dir", O_TRUNC); + } + + if(info->mode == DBA_CREAT) { + char buf[MAXPATHLEN]; + + TRUNC_IT(".pag", 0); + TRUNC_IT(".dir", 0); + } + + if(dbminit((char *) info->path) == -1) { + return FAILURE; + } + + info->dbf = pemalloc(sizeof(dba_dbm_data), info->flags&DBA_PERSISTENT); + memset(info->dbf, 0, sizeof(dba_dbm_data)); + return SUCCESS; +} + +DBA_CLOSE_FUNC(dbm) +{ + pefree(info->dbf, info->flags&DBA_PERSISTENT); + dbmclose(); +} + +DBA_FETCH_FUNC(dbm) +{ + datum gval; + char *new = NULL; + + DBM_GKEY; + gval = fetch(gkey); + if(gval.dptr) { + if(newlen) *newlen = gval.dsize; + new = estrndup(gval.dptr, gval.dsize); + } + return new; +} + +DBA_UPDATE_FUNC(dbm) +{ + datum gval; + + DBM_GKEY; + + if (mode == 1) { /* insert */ + gval = fetch(gkey); + if(gval.dptr) { + return FAILURE; + } + } + + gval.dptr = (char *) val; + gval.dsize = vallen; + + return (store(gkey, gval) == -1 ? FAILURE : SUCCESS); +} + +DBA_EXISTS_FUNC(dbm) +{ + datum gval; + DBM_GKEY; + + gval = fetch(gkey); + if(gval.dptr) { + return SUCCESS; + } + return FAILURE; +} + +DBA_DELETE_FUNC(dbm) +{ + DBM_GKEY; + return(delete(gkey) == -1 ? FAILURE : SUCCESS); +} + +DBA_FIRSTKEY_FUNC(dbm) +{ + DBM_DATA; + datum gkey; + char *key = NULL; + + gkey = firstkey(); + if(gkey.dptr) { + if(newlen) *newlen = gkey.dsize; + key = estrndup(gkey.dptr, gkey.dsize); + dba->nextkey = gkey; + } else + dba->nextkey.dptr = NULL; + return key; +} + +DBA_NEXTKEY_FUNC(dbm) +{ + DBM_DATA; + datum gkey; + char *nkey = NULL; + + if(!dba->nextkey.dptr) return NULL; + + gkey = nextkey(dba->nextkey); + if(gkey.dptr) { + if(newlen) *newlen = gkey.dsize; + nkey = estrndup(gkey.dptr, gkey.dsize); + dba->nextkey = gkey; + } else + dba->nextkey.dptr = NULL; + return nkey; +} + +DBA_OPTIMIZE_FUNC(dbm) +{ + /* dummy */ + return SUCCESS; +} + +DBA_SYNC_FUNC(dbm) +{ + return SUCCESS; +} + +DBA_INFO_FUNC(dbm) +{ +#if DBA_GDBM + if (!strcmp(DBM_VERSION, "GDBM")) + { + return dba_info_gdbm(hnd, info TSRMLS_CC); + } +#endif + return estrdup(DBM_VERSION); +} + +#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/dba/dba_flatfile.c b/ext/dba/dba_flatfile.c new file mode 100644 index 0000000..082aa5c --- /dev/null +++ b/ext/dba/dba_flatfile.c @@ -0,0 +1,188 @@ +/* + +----------------------------------------------------------------------+ + | 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: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if DBA_FLATFILE +#include "php_flatfile.h" + +#include "libflatfile/flatfile.h" + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#define FLATFILE_DATA flatfile *dba = info->dbf +#define FLATFILE_GKEY datum gkey; gkey.dptr = (char *) key; gkey.dsize = keylen + +DBA_OPEN_FUNC(flatfile) +{ + info->dbf = pemalloc(sizeof(flatfile), info->flags&DBA_PERSISTENT); + memset(info->dbf, 0, sizeof(flatfile)); + + ((flatfile*)info->dbf)->fp = info->fp; + + return SUCCESS; +} + +DBA_CLOSE_FUNC(flatfile) +{ + FLATFILE_DATA; + + if (dba->nextkey.dptr) { + efree(dba->nextkey.dptr); + } + pefree(dba, info->flags&DBA_PERSISTENT); +} + +DBA_FETCH_FUNC(flatfile) +{ + datum gval; + char *new = NULL; + + FLATFILE_DATA; + FLATFILE_GKEY; + + gval = flatfile_fetch(dba, gkey TSRMLS_CC); + if (gval.dptr) { + if (newlen) { + *newlen = gval.dsize; + } + new = estrndup(gval.dptr, gval.dsize); + efree(gval.dptr); + } + return new; +} + +DBA_UPDATE_FUNC(flatfile) +{ + datum gval; + + FLATFILE_DATA; + FLATFILE_GKEY; + gval.dptr = (char *) val; + gval.dsize = vallen; + + switch(flatfile_store(dba, gkey, gval, mode==1 ? FLATFILE_INSERT : FLATFILE_REPLACE TSRMLS_CC)) { + case -1: + php_error_docref1(NULL TSRMLS_CC, key, E_WARNING, "Operation not possible"); + return FAILURE; + default: + case 0: + return SUCCESS; + case 1: + php_error_docref1(NULL TSRMLS_CC, key, E_WARNING, "Key already exists"); + return FAILURE; + } +} + +DBA_EXISTS_FUNC(flatfile) +{ + datum gval; + FLATFILE_DATA; + FLATFILE_GKEY; + + gval = flatfile_fetch(dba, gkey TSRMLS_CC); + if (gval.dptr) { + efree(gval.dptr); + return SUCCESS; + } + return FAILURE; +} + +DBA_DELETE_FUNC(flatfile) +{ + FLATFILE_DATA; + FLATFILE_GKEY; + return(flatfile_delete(dba, gkey TSRMLS_CC) == -1 ? FAILURE : SUCCESS); +} + +DBA_FIRSTKEY_FUNC(flatfile) +{ + FLATFILE_DATA; + + if (dba->nextkey.dptr) { + efree(dba->nextkey.dptr); + } + dba->nextkey = flatfile_firstkey(dba TSRMLS_CC); + if (dba->nextkey.dptr) { + if (newlen) { + *newlen = dba->nextkey.dsize; + } + return estrndup(dba->nextkey.dptr, dba->nextkey.dsize); + } + return NULL; +} + +DBA_NEXTKEY_FUNC(flatfile) +{ + FLATFILE_DATA; + + if (!dba->nextkey.dptr) { + return NULL; + } + + if (dba->nextkey.dptr) { + efree(dba->nextkey.dptr); + } + dba->nextkey = flatfile_nextkey(dba TSRMLS_CC); + if (dba->nextkey.dptr) { + if (newlen) { + *newlen = dba->nextkey.dsize; + } + return estrndup(dba->nextkey.dptr, dba->nextkey.dsize); + } + return NULL; +} + +DBA_OPTIMIZE_FUNC(flatfile) +{ + /* dummy */ + return SUCCESS; +} + +DBA_SYNC_FUNC(flatfile) +{ + /* dummy */ + return SUCCESS; +} + +DBA_INFO_FUNC(flatfile) +{ + return estrdup(flatfile_version()); +} + +#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/dba/dba_gdbm.c b/ext/dba/dba_gdbm.c new file mode 100644 index 0000000..7534568 --- /dev/null +++ b/ext/dba/dba_gdbm.c @@ -0,0 +1,200 @@ +/* + +----------------------------------------------------------------------+ + | 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: Sascha Schumann <sascha@schumann.cx> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if DBA_GDBM +#include "php_gdbm.h" + +#ifdef GDBM_INCLUDE_FILE +#include GDBM_INCLUDE_FILE +#endif + +#define GDBM_DATA dba_gdbm_data *dba = info->dbf +#define GDBM_GKEY datum gkey; gkey.dptr = (char *) key; gkey.dsize = keylen + +typedef struct { + GDBM_FILE dbf; + datum nextkey; +} dba_gdbm_data; + +DBA_OPEN_FUNC(gdbm) +{ + GDBM_FILE dbf; + int gmode = 0; + int filemode = 0644; + + gmode = info->mode == DBA_READER ? GDBM_READER : + info->mode == DBA_WRITER ? GDBM_WRITER : + info->mode == DBA_CREAT ? GDBM_WRCREAT : + info->mode == DBA_TRUNC ? GDBM_NEWDB : -1; + + if(gmode == -1) + return FAILURE; /* not possible */ + + if(info->argc > 0) { + convert_to_long_ex(info->argv[0]); + filemode = Z_LVAL_PP(info->argv[0]); + } + + dbf = gdbm_open(info->path, 0, gmode, filemode, NULL); + + if(dbf) { + info->dbf = pemalloc(sizeof(dba_gdbm_data), info->flags&DBA_PERSISTENT); + memset(info->dbf, 0, sizeof(dba_gdbm_data)); + ((dba_gdbm_data *) info->dbf)->dbf = dbf; + return SUCCESS; + } + *error = gdbm_strerror(gdbm_errno); + return FAILURE; +} + +DBA_CLOSE_FUNC(gdbm) +{ + GDBM_DATA; + + if(dba->nextkey.dptr) free(dba->nextkey.dptr); + gdbm_close(dba->dbf); + pefree(dba, info->flags&DBA_PERSISTENT); +} + +DBA_FETCH_FUNC(gdbm) +{ + GDBM_DATA; + datum gval; + char *new = NULL; + + GDBM_GKEY; + gval = gdbm_fetch(dba->dbf, gkey); + if(gval.dptr) { + if(newlen) *newlen = gval.dsize; + new = estrndup(gval.dptr, gval.dsize); + free(gval.dptr); + } + return new; +} + +DBA_UPDATE_FUNC(gdbm) +{ + datum gval; + GDBM_DATA; + + GDBM_GKEY; + gval.dptr = (char *) val; + gval.dsize = vallen; + + if(gdbm_store(dba->dbf, gkey, gval, + mode == 1 ? GDBM_INSERT : GDBM_REPLACE) == 0) + return SUCCESS; + php_error_docref2(NULL TSRMLS_CC, key, val, E_WARNING, "%s", gdbm_strerror(gdbm_errno)); + return FAILURE; +} + +DBA_EXISTS_FUNC(gdbm) +{ + GDBM_DATA; + GDBM_GKEY; + + return gdbm_exists(dba->dbf, gkey) ? SUCCESS : FAILURE; +} + +DBA_DELETE_FUNC(gdbm) +{ + GDBM_DATA; + GDBM_GKEY; + + return gdbm_delete(dba->dbf, gkey) == -1 ? FAILURE : SUCCESS; +} + +DBA_FIRSTKEY_FUNC(gdbm) +{ + GDBM_DATA; + datum gkey; + char *key = NULL; + + if(dba->nextkey.dptr) { + free(dba->nextkey.dptr); + } + + gkey = gdbm_firstkey(dba->dbf); + if(gkey.dptr) { + key = estrndup(gkey.dptr, gkey.dsize); + if(newlen) *newlen = gkey.dsize; + dba->nextkey = gkey; + } else { + dba->nextkey.dptr = NULL; + } + return key; +} + +DBA_NEXTKEY_FUNC(gdbm) +{ + GDBM_DATA; + char *nkey = NULL; + datum gkey; + + if(!dba->nextkey.dptr) return NULL; + + gkey = gdbm_nextkey(dba->dbf, dba->nextkey); + free(dba->nextkey.dptr); + if(gkey.dptr) { + nkey = estrndup(gkey.dptr, gkey.dsize); + if(newlen) *newlen = gkey.dsize; + dba->nextkey = gkey; + } else { + dba->nextkey.dptr = NULL; + } + return nkey; +} + +DBA_OPTIMIZE_FUNC(gdbm) +{ + GDBM_DATA; + gdbm_reorganize(dba->dbf); + return SUCCESS; +} + +DBA_SYNC_FUNC(gdbm) +{ + GDBM_DATA; + + gdbm_sync(dba->dbf); + return SUCCESS; +} + +DBA_INFO_FUNC(gdbm) +{ + return estrdup(gdbm_version); +} + +#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/dba/dba_inifile.c b/ext/dba/dba_inifile.c new file mode 100644 index 0000000..e1359b6 --- /dev/null +++ b/ext/dba/dba_inifile.c @@ -0,0 +1,194 @@ +/* + +----------------------------------------------------------------------+ + | 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: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if DBA_INIFILE +#include "php_inifile.h" + +#include "libinifile/inifile.h" + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#define INIFILE_DATA \ + inifile *dba = info->dbf + +#define INIFILE_GKEY \ + key_type ini_key; \ + if (!key) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "No key specified"); \ + return 0; \ + } \ + ini_key = inifile_key_split((char*)key) /* keylen not needed here */ + +#define INIFILE_DONE \ + inifile_key_free(&ini_key) + +DBA_OPEN_FUNC(inifile) +{ + info->dbf = inifile_alloc(info->fp, info->mode == DBA_READER, info->flags&DBA_PERSISTENT TSRMLS_CC); + + return info->dbf ? SUCCESS : FAILURE; +} + +DBA_CLOSE_FUNC(inifile) +{ + INIFILE_DATA; + + inifile_free(dba, info->flags&DBA_PERSISTENT); +} + +DBA_FETCH_FUNC(inifile) +{ + val_type ini_val; + + INIFILE_DATA; + INIFILE_GKEY; + + ini_val = inifile_fetch(dba, &ini_key, skip TSRMLS_CC); + *newlen = ini_val.value ? strlen(ini_val.value) : 0; + INIFILE_DONE; + return ini_val.value; +} + +DBA_UPDATE_FUNC(inifile) +{ + val_type ini_val; + int res; + + INIFILE_DATA; + INIFILE_GKEY; + + ini_val.value = val; + + if (mode == 1) { + res = inifile_append(dba, &ini_key, &ini_val TSRMLS_CC); + } else { + res = inifile_replace(dba, &ini_key, &ini_val TSRMLS_CC); + } + INIFILE_DONE; + switch(res) { + case -1: + php_error_docref1(NULL TSRMLS_CC, key, E_WARNING, "Operation not possible"); + return FAILURE; + default: + case 0: + return SUCCESS; + case 1: + php_error_docref1(NULL TSRMLS_CC, key, E_WARNING, "Key already exists"); + return FAILURE; + } +} + +DBA_EXISTS_FUNC(inifile) +{ + val_type ini_val; + + INIFILE_DATA; + INIFILE_GKEY; + + ini_val = inifile_fetch(dba, &ini_key, 0 TSRMLS_CC); + INIFILE_DONE; + if (ini_val.value) { + inifile_val_free(&ini_val); + return SUCCESS; + } + return FAILURE; +} + +DBA_DELETE_FUNC(inifile) +{ + int res; + + INIFILE_DATA; + INIFILE_GKEY; + + res = inifile_delete(dba, &ini_key TSRMLS_CC); + + INIFILE_DONE; + return (res == -1 ? FAILURE : SUCCESS); +} + +DBA_FIRSTKEY_FUNC(inifile) +{ + INIFILE_DATA; + + if (inifile_firstkey(dba TSRMLS_CC)) { + char *result = inifile_key_string(&dba->curr.key); + *newlen = strlen(result); + return result; + } else { + return NULL; + } +} + +DBA_NEXTKEY_FUNC(inifile) +{ + INIFILE_DATA; + + if (!dba->curr.key.group && !dba->curr.key.name) { + return NULL; + } + + if (inifile_nextkey(dba TSRMLS_CC)) { + char *result = inifile_key_string(&dba->curr.key); + *newlen = strlen(result); + return result; + } else { + return NULL; + } +} + +DBA_OPTIMIZE_FUNC(inifile) +{ + /* dummy */ + return SUCCESS; +} + +DBA_SYNC_FUNC(inifile) +{ + /* dummy */ + return SUCCESS; +} + +DBA_INFO_FUNC(inifile) +{ + return estrdup(inifile_version()); +} + +#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/dba/dba_ndbm.c b/ext/dba/dba_ndbm.c new file mode 100644 index 0000000..8b5bbda --- /dev/null +++ b/ext/dba/dba_ndbm.c @@ -0,0 +1,171 @@ +/* + +----------------------------------------------------------------------+ + | 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: Sascha Schumann <sascha@schumann.cx> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if DBA_NDBM +#include "php_ndbm.h" + +#include <fcntl.h> +#ifdef NDBM_INCLUDE_FILE +#include NDBM_INCLUDE_FILE +#endif + +#define NDBM_GKEY datum gkey; gkey.dptr = (char *) key; gkey.dsize = keylen + +DBA_OPEN_FUNC(ndbm) +{ + DBM *dbf; + int gmode = 0; + int filemode = 0644; + dba_info *pinfo = (dba_info *) info; + + switch(info->mode) { + case DBA_READER: + gmode = O_RDONLY; + break; + case DBA_WRITER: + gmode = O_RDWR; + break; + case DBA_CREAT: + gmode = O_RDWR | O_CREAT; + break; + case DBA_TRUNC: + gmode = O_RDWR | O_CREAT | O_TRUNC; + break; + default: + return FAILURE; /* not possible */ + } + + if(info->argc > 0) { + convert_to_long_ex(info->argv[0]); + filemode = Z_LVAL_PP(info->argv[0]); + } + + dbf = dbm_open(info->path, gmode, filemode); + + pinfo->dbf = dbf; + return SUCCESS; +} + +DBA_CLOSE_FUNC(ndbm) +{ + dbm_close(info->dbf); +} + +DBA_FETCH_FUNC(ndbm) +{ + datum gval; + char *new = NULL; + + NDBM_GKEY; + gval = dbm_fetch(info->dbf, gkey); + if(gval.dptr) { + if(newlen) *newlen = gval.dsize; + new = estrndup(gval.dptr, gval.dsize); + } + return new; +} + +DBA_UPDATE_FUNC(ndbm) +{ + datum gval; + + NDBM_GKEY; + gval.dptr = (char *) val; + gval.dsize = vallen; + + if(!dbm_store(info->dbf, gkey, gval, mode == 1 ? DBM_INSERT : DBM_REPLACE)) + return SUCCESS; + return FAILURE; +} + +DBA_EXISTS_FUNC(ndbm) +{ + datum gval; + NDBM_GKEY; + gval = dbm_fetch(info->dbf, gkey); + if(gval.dptr) { + return SUCCESS; + } + return FAILURE; +} + +DBA_DELETE_FUNC(ndbm) +{ + NDBM_GKEY; + return(dbm_delete(info->dbf, gkey) == -1 ? FAILURE : SUCCESS); +} + +DBA_FIRSTKEY_FUNC(ndbm) +{ + datum gkey; + char *key = NULL; + + gkey = dbm_firstkey(info->dbf); + if(gkey.dptr) { + if(newlen) *newlen = gkey.dsize; + key = estrndup(gkey.dptr, gkey.dsize); + } + return key; +} + +DBA_NEXTKEY_FUNC(ndbm) +{ + datum gkey; + char *nkey = NULL; + + gkey = dbm_nextkey(info->dbf); + if(gkey.dptr) { + if(newlen) *newlen = gkey.dsize; + nkey = estrndup(gkey.dptr, gkey.dsize); + } + return nkey; +} + +DBA_OPTIMIZE_FUNC(ndbm) +{ + return SUCCESS; +} + +DBA_SYNC_FUNC(ndbm) +{ + return SUCCESS; +} + +DBA_INFO_FUNC(ndbm) +{ + return estrdup("NDBM"); +} + +#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/dba/dba_qdbm.c b/ext/dba/dba_qdbm.c new file mode 100644 index 0000000..485b199 --- /dev/null +++ b/ext/dba/dba_qdbm.c @@ -0,0 +1,194 @@ +/* + +----------------------------------------------------------------------+ + | 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: Marcin Gibula <mg@iceni.pl> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if DBA_QDBM +#include "php_qdbm.h" + +#ifdef QDBM_INCLUDE_FILE +#include QDBM_INCLUDE_FILE +#endif + +#define QDBM_DATA dba_qdbm_data *dba = info->dbf + +typedef struct { + DEPOT *dbf; +} dba_qdbm_data; + +DBA_OPEN_FUNC(qdbm) +{ + DEPOT *dbf; + + switch(info->mode) { + case DBA_READER: + dbf = dpopen(info->path, DP_OREADER, 0); + break; + case DBA_WRITER: + dbf = dpopen(info->path, DP_OWRITER, 0); + break; + case DBA_CREAT: + dbf = dpopen(info->path, DP_OWRITER | DP_OCREAT, 0); + break; + case DBA_TRUNC: + dbf = dpopen(info->path, DP_OWRITER | DP_OCREAT | DP_OTRUNC, 0); + break; + default: + return FAILURE; + } + + if (dbf) { + info->dbf = pemalloc(sizeof(dba_qdbm_data), info->flags & DBA_PERSISTENT); + memset(info->dbf, 0, sizeof(dba_qdbm_data)); + ((dba_qdbm_data *) info->dbf)->dbf = dbf; + return SUCCESS; + } + + *error = (char *) dperrmsg(dpecode); + return FAILURE; +} + +DBA_CLOSE_FUNC(qdbm) +{ + QDBM_DATA; + + dpclose(dba->dbf); + pefree(dba, info->flags & DBA_PERSISTENT); +} + +DBA_FETCH_FUNC(qdbm) +{ + QDBM_DATA; + char *value, *new = NULL; + int value_size; + + value = dpget(dba->dbf, key, keylen, 0, -1, &value_size); + if (value) { + if (newlen) *newlen = value_size; + new = estrndup(value, value_size); + free(value); + } + + return new; +} + +DBA_UPDATE_FUNC(qdbm) +{ + QDBM_DATA; + int result; + + result = dpput(dba->dbf, key, keylen, val, vallen, mode == 1 ? DP_DKEEP : DP_DOVER); + if (result) + return SUCCESS; + + php_error_docref2(NULL TSRMLS_CC, key, val, E_WARNING, "%s", dperrmsg(dpecode)); + return FAILURE; +} + +DBA_EXISTS_FUNC(qdbm) +{ + QDBM_DATA; + char *value; + + value = dpget(dba->dbf, key, keylen, 0, -1, NULL); + if (value) { + free(value); + return SUCCESS; + } + + return FAILURE; +} + +DBA_DELETE_FUNC(qdbm) +{ + QDBM_DATA; + + return dpout(dba->dbf, key, keylen) ? SUCCESS : FAILURE; +} + +DBA_FIRSTKEY_FUNC(qdbm) +{ + QDBM_DATA; + int value_size; + char *value, *new = NULL; + + dpiterinit(dba->dbf); + + value = dpiternext(dba->dbf, &value_size); + if (value) { + if (newlen) *newlen = value_size; + new = estrndup(value, value_size); + free(value); + } + + return new; +} + +DBA_NEXTKEY_FUNC(qdbm) +{ + QDBM_DATA; + int value_size; + char *value, *new = NULL; + + value = dpiternext(dba->dbf, &value_size); + if (value) { + if (newlen) *newlen = value_size; + new = estrndup(value, value_size); + free(value); + } + + return new; +} + +DBA_OPTIMIZE_FUNC(qdbm) +{ + QDBM_DATA; + + dpoptimize(dba->dbf, 0); + return SUCCESS; +} + +DBA_SYNC_FUNC(qdbm) +{ + QDBM_DATA; + + dpsync(dba->dbf); + return SUCCESS; +} + +DBA_INFO_FUNC(qdbm) +{ + return estrdup(dpversion); +} + +#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/dba/dba_tcadb.c b/ext/dba/dba_tcadb.c new file mode 100644 index 0000000..082a1ae --- /dev/null +++ b/ext/dba/dba_tcadb.c @@ -0,0 +1,221 @@ +/* + +----------------------------------------------------------------------+ + | 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: Michael Maclean <mgdm@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if DBA_TCADB +#include "php_tcadb.h" + +#ifdef TCADB_INCLUDE_FILE +#include TCADB_INCLUDE_FILE +#endif + +#define TCADB_DATA dba_tcadb_data *dba = info->dbf + +typedef struct { + TCADB *tcadb; +} dba_tcadb_data; + +DBA_OPEN_FUNC(tcadb) +{ + char *path_string; + TCADB *tcadb = tcadbnew(); + + if (tcadb) { + switch(info->mode) { + case DBA_READER: + spprintf(&path_string, 0, "%s#mode=r", info->path); + break; + case DBA_WRITER: + spprintf(&path_string, 0, "%s#mode=w", info->path); + break; + case DBA_CREAT: + spprintf(&path_string, 0, "%s#mode=wc", info->path); + break; + case DBA_TRUNC: + spprintf(&path_string, 0, "%s#mode=wct", info->path); + break; + default: + tcadbdel(tcadb); + return FAILURE; + } + + if (!tcadbopen(tcadb, path_string)) { + efree(path_string); + tcadbdel(tcadb); + return FAILURE; + } + + efree(path_string); + + info->dbf = pemalloc(sizeof(dba_tcadb_data), info->flags & DBA_PERSISTENT); + memset(info->dbf, 0, sizeof(dba_tcadb_data)); + ((dba_tcadb_data *) info->dbf)->tcadb = tcadb; + return SUCCESS; + } + + return FAILURE; +} + +DBA_CLOSE_FUNC(tcadb) +{ + TCADB_DATA; + + tcadbclose(dba->tcadb); + pefree(dba, info->flags & DBA_PERSISTENT); +} + +DBA_FETCH_FUNC(tcadb) +{ + TCADB_DATA; + char *value, *new = NULL; + int value_size; + + value = tcadbget(dba->tcadb, key, keylen, &value_size); + if (value) { + if (newlen) { + *newlen = value_size; + } + new = estrndup(value, value_size); + tcfree(value); + } + + return new; +} + +DBA_UPDATE_FUNC(tcadb) +{ + TCADB_DATA; + int result; + + if (mode == 1) { + /* Insert */ + if (tcadbvsiz(dba->tcadb, key, keylen) > -1) { + return FAILURE; + } + } + + result = tcadbput(dba->tcadb, key, keylen, val, vallen); + + if (result) { + return SUCCESS; + } + + php_error_docref2(NULL TSRMLS_CC, key, val, E_WARNING, "Error updating data"); + return FAILURE; +} + +DBA_EXISTS_FUNC(tcadb) +{ + TCADB_DATA; + char *value; + int value_len; + + value = tcadbget(dba->tcadb, key, keylen, &value_len); + if (value) { + tcfree(value); + return SUCCESS; + } + + return FAILURE; +} + +DBA_DELETE_FUNC(tcadb) +{ + TCADB_DATA; + + return tcadbout(dba->tcadb, key, keylen) ? SUCCESS : FAILURE; +} + +DBA_FIRSTKEY_FUNC(tcadb) +{ + TCADB_DATA; + int value_size; + char *value, *new = NULL; + + tcadbiterinit(dba->tcadb); + + value = tcadbiternext(dba->tcadb, &value_size); + if (value) { + if (newlen) { + *newlen = value_size; + } + new = estrndup(value, value_size); + tcfree(value); + } + + return new; +} + +DBA_NEXTKEY_FUNC(tcadb) +{ + TCADB_DATA; + int value_size; + char *value, *new = NULL; + + value = tcadbiternext(dba->tcadb, &value_size); + if (value) { + if (newlen) { + *newlen = value_size; + } + new = estrndup(value, value_size); + tcfree(value); + } + + return new; +} + +DBA_OPTIMIZE_FUNC(tcadb) +{ + TCADB_DATA; + +#if _TC_LIBVER >= 811 + return tcadboptimize(dba->tcadb, NULL) ? SUCCESS : FAILURE; +#else + return FAILURE; +#endif +} + +DBA_SYNC_FUNC(tcadb) +{ + TCADB_DATA; + + return tcadbsync(dba->tcadb) ? SUCCESS : FAILURE; +} + +DBA_INFO_FUNC(tcadb) +{ + return estrdup(tcversion); +} + +#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/dba/install_cdb.sh b/ext/dba/install_cdb.sh new file mode 100755 index 0000000..ce5f3cc --- /dev/null +++ b/ext/dba/install_cdb.sh @@ -0,0 +1,53 @@ +#! /bin/sh + +# You can use this script if you want to use an external cdb lib. If you +# compile php using --with-cdb the internal functions will be used and no +# external library is used so that this script is not necessary. +# +# cdb-0.75 lacks support for installing header files and creating a +# library which programs can link against. This shell script fills +# the gap. +# +# $Id: install_cdb.sh,v 1.2 2002-11-04 17:53:04 helly Exp $ + +if test -r "cdb.a" && test -r "auto-str.c" && test -r "byte.a"; then + : +else + echo "Please execute this script in the cdb-0.75 source directory after 'make'" + exit 1 +fi + +prefix=$1 + +if test -z "$prefix"; then + prefix=/usr/local +fi + +echo "Using prefix $prefix" + +if mkdir -p "$prefix/include" "$prefix/lib"; then + : +else + echo "Creating directories failed. Please become superuser." + exit 1 +fi + +mkdir -p tmp || exit 1 +cd tmp +ar x ../cdb.a +ar x ../byte.a +ar x ../unix.a +ar x ../byte.a +ar x ../buffer.a +cp ../error.o . + +# not really portable +ar r "$prefix/lib/libcdb.a" * +ranlib "$prefix/lib/libcdb.a" +cd .. + +rm -rf tmp + +cp cdb.h uint32.h "$prefix/include" + +echo "done" diff --git a/ext/dba/libcdb/cdb.c b/ext/dba/libcdb/cdb.c new file mode 100644 index 0000000..2b101f8 --- /dev/null +++ b/ext/dba/libcdb/cdb.c @@ -0,0 +1,194 @@ +/* + +----------------------------------------------------------------------+ + | 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: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id: bc4ee08831fe552aab0f3fdce506f7b734dde461 $ */ + +/* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#include <sys/types.h> +#include <sys/stat.h> +#ifndef PHP_WIN32 +#include <sys/mman.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <string.h> +#include <errno.h> +#include "cdb.h" + +#ifndef EPROTO +# define EPROTO -15 /* cdb 0.75's default for PROTOless systems */ +#endif + +/* {{{ cdb_match */ +static int cdb_match(struct cdb *c, char *key, unsigned int len, uint32 pos TSRMLS_DC) +{ + char buf[32]; + unsigned int n; + + while (len > 0) { + n = sizeof(buf); + if (n > len) + n = len; + if (cdb_read(c, buf, n, pos TSRMLS_CC) == -1) + return -1; + if (memcmp(buf, key, n)) + return 0; + pos += n; + key += n; + len -= n; + } + return 1; +} +/* }}} */ + +/* {{{ cdb_hash */ +uint32 cdb_hash(char *buf, unsigned int len) +{ + uint32 h; + const unsigned char * b = (unsigned char *)buf; + + h = CDB_HASHSTART; + while (len--) { + h = ( h + (h << 5)) ^ (*b++); + } + return h; +} +/* }}} */ + +/* {{{ cdb_free */ +void cdb_free(struct cdb *c TSRMLS_DC) +{ +} +/* }}} */ + +/* {{{ cdb_findstart */ +void cdb_findstart(struct cdb *c TSRMLS_DC) +{ + c->loop = 0; +} +/* }}} */ + +/* {{{ cdb_init */ +void cdb_init(struct cdb *c, php_stream *fp TSRMLS_DC) +{ + cdb_free(c TSRMLS_CC); + cdb_findstart(c TSRMLS_CC); + c->fp = fp; +} +/* }}} */ + +/* {{{ cdb_read */ +int cdb_read(struct cdb *c, char *buf, unsigned int len, uint32 pos TSRMLS_DC) +{ + if (php_stream_seek(c->fp, pos, SEEK_SET) == -1) { + errno = EPROTO; + return -1; + } + while (len > 0) { + int r; + do { + r = php_stream_read(c->fp, buf, len); + } while ((r == -1) && (errno == EINTR)); + if (r == -1) + return -1; + if (r == 0) { + errno = EPROTO; + return -1; + } + buf += r; + len -= r; + } + return 0; +} +/* }}} */ + +/* {{{ cdb_findnext */ +int cdb_findnext(struct cdb *c, char *key, unsigned int len TSRMLS_DC) +{ + char buf[8]; + uint32 pos; + uint32 u; + + if (!c->loop) { + u = cdb_hash(key, len); + if (cdb_read(c, buf, 8, (u << 3) & 2047 TSRMLS_CC) == -1) + return -1; + uint32_unpack(buf + 4,&c->hslots); + if (!c->hslots) + return 0; + uint32_unpack(buf, &c->hpos); + c->khash = u; + u >>= 8; + u %= c->hslots; + u <<= 3; + c->kpos = c->hpos + u; + } + + while (c->loop < c->hslots) { + if (cdb_read(c, buf, 8, c->kpos TSRMLS_CC) == -1) + return -1; + uint32_unpack(buf + 4, &pos); + if (!pos) + return 0; + c->loop += 1; + c->kpos += 8; + if (c->kpos == c->hpos + (c->hslots << 3)) + c->kpos = c->hpos; + uint32_unpack(buf, &u); + if (u == c->khash) { + if (cdb_read(c, buf, 8, pos TSRMLS_CC) == -1) + return -1; + uint32_unpack(buf, &u); + if (u == len) + switch(cdb_match(c, key, len, pos + 8 TSRMLS_CC)) { + case -1: + return -1; + case 1: + uint32_unpack(buf + 4, &c->dlen); + c->dpos = pos + 8 + len; + return 1; + } + } + } + + return 0; +} +/* }}} */ + +/* {{{ cdb_find */ +int cdb_find(struct cdb *c, char *key, unsigned int len TSRMLS_DC) +{ + cdb_findstart(c TSRMLS_CC); + return cdb_findnext(c, key, len TSRMLS_CC); +} +/* }}} */ + +/* {{{ cdb_version */ +char *cdb_version() +{ + return "0.75, $Id: bc4ee08831fe552aab0f3fdce506f7b734dde461 $"; +} +/* }}} */ diff --git a/ext/dba/libcdb/cdb.h b/ext/dba/libcdb/cdb.h new file mode 100644 index 0000000..5be8ec4 --- /dev/null +++ b/ext/dba/libcdb/cdb.h @@ -0,0 +1,57 @@ +/* + +----------------------------------------------------------------------+ + | 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: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +/* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ + +#ifndef CDB_H +#define CDB_H + +#include "uint32.h" + +#define CDB_HASHSTART 5381 + +struct cdb { + php_stream *fp; + uint32 loop; /* number of hash slots searched under this key */ + uint32 khash; /* initialized if loop is nonzero */ + uint32 kpos; /* initialized if loop is nonzero */ + uint32 hpos; /* initialized if loop is nonzero */ + uint32 hslots; /* initialized if loop is nonzero */ + uint32 dpos; /* initialized if cdb_findnext() returns 1 */ + uint32 dlen; /* initialized if cdb_findnext() returns 1 */ +}; + +uint32 cdb_hash(char *, unsigned int); + +void cdb_free(struct cdb * TSRMLS_DC); +void cdb_init(struct cdb *, php_stream *fp TSRMLS_DC); + +int cdb_read(struct cdb *, char *, unsigned int, uint32 TSRMLS_DC); + +void cdb_findstart(struct cdb * TSRMLS_DC); +int cdb_findnext(struct cdb *, char *, unsigned int TSRMLS_DC); +int cdb_find(struct cdb *, char *, unsigned int TSRMLS_DC); + +#define cdb_datapos(c) ((c)->dpos) +#define cdb_datalen(c) ((c)->dlen) + +char *cdb_version(); + +#endif diff --git a/ext/dba/libcdb/cdb_make.c b/ext/dba/libcdb/cdb_make.c new file mode 100644 index 0000000..606b56e --- /dev/null +++ b/ext/dba/libcdb/cdb_make.c @@ -0,0 +1,244 @@ +/* + +----------------------------------------------------------------------+ + | 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: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id: 154118c15260d2e1f134cf7534ff244ba31b4353 $ */ + +/* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#include <sys/types.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include "cdb.h" +#include "cdb_make.h" +#include "uint32.h" + +/* {{{ cdb_make_write */ +static int cdb_make_write(struct cdb_make *c, char *buf, uint32 sz TSRMLS_DC) { + return php_stream_write(c->fp, buf, sz) == sz ? 0 : -1; +} + +/* {{{ cdb_posplus */ +static int cdb_posplus(struct cdb_make *c, uint32 len) +{ + uint32 newpos = c->pos + len; + if (newpos < len) { + errno = ENOMEM; + return -1; + } + c->pos = newpos; + return 0; +} +/* }}} */ + +/* {{{ cdb_make_start */ +int cdb_make_start(struct cdb_make *c, php_stream * f TSRMLS_DC) +{ + c->head = 0; + c->split = 0; + c->hash = 0; + c->numentries = 0; + c->fp = f; + c->pos = sizeof(c->final); + if (php_stream_seek(f, c->pos, SEEK_SET) == -1) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Fseek failed"); + return -1; + } + return php_stream_tell(c->fp); +} +/* }}} */ + +/* {{{ cdb_make_addend */ +int cdb_make_addend(struct cdb_make *c, unsigned int keylen, unsigned int datalen, uint32 h TSRMLS_DC) +{ + struct cdb_hplist *head; + + head = c->head; + if (!head || (head->num >= CDB_HPLIST)) { + head = (struct cdb_hplist *) emalloc(sizeof(struct cdb_hplist)); + if (!head) + return -1; + head->num = 0; + head->next = c->head; + c->head = head; + } + head->hp[head->num].h = h; + head->hp[head->num].p = c->pos; + ++head->num; + ++c->numentries; + if (cdb_posplus(c,8) == -1) + return -1; + if (cdb_posplus(c, keylen) == -1) + return -1; + if (cdb_posplus(c, datalen) == -1) + return -1; + return 0; +} +/* }}} */ + +/* {{{ cdb_make_addbegin */ +int cdb_make_addbegin(struct cdb_make *c, unsigned int keylen, unsigned int datalen TSRMLS_DC) +{ + char buf[8]; + + if (keylen > 0xffffffff) { + errno = ENOMEM; + return -1; + } + if (datalen > 0xffffffff) { + errno = ENOMEM; + return -1; + } + + uint32_pack(buf, keylen); + uint32_pack(buf + 4, datalen); + if (cdb_make_write(c, buf, 8 TSRMLS_CC) != 0) + return -1; + return 0; +} + +/* {{{ cdb_make_add */ +int cdb_make_add(struct cdb_make *c,char *key,unsigned int keylen,char *data,unsigned int datalen TSRMLS_DC) +{ + if (cdb_make_addbegin(c, keylen, datalen TSRMLS_CC) == -1) + return -1; + if (cdb_make_write(c, key, keylen TSRMLS_CC) != 0) + return -1; + if (cdb_make_write(c, data, datalen TSRMLS_CC) != 0) + return -1; + return cdb_make_addend(c, keylen, datalen, cdb_hash(key, keylen) TSRMLS_CC); +} +/* }}} */ + +/* {{{ cdb_make_finish */ +int cdb_make_finish(struct cdb_make *c TSRMLS_DC) +{ + char buf[8]; + int i; + uint32 len; + uint32 u; + uint32 memsize; + uint32 count; + uint32 where; + struct cdb_hplist *x; + struct cdb_hp *hp; + + for (i = 0;i < 256;++i) + c->count[i] = 0; + + for (x = c->head; x; x = x->next) { + i = x->num; + while (i--) + ++c->count[255 & x->hp[i].h]; + } + + memsize = 1; + for (i = 0;i < 256;++i) { + u = c->count[i] * 2; + if (u > memsize) + memsize = u; + } + + memsize += c->numentries; /* no overflow possible up to now */ + u = (uint32) 0 - (uint32) 1; + u /= sizeof(struct cdb_hp); + if (memsize > u) { + errno = ENOMEM; + return -1; + } + + c->split = (struct cdb_hp *) safe_emalloc(memsize, sizeof(struct cdb_hp), 0); + if (!c->split) + return -1; + + c->hash = c->split + c->numentries; + + u = 0; + for (i = 0;i < 256;++i) { + u += c->count[i]; /* bounded by numentries, so no overflow */ + c->start[i] = u; + } + + for (x = c->head; x; x = x->next) { + i = x->num; + while (i--) + c->split[--c->start[255 & x->hp[i].h]] = x->hp[i]; + } + + for (i = 0;i < 256;++i) { + count = c->count[i]; + + len = count + count; /* no overflow possible */ + uint32_pack(c->final + 8 * i,c->pos); + uint32_pack(c->final + 8 * i + 4,len); + + for (u = 0;u < len;++u) + c->hash[u].h = c->hash[u].p = 0; + + hp = c->split + c->start[i]; + for (u = 0;u < count;++u) { + where = (hp->h >> 8) % len; + while (c->hash[where].p) + if (++where == len) + where = 0; + c->hash[where] = *hp++; + } + + for (u = 0;u < len;++u) { + uint32_pack(buf, c->hash[u].h); + uint32_pack(buf + 4, c->hash[u].p); + if (cdb_make_write(c, buf, 8 TSRMLS_CC) != 0) + return -1; + if (cdb_posplus(c, 8) == -1) + return -1; + } + } + + if (c->split) + efree(c->split); + + for (x = c->head; x; c->head = x) { + x = x->next; + efree(c->head); + } + + if (php_stream_flush(c->fp) != 0) + return -1; + php_stream_rewind(c->fp); + if (php_stream_tell(c->fp) != 0) + return -1; + if (cdb_make_write(c, c->final, sizeof(c->final) TSRMLS_CC) != 0) + return -1; + return php_stream_flush(c->fp); +} +/* }}} */ + +/* {{{ cdb_make_version */ +char *cdb_make_version() +{ + return "0.75, $Id: 154118c15260d2e1f134cf7534ff244ba31b4353 $"; +} diff --git a/ext/dba/libcdb/cdb_make.h b/ext/dba/libcdb/cdb_make.h new file mode 100644 index 0000000..5bb0ddf --- /dev/null +++ b/ext/dba/libcdb/cdb_make.h @@ -0,0 +1,64 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +/* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ + +#ifndef CDB_MAKE_H +#define CDB_MAKE_H + +#include <stdio.h> +#include "uint32.h" + +#define CDB_HPLIST 1000 + +struct cdb_hp { + uint32 h; + uint32 p; +}; + +struct cdb_hplist { + struct cdb_hp hp[CDB_HPLIST]; + struct cdb_hplist *next; + int num; +} ; + +struct cdb_make { + /* char bspace[8192]; */ + char final[2048]; + uint32 count[256]; + uint32 start[256]; + struct cdb_hplist *head; + struct cdb_hp *split; /* includes space for hash */ + struct cdb_hp *hash; + uint32 numentries; + /* buffer b; */ + uint32 pos; + /* int fd; */ + php_stream * fp; +}; + +int cdb_make_start(struct cdb_make *, php_stream * TSRMLS_DC); +int cdb_make_addbegin(struct cdb_make *, unsigned int, unsigned int TSRMLS_DC); +int cdb_make_addend(struct cdb_make *, unsigned int, unsigned int, uint32 TSRMLS_DC); +int cdb_make_add(struct cdb_make *, char *, unsigned int, char *, unsigned int TSRMLS_DC); +int cdb_make_finish(struct cdb_make * TSRMLS_DC); +char *cdb_make_version(); + +#endif diff --git a/ext/dba/libcdb/uint32.c b/ext/dba/libcdb/uint32.c new file mode 100644 index 0000000..803a3d5 --- /dev/null +++ b/ext/dba/libcdb/uint32.c @@ -0,0 +1,49 @@ +/* + +----------------------------------------------------------------------+ + | 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: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +/* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#include "uint32.h" + +/* {{{ uint32_pack */ +void uint32_pack(char *out, uint32 in) +{ + out[0] = in&0xff; in>>=8; + out[1] = in&0xff; in>>=8; + out[2] = in&0xff; in>>=8; + out[3] = in&0xff; +} +/* }}} */ + +/* {{{ uint32_unpack */ +void uint32_unpack(const char *in, uint32 *out) +{ + *out = (((uint32)(unsigned char)in[3])<<24) | + (((uint32)(unsigned char)in[2])<<16) | + (((uint32)(unsigned char)in[1])<<8) | + (((uint32)(unsigned char)in[0])); +} +/* }}} */ diff --git a/ext/dba/libcdb/uint32.h b/ext/dba/libcdb/uint32.h new file mode 100644 index 0000000..ac44f05 --- /dev/null +++ b/ext/dba/libcdb/uint32.h @@ -0,0 +1,39 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +/* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ + +#ifndef UINT32_H +#define UINT32_H + +#if SIZEOF_INT == 4 +/* Most 32-bit and 64-bit systems have 32-bit ints */ +typedef unsigned int uint32; +#elif SIZEOF_LONG == 4 +/* 16-bit systems? */ +typedef unsigned long uint32; +#else +#error Need type which holds 32 bits +#endif + +void uint32_pack(char *out, uint32 in); +void uint32_unpack(const char *in, uint32 *out); + +#endif diff --git a/ext/dba/libflatfile/flatfile.c b/ext/dba/libflatfile/flatfile.c new file mode 100644 index 0000000..194f016 --- /dev/null +++ b/ext/dba/libflatfile/flatfile.c @@ -0,0 +1,320 @@ +/* + +----------------------------------------------------------------------+ + | 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: Marcus Boerger <helly@php.net> | + | based on ext/db/db.c by: | + | Rasmus Lerdorf <rasmus@php.net> | + | Jim Winstead <jimw@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id: 6ce2f616c81b8404a2b4143c0be5cadeaa0d4742 $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#include "php_globals.h" + +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#if HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include "flatfile.h" + +#define FLATFILE_BLOCK_SIZE 1024 + +/* + * ret = -1 means that database was opened for read-only + * ret = 0 success + * ret = 1 key already exists - nothing done + */ + +/* {{{ flatfile_store + */ +int flatfile_store(flatfile *dba, datum key_datum, datum value_datum, int mode TSRMLS_DC) { + if (mode == FLATFILE_INSERT) { + if (flatfile_findkey(dba, key_datum TSRMLS_CC)) { + return 1; + } + php_stream_seek(dba->fp, 0L, SEEK_END); + php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", key_datum.dsize); + php_stream_flush(dba->fp); + if (php_stream_write(dba->fp, key_datum.dptr, key_datum.dsize) < key_datum.dsize) { + return -1; + } + php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", value_datum.dsize); + php_stream_flush(dba->fp); + if (php_stream_write(dba->fp, value_datum.dptr, value_datum.dsize) < value_datum.dsize) { + return -1; + } + } else { /* FLATFILE_REPLACE */ + flatfile_delete(dba, key_datum TSRMLS_CC); + php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", key_datum.dsize); + php_stream_flush(dba->fp); + if (php_stream_write(dba->fp, key_datum.dptr, key_datum.dsize) < key_datum.dsize) { + return -1; + } + php_stream_printf(dba->fp TSRMLS_CC, "%zu\n", value_datum.dsize); + if (php_stream_write(dba->fp, value_datum.dptr, value_datum.dsize) < value_datum.dsize) { + return -1; + } + } + + php_stream_flush(dba->fp); + return 0; +} +/* }}} */ + +/* {{{ flatfile_fetch + */ +datum flatfile_fetch(flatfile *dba, datum key_datum TSRMLS_DC) { + datum value_datum = {NULL, 0}; + char buf[16]; + + if (flatfile_findkey(dba, key_datum TSRMLS_CC)) { + if (php_stream_gets(dba->fp, buf, sizeof(buf))) { + value_datum.dsize = atoi(buf); + value_datum.dptr = safe_emalloc(value_datum.dsize, 1, 1); + value_datum.dsize = php_stream_read(dba->fp, value_datum.dptr, value_datum.dsize); + } else { + value_datum.dptr = NULL; + value_datum.dsize = 0; + } + } + return value_datum; +} +/* }}} */ + +/* {{{ flatfile_delete + */ +int flatfile_delete(flatfile *dba, datum key_datum TSRMLS_DC) { + char *key = key_datum.dptr; + size_t size = key_datum.dsize; + size_t buf_size = FLATFILE_BLOCK_SIZE; + char *buf = emalloc(buf_size); + size_t num; + size_t pos; + + php_stream_rewind(dba->fp); + while(!php_stream_eof(dba->fp)) { + /* read in the length of the key name */ + if (!php_stream_gets(dba->fp, buf, 15)) { + break; + } + num = atoi(buf); + if (num >= buf_size) { + buf_size = num + FLATFILE_BLOCK_SIZE; + buf = erealloc(buf, buf_size); + } + pos = php_stream_tell(dba->fp); + + /* read in the key name */ + num = php_stream_read(dba->fp, buf, num); + if (num < 0) { + break; + } + + if (size == num && !memcmp(buf, key, size)) { + php_stream_seek(dba->fp, pos, SEEK_SET); + php_stream_putc(dba->fp, 0); + php_stream_flush(dba->fp); + php_stream_seek(dba->fp, 0L, SEEK_END); + efree(buf); + return SUCCESS; + } + + /* read in the length of the value */ + if (!php_stream_gets(dba->fp, buf, 15)) { + break; + } + num = atoi(buf); + if (num >= buf_size) { + buf_size = num + FLATFILE_BLOCK_SIZE; + buf = erealloc(buf, buf_size); + } + /* read in the value */ + num = php_stream_read(dba->fp, buf, num); + if (num < 0) { + break; + } + } + efree(buf); + return FAILURE; +} +/* }}} */ + +/* {{{ flatfile_findkey + */ +int flatfile_findkey(flatfile *dba, datum key_datum TSRMLS_DC) { + size_t buf_size = FLATFILE_BLOCK_SIZE; + char *buf = emalloc(buf_size); + size_t num; + int ret=0; + void *key = key_datum.dptr; + size_t size = key_datum.dsize; + + php_stream_rewind(dba->fp); + while (!php_stream_eof(dba->fp)) { + if (!php_stream_gets(dba->fp, buf, 15)) { + break; + } + num = atoi(buf); + if (num >= buf_size) { + buf_size = num + FLATFILE_BLOCK_SIZE; + buf = erealloc(buf, buf_size); + } + num = php_stream_read(dba->fp, buf, num); + if (num < 0) { + break; + } + if (size == num) { + if (!memcmp(buf, key, size)) { + ret = 1; + break; + } + } + if (!php_stream_gets(dba->fp, buf, 15)) { + break; + } + num = atoi(buf); + if (num >= buf_size) { + buf_size = num + FLATFILE_BLOCK_SIZE; + buf = erealloc(buf, buf_size); + } + num = php_stream_read(dba->fp, buf, num); + if (num < 0) { + break; + } + } + efree(buf); + return ret; +} +/* }}} */ + +/* {{{ flatfile_firstkey + */ +datum flatfile_firstkey(flatfile *dba TSRMLS_DC) { + datum res; + size_t num; + size_t buf_size = FLATFILE_BLOCK_SIZE; + char *buf = emalloc(buf_size); + + php_stream_rewind(dba->fp); + while(!php_stream_eof(dba->fp)) { + if (!php_stream_gets(dba->fp, buf, 15)) { + break; + } + num = atoi(buf); + if (num >= buf_size) { + buf_size = num + FLATFILE_BLOCK_SIZE; + buf = erealloc(buf, buf_size); + } + num = php_stream_read(dba->fp, buf, num); + if (num < 0) { + break; + } + if (*(buf) != 0) { + dba->CurrentFlatFilePos = php_stream_tell(dba->fp); + res.dptr = buf; + res.dsize = num; + return res; + } + if (!php_stream_gets(dba->fp, buf, 15)) { + break; + } + num = atoi(buf); + if (num >= buf_size) { + buf_size = num + FLATFILE_BLOCK_SIZE; + buf = erealloc(buf, buf_size); + } + num = php_stream_read(dba->fp, buf, num); + if (num < 0) { + break; + } + } + efree(buf); + res.dptr = NULL; + res.dsize = 0; + return res; +} +/* }}} */ + +/* {{{ flatfile_nextkey + */ +datum flatfile_nextkey(flatfile *dba TSRMLS_DC) { + datum res; + size_t num; + size_t buf_size = FLATFILE_BLOCK_SIZE; + char *buf = emalloc(buf_size); + + php_stream_seek(dba->fp, dba->CurrentFlatFilePos, SEEK_SET); + while(!php_stream_eof(dba->fp)) { + if (!php_stream_gets(dba->fp, buf, 15)) { + break; + } + num = atoi(buf); + if (num >= buf_size) { + buf_size = num + FLATFILE_BLOCK_SIZE; + buf = erealloc(buf, buf_size); + } + num = php_stream_read(dba->fp, buf, num); + if (num < 0) { + break; + } + if (!php_stream_gets(dba->fp, buf, 15)) { + break; + } + num = atoi(buf); + if (num >= buf_size) { + buf_size = num + FLATFILE_BLOCK_SIZE; + buf = erealloc(buf, buf_size); + } + num = php_stream_read(dba->fp, buf, num); + if (num < 0) { + break; + } + if (*(buf)!=0) { + dba->CurrentFlatFilePos = php_stream_tell(dba->fp); + res.dptr = buf; + res.dsize = num; + return res; + } + } + efree(buf); + res.dptr = NULL; + res.dsize = 0; + return res; +} +/* }}} */ + +/* {{{ flatfile_version */ +char *flatfile_version() +{ + return "1.0, $Id: 6ce2f616c81b8404a2b4143c0be5cadeaa0d4742 $"; +} +/* }}} */ + +/* + * 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/dba/libflatfile/flatfile.h b/ext/dba/libflatfile/flatfile.h new file mode 100644 index 0000000..b8fbedd --- /dev/null +++ b/ext/dba/libflatfile/flatfile.h @@ -0,0 +1,48 @@ +/* + +----------------------------------------------------------------------+ + | 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: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifndef PHP_LIB_FLATFILE_H +#define PHP_LIB_FLATFILE_H + +typedef struct { + char *dptr; + size_t dsize; +} datum; + +typedef struct { + char *lockfn; + int lockfd; + php_stream *fp; + size_t CurrentFlatFilePos; + datum nextkey; +} flatfile; + +#define FLATFILE_INSERT 1 +#define FLATFILE_REPLACE 0 + +int flatfile_store(flatfile *dba, datum key_datum, datum value_datum, int mode TSRMLS_DC); +datum flatfile_fetch(flatfile *dba, datum key_datum TSRMLS_DC); +int flatfile_delete(flatfile *dba, datum key_datum TSRMLS_DC); +int flatfile_findkey(flatfile *dba, datum key_datum TSRMLS_DC); +datum flatfile_firstkey(flatfile *dba TSRMLS_DC); +datum flatfile_nextkey(flatfile *dba TSRMLS_DC); +char *flatfile_version(); + +#endif diff --git a/ext/dba/libinifile/inifile.c b/ext/dba/libinifile/inifile.c new file mode 100644 index 0000000..0db90b5 --- /dev/null +++ b/ext/dba/libinifile/inifile.c @@ -0,0 +1,593 @@ +/* + +----------------------------------------------------------------------+ + | 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: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id: 89373b1e33a6204bf8d50f955dc09d37ecf29ea2 $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#include "php_globals.h" + +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#if HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include "inifile.h" + +/* ret = -1 means that database was opened for read-only + * ret = 0 success + * ret = 1 key already exists - nothing done + */ + +/* {{{ inifile_version */ +char *inifile_version() +{ + return "1.0, $Id: 89373b1e33a6204bf8d50f955dc09d37ecf29ea2 $"; +} +/* }}} */ + +/* {{{ inifile_free_key */ +void inifile_key_free(key_type *key) +{ + if (key->group) { + efree(key->group); + } + if (key->name) { + efree(key->name); + } + memset(key, 0, sizeof(key_type)); +} +/* }}} */ + +/* {{{ inifile_free_val */ +void inifile_val_free(val_type *val) +{ + if (val->value) { + efree(val->value); + } + memset(val, 0, sizeof(val_type)); +} +/* }}} */ + +/* {{{ inifile_free_val */ +void inifile_line_free(line_type *ln) +{ + inifile_key_free(&ln->key); + inifile_val_free(&ln->val); + ln->pos = 0; +} +/* }}} */ + +/* {{{ inifile_alloc */ +inifile * inifile_alloc(php_stream *fp, int readonly, int persistent TSRMLS_DC) +{ + inifile *dba; + + if (!readonly) { + if (!php_stream_truncate_supported(fp)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't truncate this stream"); + return NULL; + } + } + + dba = pemalloc(sizeof(inifile), persistent); + memset(dba, 0, sizeof(inifile)); + dba->fp = fp; + dba->readonly = readonly; + return dba; +} +/* }}} */ + +/* {{{ inifile_free */ +void inifile_free(inifile *dba, int persistent) +{ + if (dba) { + inifile_line_free(&dba->curr); + inifile_line_free(&dba->next); + pefree(dba, persistent); + } +} +/* }}} */ + +/* {{{ inifile_key_split */ +key_type inifile_key_split(const char *group_name) +{ + key_type key; + char *name; + + if (group_name[0] == '[' && (name = strchr(group_name, ']')) != NULL) { + key.group = estrndup(group_name+1, name - (group_name + 1)); + key.name = estrdup(name+1); + } else { + key.group = estrdup(""); + key.name = estrdup(group_name); + } + return key; +} +/* }}} */ + +/* {{{ inifile_key_string */ +char * inifile_key_string(const key_type *key) +{ + if (key->group && *key->group) { + char *result; + spprintf(&result, 0, "[%s]%s", key->group, key->name ? key->name : ""); + return result; + } else if (key->name) { + return estrdup(key->name); + } else { + return NULL; + } +} +/* }}} */ + +/* {{{ etrim */ +static char *etrim(const char *str) +{ + char *val; + size_t l; + + if (!str) { + return NULL; + } + val = (char*)str; + while (*val && strchr(" \t\r\n", *val)) { + val++; + } + l = strlen(val); + while (l && (strchr(" \t\r\n", val[l-1]))) { + l--; + } + return estrndup(val, l); +} +/* }}} */ + +/* {{{ inifile_findkey + */ +static int inifile_read(inifile *dba, line_type *ln TSRMLS_DC) { + char *fline; + char *pos; + + inifile_val_free(&ln->val); + while ((fline = php_stream_gets(dba->fp, NULL, 0)) != NULL) { + if (fline) { + if (fline[0] == '[') { + /* A value name cannot start with '[' + * So either we find a ']' or we found an error + */ + pos = strchr(fline+1, ']'); + if (pos) { + *pos = '\0'; + inifile_key_free(&ln->key); + ln->key.group = etrim(fline+1); + ln->key.name = estrdup(""); + ln->pos = php_stream_tell(dba->fp); + efree(fline); + return 1; + } else { + efree(fline); + continue; + } + } else { + pos = strchr(fline, '='); + if (pos) { + *pos = '\0'; + /* keep group or make empty if not existent */ + if (!ln->key.group) { + ln->key.group = estrdup(""); + } + if (ln->key.name) { + efree(ln->key.name); + } + ln->key.name = etrim(fline); + ln->val.value = etrim(pos+1); + ln->pos = php_stream_tell(dba->fp); + efree(fline); + return 1; + } else { + /* simply ignore lines without '=' + * those should be comments + */ + efree(fline); + continue; + } + } + } + } + inifile_line_free(ln); + return 0; +} +/* }}} */ + +/* {{{ inifile_key_cmp */ +/* 0 = EQUAL + * 1 = GROUP-EQUAL,NAME-DIFFERENT + * 2 = DIFFERENT + */ +static int inifile_key_cmp(const key_type *k1, const key_type *k2 TSRMLS_DC) +{ + assert(k1->group && k1->name && k2->group && k2->name); + + if (!strcasecmp(k1->group, k2->group)) { + if (!strcasecmp(k1->name, k2->name)) { + return 0; + } else { + return 1; + } + } else { + return 2; + } +} +/* }}} */ + +/* {{{ inifile_fetch + */ +val_type inifile_fetch(inifile *dba, const key_type *key, int skip TSRMLS_DC) { + line_type ln = {{NULL,NULL},{NULL}}; + val_type val; + int res, grp_eq = 0; + + if (skip == -1 && dba->next.key.group && dba->next.key.name && !inifile_key_cmp(&dba->next.key, key TSRMLS_CC)) { + /* we got position already from last fetch */ + php_stream_seek(dba->fp, dba->next.pos, SEEK_SET); + } else { + /* specific instance or not same key -> restart search */ + /* the slow way: restart and seacrch */ + php_stream_rewind(dba->fp); + inifile_line_free(&dba->next); + } + if (skip == -1) { + skip = 0; + } + while(inifile_read(dba, &ln TSRMLS_CC)) { + if (!(res=inifile_key_cmp(&ln.key, key TSRMLS_CC))) { + if (!skip) { + val.value = estrdup(ln.val.value ? ln.val.value : ""); + /* allow faster access by updating key read into next */ + inifile_line_free(&dba->next); + dba->next = ln; + dba->next.pos = php_stream_tell(dba->fp); + return val; + } + skip--; + } else if (res == 1) { + grp_eq = 1; + } else if (grp_eq) { + /* we are leaving group now: that means we cannot find the key */ + break; + } + } + inifile_line_free(&ln); + dba->next.pos = php_stream_tell(dba->fp); + return ln.val; +} +/* }}} */ + +/* {{{ inifile_firstkey + */ +int inifile_firstkey(inifile *dba TSRMLS_DC) { + inifile_line_free(&dba->curr); + dba->curr.pos = 0; + return inifile_nextkey(dba TSRMLS_CC); +} +/* }}} */ + +/* {{{ inifile_nextkey + */ +int inifile_nextkey(inifile *dba TSRMLS_DC) { + line_type ln = {{NULL,NULL},{NULL}}; + + /*inifile_line_free(&dba->next); ??? */ + php_stream_seek(dba->fp, dba->curr.pos, SEEK_SET); + ln.key.group = estrdup(dba->curr.key.group ? dba->curr.key.group : ""); + inifile_read(dba, &ln TSRMLS_CC); + inifile_line_free(&dba->curr); + dba->curr = ln; + return ln.key.group || ln.key.name; +} +/* }}} */ + +/* {{{ inifile_truncate + */ +static int inifile_truncate(inifile *dba, size_t size TSRMLS_DC) +{ + int res; + + if ((res=php_stream_truncate_set_size(dba->fp, size)) != 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error in ftruncate: %d", res); + return FAILURE; + } + php_stream_seek(dba->fp, size, SEEK_SET); + return SUCCESS; +} +/* }}} */ + +/* {{{ inifile_find_group + * if found pos_grp_start points to "[group_name]" + */ +static int inifile_find_group(inifile *dba, const key_type *key, size_t *pos_grp_start TSRMLS_DC) +{ + int ret = FAILURE; + + php_stream_flush(dba->fp); + php_stream_seek(dba->fp, 0, SEEK_SET); + inifile_line_free(&dba->curr); + inifile_line_free(&dba->next); + + if (key->group && strlen(key->group)) { + int res; + line_type ln = {{NULL,NULL},{NULL}}; + + res = 1; + while(inifile_read(dba, &ln TSRMLS_CC)) { + if ((res=inifile_key_cmp(&ln.key, key TSRMLS_CC)) < 2) { + ret = SUCCESS; + break; + } + *pos_grp_start = php_stream_tell(dba->fp); + } + inifile_line_free(&ln); + } else { + *pos_grp_start = 0; + ret = SUCCESS; + } + if (ret == FAILURE) { + *pos_grp_start = php_stream_tell(dba->fp); + } + return ret; +} +/* }}} */ + +/* {{{ inifile_next_group + * only valid after a call to inifile_find_group + * if any next group is found pos_grp_start points to "[group_name]" or whitespace before that + */ +static int inifile_next_group(inifile *dba, const key_type *key, size_t *pos_grp_start TSRMLS_DC) +{ + int ret = FAILURE; + line_type ln = {{NULL,NULL},{NULL}}; + + *pos_grp_start = php_stream_tell(dba->fp); + ln.key.group = estrdup(key->group); + while(inifile_read(dba, &ln TSRMLS_CC)) { + if (inifile_key_cmp(&ln.key, key TSRMLS_CC) == 2) { + ret = SUCCESS; + break; + } + *pos_grp_start = php_stream_tell(dba->fp); + } + inifile_line_free(&ln); + return ret; +} +/* }}} */ + +/* {{{ inifile_copy_to + */ +static int inifile_copy_to(inifile *dba, size_t pos_start, size_t pos_end, inifile **ini_copy TSRMLS_DC) +{ + php_stream *fp; + + if (pos_start == pos_end) { + *ini_copy = NULL; + return SUCCESS; + } + if ((fp = php_stream_temp_create(0, 64 * 1024)) == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not create temporary stream"); + *ini_copy = NULL; + return FAILURE; + } + + if ((*ini_copy = inifile_alloc(fp, 1, 0 TSRMLS_CC)) == NULL) { + /* writes error */ + return FAILURE; + } + php_stream_seek(dba->fp, pos_start, SEEK_SET); + if (!php_stream_copy_to_stream(dba->fp, fp, pos_end - pos_start)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy group [%zu - %zu] to temporary stream", pos_start, pos_end); + return FAILURE; + } + return SUCCESS; +} +/* }}} */ + +/* {{{ inifile_filter + * copy from to dba while ignoring key name (group must equal) + */ +static int inifile_filter(inifile *dba, inifile *from, const key_type *key TSRMLS_DC) +{ + size_t pos_start = 0, pos_next = 0, pos_curr; + int ret = SUCCESS; + line_type ln = {{NULL,NULL},{NULL}}; + + php_stream_seek(from->fp, 0, SEEK_SET); + php_stream_seek(dba->fp, 0, SEEK_END); + while(inifile_read(from, &ln TSRMLS_CC)) { + switch(inifile_key_cmp(&ln.key, key TSRMLS_CC)) { + case 0: + pos_curr = php_stream_tell(from->fp); + if (pos_start != pos_next) { + php_stream_seek(from->fp, pos_start, SEEK_SET); + if (!php_stream_copy_to_stream(from->fp, dba->fp, pos_next - pos_start)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy [%zu - %zu] from temporary stream", pos_next, pos_start); + ret = FAILURE; + } + php_stream_seek(from->fp, pos_curr, SEEK_SET); + } + pos_next = pos_start = pos_curr; + break; + case 1: + pos_next = php_stream_tell(from->fp); + break; + case 2: + /* the function is meant to process only entries from same group */ + assert(0); + break; + } + } + if (pos_start != pos_next) { + php_stream_seek(from->fp, pos_start, SEEK_SET); + if (!php_stream_copy_to_stream(from->fp, dba->fp, pos_next - pos_start)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy [%zu - %zu] from temporary stream", pos_next, pos_start); + ret = FAILURE; + } + } + inifile_line_free(&ln); + return SUCCESS; +} +/* }}} */ + +/* {{{ inifile_delete_replace_append + */ +static int inifile_delete_replace_append(inifile *dba, const key_type *key, const val_type *value, int append TSRMLS_DC) +{ + size_t pos_grp_start, pos_grp_next; + inifile *ini_tmp = NULL; + php_stream *fp_tmp = NULL; + int ret; + + /* 1) Search group start + * 2) Search next group + * 3) If not append: Copy group to ini_tmp + * 4) Open temp_stream and copy remainder + * 5) Truncate stream + * 6) If not append AND key.name given: Filtered copy back from ini_tmp + * to stream. Otherwise the user wanted to delete the group. + * 7) Append value if given + * 8) Append temporary stream + */ + + assert(!append || (key->name && value)); /* missuse */ + + /* 1 - 3 */ + inifile_find_group(dba, key, &pos_grp_start TSRMLS_CC); + inifile_next_group(dba, key, &pos_grp_next TSRMLS_CC); + if (append) { + ret = SUCCESS; + } else { + ret = inifile_copy_to(dba, pos_grp_start, pos_grp_next, &ini_tmp TSRMLS_CC); + } + + /* 4 */ + if (ret == SUCCESS) { + fp_tmp = php_stream_temp_create(0, 64 * 1024); + if (!fp_tmp) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not create temporary stream"); + ret = FAILURE; + } else { + php_stream_seek(dba->fp, 0, SEEK_END); + if (pos_grp_next != (size_t)php_stream_tell(dba->fp)) { + php_stream_seek(dba->fp, pos_grp_next, SEEK_SET); + if (!php_stream_copy_to_stream(dba->fp, fp_tmp, PHP_STREAM_COPY_ALL)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy remainder to temporary stream"); + ret = FAILURE; + } + } + } + } + + /* 5 */ + if (ret == SUCCESS) { + if (!value || (key->name && strlen(key->name))) { + ret = inifile_truncate(dba, append ? pos_grp_next : pos_grp_start TSRMLS_CC); /* writes error on fail */ + } + } + + if (ret == SUCCESS) { + if (key->name && strlen(key->name)) { + /* 6 */ + if (!append && ini_tmp) { + ret = inifile_filter(dba, ini_tmp, key TSRMLS_CC); + } + + /* 7 */ + /* important: do not query ret==SUCCESS again: inifile_filter might fail but + * however next operation must be done. + */ + if (value) { + if (pos_grp_start == pos_grp_next && key->group && strlen(key->group)) { + php_stream_printf(dba->fp TSRMLS_CC, "[%s]\n", key->group); + } + php_stream_printf(dba->fp TSRMLS_CC, "%s=%s\n", key->name, value->value ? value->value : ""); + } + } + + /* 8 */ + /* important: do not query ret==SUCCESS again: inifile_filter might fail but + * however next operation must be done. + */ + if (fp_tmp && php_stream_tell(fp_tmp)) { + php_stream_seek(fp_tmp, 0, SEEK_SET); + php_stream_seek(dba->fp, 0, SEEK_END); + if (!php_stream_copy_to_stream(fp_tmp, dba->fp, PHP_STREAM_COPY_ALL)) { + php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "Could not copy from temporary stream - ini file truncated"); + ret = FAILURE; + } + } + } + + if (ini_tmp) { + php_stream_close(ini_tmp->fp); + inifile_free(ini_tmp, 0); + } + if (fp_tmp) { + php_stream_close(fp_tmp); + } + php_stream_flush(dba->fp); + php_stream_seek(dba->fp, 0, SEEK_SET); + + return ret; +} +/* }}} */ + +/* {{{ inifile_delete + */ +int inifile_delete(inifile *dba, const key_type *key TSRMLS_DC) +{ + return inifile_delete_replace_append(dba, key, NULL, 0 TSRMLS_CC); +} +/* }}} */ + +/* {{{ inifile_relace + */ +int inifile_replace(inifile *dba, const key_type *key, const val_type *value TSRMLS_DC) +{ + return inifile_delete_replace_append(dba, key, value, 0 TSRMLS_CC); +} +/* }}} */ + +/* {{{ inifile_append + */ +int inifile_append(inifile *dba, const key_type *key, const val_type *value TSRMLS_DC) +{ + return inifile_delete_replace_append(dba, key, value, 1 TSRMLS_CC); +} +/* }}} */ + +/* + * 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/dba/libinifile/inifile.h b/ext/dba/libinifile/inifile.h new file mode 100644 index 0000000..5a25573 --- /dev/null +++ b/ext/dba/libinifile/inifile.h @@ -0,0 +1,66 @@ +/* + +----------------------------------------------------------------------+ + | 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: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifndef PHP_LIB_INIFILE_H +#define PHP_LIB_INIFILE_H + +typedef struct { + char *group; + char *name; +} key_type; + +typedef struct { + char *value; +} val_type; + +typedef struct { + key_type key; + val_type val; + size_t pos; +} line_type; + +typedef struct { + char *lockfn; + int lockfd; + php_stream *fp; + int readonly; + line_type curr; + line_type next; +} inifile; + +val_type inifile_fetch(inifile *dba, const key_type *key, int skip TSRMLS_DC); +int inifile_firstkey(inifile *dba TSRMLS_DC); +int inifile_nextkey(inifile *dba TSRMLS_DC); +int inifile_delete(inifile *dba, const key_type *key TSRMLS_DC); +int inifile_replace(inifile *dba, const key_type *key, const val_type *val TSRMLS_DC); +int inifile_append(inifile *dba, const key_type *key, const val_type *val TSRMLS_DC); +char *inifile_version(); + +key_type inifile_key_split(const char *group_name); +char * inifile_key_string(const key_type *key); + +void inifile_key_free(key_type *key); +void inifile_val_free(val_type *val); +void inifile_line_free(line_type *ln); + +inifile * inifile_alloc(php_stream *fp, int readonly, int persistent TSRMLS_DC); +void inifile_free(inifile *dba, int persistent); + +#endif diff --git a/ext/dba/php_cdb.h b/ext/dba/php_cdb.h new file mode 100644 index 0000000..a046f07 --- /dev/null +++ b/ext/dba/php_cdb.h @@ -0,0 +1,12 @@ +#ifndef PHP_CDB_H +#define PHP_CDB_H + +#if DBA_CDB + +#include "php_dba.h" + +DBA_FUNCS(cdb); + +#endif + +#endif diff --git a/ext/dba/php_db1.h b/ext/dba/php_db1.h new file mode 100644 index 0000000..c0bb5f0 --- /dev/null +++ b/ext/dba/php_db1.h @@ -0,0 +1,12 @@ +#ifndef PHP_DB1_H +#define PHP_DB1_H + +#if DBA_DB1 + +#include "php_dba.h" + +DBA_FUNCS(db1); + +#endif + +#endif diff --git a/ext/dba/php_db2.h b/ext/dba/php_db2.h new file mode 100644 index 0000000..2a95223 --- /dev/null +++ b/ext/dba/php_db2.h @@ -0,0 +1,12 @@ +#ifndef PHP_DB2_H +#define PHP_DB2_H + +#if DBA_DB2 + +#include "php_dba.h" + +DBA_FUNCS(db2); + +#endif + +#endif diff --git a/ext/dba/php_db3.h b/ext/dba/php_db3.h new file mode 100644 index 0000000..58bb0b6 --- /dev/null +++ b/ext/dba/php_db3.h @@ -0,0 +1,12 @@ +#ifndef PHP_DB3_H +#define PHP_DB3_H + +#if DBA_DB3 + +#include "php_dba.h" + +DBA_FUNCS(db3); + +#endif + +#endif diff --git a/ext/dba/php_db4.h b/ext/dba/php_db4.h new file mode 100644 index 0000000..fa814c3 --- /dev/null +++ b/ext/dba/php_db4.h @@ -0,0 +1,12 @@ +#ifndef PHP_DB4_H +#define PHP_DB4_H + +#if DBA_DB4 + +#include "php_dba.h" + +DBA_FUNCS(db4); + +#endif + +#endif diff --git a/ext/dba/php_dba.h b/ext/dba/php_dba.h new file mode 100644 index 0000000..1e931df --- /dev/null +++ b/ext/dba/php_dba.h @@ -0,0 +1,153 @@ +/* + +----------------------------------------------------------------------+ + | 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: Sascha Schumann <sascha@schumann.cx> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifndef PHP_DBA_H +#define PHP_DBA_H + +#if HAVE_DBA + +typedef enum { + /* do not allow 0 here */ + DBA_READER = 1, + DBA_WRITER, + DBA_TRUNC, + DBA_CREAT +} dba_mode_t; + +typedef struct dba_lock { + php_stream *fp; + char *name; + int mode; /* LOCK_EX,LOCK_SH */ +} dba_lock; + +typedef struct dba_info { + /* public */ + void *dbf; /* ptr to private data or whatever */ + char *path; + dba_mode_t mode; + php_stream *fp; /* this is the database stream for builtin handlers */ + int fd; + /* arg[cv] are only available when the dba_open handler is called! */ + int argc; + zval ***argv; + /* private */ + int flags; /* whether and how dba did locking and other flags*/ + struct dba_handler *hnd; + dba_lock lock; +} dba_info; + +#define DBA_LOCK_READER (0x0001) +#define DBA_LOCK_WRITER (0x0002) +#define DBA_LOCK_CREAT (0x0004) +#define DBA_LOCK_TRUNC (0x0008) + +#define DBA_LOCK_EXT (0) +#define DBA_LOCK_ALL (DBA_LOCK_READER|DBA_LOCK_WRITER|DBA_LOCK_CREAT|DBA_LOCK_TRUNC) +#define DBA_LOCK_WCT (DBA_LOCK_WRITER|DBA_LOCK_CREAT|DBA_LOCK_TRUNC) + +#define DBA_STREAM_OPEN (0x0010) +#define DBA_PERSISTENT (0x0020) + +#define DBA_CAST_AS_FD (0x0050) +#define DBA_NO_APPEND (0x00D0) + +extern zend_module_entry dba_module_entry; +#define dba_module_ptr &dba_module_entry + +typedef struct dba_handler { + char *name; /* handler name */ + int flags; /* whether and how dba does locking and other flags*/ + int (*open)(dba_info *, char **error TSRMLS_DC); + void (*close)(dba_info * TSRMLS_DC); + char* (*fetch)(dba_info *, char *, int, int, int * TSRMLS_DC); + int (*update)(dba_info *, char *, int, char *, int, int TSRMLS_DC); + int (*exists)(dba_info *, char *, int TSRMLS_DC); + int (*delete)(dba_info *, char *, int TSRMLS_DC); + char* (*firstkey)(dba_info *, int * TSRMLS_DC); + char* (*nextkey)(dba_info *, int * TSRMLS_DC); + int (*optimize)(dba_info * TSRMLS_DC); + int (*sync)(dba_info * TSRMLS_DC); + char* (*info)(struct dba_handler *hnd, dba_info * TSRMLS_DC); + /* dba_info==NULL: Handler info, dba_info!=NULL: Database info */ +} dba_handler; + +/* common prototypes which must be supplied by modules */ + +#define DBA_OPEN_FUNC(x) \ + int dba_open_##x(dba_info *info, char **error TSRMLS_DC) +#define DBA_CLOSE_FUNC(x) \ + void dba_close_##x(dba_info *info TSRMLS_DC) +#define DBA_FETCH_FUNC(x) \ + char *dba_fetch_##x(dba_info *info, char *key, int keylen, int skip, int *newlen TSRMLS_DC) +#define DBA_UPDATE_FUNC(x) \ + int dba_update_##x(dba_info *info, char *key, int keylen, char *val, int vallen, int mode TSRMLS_DC) +#define DBA_EXISTS_FUNC(x) \ + int dba_exists_##x(dba_info *info, char *key, int keylen TSRMLS_DC) +#define DBA_DELETE_FUNC(x) \ + int dba_delete_##x(dba_info *info, char *key, int keylen TSRMLS_DC) +#define DBA_FIRSTKEY_FUNC(x) \ + char *dba_firstkey_##x(dba_info *info, int *newlen TSRMLS_DC) +#define DBA_NEXTKEY_FUNC(x) \ + char *dba_nextkey_##x(dba_info *info, int *newlen TSRMLS_DC) +#define DBA_OPTIMIZE_FUNC(x) \ + int dba_optimize_##x(dba_info *info TSRMLS_DC) +#define DBA_SYNC_FUNC(x) \ + int dba_sync_##x(dba_info *info TSRMLS_DC) +#define DBA_INFO_FUNC(x) \ + char *dba_info_##x(dba_handler *hnd, dba_info *info TSRMLS_DC) + +#define DBA_FUNCS(x) \ + DBA_OPEN_FUNC(x); \ + DBA_CLOSE_FUNC(x); \ + DBA_FETCH_FUNC(x); \ + DBA_UPDATE_FUNC(x); \ + DBA_DELETE_FUNC(x); \ + DBA_EXISTS_FUNC(x); \ + DBA_FIRSTKEY_FUNC(x); \ + DBA_NEXTKEY_FUNC(x); \ + DBA_OPTIMIZE_FUNC(x); \ + DBA_SYNC_FUNC(x); \ + DBA_INFO_FUNC(x) + +#define VALLEN(p) Z_STRVAL_PP(p), Z_STRLEN_PP(p) + +PHP_FUNCTION(dba_open); +PHP_FUNCTION(dba_popen); +PHP_FUNCTION(dba_close); +PHP_FUNCTION(dba_firstkey); +PHP_FUNCTION(dba_nextkey); +PHP_FUNCTION(dba_replace); +PHP_FUNCTION(dba_insert); +PHP_FUNCTION(dba_delete); +PHP_FUNCTION(dba_exists); +PHP_FUNCTION(dba_fetch); +PHP_FUNCTION(dba_optimize); +PHP_FUNCTION(dba_sync); +PHP_FUNCTION(dba_handlers); +PHP_FUNCTION(dba_list); +PHP_FUNCTION(dba_key_split); + +#else +#define dba_module_ptr NULL +#endif + +#define phpext_dba_ptr dba_module_ptr + +#endif diff --git a/ext/dba/php_dbm.h b/ext/dba/php_dbm.h new file mode 100644 index 0000000..4c963d1 --- /dev/null +++ b/ext/dba/php_dbm.h @@ -0,0 +1,12 @@ +#ifndef PHP_DBM_H +#define PHP_DBM_H + +#if DBA_DBM + +#include "php_dba.h" + +DBA_FUNCS(dbm); + +#endif + +#endif diff --git a/ext/dba/php_flatfile.h b/ext/dba/php_flatfile.h new file mode 100644 index 0000000..afa9f6d --- /dev/null +++ b/ext/dba/php_flatfile.h @@ -0,0 +1,12 @@ +#ifndef PHP_FLATFILE_H +#define PHP_FLATFILE_H + +#if DBA_FLATFILE + +#include "php_dba.h" + +DBA_FUNCS(flatfile); + +#endif + +#endif diff --git a/ext/dba/php_gdbm.h b/ext/dba/php_gdbm.h new file mode 100644 index 0000000..3068404 --- /dev/null +++ b/ext/dba/php_gdbm.h @@ -0,0 +1,12 @@ +#ifndef PHP_GDBM_H +#define PHP_GDBM_H + +#if DBA_GDBM + +#include "php_dba.h" + +DBA_FUNCS(gdbm); + +#endif + +#endif diff --git a/ext/dba/php_inifile.h b/ext/dba/php_inifile.h new file mode 100644 index 0000000..69444df --- /dev/null +++ b/ext/dba/php_inifile.h @@ -0,0 +1,12 @@ +#ifndef PHP_INIFILE_H +#define PHP_INIFILE_H + +#if DBA_INIFILE + +#include "php_dba.h" + +DBA_FUNCS(inifile); + +#endif + +#endif diff --git a/ext/dba/php_ndbm.h b/ext/dba/php_ndbm.h new file mode 100644 index 0000000..b1ebf15 --- /dev/null +++ b/ext/dba/php_ndbm.h @@ -0,0 +1,12 @@ +#ifndef PHP_NDBM_H +#define PHP_NDBM_H + +#if DBA_NDBM + +#include "php_dba.h" + +DBA_FUNCS(ndbm); + +#endif + +#endif diff --git a/ext/dba/php_qdbm.h b/ext/dba/php_qdbm.h new file mode 100644 index 0000000..c88efcf --- /dev/null +++ b/ext/dba/php_qdbm.h @@ -0,0 +1,12 @@ +#ifndef PHP_QDBM_H +#define PHP_QDBM_H + +#if DBA_QDBM + +#include "php_dba.h" + +DBA_FUNCS(qdbm); + +#endif + +#endif diff --git a/ext/dba/php_tcadb.h b/ext/dba/php_tcadb.h new file mode 100644 index 0000000..6aa9aa7 --- /dev/null +++ b/ext/dba/php_tcadb.h @@ -0,0 +1,41 @@ +/* + +----------------------------------------------------------------------+ + | 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: Michael Maclean <mgdm@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifndef PHP_TCADB_H +#define PHP_TCADB_H + +#if DBA_TCADB + +#include "php_dba.h" + +DBA_FUNCS(tcadb); + +#endif + +#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/dba/tests/bug36436.phpt b/ext/dba/tests/bug36436.phpt new file mode 100644 index 0000000..19254df --- /dev/null +++ b/ext/dba/tests/bug36436.phpt @@ -0,0 +1,37 @@ +--TEST-- +Bug #36436 (DBA problem with Berkeley DB4) +--SKIPIF-- +<?php + $handler = 'db4'; + require_once(dirname(__FILE__) .'/skipif.inc'); +?> +--FILE-- +<?php + +$handler = 'db4'; +require_once(dirname(__FILE__) .'/test.inc'); + +$db = dba_popen($db_filename, 'c', 'db4'); + +dba_insert('X', 'XYZ', $db); +dba_insert('Y', '123', $db); + +var_dump($db, dba_fetch('X', $db)); + +var_dump(dba_firstkey($db)); +var_dump(dba_nextkey($db)); + +dba_close($db); + +?> +===DONE=== +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +resource(%d) of type (dba persistent) +string(3) "XYZ" +string(1) "X" +string(1) "Y" +===DONE=== diff --git a/ext/dba/tests/bug38698.phpt b/ext/dba/tests/bug38698.phpt new file mode 100644 index 0000000..56dde85 --- /dev/null +++ b/ext/dba/tests/bug38698.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #38698 (Bug #38698 for some keys cdbmake creates corrupted db and cdb can't read valid db) +--SKIPIF-- +<?php + $handler = 'cdb_make'; + require_once(dirname(__FILE__) .'/skipif.inc'); +?> +--FILE-- +<?php + +$db_file = dirname(__FILE__) .'/129php.cdb'; + +if (($db_make=dba_open($db_file, "n", 'cdb_make'))!==FALSE) { + dba_insert(pack('i',129), "Booo!", $db_make); + dba_close($db_make); + // write md5 checksum of generated database file + var_dump(md5_file($db_file)); + @unlink($db_file); +} else { + echo "Error creating database\n"; +} +?> +===DONE=== +--EXPECT-- +string(32) "1f34b74bde3744265acfc21e0f30af95" +===DONE=== diff --git a/ext/dba/tests/bug48240.phpt b/ext/dba/tests/bug48240.phpt new file mode 100644 index 0000000..5a72073 --- /dev/null +++ b/ext/dba/tests/bug48240.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #48240 (DBA Segmentation fault dba_nextkey) +--SKIPIF-- +<?php + $handler = 'db4'; + require_once(dirname(__FILE__) .'/skipif.inc'); +?> +--FILE-- +<?php + +$handler = 'db4'; +require_once(dirname(__FILE__) .'/test.inc'); + +$db = dba_open($db_filename, 'c', 'db4'); + +var_dump(dba_nextkey($db)); + +dba_close($db); + +?> +===DONE=== +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECT-- +bool(false) +===DONE=== diff --git a/ext/dba/tests/bug49125.phpt b/ext/dba/tests/bug49125.phpt new file mode 100644 index 0000000..e06495a --- /dev/null +++ b/ext/dba/tests/bug49125.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #49125 (Error in dba_exists C code) +--SKIPIF-- +<?php + $handler = 'db4'; + require_once(dirname(__FILE__) .'/skipif.inc'); +?> +--FILE-- +<?php + +error_reporting(E_ALL); + +$handler = 'db4'; +require_once(dirname(__FILE__) .'/test.inc'); + +$db = dba_popen($db_filename, 'c', 'db4'); + +dba_insert('foo', 'foo', $db); + +var_dump(dba_exists('foo', $db)); + +dba_close($db); + +?> +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECT-- +bool(true) diff --git a/ext/dba/tests/clean.inc b/ext/dba/tests/clean.inc new file mode 100644 index 0000000..7c53e7e --- /dev/null +++ b/ext/dba/tests/clean.inc @@ -0,0 +1,5 @@ +<?php + $db_filename = dirname(__FILE__) .'/test0.dbm'; // see test.inc + @unlink($db_filename); + @unlink($db_filename.'.lck'); +?> diff --git a/ext/dba/tests/dba001.phpt b/ext/dba/tests/dba001.phpt new file mode 100644 index 0000000..b63829a --- /dev/null +++ b/ext/dba/tests/dba001.phpt @@ -0,0 +1,25 @@ +--TEST-- +DBA File Creation Test +--SKIPIF-- +<?php + require_once(dirname(__FILE__) .'/skipif.inc'); + die("info $HND handler used"); +?> +--FILE-- +<?php + require_once(dirname(__FILE__) .'/test.inc'); + echo "database handler: $handler\n"; + if (($db_file=dba_open($db_file, "n", $handler))!==FALSE) { + echo "database file created\n"; + dba_close($db_file); + } else { + echo "$db_file does not exist\n"; + } +?> +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: %s +database file created diff --git a/ext/dba/tests/dba002.phpt b/ext/dba/tests/dba002.phpt new file mode 100644 index 0000000..e60e733 --- /dev/null +++ b/ext/dba/tests/dba002.phpt @@ -0,0 +1,26 @@ +--TEST-- +DBA Insert/Fetch Test +--SKIPIF-- +<?php + require_once(dirname(__FILE__) .'/skipif.inc'); + die("info $HND handler used"); +?> +--FILE-- +<?php + require_once(dirname(__FILE__) .'/test.inc'); + echo "database handler: $handler\n"; + if (($db_file=dba_open($db_file, "n", $handler))!==FALSE) { + dba_insert("key1", "This is a test insert", $db_file); + echo dba_fetch("key1", $db_file); + dba_close($db_file); + } else { + echo "Error creating database\n"; + } +?> +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: %s +This is a test insert diff --git a/ext/dba/tests/dba003.phpt b/ext/dba/tests/dba003.phpt new file mode 100644 index 0000000..a027b53 --- /dev/null +++ b/ext/dba/tests/dba003.phpt @@ -0,0 +1,28 @@ +--TEST-- +DBA Insert/Replace/Fetch Test +--SKIPIF-- +<?php + require_once(dirname(__FILE__) .'/skipif.inc'); + die("info $HND handler used"); +?> +--FILE-- +<?php + require_once(dirname(__FILE__) .'/test.inc'); + echo "database handler: $handler\n"; + if (($db_file=dba_open($db_file, "n", $handler))!==FALSE) { + dba_insert("key1", "This is a test insert", $db_file); + dba_replace("key1", "This is the replacement text", $db_file); + $a = dba_fetch("key1", $db_file); + dba_close($db_file); + echo $a; + } else { + echo "Error creating database\n"; + } +?> +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: %s +This is the replacement text diff --git a/ext/dba/tests/dba004.phpt b/ext/dba/tests/dba004.phpt new file mode 100644 index 0000000..6e7180c --- /dev/null +++ b/ext/dba/tests/dba004.phpt @@ -0,0 +1,32 @@ +--TEST-- +DBA Multiple Insert/Fetch Test +--SKIPIF-- +<?php + require_once(dirname(__FILE__) .'/skipif.inc'); + die("info $HND handler used"); +?> +--FILE-- +<?php + require_once(dirname(__FILE__) .'/test.inc'); + echo "database handler: $handler\n"; + if (($db_file=dba_open($db_file, "n", $handler))!==FALSE) { + dba_insert("key1", "Content String 1", $db_file); + dba_insert("key2", "Content String 2", $db_file); + dba_insert("key3", "Third Content String", $db_file); + dba_insert("key4", "Another Content String", $db_file); + dba_insert("key5", "The last content string", $db_file); + $a = dba_fetch("key4", $db_file); + $b = dba_fetch("key2", $db_file); + dba_close($db_file); + echo "$a $b"; + } else { + echo "Error creating database\n"; + } +?> +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: %s +Another Content String Content String 2 diff --git a/ext/dba/tests/dba005.phpt b/ext/dba/tests/dba005.phpt new file mode 100644 index 0000000..68ad600 --- /dev/null +++ b/ext/dba/tests/dba005.phpt @@ -0,0 +1,39 @@ +--TEST-- +DBA FirstKey/NextKey Loop Test With 5 Items +--SKIPIF-- +<?php + require_once(dirname(__FILE__) .'/skipif.inc'); + die("info $HND handler used"); +?> +--FILE-- +<?php + require_once(dirname(__FILE__) .'/test.inc'); + echo "database handler: $handler\n"; + if (($db_file=dba_open($db_file, "n", $handler))!==FALSE) { + dba_insert("key1", "Content String 1", $db_file); + dba_insert("key2", "Content String 2", $db_file); + dba_insert("key3", "Third Content String", $db_file); + dba_insert("key4", "Another Content String", $db_file); + dba_insert("key5", "The last content string", $db_file); + $a = dba_firstkey($db_file); + $i=0; + while($a) { + $a = dba_nextkey($db_file); + $i++; + } + echo $i; + for ($i=1; $i<6; $i++) { + echo dba_exists("key$i", $db_file) ? "Y" : "N"; + } + dba_close($db_file); + } else { + echo "Error creating database\n"; + } +?> +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: %s +5YYYYY diff --git a/ext/dba/tests/dba006.phpt b/ext/dba/tests/dba006.phpt new file mode 100644 index 0000000..a3fc738 --- /dev/null +++ b/ext/dba/tests/dba006.phpt @@ -0,0 +1,41 @@ +--TEST-- +DBA FirstKey/NextKey with 2 deletes +--SKIPIF-- +<?php + require_once(dirname(__FILE__) .'/skipif.inc'); + die("info $HND handler used"); +?> +--FILE-- +<?php + require_once(dirname(__FILE__) .'/test.inc'); + echo "database handler: $handler\n"; + if (($db_file=dba_open($db_file, "n", $handler))!==FALSE) { + dba_insert("key1", "Content String 1", $db_file); + dba_insert("key2", "Content String 2", $db_file); + dba_insert("key3", "Third Content String", $db_file); + dba_insert("key4", "Another Content String", $db_file); + dba_insert("key5", "The last content string", $db_file); + dba_delete("key3", $db_file); + dba_delete("key1", $db_file); + $a = dba_firstkey($db_file); + $i=0; + while($a) { + $a = dba_nextkey($db_file); + $i++; + } + echo $i; + for ($i=1; $i<6; $i++) { + echo dba_exists("key$i", $db_file) ? "Y" : "N"; + } + dba_close($db_file); + } else { + echo "Error creating database\n"; + } +?> +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: %s +3NYNYY diff --git a/ext/dba/tests/dba007.phpt b/ext/dba/tests/dba007.phpt new file mode 100644 index 0000000..2519fdc --- /dev/null +++ b/ext/dba/tests/dba007.phpt @@ -0,0 +1,52 @@ +--TEST-- +DBA Multiple File Creation Test +--SKIPIF-- +<?php + require_once(dirname(__FILE__) .'/skipif.inc'); + if (!function_exists('dba_list')) die('skip dba_list() not available'); + die("info $HND handler used"); +?> +--FILE-- +<?php + require_once(dirname(__FILE__) .'/test.inc'); + echo "database handler: $handler\n"; + $db_file1 = $db_filename1 = dirname(__FILE__).'/test1.dbm'; + $db_file2 = $db_filename2 = dirname(__FILE__).'/test2.dbm'; + if (($db_file=dba_open($db_file, "n", $handler))!==FALSE) { + echo "database file created\n"; + } else { + echo "$db_file does not exist\n"; + } + if (($db_file1=dba_open($db_file1, "n", $handler))!==FALSE) { + echo "database file created\n"; + } else { + echo "$db_file does not exist\n"; + } + if (($db_file2=dba_open($db_file2, "n", $handler))!==FALSE) { + echo "database file created\n"; + } else { + echo "$db_file does not exist\n"; + } + var_dump(dba_list()); + dba_close($db_file); + + @unlink($db_filename1); + @unlink($db_filename2); +?> +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: %s +database file created +database file created +database file created +array(3) { + [%d]=> + string(%d) "%stest0.dbm" + [%d]=> + string(%d) "%stest1.dbm" + [%d]=> + string(%d) "%stest2.dbm" +} diff --git a/ext/dba/tests/dba008.phpt b/ext/dba/tests/dba008.phpt new file mode 100644 index 0000000..f7015d9 --- /dev/null +++ b/ext/dba/tests/dba008.phpt @@ -0,0 +1,37 @@ +--TEST-- +DBA magic_quotes_runtime Test +--SKIPIF-- +<?php + die('skip, magic_quotes removed'); + require_once(dirname(__FILE__) .'/skipif.inc'); + die("info $HND handler used"); +?> +--FILE-- +<?php + require_once(dirname(__FILE__) .'/test.inc'); + echo "database handler: $handler\n"; + if (($db_file=dba_open($db_file, "n", $handler))!==FALSE) { + ini_set('magic_quotes_runtime', 0); + dba_insert("key1", '"', $db_file); + var_dump(dba_fetch("key1", $db_file)); + ini_set('magic_quotes_runtime', 1); + var_dump(dba_fetch("key1", $db_file)); + dba_replace("key1", '\"', $db_file); + var_dump(dba_fetch("key1", $db_file)); + ini_set('magic_quotes_runtime', 0); + var_dump(dba_fetch("key1", $db_file)); + dba_close($db_file); + } else { + echo "Error creating database\n"; + } +?> +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: %s +string(1) """ +string(2) "\"" +string(2) "\"" +string(1) """ diff --git a/ext/dba/tests/dba009.phpt b/ext/dba/tests/dba009.phpt new file mode 100644 index 0000000..698657b --- /dev/null +++ b/ext/dba/tests/dba009.phpt @@ -0,0 +1,37 @@ +--TEST-- +DBA dba_popen Test +--SKIPIF-- +<?php + require_once(dirname(__FILE__) .'/skipif.inc'); + print("info $HND handler used"); +?> +--FILE-- +<?php + require_once(dirname(__FILE__) .'/test.inc'); + echo "database handler: $handler\n"; + if (($db=dba_popen($db_file, "n", $handler))!==FALSE) { + echo "Opened\n"; + dba_insert("a", "Inserted", $db); + echo dba_fetch("a", $db)."\n"; + dba_close($db); + echo "Closed\n"; + } else { + echo "Error creating database\n"; + } + if (($db=dba_popen($db_file, "n", $handler))!==FALSE) { + echo "Opened\n"; + dba_insert("a", "Inserted", $db); + echo dba_fetch("a", $db)."\n"; + } +?> +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: %s +Opened +Inserted +Closed +Opened +Inserted diff --git a/ext/dba/tests/dba010.phpt b/ext/dba/tests/dba010.phpt new file mode 100644 index 0000000..c818373 --- /dev/null +++ b/ext/dba/tests/dba010.phpt @@ -0,0 +1,44 @@ +--TEST-- +DBA with array keys +--SKIPIF-- +<?php + require_once(dirname(__FILE__) .'/skipif.inc'); + die("info $HND handler used"); +?> +--FILE-- +<?php +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; +if (($db_file=dba_open($db_file, "n", $handler))!==FALSE) { + dba_insert(array("", "name0") , "Content String 1", $db_file); + dba_insert(array("key1", "name1") , "Content String 1", $db_file); + dba_insert(array("key2","name2"), "Content String 2", $db_file); + dba_insert("[key3]name3", "Third Content String", $db_file); + dba_insert(array("key4","name4"), "Another Content String", $db_file); + dba_insert(array("key5","name5"), "The last content string", $db_file); + $a = dba_firstkey($db_file); + $i=0; + while($a) { + $a = dba_nextkey($db_file); + $i++; + } + echo $i; + echo dba_exists(array("","name0"), $db_file) ? "Y" : "N"; + for ($i=1; $i<5; $i++) { + echo dba_exists("[key$i]name$i", $db_file) ? "Y" : "N"; + } + echo dba_exists(array("key5","name5"), $db_file) ? "Y" : "N"; + echo "\n"; + dba_close($db_file); +} else { + echo "Error creating database\n"; +} + +?> +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: %s +6YYYYYY diff --git a/ext/dba/tests/dba011.phpt b/ext/dba/tests/dba011.phpt new file mode 100644 index 0000000..71164be --- /dev/null +++ b/ext/dba/tests/dba011.phpt @@ -0,0 +1,38 @@ +--TEST-- +DBA argument tests +--SKIPIF-- +<?php +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; +var_dump(dba_open($db_file)); +var_dump(dba_open($db_file, 'n')); +var_dump(dba_open($db_file, 'n', 'bogus')); +var_dump(dba_open($db_file, 'q', $handler)); +var_dump(dba_open($db_file, 'nq', $handler)); +var_dump(dba_open($db_file, 'n', $handler, 2, 3, 4, 5, 6, 7, 8)); +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: flatfile + +Warning: Wrong parameter count for dba_open() in %sdba011.php on line %d +NULL +resource(%d) of type (dba) + +Warning: dba_open(%stest0.dbm,n): No such handler: bogus in %sdba011.php on line %d +bool(false) + +Warning: dba_open(%stest0.dbm,q): Illegal DBA mode in %sdba011.php on line %d +bool(false) + +Warning: dba_open(%stest0.dbm,nq): Illegal DBA mode in %sdba011.php on line %d +bool(false) +resource(%d) of type (dba) diff --git a/ext/dba/tests/dba012.phpt b/ext/dba/tests/dba012.phpt new file mode 100644 index 0000000..821c4e2 --- /dev/null +++ b/ext/dba/tests/dba012.phpt @@ -0,0 +1,42 @@ +--TEST-- +DBA dba.default_handler tests +--SKIPIF-- +<?php +$handler = "flatfile"; +require_once(dirname(__FILE__) .'/skipif.inc'); +?> +--INI-- +dba.default_handler=flatfile +--FILE-- +<?php +$handler = "flatfile"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; + +echo "Test 1\n"; + +ini_set('dba.default_handler', 'does_not_exist'); + +var_dump(dba_open($db_filename, 'c')); + +echo "Test 2\n"; + +ini_set('dba.default_handler', ''); + +var_dump(dba_open($db_filename, 'n')); + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: flatfile +Test 1 + +Warning: ini_set(): No such handler: does_not_exist in %sdba012.php on line %d +resource(%d) of type (dba) +Test 2 + +Warning: dba_open(%stest0.dbm,n): No default handler selected in %sdba012.php on line %d +bool(false) diff --git a/ext/dba/tests/dba013.phpt b/ext/dba/tests/dba013.phpt new file mode 100644 index 0000000..bf95642 --- /dev/null +++ b/ext/dba/tests/dba013.phpt @@ -0,0 +1,27 @@ +--TEST-- +DBA with array key with empty array +--SKIPIF-- +<?php +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; + +if (($db_file=dba_open($db_file, "n", $handler))!==FALSE) { + dba_insert(array(), "Content String 1", $db_file); +} else { + echo "Error creating database\n"; +} + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: %s + +Catchable fatal error: dba_insert(): Key does not have exactly two elements: (key, name) in %sdba013.php on line %d diff --git a/ext/dba/tests/dba014.phpt b/ext/dba/tests/dba014.phpt new file mode 100644 index 0000000..7e52be7 --- /dev/null +++ b/ext/dba/tests/dba014.phpt @@ -0,0 +1,27 @@ +--TEST-- +DBA with array key with array containing too many elements +--SKIPIF-- +<?php +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; + +if (($db_file=dba_open($db_file, "n", $handler))!==FALSE) { + dba_insert(array("a", "b", "c"), "Content String 2", $db_file); +} else { + echo "Error creating database\n"; +} + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: %s + +Catchable fatal error: dba_insert(): Key does not have exactly two elements: (key, name) in %sdba014.php on line %d diff --git a/ext/dba/tests/dba015.phpt b/ext/dba/tests/dba015.phpt new file mode 100644 index 0000000..9f560c5 --- /dev/null +++ b/ext/dba/tests/dba015.phpt @@ -0,0 +1,76 @@ +--TEST-- +DBA with persistent connections +--SKIPIF-- +<?php +$handler = "flatfile"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php + +$handler = "flatfile"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; + +echo "Test 1\n"; +$db_file1 = dba_popen($db_filename, 'n', 'flatfile'); +dba_insert("key1", "This is a test insert 1", $db_file1); +echo dba_fetch("key1", $db_file1), "\n"; + + +echo "Test 2\n"; +$db_file2 = dba_popen($db_filename, 'n', 'flatfile'); +if ($db_file1 === $db_file2) { + echo "resources are the same\n"; +} else { + echo "resources are different\n"; +} + + +echo "Test 3 - fetch both rows from second resource\n"; +dba_insert("key2", "This is a test insert 2", $db_file2); +echo dba_fetch("key1", $db_file2), "\n"; +echo dba_fetch("key2", $db_file2), "\n"; + + +echo "Test 4 - fetch both rows from first resource\n"; +echo dba_fetch("key1", $db_file1), "\n"; +echo dba_fetch("key2", $db_file1), "\n"; + +echo "Test 5 - close 2nd resource\n"; +dba_close($db_file2); +var_dump($db_file1); +var_dump($db_file2); + +echo "Test 6 - query after closing 2nd resource\n"; +echo dba_fetch("key1", $db_file1), "\n"; +echo dba_fetch("key2", $db_file1), "\n"; + +?> +===DONE=== +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--XFAIL-- +Test 6 crashes in flatfile_findkey with dba pointer of NULL, bug http://bugs.php.net/bug.php?id=51278 +--EXPECTF-- +database handler: flatfile +Test 1 +This is a test insert 1 +Test 2 +resources are different +Test 3 - fetch both rows from second resource +This is a test insert 1 +This is a test insert 2 +Test 4 - fetch both rows from first resource +This is a test insert 1 +This is a test insert 2 +Test 5 - close 2nd resource +resource(%d) of type (dba persistent) +resource(%d) of type (Unknown) +Test 6 - query after closing 2nd resource +This is a test insert 1 +This is a test insert 2 +===DONE=== diff --git a/ext/dba/tests/dba016.phpt b/ext/dba/tests/dba016.phpt new file mode 100644 index 0000000..29726ac --- /dev/null +++ b/ext/dba/tests/dba016.phpt @@ -0,0 +1,23 @@ +--TEST-- +DBA lock modifier error message test +--SKIPIF-- +<?php +$handler = "flatfile"; +require_once(dirname(__FILE__) .'/skipif.inc'); +?> +--FILE-- +<?php + +$handler = "flatfile"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; + +$db_file1 = dba_popen($db_filename, 'n-t', 'flatfile'); + +?> +===DONE=== +--EXPECTF-- +database handler: flatfile + +Warning: dba_popen(%stest0.dbm,n-t): You cannot combine modifiers - (no lock) and t (test lock) in %sdba016.php on line %d +===DONE=== diff --git a/ext/dba/tests/dba_cdb.phpt b/ext/dba/tests/dba_cdb.phpt new file mode 100644 index 0000000..b9ef68f --- /dev/null +++ b/ext/dba/tests/dba_cdb.phpt @@ -0,0 +1,51 @@ +--TEST-- +DBA CDB handler test +--SKIPIF-- +<?php + $handler = 'cdb'; + require_once(dirname(__FILE__) .'/skipif.inc'); + die('info CDB does not support replace or delete'); +?> +--FILE-- +<?php + $handler = 'cdb'; + require_once(dirname(__FILE__) .'/test.inc'); + require_once(dirname(__FILE__) .'/dba_handler.inc'); +?> +===DONE=== +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECT-- +database handler: cdb +5YYYYY +Content String 2 +array(5) { + ["key1"]=> + string(16) "Content String 1" + ["key2"]=> + string(16) "Content String 2" + ["key3"]=> + string(20) "Third Content String" + ["key4"]=> + string(22) "Another Content String" + ["key5"]=> + string(23) "The last content string" +} +--NO-LOCK-- +5YYYYY +Content String 2 +array(5) { + ["key1"]=> + string(16) "Content String 1" + ["key2"]=> + string(16) "Content String 2" + ["key3"]=> + string(20) "Third Content String" + ["key4"]=> + string(22) "Another Content String" + ["key5"]=> + string(23) "The last content string" +} +===DONE=== diff --git a/ext/dba/tests/dba_cdb_001.phpt b/ext/dba/tests/dba_cdb_001.phpt new file mode 100644 index 0000000..4372754 --- /dev/null +++ b/ext/dba/tests/dba_cdb_001.phpt @@ -0,0 +1,89 @@ +--TEST-- +DBA CDB handler test +--SKIPIF-- +<?php +$handler = 'cdb'; +require_once(dirname(__FILE__) .'/skipif.inc'); +die('info CDB does not support replace or delete'); +?> +--FILE-- +<?php + +$handler = 'cdb'; +require_once(dirname(__FILE__) .'/test.inc'); + +echo "Test 0\n"; + +if (($db_file = dba_open($db_filename, 'n', $handler))!==FALSE) { + var_dump(dba_insert("key1", "Content String 1", $db_file)); + var_dump(dba_replace("key1", "New Content String", $db_file)); + var_dump(dba_fetch("key1", $db_file)); + var_dump(dba_firstkey($db_file)); + var_dump(dba_delete("key1", $db_file)); + var_dump(dba_optimize($db_file)); + var_dump(dba_sync($db_file)); + dba_close($db_file); +} +else { + echo "Failed to open DB\n"; +} + +unlink($db_filename); + +echo "Test 1\n"; + +if (($db_file = dba_open($db_filename, 'c', $handler))!==FALSE) { + dba_insert("key1", "Content String 1", $db_file); + dba_close($db_file); +} +else { + echo "Failed to open DB\n"; +} + +echo "Test 2\n"; + +if (($db_file = dba_open($db_filename, 'r', $handler))!==FALSE) { + dba_insert("key1", "Content String 1", $db_file); + dba_close($db_file); +} +else { + echo "Failed to open DB\n"; +} + +echo "Test 3\n"; + +if (($db_file = dba_open($db_filename, 'w', $handler))!==FALSE) { + echo dba_fetch("key1", $db_file), "\n"; + dba_close($db_file); +} +else { + echo "Failed to open DB\n"; +} + +?> +===DONE=== +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +Test 0 +bool(true) +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) +bool(true) +Test 1 + +Warning: dba_open(%stest0.dbm,c): Driver initialization failed for handler: cdb: Update operations are not supported in %sdba_cdb_001.php on line %d +Failed to open DB +Test 2 + +Warning: dba_insert(): You cannot perform a modification to a database without proper access in %sdba_cdb_001.php on line %d +Test 3 + +Warning: dba_open(%stest0.dbm,w): Driver initialization failed for handler: cdb: Update operations are not supported in %sdba_cdb_001.php on line %d +Failed to open DB +===DONE=== diff --git a/ext/dba/tests/dba_cdb_make.phpt b/ext/dba/tests/dba_cdb_make.phpt new file mode 100644 index 0000000..6a5f2dd --- /dev/null +++ b/ext/dba/tests/dba_cdb_make.phpt @@ -0,0 +1,40 @@ +--TEST-- +DBA CDB_MAKE handler test +--SKIPIF-- +<?php + $handler = 'cdb_make'; + require_once(dirname(__FILE__) .'/skipif.inc'); + die('info CDB_MAKE does not support reading'); +?> +--FILE-- +<?php + $handler = 'cdb_make'; + require_once(dirname(__FILE__) .'/test.inc'); + echo "database handler: $handler\n"; + // print md5 checksum of test.cdb which is generated by cdb_make program + var_dump(md5_file(dirname(__FILE__).'/test.cdb')); + if (($db_make=dba_open($db_file, "n", $handler))!==FALSE) { + dba_insert("1", "1", $db_make); + dba_insert("2", "2", $db_make); + dba_insert("1", "3", $db_make); + dba_insert("2", "1", $db_make); + dba_insert("3", "3", $db_make); + dba_insert("1", "2", $db_make); + dba_insert("4", "4", $db_make); +// dba_replace cdb_make doesn't know replace + dba_close($db_make); + // write md5 checksum of generated database file + var_dump(md5_file($db_file)); + // no need to test created database: this is done by dba_cdb_read.phpt + } else { + echo "Error creating database\n"; + } +?> +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECT-- +database handler: cdb_make +string(32) "12fc5ba2b9dcfef2480e5324eeb5f3e5" +string(32) "12fc5ba2b9dcfef2480e5324eeb5f3e5" diff --git a/ext/dba/tests/dba_cdb_read.phpt b/ext/dba/tests/dba_cdb_read.phpt new file mode 100644 index 0000000..71575f5 --- /dev/null +++ b/ext/dba/tests/dba_cdb_read.phpt @@ -0,0 +1,65 @@ +--TEST-- +DBA CDB handler test (read only) +--SKIPIF-- +<?php + $handler = 'cdb_make'; + require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php + echo "database handler: cdb\n"; + $handler = 'cdb'; + $db_file = dirname(__FILE__).'/test.cdb'; + if (($db_file=dba_open($db_file, "r", $handler))!==FALSE) { + // read key sequence + $a = dba_firstkey($db_file); + $count= 0; + $keys = $a; + while($a) { + $a = dba_nextkey($db_file); + $keys .= $a; + $count++; + } + // display number of entries and key existance + echo $count; + for ($i=1; $i<8; $i++) { + echo dba_exists($i, $db_file) ? "Y" : "N"; + } + echo "\n="; + echo dba_fetch(1, $db_file); + echo dba_fetch(2, $db_file); + echo dba_fetch(3, $db_file); + echo dba_fetch(4, $db_file); + echo "\n#"; + echo dba_fetch(1, $db_file); + echo dba_fetch(1, $db_file); + echo dba_fetch(2, $db_file); + echo dba_fetch(2, $db_file); + echo "\n?".$keys; + // with skip = 0 dba_fetch must fetch the first result + echo "\n#"; + $skip = array(); + for ($i=0; $i < strlen($keys); $i++) { + $key = substr($keys, $i, 1); + $skip[$key] = 0; + echo dba_fetch($key, $db_file); + } + echo "\n="; + for ($i=0; $i < strlen($keys); $i++) { + $key = substr($keys, $i, 1); + echo dba_fetch($key, $skip[$key], $db_file); + $skip[$key]++; + } + dba_close($db_file); + } else { + echo "Error creating database\n"; + } +?> +--EXPECT-- +database handler: cdb +7YYYYNNN +=1234 +#1122 +?1212314 +#1212314 +=1231324 diff --git a/ext/dba/tests/dba_db1.phpt b/ext/dba/tests/dba_db1.phpt new file mode 100644 index 0000000..a246003 --- /dev/null +++ b/ext/dba/tests/dba_db1.phpt @@ -0,0 +1,46 @@ +--TEST-- +DBA DB1 handler test +--SKIPIF-- +<?php + $handler = 'db1'; + require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php + $handler = 'db1'; + require_once dirname(__FILE__) .'/test.inc'; + require_once dirname(__FILE__) .'/dba_handler.inc'; +?> +===DONE=== +--EXPECT-- +database handler: db1 +3NYNYY +Content String 2 +Content 2 replaced +Read during write: not allowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +--NO-LOCK-- +3NYNYY +Content String 2 +Content 2 replaced +Read during write: not allowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +===DONE=== diff --git a/ext/dba/tests/dba_db2.phpt b/ext/dba/tests/dba_db2.phpt new file mode 100644 index 0000000..89d8a92 --- /dev/null +++ b/ext/dba/tests/dba_db2.phpt @@ -0,0 +1,46 @@ +--TEST-- +DBA DB2 handler test +--SKIPIF-- +<?php + $handler = 'db2'; + require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php + $handler = 'db2'; + require_once dirname(__FILE__) .'/test.inc'; + require_once dirname(__FILE__) .'/dba_handler.inc'; +?> +===DONE=== +--EXPECT-- +database handler: db2 +3NYNYY +Content String 2 +Content 2 replaced +Read during write: not allowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +--NO-LOCK-- +3NYNYY +Content String 2 +Content 2 replaced +Read during write: not allowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +===DONE=== diff --git a/ext/dba/tests/dba_db3.phpt b/ext/dba/tests/dba_db3.phpt new file mode 100644 index 0000000..257c882 --- /dev/null +++ b/ext/dba/tests/dba_db3.phpt @@ -0,0 +1,46 @@ +--TEST-- +DBA DB3 handler test +--SKIPIF-- +<?php + $handler = 'db3'; + require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php + $handler = 'db3'; + require_once dirname(__FILE__) .'/test.inc'; + require_once dirname(__FILE__) .'/dba_handler.inc'; +?> +===DONE=== +--EXPECT-- +database handler: db3 +3NYNYY +Content String 2 +Content 2 replaced +Read during write: not allowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +--NO-LOCK-- +3NYNYY +Content String 2 +Content 2 replaced +Read during write: not allowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +===DONE=== diff --git a/ext/dba/tests/dba_db4_000.phpt b/ext/dba/tests/dba_db4_000.phpt new file mode 100644 index 0000000..bbbc52c --- /dev/null +++ b/ext/dba/tests/dba_db4_000.phpt @@ -0,0 +1,50 @@ +--TEST-- +DBA DB4 handler test +--SKIPIF-- +<?php +$handler = 'db4'; +require_once(dirname(__FILE__) .'/skipif.inc'); +?> +--FILE-- +<?php +$handler = 'db4'; +require_once(dirname(__FILE__) .'/test.inc'); +require_once(dirname(__FILE__) .'/dba_handler.inc'); +?> +===DONE=== +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECT-- +database handler: db4 +3NYNYY +Content String 2 +Content 2 replaced +Read during write: not allowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +--NO-LOCK-- +3NYNYY +Content String 2 +Content 2 replaced +Read during write: not allowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +===DONE=== diff --git a/ext/dba/tests/dba_db4_001.phpt b/ext/dba/tests/dba_db4_001.phpt new file mode 100644 index 0000000..ecc8389 --- /dev/null +++ b/ext/dba/tests/dba_db4_001.phpt @@ -0,0 +1,32 @@ +--TEST-- +DBA DB4 New File Creation open("c") & Insert Test +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php + +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; +if (($db_file = dba_open($db_filename, "c", $handler)) !== FALSE) { + echo "database file created\n"; + dba_insert("key1", "This is a test insert", $db_file); + echo dba_fetch("key1", $db_file), "\n"; + dba_close($db_file); +} else { + echo "Error creating $db_filename\n"; +} + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 +database file created +This is a test insert diff --git a/ext/dba/tests/dba_db4_002.phpt b/ext/dba/tests/dba_db4_002.phpt new file mode 100644 index 0000000..18ac0ec --- /dev/null +++ b/ext/dba/tests/dba_db4_002.phpt @@ -0,0 +1,32 @@ +--TEST-- +DBA DB4 New File Creation open("n") & Insert Test +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php + +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; +if (($db_file = dba_open($db_filename, "n", $handler)) !== FALSE) { + echo "database file created\n"; + dba_insert("key1", "This is a test insert", $db_file); + echo dba_fetch("key1", $db_file), "\n"; + dba_close($db_file); +} else { + echo "Error creating $db_filename\n"; +} + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 +database file created +This is a test insert diff --git a/ext/dba/tests/dba_db4_003.phpt b/ext/dba/tests/dba_db4_003.phpt new file mode 100644 index 0000000..7e8568c --- /dev/null +++ b/ext/dba/tests/dba_db4_003.phpt @@ -0,0 +1,46 @@ +--TEST-- +DBA DB4 File Creation open("c") with existing file +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php + +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; + +var_dump(file_put_contents($db_filename, "Dummy contents")); + +if (($db_file = dba_open($db_filename, "c", $handler)) !== FALSE) { + if (file_exists($db_filename)) { + echo "database file created\n"; + dba_close($db_file); + } else { + echo "File did not get created\n"; + } +} else { + echo "Error creating $db_filename\n"; +} + +// Check the file still exists +$s = file_get_contents($db_filename); +echo "$s\n"; + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 +int(14) + +Notice: dba_open(): %stest0.dbm: unexpected file type or format in %sdba_db4_003.php on line %d + +Warning: dba_open(%stest0.dbm,c): Driver initialization failed for handler: db4: Invalid argument in %sdba_db4_003.php on line %d +Error creating %stest0.dbm +Dummy contents diff --git a/ext/dba/tests/dba_db4_004.phpt b/ext/dba/tests/dba_db4_004.phpt new file mode 100644 index 0000000..ca876f8 --- /dev/null +++ b/ext/dba/tests/dba_db4_004.phpt @@ -0,0 +1,40 @@ +--TEST-- +DBA DB4 Truncate Existing File open("n") +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php + +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; + +var_dump(file_put_contents($db_filename, "Dummy contents")); + +if (($db_file = dba_open($db_filename, "n", $handler)) !== FALSE) { + if (file_exists($db_filename)) { + echo "database file created\n"; + dba_insert("key1", "This is a test insert", $db_file); + echo dba_fetch("key1", $db_file), "\n"; + dba_close($db_file); + } else { + echo "File did not get created\n"; + } +} else { + echo "Error creating $db_filename\n"; +} + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 +int(14) +database file created +This is a test insert diff --git a/ext/dba/tests/dba_db4_005.phpt b/ext/dba/tests/dba_db4_005.phpt new file mode 100644 index 0000000..54bb475 --- /dev/null +++ b/ext/dba/tests/dba_db4_005.phpt @@ -0,0 +1,32 @@ +--TEST-- +DBA DB4 New File Creation popen("c") & Insert Test +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php + +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; +if (($db_file = dba_popen($db_filename, "c", $handler)) !== FALSE) { + echo "database file created\n"; + dba_insert("key1", "This is a test insert", $db_file); + echo dba_fetch("key1", $db_file), "\n"; + dba_close($db_file); +} else { + echo "Error creating $db_filename\n"; +} + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 +database file created +This is a test insert diff --git a/ext/dba/tests/dba_db4_006.phpt b/ext/dba/tests/dba_db4_006.phpt new file mode 100644 index 0000000..7d95385 --- /dev/null +++ b/ext/dba/tests/dba_db4_006.phpt @@ -0,0 +1,32 @@ +--TEST-- +DBA DB4 New File Creation popen("n") & Insert Test +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php + +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; +if (($db_file = dba_popen($db_filename, "n", $handler)) !== FALSE) { + echo "database file created\n"; + dba_insert("key1", "This is a test insert", $db_file); + echo dba_fetch("key1", $db_file), "\n"; + dba_close($db_file); +} else { + echo "Error creating $db_filename\n"; +} + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 +database file created +This is a test insert diff --git a/ext/dba/tests/dba_db4_007.phpt b/ext/dba/tests/dba_db4_007.phpt new file mode 100644 index 0000000..bd95e0b --- /dev/null +++ b/ext/dba/tests/dba_db4_007.phpt @@ -0,0 +1,41 @@ +--TEST-- +DBA DB4 File Creation popen("c") with existing invalid file +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php + +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; + +var_dump(file_put_contents($db_filename, "Dummy contents")); + +if (($db_file = dba_popen($db_filename, "c", $handler)) !== FALSE) { + if (file_exists($db_filename)) { + echo "database file created\n"; + dba_close($db_file); + } else { + echo "File did not get created\n"; + } +} else { + echo "Error creating $db_filename\n"; +} + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 +int(14) + +Notice: dba_popen(): %stest0.dbm: unexpected file type or format in %sdba_db4_007.php on line %d + +Warning: dba_popen(%stest0.dbm,c): Driver initialization failed for handler: db4: Invalid argument in %sdba_db4_007.php on line %d +Error creating %stest0.dbm diff --git a/ext/dba/tests/dba_db4_008.phpt b/ext/dba/tests/dba_db4_008.phpt new file mode 100644 index 0000000..80f62ea --- /dev/null +++ b/ext/dba/tests/dba_db4_008.phpt @@ -0,0 +1,40 @@ +--TEST-- +DBA DB4 Truncate Existing File popen("n") +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php + +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; + +var_dump(file_put_contents($db_filename, "Dummy contents")); + +if (($db_file = dba_popen($db_filename, "n", $handler)) !== FALSE) { + if (file_exists($db_filename)) { + echo "database file created\n"; + dba_insert("key1", "This is a test insert", $db_file); + echo dba_fetch("key1", $db_file), "\n"; + dba_close($db_file); + } else { + echo "File did not get created\n"; + } +} else { + echo "Error creating $db_filename\n"; +} + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 +int(14) +database file created +This is a test insert diff --git a/ext/dba/tests/dba_db4_009.phpt b/ext/dba/tests/dba_db4_009.phpt new file mode 100644 index 0000000..5a870c9 --- /dev/null +++ b/ext/dba/tests/dba_db4_009.phpt @@ -0,0 +1,53 @@ +--TEST-- +DBA DB4 Multiple File Creation Test +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; +$db_file1 = $db_filename1 = dirname(__FILE__).'/test1.dbm'; +$db_file2 = $db_filename2 = dirname(__FILE__).'/test2.dbm'; +if (($db_file=dba_open($db_file, "n", $handler))!==FALSE) { + echo "database file created\n"; +} else { + echo "$db_file does not exist\n"; +} +if (($db_file1=dba_open($db_file1, "n", $handler))!==FALSE) { + echo "database file created\n"; +} else { + echo "$db_file does not exist\n"; +} +if (($db_file2=dba_open($db_file2, "n", $handler))!==FALSE) { + echo "database file created\n"; +} else { + echo "$db_file does not exist\n"; +} +var_dump(dba_list()); +dba_close($db_file); + +@unlink($db_filename1); +@unlink($db_filename2); +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 +database file created +database file created +database file created +array(3) { + [%d]=> + string(%d) "%stest0.dbm" + [%d]=> + string(%d) "%stest1.dbm" + [%d]=> + string(%d) "%stest2.dbm" +} diff --git a/ext/dba/tests/dba_db4_010.phpt b/ext/dba/tests/dba_db4_010.phpt new file mode 100644 index 0000000..fb31f05 --- /dev/null +++ b/ext/dba/tests/dba_db4_010.phpt @@ -0,0 +1,38 @@ +--TEST-- +DBA DB4 magic_quotes_runtime Test +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; +if (($db_file=dba_open($db_file, "n", $handler))!==FALSE) { + ini_set('magic_quotes_runtime', 0); + dba_insert("key1", '"', $db_file); + var_dump(dba_fetch("key1", $db_file)); + ini_set('magic_quotes_runtime', 1); + var_dump(dba_fetch("key1", $db_file)); + dba_replace("key1", '\"', $db_file); + var_dump(dba_fetch("key1", $db_file)); + ini_set('magic_quotes_runtime', 0); + var_dump(dba_fetch("key1", $db_file)); + dba_close($db_file); +} else { + echo "Error creating database\n"; +} +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 +string(1) """ +string(2) "\"" +string(2) "\"" +string(1) """ diff --git a/ext/dba/tests/dba_db4_011.phpt b/ext/dba/tests/dba_db4_011.phpt new file mode 100644 index 0000000..ce9be27 --- /dev/null +++ b/ext/dba/tests/dba_db4_011.phpt @@ -0,0 +1,36 @@ +--TEST-- +DBA DB4 with repeated key +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; +if (($db_file=dba_open($db_filename, "c", $handler))!==FALSE) { + var_dump(dba_insert("key1", "Content String 1", $db_file)); + var_dump(dba_insert("key2", "Content String 2", $db_file)); + var_dump(dba_insert("key2", "Same key", $db_file)); + echo dba_fetch("key1", $db_file), "\n"; + echo dba_fetch("key2", $db_file), "\n"; + dba_close($db_file); +} else { + echo "Error creating database\n"; +} + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 +bool(true) +bool(true) +bool(false) +Content String 1 +Content String 2 diff --git a/ext/dba/tests/dba_db4_012.phpt b/ext/dba/tests/dba_db4_012.phpt new file mode 100644 index 0000000..2caa43c --- /dev/null +++ b/ext/dba/tests/dba_db4_012.phpt @@ -0,0 +1,31 @@ +--TEST-- +DBA DB4 New File Creation open("rl") +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php + +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; +if (($db_file = dba_open($db_filename, "rl", $handler)) !== FALSE) { + echo "database file created\n"; + dba_close($db_file); +} else { + echo "Error creating $db_filename\n"; +} + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 + +Warning: dba_open(%stest0.dbm,rl): Driver initialization failed for handler: db4: No such file or directory in %sdba_db4_012.php on line %d +Error creating %stest0.dbm diff --git a/ext/dba/tests/dba_db4_013.phpt b/ext/dba/tests/dba_db4_013.phpt new file mode 100644 index 0000000..ba2d171 --- /dev/null +++ b/ext/dba/tests/dba_db4_013.phpt @@ -0,0 +1,40 @@ +--TEST-- +DBA DB4 File open("rl") & Insert Test +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php + +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; + +if (($db_file = dba_popen($db_filename, "c", $handler)) !== FALSE) { + echo "database file created\n"; + dba_close($db_file); +} + +if (($db_file = dba_popen($db_filename, "rl", $handler)) !== FALSE) { + echo "database file opened\n"; + dba_insert("key1", "This is a test insert", $db_file); + echo dba_fetch("key1", $db_file), "\n"; + dba_close($db_file); +} else { + echo "Error creating $db_filename\n"; +} + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 +database file created +database file opened + +Warning: dba_insert(): You cannot perform a modification to a database without proper access in %sdba_db4_013.php on line %d diff --git a/ext/dba/tests/dba_db4_014.phpt b/ext/dba/tests/dba_db4_014.phpt new file mode 100644 index 0000000..6fb22f8 --- /dev/null +++ b/ext/dba/tests/dba_db4_014.phpt @@ -0,0 +1,32 @@ +--TEST-- +DBA DB4 File open("wl") & Insert Test +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php + +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; + +if (($db_file = dba_open($db_filename, "wl", $handler)) !== FALSE) { + echo "database file opened\n"; + dba_close($db_file); +} else { + echo "Error creating $db_filename\n"; +} + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 + +Warning: dba_open(%stest0.dbm,wl): Driver initialization failed for handler: db4: No such file or directory in %sdba_db4_014.php on line %d +Error creating %stest0.dbm diff --git a/ext/dba/tests/dba_db4_015.phpt b/ext/dba/tests/dba_db4_015.phpt new file mode 100644 index 0000000..a153567 --- /dev/null +++ b/ext/dba/tests/dba_db4_015.phpt @@ -0,0 +1,39 @@ +--TEST-- +DBA DB4 File open("wl") & Insert Test +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php + +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; + +if (($db_file = dba_popen($db_filename, "c", $handler)) !== FALSE) { + echo "database file created\n"; + dba_close($db_file); +} + +if (($db_file = dba_popen($db_filename, "wl", $handler)) !== FALSE) { + echo "database file opened\n"; + dba_insert("key1", "This is a test insert", $db_file); + echo dba_fetch("key1", $db_file), "\n"; + dba_close($db_file); +} else { + echo "Error creating $db_filename\n"; +} + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 +database file created +database file opened +This is a test insert diff --git a/ext/dba/tests/dba_db4_016.phpt b/ext/dba/tests/dba_db4_016.phpt new file mode 100644 index 0000000..b79cc71 --- /dev/null +++ b/ext/dba/tests/dba_db4_016.phpt @@ -0,0 +1,59 @@ +--TEST-- +DBA DB4 File Creation popen("c") with existing valid file +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php + +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; + +if (($db_file = dba_popen($db_filename, "c", $handler)) !== FALSE) { + if (file_exists($db_filename)) { + echo "database file created\n"; + var_dump(dba_insert("key1", "This is a test insert", $db_file)); + echo dba_fetch("key1", $db_file), "\n"; + dba_close($db_file); + } else { + echo "File did not get created\n"; + } +} else { + echo "Error creating $db_filename\n"; +} + +// Now test reopening it +if (($db_file = dba_popen($db_filename, "c", $handler)) !== FALSE) { + if (file_exists($db_filename)) { + echo "database file created\n"; + var_dump(dba_insert("key1", "second open test", $db_file)); + var_dump(dba_insert("key2", "second open test row 2", $db_file)); + echo dba_fetch("key1", $db_file), "\n"; + echo dba_fetch("key2", $db_file), "\n"; + dba_close($db_file); + } else { + echo "File did not get created\n"; + } +} else { + echo "Error creating $db_filename\n"; +} + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 +database file created +bool(true) +This is a test insert +database file created +bool(false) +bool(true) +This is a test insert +second open test row 2 diff --git a/ext/dba/tests/dba_db4_017.phpt b/ext/dba/tests/dba_db4_017.phpt new file mode 100644 index 0000000..12bf3df --- /dev/null +++ b/ext/dba/tests/dba_db4_017.phpt @@ -0,0 +1,37 @@ +--TEST-- +DBA DB4 file creation dba_open("cd") +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +?> +--FILE-- +<?php + +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; + +if (($db_file = dba_open($db_filename, "cd", $handler)) !== FALSE) { + if (file_exists($db_filename)) { + echo "database file created\n"; + var_dump(dba_insert("key1", "This is a test insert", $db_file)); + echo dba_fetch("key1", $db_file), "\n"; + dba_close($db_file); + } else { + echo "File did not get created\n"; + } +} else { + echo "Error creating $db_filename\n"; +} + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 +database file created +bool(true) +This is a test insert diff --git a/ext/dba/tests/dba_db4_018.phpt b/ext/dba/tests/dba_db4_018.phpt new file mode 100644 index 0000000..ecd1980 --- /dev/null +++ b/ext/dba/tests/dba_db4_018.phpt @@ -0,0 +1,76 @@ +--TEST-- +DBA DB4 with persistent connections +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php + +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; + +echo "Test 1\n"; +$db_file1 = dba_popen($db_filename, 'n', 'flatfile'); +dba_insert("key1", "This is a test insert 1", $db_file1); +echo dba_fetch("key1", $db_file1), "\n"; + + +echo "Test 2\n"; +$db_file2 = dba_popen($db_filename, 'n', 'flatfile'); +if ($db_file1 === $db_file2) { + echo "resources are the same\n"; +} else { + echo "resources are different\n"; +} + + +echo "Test 3 - fetch both rows from second resource\n"; +dba_insert("key2", "This is a test insert 2", $db_file2); +echo dba_fetch("key1", $db_file2), "\n"; +echo dba_fetch("key2", $db_file2), "\n"; + + +echo "Test 4 - fetch both rows from first resource\n"; +echo dba_fetch("key1", $db_file1), "\n"; +echo dba_fetch("key2", $db_file1), "\n"; + +echo "Test 5 - close 2nd resource\n"; +dba_close($db_file2); +var_dump($db_file1); +var_dump($db_file2); + +echo "Test 6 - query after closing 2nd resource\n"; +echo dba_fetch("key1", $db_file1), "\n"; +echo dba_fetch("key2", $db_file1), "\n"; + +?> +===DONE=== +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--XFAIL-- +Test 6 crashes with dba pointer of NULL, bug http://bugs.php.net/bug.php?id=51278 +--EXPECTF-- +database handler: db4 +Test 1 +This is a test insert 1 +Test 2 +resources are different +Test 3 - fetch both rows from second resource +This is a test insert 1 +This is a test insert 2 +Test 4 - fetch both rows from first resource +This is a test insert 1 +This is a test insert 2 +Test 5 - close 2nd resource +resource(%d) of type (dba persistent) +resource(%d) of type (Unknown) +Test 6 - query after closing 2nd resource +This is a test insert 1 +This is a test insert 2 +===DONE=== diff --git a/ext/dba/tests/dba_db4_handlers.phpt b/ext/dba/tests/dba_db4_handlers.phpt new file mode 100644 index 0000000..d238f43 --- /dev/null +++ b/ext/dba/tests/dba_db4_handlers.phpt @@ -0,0 +1,50 @@ +--TEST-- +DBA DB4 Handler Test +--SKIPIF-- +<?php +$handler="db4"; +require(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php +$handler="db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; + +function check($h) +{ + if (!$h) { + return; + } + + foreach ($h as $key) { + if ($key === "db4") { + echo "Success: db4 enabled\n"; + } + } +} + +echo "Test 1\n"; + +check(dba_handlers()); + +echo "Test 2 - full info\n"; +$h = dba_handlers(1); +foreach ($h as $key => $val) { + if ($key === "db4") { + echo "$val\n"; + } +} + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTREGEX-- +database handler: db4 +Test 1 +Success: db4 enabled +Test 2 - full info +.*Berkeley DB (4|5).* diff --git a/ext/dba/tests/dba_db4_optimize.phpt b/ext/dba/tests/dba_db4_optimize.phpt new file mode 100644 index 0000000..de27dd8 --- /dev/null +++ b/ext/dba/tests/dba_db4_optimize.phpt @@ -0,0 +1,38 @@ +--TEST-- +DBA DB4 Optimize Test +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; +if (($db_file=dba_open($db_filename, "n", $handler))!==FALSE) { + dba_insert("key1", "Content String 1", $db_file); + dba_insert("key2", "Content String 2", $db_file); + for ($i=1; $i<3; $i++) { + echo dba_exists("key$i", $db_file) ? "Y" : "N"; + } + echo "\n"; + var_dump(dba_optimize($db_file)); + dba_close($db_file); +} else { + echo "Error creating database\n"; +} + +?> +===DONE=== +<?php exit(0); ?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 +YY +bool(true) +===DONE=== diff --git a/ext/dba/tests/dba_db4_sync.phpt b/ext/dba/tests/dba_db4_sync.phpt new file mode 100644 index 0000000..8c4e248 --- /dev/null +++ b/ext/dba/tests/dba_db4_sync.phpt @@ -0,0 +1,38 @@ +--TEST-- +DBA DB4 Sync Test +--SKIPIF-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php +$handler = "db4"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; +if (($db_file=dba_open($db_filename, "n", $handler))!==FALSE) { + dba_insert("key1", "Content String 1", $db_file); + dba_insert("key2", "Content String 2", $db_file); + for ($i=1; $i<3; $i++) { + echo dba_exists("key$i", $db_file) ? "Y" : "N"; + } + echo "\n"; + var_dump(dba_sync($db_file)); + dba_close($db_file); +} else { + echo "Error creating database\n"; +} + +?> +===DONE=== +<?php exit(0); ?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: db4 +YY +bool(true) +===DONE=== diff --git a/ext/dba/tests/dba_dbm.phpt b/ext/dba/tests/dba_dbm.phpt new file mode 100644 index 0000000..dd1fe1e --- /dev/null +++ b/ext/dba/tests/dba_dbm.phpt @@ -0,0 +1,46 @@ +--TEST-- +DBA DBM handler test +--SKIPIF-- +<?php + $handler = 'dbm'; + require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php + $handler = 'dbm'; + require_once dirname(__FILE__) .'/test.inc'; + require_once dirname(__FILE__) .'/dba_handler.inc'; +?> +===DONE=== +--EXPECT-- +database handler: dbm +3NYNYY +Content String 2 +Content 2 replaced +Read during write: not allowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +--NO-LOCK-- +3NYNYY +Content String 2 +Content 2 replaced +Read during write: not allowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +===DONE=== diff --git a/ext/dba/tests/dba_flatfile.phpt b/ext/dba/tests/dba_flatfile.phpt new file mode 100644 index 0000000..8e1ca6a --- /dev/null +++ b/ext/dba/tests/dba_flatfile.phpt @@ -0,0 +1,50 @@ +--TEST-- +DBA FlatFile handler test +--SKIPIF-- +<?php + $handler = 'flatfile'; + require_once(dirname(__FILE__) .'/skipif.inc'); +?> +--FILE-- +<?php + $handler = 'flatfile'; + require_once(dirname(__FILE__) .'/test.inc'); + require_once(dirname(__FILE__) .'/dba_handler.inc'); +?> +===DONE=== +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECT-- +database handler: flatfile +3NYNYY +Content String 2 +Content 2 replaced +Read during write: not allowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +--NO-LOCK-- +3NYNYY +Content String 2 +Content 2 replaced +Read during write: not allowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +===DONE=== diff --git a/ext/dba/tests/dba_gdbm.phpt b/ext/dba/tests/dba_gdbm.phpt new file mode 100644 index 0000000..33d7d20 --- /dev/null +++ b/ext/dba/tests/dba_gdbm.phpt @@ -0,0 +1,34 @@ +--TEST-- +DBA GDBM handler test +--SKIPIF-- +<?php + $handler = 'gdbm'; + require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php + $handler = 'gdbm'; + require_once dirname(__FILE__) .'/test.inc'; + $lock_flag = ''; // lock in library + require_once dirname(__FILE__) .'/dba_handler.inc'; + + // Read during write is system dependant. Important is that there is no deadlock +?> +===DONE=== +--EXPECTF-- +database handler: gdbm +3NYNYY +Content String 2 +Content 2 replaced +Read during write:%sallowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +===DONE=== diff --git a/ext/dba/tests/dba_handler.inc b/ext/dba/tests/dba_handler.inc new file mode 100644 index 0000000..1c3f512 --- /dev/null +++ b/ext/dba/tests/dba_handler.inc @@ -0,0 +1,90 @@ +<?php + +echo "database handler: $handler\n"; + +do { + if (($db_file = dba_open($db_filename, 'n'.$lock_flag, $handler))!==FALSE) { + dba_insert("key1", "Content String 1", $db_file); + dba_insert("key2", "Content String 2", $db_file); + dba_insert("key3", "Third Content String", $db_file); + dba_insert("key4", "Another Content String", $db_file); + dba_insert("key5", "The last content string", $db_file); + if ($handler != 'cdb') { + dba_delete("key3", $db_file); + dba_delete("key1", $db_file); + } else { + dba_close($db_file); + if (($db_file = dba_open($db_filename, 'r'.$lock_flag, $handler))===FALSE) { + echo "Error reopening database\n"; + } + } + $a = dba_firstkey($db_file); + $i=0; + while($a) { + $a = dba_nextkey($db_file); + $i++; + } + echo $i; + for ($i=1; $i<6; $i++) { + echo dba_exists("key$i", $db_file) ? "Y" : "N"; + } + echo "\n"; + echo dba_fetch("key2", $db_file)."\n"; + if ($handler != 'cdb') { + dba_replace("key2", "Content 2 replaced", $db_file); + echo dba_fetch("key2", $db_file)."\n"; + } + dba_close($db_file); + } else { + echo "Error creating database\n"; + } + if ($handler != 'cdb') { + $db_writer = dba_open($db_filename, 'c'.$lock_flag, $handler); + if (($dba_reader = @dba_open($db_filename, 'r'.$lock_flag.($lock_flag ? 't' : ''), $handler))===false) { + echo "Read during write: not allowed\n"; + } else { + echo "Read during write: allowed\n"; + } + if ($db_writer!==FALSE) { + dba_insert("key number 6", "The 6th value", $db_writer); + @dba_insert("key number 6", "The 6th value inserted again would be an error", $db_writer); + dba_replace("key2", "Content 2 replaced 2nd time", $db_writer); + dba_delete("key4", $db_writer); + echo dba_fetch("key2", $db_writer)."\n"; + echo dba_fetch("key number 6", $db_writer)."\n"; + dba_close($db_writer); // when the writer is open at least db3 would fail because of buffered io. + } else { + die("Error reopening database\n"); + } + } + if (($db_file = dba_open($db_filename, 'r'.$lock_flag, $handler))!==FALSE) { + $key = dba_firstkey($db_file); + $res = array(); + while($key) { + $res[$key] = dba_fetch($key, $db_file); + $key = dba_nextkey($db_file); + } + ksort($res); + var_dump($res); + dba_close($db_file); + } else { + echo "Error reading database\n"; + } + if (!empty($dba_reader)) { + dba_close($dba_reader); + } + if (($db_file = dba_popen($db_filename, 'r'.($lock_flag==''?'':'-'), $handler))!==FALSE) { + if ($handler == 'dbm') { + dba_close($db_file); + } + } + + if ($lock_flag == '') { + break; + } else { + echo "--NO-LOCK--\n"; + $lock_flag = ''; + } +} while(1); + +?>
\ No newline at end of file diff --git a/ext/dba/tests/dba_handlers.phpt b/ext/dba/tests/dba_handlers.phpt new file mode 100644 index 0000000..9f66a79 --- /dev/null +++ b/ext/dba/tests/dba_handlers.phpt @@ -0,0 +1,69 @@ +--TEST-- +DBA Handler Test +--SKIPIF-- +<?php +$handler="flatfile"; +require(dirname(__FILE__) .'/skipif.inc'); +die("info $HND handler used"); +?> +--FILE-- +<?php +$handler="flatfile"; +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; + +function check($h) +{ + if (!$h) { + return; + } + + foreach ($h as $key) { + if ($key === "flatfile") { + echo "Success: flatfile enabled\n"; + } + } +} + +echo "Test 1\n"; + +check(dba_handlers()); + +echo "Test 2\n"; + +check(dba_handlers(null)); + +echo "Test 3\n"; + +check(dba_handlers(1, 2)); + +echo "Test 4\n"; + +check(dba_handlers(0)); + +echo "Test 5 - full info\n"; +$h = dba_handlers(1); +foreach ($h as $key => $val) { + if ($key === "flatfile") { + echo "Success: flatfile enabled\n"; + } +} + +?> +--CLEAN-- +<?php +require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: flatfile +Test 1 +Success: flatfile enabled +Test 2 +Success: flatfile enabled +Test 3 + +Warning: dba_handlers() expects at most 1 parameter, 2 given in %sdba_handlers.php on line %d +Test 4 +Success: flatfile enabled +Test 5 - full info +Success: flatfile enabled diff --git a/ext/dba/tests/dba_inifile.phpt b/ext/dba/tests/dba_inifile.phpt new file mode 100644 index 0000000..81ab738 --- /dev/null +++ b/ext/dba/tests/dba_inifile.phpt @@ -0,0 +1,46 @@ +--TEST-- +DBA INIFILE handler test +--SKIPIF-- +<?php + $handler = 'inifile'; + require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php + $handler = 'inifile'; + require_once dirname(__FILE__) .'/test.inc'; + require_once dirname(__FILE__) .'/dba_handler.inc'; +?> +===DONE=== +--EXPECT-- +database handler: inifile +3NYNYY +Content String 2 +Content 2 replaced +Read during write: not allowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +--NO-LOCK-- +3NYNYY +Content String 2 +Content 2 replaced +Read during write: not allowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +===DONE=== diff --git a/ext/dba/tests/dba_ndbm.phpt b/ext/dba/tests/dba_ndbm.phpt new file mode 100644 index 0000000..b0f5542 --- /dev/null +++ b/ext/dba/tests/dba_ndbm.phpt @@ -0,0 +1,46 @@ +--TEST-- +DBA NDBM handler test +--SKIPIF-- +<?php + $handler = 'ndbm'; + require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php + $handler = 'ndbm'; + require_once dirname(__FILE__) .'/test.inc'; + require_once dirname(__FILE__) .'/dba_handler.inc'; +?> +===DONE=== +--EXPECT-- +database handler: ndbm +3NYNYY +Content String 2 +Content 2 replaced +Read during write: not allowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +--NO-LOCK-- +3NYNYY +Content String 2 +Content 2 replaced +Read during write: not allowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +===DONE=== diff --git a/ext/dba/tests/dba_optimize.phpt b/ext/dba/tests/dba_optimize.phpt new file mode 100644 index 0000000..794d7e8 --- /dev/null +++ b/ext/dba/tests/dba_optimize.phpt @@ -0,0 +1,51 @@ +--TEST-- +DBA Optimize Test +--SKIPIF-- +<?php + require_once dirname(__FILE__) .'/skipif.inc'; + die("info $HND handler used"); +?> +--FILE-- +<?php +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; +if (($db_file=dba_open($db_filename, "n", $handler))!==FALSE) { + dba_insert("key1", "Content String 1", $db_file); + dba_insert("key2", "Content String 2", $db_file); + $a = dba_firstkey($db_file); + $i=0; + while($a) { + $a = dba_nextkey($db_file); + $i++; + } + echo $i; + for ($i=1; $i<3; $i++) { + echo dba_exists("key$i", $db_file) ? "Y" : "N"; + } + echo "\n"; + var_dump(dba_optimize()); + var_dump(dba_optimize("")); + var_dump(dba_optimize($db_file)); + dba_close($db_file); +} else { + echo "Error creating database\n"; +} + +?> +===DONE=== +<?php exit(0); ?> +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: flatfile +2YY + +Warning: dba_optimize() expects exactly 1 parameter, 0 given in %sdba_optimize.php on line %d +NULL + +Warning: dba_optimize() expects parameter 1 to be resource, string given in %sdba_optimize.php on line %d +NULL +bool(true) +===DONE=== diff --git a/ext/dba/tests/dba_qdbm.phpt b/ext/dba/tests/dba_qdbm.phpt new file mode 100644 index 0000000..ef216d9 --- /dev/null +++ b/ext/dba/tests/dba_qdbm.phpt @@ -0,0 +1,34 @@ +--TEST-- +DBA QDBM handler test +--SKIPIF-- +<?php + $handler = 'qdbm'; + require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php + $handler = 'qdbm'; + require_once dirname(__FILE__) .'/test.inc'; + $lock_flag = ''; // lock in library + require_once dirname(__FILE__) .'/dba_handler.inc'; +?> +===DONE=== +--EXPECTF-- +database handler: qdbm +3NYNYY +Content String 2 +Content 2 replaced +Read during write:%sallowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} + +Warning: dba_popen(%stest0.dbm,r-): Locking cannot be disabled for handler qdbm in %sdba_handler.inc on line %d +===DONE=== diff --git a/ext/dba/tests/dba_split.phpt b/ext/dba/tests/dba_split.phpt new file mode 100644 index 0000000..0989f09 --- /dev/null +++ b/ext/dba/tests/dba_split.phpt @@ -0,0 +1,83 @@ +--TEST-- +DBA Split Test +--SKIPIF-- +<?php + require_once dirname(__FILE__) .'/skipif.inc'; + die("info $HND handler used"); +?> +--FILE-- +<?php +var_dump(dba_key_split("key1", "name")); +var_dump(dba_key_split(1)); +var_dump(dba_key_split(null)); +var_dump(dba_key_split("")); +var_dump(dba_key_split("name1")); +var_dump(dba_key_split("[key1")); +var_dump(dba_key_split("[key1]")); +var_dump(dba_key_split("key1]")); +var_dump(dba_key_split("[key1]name1")); +var_dump(dba_key_split("[key1]name1[key2]name2")); +var_dump(dba_key_split("[key1]name1")); + +?> +===DONE=== +<?php exit(0); ?> +--EXPECTF-- +Warning: Wrong parameter count for dba_key_split() in %sdba_split.php on line %d +NULL +array(2) { + [0]=> + string(0) "" + [1]=> + string(1) "1" +} +bool(false) +array(2) { + [0]=> + string(0) "" + [1]=> + string(0) "" +} +array(2) { + [0]=> + string(0) "" + [1]=> + string(5) "name1" +} +array(2) { + [0]=> + string(0) "" + [1]=> + string(5) "[key1" +} +array(2) { + [0]=> + string(4) "key1" + [1]=> + string(0) "" +} +array(2) { + [0]=> + string(0) "" + [1]=> + string(5) "key1]" +} +array(2) { + [0]=> + string(4) "key1" + [1]=> + string(5) "name1" +} +array(2) { + [0]=> + string(4) "key1" + [1]=> + string(16) "name1[key2]name2" +} +array(2) { + [0]=> + string(4) "key1" + [1]=> + string(5) "name1" +} +===DONE=== diff --git a/ext/dba/tests/dba_sync.phpt b/ext/dba/tests/dba_sync.phpt new file mode 100644 index 0000000..e0906ee --- /dev/null +++ b/ext/dba/tests/dba_sync.phpt @@ -0,0 +1,51 @@ +--TEST-- +DBA Sync Test +--SKIPIF-- +<?php + require_once dirname(__FILE__) .'/skipif.inc'; + die("info $HND handler used"); +?> +--FILE-- +<?php +require_once(dirname(__FILE__) .'/test.inc'); +echo "database handler: $handler\n"; +if (($db_file=dba_open($db_filename, "n", $handler))!==FALSE) { + dba_insert("key1", "Content String 1", $db_file); + dba_insert("key2", "Content String 2", $db_file); + $a = dba_firstkey($db_file); + $i=0; + while($a) { + $a = dba_nextkey($db_file); + $i++; + } + echo $i; + for ($i=1; $i<3; $i++) { + echo dba_exists("key$i", $db_file) ? "Y" : "N"; + } + echo "\n"; + var_dump(dba_sync()); + var_dump(dba_sync("")); + var_dump(dba_sync($db_file)); + dba_close($db_file); +} else { + echo "Error creating database\n"; +} + +?> +===DONE=== +<?php exit(0); ?> +--CLEAN-- +<?php + require(dirname(__FILE__) .'/clean.inc'); +?> +--EXPECTF-- +database handler: flatfile +2YY + +Warning: dba_sync() expects exactly 1 parameter, 0 given in %sdba_sync.php on line %d +NULL + +Warning: dba_sync() expects parameter 1 to be resource, string given in %sdba_sync.php on line %d +NULL +bool(true) +===DONE=== diff --git a/ext/dba/tests/dba_tcadb.phpt b/ext/dba/tests/dba_tcadb.phpt new file mode 100644 index 0000000..52dd4de --- /dev/null +++ b/ext/dba/tests/dba_tcadb.phpt @@ -0,0 +1,50 @@ +--TEST-- +DBA TCADB handler test +--SKIPIF-- +<?php + $handler = 'tcadb'; + require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php + $handler = 'tcadb'; + require_once dirname(__FILE__) .'/skipif.inc'; + $lock_flag = 'l'; + $db_filename = $db_file = dirname(__FILE__) .'/test0.tch'; + @unlink($db_filename); + @unlink($db_filename.'.lck'); + require_once dirname(__FILE__) .'/dba_handler.inc'; +?> +===DONE=== +--EXPECT-- +database handler: tcadb +3NYNYY +Content String 2 +Content 2 replaced +Read during write: not allowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +--NO-LOCK-- +3NYNYY +Content String 2 +Content 2 replaced +Read during write: not allowed +Content 2 replaced 2nd time +The 6th value +array(3) { + ["key number 6"]=> + string(13) "The 6th value" + ["key2"]=> + string(27) "Content 2 replaced 2nd time" + ["key5"]=> + string(23) "The last content string" +} +===DONE=== diff --git a/ext/dba/tests/skipif.inc b/ext/dba/tests/skipif.inc new file mode 100644 index 0000000..e75000f --- /dev/null +++ b/ext/dba/tests/skipif.inc @@ -0,0 +1,23 @@ +<?php + if (!extension_loaded('dba')) die('skip dba extension not available'); + if (!function_exists('dba_handlers')) die ('skip dba_handlers() not available'); + if (!sizeof(dba_handlers())) die('skip no handlers installed'); + if (!isset($handler)) { + $handlers = dba_handlers(); + if (in_array('flatfile', $handlers)) { + $handler = 'flatfile'; + } else { + $handlers = array_diff($handlers, array('cdb', 'cdb_make')); /* these can only read OR write */ + if (count($handlers)==0) { + die('skip no handler available that can be used for the test'); + } + $handler = array_shift($handlers); + } + } else { + if (!in_array($handler, dba_handlers())) { + $HND = strtoupper($handler); + die("skip $HND handler not available"); + } + } + $HND = strtoupper($handler); +?> diff --git a/ext/dba/tests/test.cdb b/ext/dba/tests/test.cdb Binary files differnew file mode 100644 index 0000000..21529c6 --- /dev/null +++ b/ext/dba/tests/test.cdb diff --git a/ext/dba/tests/test.inc b/ext/dba/tests/test.inc new file mode 100644 index 0000000..7c4e207 --- /dev/null +++ b/ext/dba/tests/test.inc @@ -0,0 +1,7 @@ +<?php + require_once dirname(__FILE__) .'/skipif.inc'; + $lock_flag = 'l'; + $db_filename = $db_file = dirname(__FILE__) .'/test0.dbm'; + @unlink($db_filename); + @unlink($db_filename.'.lck'); +?> |