helly           Mon Dec 30 14:13:45 2002 EDT

  Added files:                 (Branch: PHP_4_3)
    /php4/ext/dba       dba_db4.c php_db4.h 
    /php4/ext/dba/tests dba_db4.phpt 

  Modified files:              
    /php4/ext/dba       config.m4 dba.c dba_db3.c php_dba.h 
  Log:
  MFH: (configure problems & db4 sub module
  @- Improved dba extension (Marcus)
  @
    . Added support for internal error handling of Berkeley db libraries.
  @
    . Disallow Berkeley db versions 4.1.0 to 4.1.24 due to locking problems.
  @
    . Disallow linkage of Berkeley db submodules against libraries with
  @
      different major version.
  @
    . Disallow configuring of more than one Berkeley db handler. 
  
Index: php4/ext/dba/config.m4
diff -u php4/ext/dba/config.m4:1.29.2.2 php4/ext/dba/config.m4:1.29.2.3
--- php4/ext/dba/config.m4:1.29.2.2     Mon Dec 30 04:23:33 2002
+++ php4/ext/dba/config.m4      Mon Dec 30 14:13:44 2002
@@ -1,8 +1,12 @@
 dnl
-dnl $Id: config.m4,v 1.29.2.2 2002/12/30 09:23:33 derick Exp $
+dnl $Id: config.m4,v 1.29.2.3 2002/12/30 19:13:44 helly Exp $
 dnl
 
-dnl Suppose we need FlatFile if no or only CDB is used.
+dnl Suppose we need FlatFile if no support or only CDB is used.
+
+AC_DEFUN(PHP_DBA_STD_BEGIN,[
+  unset THIS_INCLUDE THIS_INC_DIR THIS_LIBS THIS_LFLAGS THIS_PREFIX THIS_RESULT
+])
 
 AC_DEFUN(PHP_TEMP_LDFLAGS,[
   old_LDFLAGS=$LDFLAGS
@@ -14,7 +18,6 @@
 dnl Assign INCLUDE/LFLAGS from PREFIX
 AC_DEFUN(PHP_DBA_STD_ASSIGN,[
   if test -n "$THIS_PREFIX" && test "$THIS_PREFIX" != "/usr"; then
-    THIS_INCLUDE=$THIS_PREFIX/include
     THIS_LFLAGS=$THIS_PREFIX/lib
   fi
 ])
@@ -22,30 +25,44 @@
 dnl Standard check
 AC_DEFUN(PHP_DBA_STD_CHECK,[
   THIS_RESULT="yes"
-  if test "$THIS_PREFIX" != "/usr" -a "$THIS_INCLUDE" = ""; then
+  if test -z "$THIS_INCLUDE"; then
     AC_MSG_ERROR(cannot find necessary header file(s))
   fi
-  if test "$THIS_LIBS" = "" ; then
+  if test -z "$THIS_LIBS"; then
     AC_MSG_ERROR(cannot find necessary library)
   fi
 ])
 
 dnl Attach THIS_x to DBA_x
 AC_DEFUN(PHP_DBA_STD_ATTACH,[
-  PHP_ADD_INCLUDE($THIS_INCLUDE)
+  if test -n "$THIS_INC_DIR" -a "$THIS_PREFIX" != "/usr"; then
+    PHP_ADD_INCLUDE($THIS_INC_DIR)
+  fi
   PHP_ADD_LIBRARY_WITH_PATH($THIS_LIBS, $THIS_LFLAGS, DBA_SHARED_LIBADD)
-  unset THIS_INCLUDE THIS_LIBS THIS_LFLAGS THIS_PREFIX
+  unset THIS_INCLUDE THIS_INC_DIR THIS_LIBS THIS_LFLAGS THIS_PREFIX
 ])
 
 dnl Print the result message
+dnl parameters(name [, full name [, empty or error message]])
 AC_DEFUN(AC_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" -o "$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
+  unset THIS_RESULT THIS_NAME THIS_FULL_NAME
 ])
 
 PHP_ARG_ENABLE(dba,whether to enable DBA,
@@ -54,163 +71,250 @@
 AC_ARG_WITH(gdbm,
 [  --with-gdbm[=DIR]         DBA: Include GDBM support],[
   if test "$withval" != "no"; then
-    for i in /usr/local /usr $withval; do
+    PHP_DBA_STD_BEGIN
+    for i in $withval /usr/local /usr; do
       if test -f "$i/include/gdbm.h"; then
-        THIS_PREFIX="$i"
+        THIS_PREFIX=$i
+        THIS_INCLUDE=$i/include/gdbm.h
+        THIS_INC_DIR=$i/include
+        break
       fi
     done
 
-    unset ac_cv_lib_gdbm_gdbm_open
-    PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/lib,[
-    AC_CHECK_LIB(gdbm, gdbm_open, [AC_DEFINE(DBA_GDBM, 1, [ ]) THIS_LIBS=gdbm])
-    ])
+    if test -n "$THIS_INCLUDE"; then
+      unset ac_cv_lib_gdbm_gdbm_open
+      PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/lib,[
+        AC_CHECK_LIB(gdbm, gdbm_open, [
+          AC_DEFINE(DBA_GDBM, 1, [ ]) 
+          THIS_LIBS=gdbm
+          break
+        ])
+      ])
+    fi
     
     PHP_DBA_STD_ASSIGN
     PHP_DBA_STD_CHECK
     PHP_DBA_STD_ATTACH
   fi
 ])
-AC_MSG_CHECKING(for GDBM support)
-AC_DBA_STD_RESULT
+AC_DBA_STD_RESULT(gdbm)
 
 AC_ARG_WITH(ndbm,
 [  --with-ndbm[=DIR]         DBA: Include NDBM support],[
   if test "$withval" != "no"; then
-    for i in /usr/local /usr $withval; do
-      if test -f "$i/include/db1/ndbm.h" ; then
-        THIS_PREFIX=$i
-        NDBM_EXTRA=db1/ndbm.h
-      elif test -f "$i/include/ndbm.h" ; then
+    PHP_DBA_STD_BEGIN
+    for i in $withval /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
-        NDBM_EXTRA=ndbm.h
+        THIS_INCLUDE=$i/include/db1/ndbm.h
+        break
       fi
-       done
+    done
     
-    if test "$NDBM_EXTRA" != ""; then
-      AC_DEFINE_UNQUOTED(NDBM_INCLUDE_FILE, "$NDBM_EXTRA", [ ])
+    if test -n "$THIS_INCLUDE"; then
+      AC_DEFINE_UNQUOTED(NDBM_INCLUDE_FILE, "$THIS_INCLUDE", [ ])
+      for LIB in ndbm db1 c; do
+        PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/lib,[
+          AC_CHECK_LIB($LIB, dbm_open, [
+            AC_DEFINE(DBA_NDBM,1, [ ]) 
+            THIS_LIBS=$LIB
+            break
+          ])
+        ])
+      done
     fi
 
-    for LIB in db1 ndbm c; do
-      PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/lib,[
-      AC_CHECK_LIB($LIB, dbm_open, [AC_DEFINE(DBA_NDBM,1, [ ]) THIS_LIBS=$LIB])
-      ])
-    done
-    
     PHP_DBA_STD_ASSIGN
     PHP_DBA_STD_CHECK
     PHP_DBA_STD_ATTACH
   fi
 ])
-AC_MSG_CHECKING(for NDBM support)
-AC_DBA_STD_RESULT
+AC_DBA_STD_RESULT(ndbm)
 
-AC_ARG_WITH(db2,
-[  --with-db2[=DIR]          DBA: Include Berkeley DB2 support],[
+dnl Berkeley specific (library and version test)
+dnl parameters(version, library list, function)
+AC_DEFUN(PHP_DBA_DB_CHECK,[
+  for LIB in $2; do
+    PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/lib,[
+      AC_CHECK_LIB($LIB, $3, [
+        AC_TRY_RUN([
+#include "$THIS_INCLUDE"
+int main() {
+  return (DB_VERSION_MAJOR == $1) ? 0 : 1;
+}
+        ],[
+          THIS_LIBS=$LIB
+          break
+        ],[ ],[
+          THIS_LIBS=$LIB
+          break
+        ])
+      ])
+    ])
+  done
+  if test "$1" = "4"; then
+    AC_MSG_CHECKING(for db4 minor version and patch level)
+    AC_TRY_RUN([
+#include "$THIS_INCLUDE"
+int main() {
+  return (DB_VERSION_MINOR != 1 || DB_VERSION_PATCH >= 25) ? 0 : 1;
+}
+    ],[
+      AC_MSG_RESULT(ok)
+    ],[
+      AC_MSG_ERROR(Version 4.1 requires patch level 25)
+    ],[
+      AC_MSG_RESULT(crosscompiling)
+    ])
+  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
+  fi
+  PHP_DBA_STD_ASSIGN
+  PHP_DBA_STD_CHECK
+  PHP_DBA_STD_ATTACH
+])
+
+AC_ARG_WITH(db4,
+[  --with-db4[=DIR]          DBA: Include Berkeley DB4 support],[
   if test "$withval" != "no"; then
-    for i in /usr/local /usr /usr/BerkeleyDB $withval/BerkeleyDB $withval; do
-      if test -f "$i/db2/db.h"; then
-        THIS_PREFIX=$i
-        DB2_EXTRA=db2
-      elif test -f "$i/include/db2/db.h"; then
+    PHP_DBA_STD_BEGIN
+    for i in $withval /usr/local/BerkeleyDB.4.1 /usr/local/BerkeleyDB.4.0 /usr/local 
+/usr; do
+      if test -f "$i/db4/db.h"; then
+        THIS_PREFIX=$i
+        THIS_INCLUDE=$i/db4/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
-        DB2_EXTRA=db2/db.h
-      elif test -f "$i/include/db/db2.h"; then
-        THIS_PREFIX=$i
-        DB2_EXTRA=db/db2.h
-      elif test -f "$i/include/db2.h"; then
-        THIS_PREFIX=$i
-        DB2_EXTRA=db2.h
-      elif test -f "$i/include/db.h" ; then
+        THIS_INCLUDE=$i/include/db4.h
+        break
+      elif test -f "$i/include/db.h"; then
         THIS_PREFIX=$i
-        DB2_EXTRA=db.h
+        THIS_INCLUDE=$i/include/db.h
+        break
       fi
-       done
-
-    if test "$DB2_EXTRA" = "db2" ; then
-      DBA_INCLUDE="$DBA_INCLUDE -I$THIS_PREFIX/db2"
-      DB2_EXTRA=db.h
-    fi
-    
-    if test -n "$DB2_EXTRA"; then
-      AC_DEFINE_UNQUOTED(DB2_INCLUDE_FILE, "$DB2_EXTRA", [ ])
-    fi
-
-    for LIB in db db2 c; do
-      PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/lib,[
-      AC_CHECK_LIB($LIB, db_appinit, [AC_DEFINE(DBA_DB2,1,[ ]) THIS_LIBS=$LIB])
-      ])
     done
-    
-    PHP_DBA_STD_ASSIGN
-    PHP_DBA_STD_CHECK
-    PHP_DBA_STD_ATTACH
+    PHP_DBA_DB_CHECK(4, db-4.1 db-4.0 db-4 db4 db, db_create)
   fi
 ])
-AC_MSG_CHECKING(for Berkeley DB2 support)
-AC_DBA_STD_RESULT
+AC_DBA_STD_RESULT(db4,Berkeley DB4)
 
 AC_ARG_WITH(db3,
 [  --with-db3[=DIR]          DBA: Include Berkeley DB3 support],[
   if test "$withval" != "no"; then
-    for i in /usr/local /usr /usr/local/BerkeleyDB.3.0 $withval; do
+    PHP_DBA_STD_BEGIN
+    if test "$HAVE_DB4" = "1"; then
+      AC_DBA_STD_RESULT(db3,Berkeley DB3,You cannot combine --with-db3 with 
+--with-db4)
+    fi
+    for i in $withval /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
-        DB3_EXTRA=db3
+        THIS_INCLUDE=$i/include/db3/db.h
+        break
       elif test -f "$i/include/db3/db.h"; then
         THIS_PREFIX=$i
-        DB3_EXTRA=db3/db.h
+        THIS_INCLUDE=$i/include/db3/db.h
+        break
       elif test -f "$i/include/db/db3.h"; then
         THIS_PREFIX=$i
-        DB3_EXTRA=db/db3.h
+        THIS_INCLUDE=$i/include/db/db3.h
+        break
       elif test -f "$i/include/db3.h"; then
         THIS_PREFIX=$i
-        DB3_EXTRA=db3.h
+        THIS_INCLUDE=$i/include/db3.h
+        break
       elif test -f "$i/include/db.h"; then
         THIS_PREFIX=$i
-        DB3_EXTRA=db.h
+        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, db_create)
+  fi
+      ])
+AC_DBA_STD_RESULT(db3,Berkeley DB3)
 
-    if test -n "$DB3_EXTRA"; then
-      AC_DEFINE_UNQUOTED(DB3_INCLUDE_FILE, "$DB3_EXTRA", [ ])
+AC_ARG_WITH(db2,
+[  --with-db2[=DIR]          DBA: Include Berkeley DB2 support],[
+  if test "$withval" != "no"; then
+    PHP_DBA_STD_BEGIN
+    if test "$HAVE_DB3" = "1" -o "$HAVE_DB4" = "1"; then
+      AC_DBA_STD_RESULT(db2,Berkeley DB2,You cannot combine --with-db2 with 
+--with-db3 or --with-db4)
     fi
-
-    for LIB in db-3.1 db-3 db3 db; do
-      PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/lib,[
-      AC_CHECK_LIB($LIB, db_create, [AC_DEFINE(DBA_DB3,1,[ ]) THIS_LIBS=$LIB])
-      ])
+    for i in $withval $withval/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_STD_ASSIGN
-    PHP_DBA_STD_CHECK
-    PHP_DBA_STD_ATTACH
+    PHP_DBA_DB_CHECK(2, db-2 db2 db, db_appinit)
   fi
 ])
-AC_MSG_CHECKING(for Berkeley DB3 support)
-AC_DBA_STD_RESULT
+AC_DBA_STD_RESULT(db2,Berkeley DB2)
 
 AC_ARG_WITH(dbm,
 [  --with-dbm[=DIR]          DBA: Include DBM support],[
   if test "$withval" != "no"; then
-    for i in /usr/local /usr $withval; do
-      if test -f "$i/include/dbm.h" ; then
-        THIS_PREFIX=$i
+    PHP_DBA_STD_BEGIN
+    for i in $withval /usr/local /usr; do
+      if test -f "$i/include/dbm.h"; then
+        THIS_PREFIX=$i
+        THIS_INCLUDE=$i/include/dbm.h
+        THIS_INC_DIR=$i/include
+        break
       fi
-       done
-
-    for LIB in db1 dbm c; do
-      PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/lib,[
-      AC_CHECK_LIB($LIB, dbminit, [AC_DEFINE(DBA_DBM,1,[ ]) THIS_LIBS=$LIB])
-      ])
     done
+
+    if test -n "$THIS_INCLUDE"; then
+      for LIB in db1 dbm c; do
+        PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/lib,[
+          AC_CHECK_LIB($LIB, dbminit, [
+            AC_DEFINE(DBA_DBM,1,[ ]) 
+            THIS_LIBS=$LIB
+            break
+          ])
+        ])
+      done
+    fi
     
     PHP_DBA_STD_ASSIGN
     PHP_DBA_STD_CHECK
     PHP_DBA_STD_ATTACH
   fi
 ])
-AC_MSG_CHECKING(for DBM support)
-AC_DBA_STD_RESULT
+AC_DBA_STD_RESULT(dbm)
 
 AC_DEFUN(PHP_DBA_BUILTIN_CDB,[
   PHP_ADD_BUILD_DIR($ext_builddir/libcdb)
@@ -226,17 +330,27 @@
   if test "$withval" != "no"; then
     PHP_DBA_BUILTIN_CDB
   elif test "$withval" != "no"; then
-    for i in /usr/local /usr $withval; do
-      if test -f "$i/include/cdb.h" ; then
-        THIS_PREFIX=$i
+    PHP_DBA_STD_BEGIN
+    for i in $withval /usr/local /usr; do
+      if test -f "$i/include/cdb.h"; then
+        THIS_PREFIX=$i
+        THIS_INCLUDE=$i/include/cdb.h
+        THIS_INC_DIR=$i/include
+        break
       fi
     done
 
-    for LIB in cdb c; do
-      PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/lib,[
-      AC_CHECK_LIB($LIB, cdb_read, [AC_DEFINE(DBA_CDB,1,[ ]) THIS_LIBS=$LIB])
-      ])
-    done
+    if test -n "$THIS_INCLUDE"; then
+      for LIB in cdb c; do
+        PHP_TEMP_LDFLAGS(-L$THIS_PREFIX/lib,[
+          AC_CHECK_LIB($LIB, cdb_read, [
+            AC_DEFINE(DBA_CDB,1,[ ]) 
+            THIS_LIBS=$LIB
+            break
+          ])
+        ])
+      done
+    fi
     
     PHP_DBA_STD_ASSIGN
     PHP_DBA_STD_CHECK
@@ -247,8 +361,7 @@
     PHP_DBA_BUILTIN_CDB
   fi
 ])
-AC_MSG_CHECKING(for CDB support)
-AC_DBA_STD_RESULT
+AC_DBA_STD_RESULT(cdb)
 
 AC_DEFUN(PHP_DBA_BUILTIN_FLATFILE,[
   PHP_ADD_BUILD_DIR($ext_builddir/libflatfile)
@@ -270,14 +383,13 @@
     PHP_DBA_BUILTIN_FLATFILE
   fi
 ])
-AC_MSG_CHECKING(for FlatFile support)
-AC_DBA_STD_RESULT
+AC_DBA_STD_RESULT(FlatFile,FlatFile)
 
 AC_MSG_CHECKING(whether to enable DBA interface)
 if test "$HAVE_DBA" = "1"; then
   AC_MSG_RESULT(yes)
   AC_DEFINE(HAVE_DBA, 1, [ ])
-  PHP_NEW_EXTENSION(dba, dba.c dba_cdb.c dba_db2.c dba_dbm.c dba_gdbm.c dba_ndbm.c 
dba_db3.c $cdb_sources $flat_sources, $ext_shared)
+  PHP_NEW_EXTENSION(dba, dba.c dba_cdb.c dba_db2.c dba_dbm.c dba_gdbm.c dba_ndbm.c 
+dba_db3.c dba_db4.c $cdb_sources $flat_sources, $ext_shared)
   PHP_SUBST(DBA_SHARED_LIBADD)
 else
   AC_MSG_RESULT(no)
Index: php4/ext/dba/dba.c
diff -u php4/ext/dba/dba.c:1.61.2.9 php4/ext/dba/dba.c:1.61.2.10
--- php4/ext/dba/dba.c:1.61.2.9 Fri Dec 20 20:20:32 2002
+++ php4/ext/dba/dba.c  Mon Dec 30 14:13:44 2002
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: dba.c,v 1.61.2.9 2002/12/21 01:20:32 andrei Exp $ */
+/* $Id: dba.c,v 1.61.2.10 2002/12/30 19:13:44 helly Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -44,6 +44,7 @@
 #include "php_cdb.h"
 #include "php_db2.h"
 #include "php_db3.h"
+#include "php_db4.h"
 #include "php_flatfile.h"
 
 /* {{{ dba_functions[]
@@ -70,6 +71,7 @@
 /* }}} */
 
 PHP_MINIT_FUNCTION(dba);
+PHP_MSHUTDOWN_FUNCTION(dba);
 PHP_MINFO_FUNCTION(dba);
 
 zend_module_entry dba_module_entry = {
@@ -77,7 +79,7 @@
        "dba",
        dba_functions, 
        PHP_MINIT(dba), 
-       NULL,
+       PHP_MSHUTDOWN(dba),
        NULL,
        NULL,
        PHP_MINFO(dba),
@@ -89,21 +91,6 @@
 ZEND_GET_MODULE(dba)
 #endif
 
-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);
-} dba_handler;
-
 /* {{{ macromania */
 
 #define DBA_ID_PARS                                                                   
                 \
@@ -156,14 +143,14 @@
 
 /* a DBA handler must have specific routines */
 
-#define DBA_NAMED_HND(name, x, flags) \
+#define DBA_NAMED_HND(alias, name, flags) \
 {\
-       #name, flags, dba_open_##x, dba_close_##x, dba_fetch_##x, dba_update_##x, \
-       dba_exists_##x, dba_delete_##x, dba_firstkey_##x, dba_nextkey_##x, \
-       dba_optimize_##x, dba_sync_##x \
+       #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 \
 },
 
-#define DBA_HND(x, flags) DBA_NAMED_HND(x, x, flags)
+#define DBA_HND(name, flags) DBA_NAMED_HND(name, name, flags)
 
 /* check whether the user has write access */
 #define DBA_WRITE_CHECK \
@@ -198,6 +185,9 @@
 #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_FLATFILE
        DBA_HND(flatfile, DBA_STREAM_OPEN|DBA_LOCK_ALL) /* No lock in lib */
 #endif
@@ -231,7 +221,7 @@
 static void dba_close_rsrc(zend_rsrc_list_entry *rsrc TSRMLS_DC)
 {
        dba_info *info = (dba_info *)rsrc->ptr; 
-
+       
        dba_close(info TSRMLS_CC);
 }
 /* }}} */
@@ -357,7 +347,7 @@
        int i;
        int lock_mode, lock_flag, lock_dbf = 0;
        char *file_mode;
-       char mode[4], *pmode, *lock_file_mode;
+       char mode[4], *pmode, *lock_file_mode = NULL;
        
        if(ac < 3) {
                WRONG_PARAM_COUNT;
@@ -429,6 +419,10 @@
                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;
@@ -583,7 +577,7 @@
 
        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", 
Z_STRVAL_PP(args[2]), error?": ":"", error?error:"");
+               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;
        }
@@ -807,7 +801,7 @@
 }
 /* }}} */
 
-#endif
+#endif /* HAVE_DBA */
 
 /*
  * Local variables:
Index: php4/ext/dba/dba_db3.c
diff -u php4/ext/dba/dba_db3.c:1.21.2.2 php4/ext/dba/dba_db3.c:1.21.2.3
--- php4/ext/dba/dba_db3.c:1.21.2.2     Fri Dec 20 15:25:19 2002
+++ php4/ext/dba/dba_db3.c      Mon Dec 30 14:13:44 2002
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: dba_db3.c,v 1.21.2.2 2002/12/20 20:25:19 helly Exp $ */
+/* $Id: dba_db3.c,v 1.21.2.3 2002/12/30 19:13:44 helly Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -35,6 +35,13 @@
 #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; \
@@ -50,7 +57,7 @@
 {
        DB *dbp = NULL;
        DBTYPE type;
-       int gmode = 0;
+       int gmode = 0, err;
        int filemode = 0644;
        struct stat check_stat;
        int s = VCWD_STAT(info->path, &check_stat);
@@ -65,30 +72,36 @@
                info->mode == DBA_WRITER ? 0         : 
                info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1;
 
-       if (gmode == -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_create(&dbp, NULL, 0) == 0 &&
-#if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
-                       dbp->open(dbp, 0, info->path, NULL, type, gmode, filemode) == 
0) {
-#else
-                       dbp->open(dbp, info->path, NULL, type, gmode, filemode) == 0) {
+#ifdef DB_FCNTL_LOCKING
+       gmode |= DB_FCNTL_LOCKING;
 #endif
-               dba_db3_data *data;
 
-               data = pemalloc(sizeof(*data), info->flags&DBA_PERSISTENT);
-               data->dbp = dbp;
-               data->cursor = NULL;
-               info->dbf = data;
+       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 if (dbp != NULL) {
-               dbp->close(dbp, 0);
+                       return SUCCESS;
+               } else {
+                       dbp->close(dbp, 0);
+                       *error = db_strerror(err);
+               }
+       } else {
+               *error = db_strerror(err);
        }
 
        return FAILURE;
Index: php4/ext/dba/php_dba.h
diff -u php4/ext/dba/php_dba.h:1.19.2.2 php4/ext/dba/php_dba.h:1.19.2.3
--- php4/ext/dba/php_dba.h:1.19.2.2     Fri Dec 20 15:25:19 2002
+++ php4/ext/dba/php_dba.h      Mon Dec 30 14:13:44 2002
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: php_dba.h,v 1.19.2.2 2002/12/20 20:25:19 helly Exp $ */
+/* $Id: php_dba.h,v 1.19.2.3 2002/12/30 19:13:44 helly Exp $ */
 
 #ifndef PHP_DBA_H
 #define PHP_DBA_H
@@ -67,6 +67,21 @@
 
 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);
+} dba_handler;
 
 /* common prototypes which must be supplied by modules */
 

Index: php4/ext/dba/dba_db4.c
+++ php4/ext/dba/dba_db4.c
/*
   +----------------------------------------------------------------------+
   | PHP Version 4                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2002 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.02 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available at through the world-wide-web at                           |
   | http://www.php.net/license/2_02.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          |
   | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sascha Schumann <[EMAIL PROTECTED]>                         |
   +----------------------------------------------------------------------+
 */

/* $Id: dba_db4.c,v 1.1 2002/11/26 12:05:59 helly Exp $ */

#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

#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;
        int filemode = 0644;
        struct stat check_stat;
        int s = VCWD_STAT(info->path, &check_stat);

        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_create(&dbp, NULL, 0) == 0 &&
#if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
                        dbp->open(dbp, 0, info->path, NULL, type, gmode, filemode) == 
0) {
#else
                        dbp->open(dbp, info->path, NULL, type, gmode, filemode) == 0) {
#endif
                dba_db4_data *data;

                data = emalloc(sizeof(*data));
                data->dbp = dbp;
                data->cursor = NULL;
                info->dbf = data;
                
                return SUCCESS;
        } else if (dbp != NULL) {
                dbp->close(dbp, 0);
        }

        return FAILURE;
}

DBA_CLOSE_FUNC(db4)
{
        DB4_DATA;
        
        if (dba->cursor) dba->cursor->c_close(dba->cursor);
        dba->dbp->close(dba->dbp, 0);
        efree(dba);
}

DBA_FETCH_FUNC(db4)
{
        DBT gval;
        char *new = NULL;
        DB4_DATA;
        DB4_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(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 (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
                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 (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(db4)
{
        return SUCCESS;
}

DBA_SYNC_FUNC(db4)
{
        DB4_DATA;

        return dba->dbp->sync(dba->dbp, 0) ? FAILURE : SUCCESS;
}

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */

Index: php4/ext/dba/php_db4.h
+++ php4/ext/dba/php_db4.h
#ifndef PHP_DB4_H
#define PHP_DB4_H

#if DBA_DB4

#include "php_dba.h"

DBA_FUNCS(db4);

#endif

#endif

Index: php4/ext/dba/tests/dba_db4.phpt
+++ php4/ext/dba/tests/dba_db4.phpt
--TEST--
DBA DB4 handler test
--SKIPIF--
<?php 
        require_once('skipif.inc');
        if (!in_array('db4', dba_handlers())) die('skip DB4 handler not available');
?>
--FILE--
<?php
        require_once('test.inc');
        $handler = ini_get('dba.default_handler');//'db4';
        require_once('dba_handler.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"
}

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to