[Python-checkins] r58384 - in python/trunk: Modules/_bsddb.c Modules/bsddb.h setup.py

gregory.p.smith python-checkins at python.org
Tue Oct 9 08:02:22 CEST 2007


Author: gregory.p.smith
Date: Tue Oct  9 08:02:21 2007
New Revision: 58384

Added:
   python/trunk/Modules/bsddb.h
Modified:
   python/trunk/Modules/_bsddb.c
   python/trunk/setup.py
Log:
Splits Modules/_bsddb.c up into bsddb.h and _bsddb.c and adds a C API
object available as bsddb.db.api.  This is based on the patch submitted
by Duncan Grisby here:
  http://sourceforge.net/tracker/index.php?func=detail&aid=1551895&group_id=13900&atid=313900
See this thread for additional info:
  http://sourceforge.net/mailarchive/forum.php?thread_name=E1GAVDK-0002rk-Iw%40apasphere.com&forum_name=pybsddb-users

It also cleans up the code a little by removing some ifdef/endifs for
python prior to 2.1 and for unsupported Berkeley DB <= 3.2.


Modified: python/trunk/Modules/_bsddb.c
==============================================================================
--- python/trunk/Modules/_bsddb.c	(original)
+++ python/trunk/Modules/_bsddb.c	Tue Oct  9 08:02:21 2007
@@ -87,20 +87,15 @@
 
 #include <stddef.h>   /* for offsetof() */
 #include <Python.h>
-#include <db.h>
 
-/* --------------------------------------------------------------------- */
-/* Various macro definitions */
+#define COMPILING_BSDDB_C
+#include "bsddb.h"
+#undef COMPILING_BSDDB_C
 
-/* 40 = 4.0, 33 = 3.3; this will break if the second number is > 9 */
-#define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
-#if DB_VERSION_MINOR > 9
-#error "eek! DBVER can't handle minor versions > 9"
-#endif
-
-#define PY_BSDDB_VERSION "4.5.0"
 static char *rcs_id = "$Id$";
 
+/* --------------------------------------------------------------------- */
+/* Various macro definitions */
 
 #if (PY_VERSION_HEX < 0x02050000)
 typedef int Py_ssize_t;
@@ -196,107 +191,15 @@
 /* --------------------------------------------------------------------- */
 /* Structure definitions */
 
-#if PYTHON_API_VERSION >= 1010       /* python >= 2.1 support weak references */
-#define HAVE_WEAKREF
-#else
-#undef HAVE_WEAKREF
-#endif
-
-/* if Python >= 2.1 better support warnings */
-#if PYTHON_API_VERSION >= 1010
-#define HAVE_WARNINGS
-#else
-#undef HAVE_WARNINGS
+#if PYTHON_API_VERSION < 1010
+#error "Python 2.1 or later required"
 #endif
 
-#if PYTHON_API_VERSION <= 1007
-    /* 1.5 compatibility */
-#define PyObject_New PyObject_NEW
-#define PyObject_Del PyMem_DEL
-#endif
-
-struct behaviourFlags {
-    /* What is the default behaviour when DB->get or DBCursor->get returns a
-       DB_NOTFOUND || DB_KEYEMPTY error?  Return None or raise an exception? */
-    unsigned int getReturnsNone : 1;
-    /* What is the default behaviour for DBCursor.set* methods when DBCursor->get
-     * returns a DB_NOTFOUND || DB_KEYEMPTY  error?  Return None or raise? */
-    unsigned int cursorSetReturnsNone : 1;
-};
 
+/* Defaults for moduleFlags in DBEnvObject and DBObject. */
 #define DEFAULT_GET_RETURNS_NONE                1
 #define DEFAULT_CURSOR_SET_RETURNS_NONE         1   /* 0 in pybsddb < 4.2, python < 2.4 */
 
-typedef struct {
-    PyObject_HEAD
-    DB_ENV*     db_env;
-    u_int32_t   flags;             /* saved flags from open() */
-    int         closed;
-    struct behaviourFlags moduleFlags;
-#ifdef HAVE_WEAKREF
-    PyObject        *in_weakreflist; /* List of weak references */
-#endif
-} DBEnvObject;
-
-
-typedef struct {
-    PyObject_HEAD
-    DB*             db;
-    DBEnvObject*    myenvobj;  /* PyObject containing the DB_ENV */
-    u_int32_t       flags;     /* saved flags from open() */
-    u_int32_t       setflags;  /* saved flags from set_flags() */
-    int             haveStat;
-    struct behaviourFlags moduleFlags;
-#if (DBVER >= 33)
-    PyObject*       associateCallback;
-    PyObject*       btCompareCallback;
-    int             primaryDBType;
-#endif
-#ifdef HAVE_WEAKREF
-    PyObject        *in_weakreflist; /* List of weak references */
-#endif
-} DBObject;
-
-
-typedef struct {
-    PyObject_HEAD
-    DBC*            dbc;
-    DBObject*       mydb;
-#ifdef HAVE_WEAKREF
-    PyObject        *in_weakreflist; /* List of weak references */
-#endif
-} DBCursorObject;
-
-
-typedef struct {
-    PyObject_HEAD
-    DB_TXN*         txn;
-    PyObject        *env;
-#ifdef HAVE_WEAKREF
-    PyObject        *in_weakreflist; /* List of weak references */
-#endif
-} DBTxnObject;
-
-
-typedef struct {
-    PyObject_HEAD
-    DB_LOCK         lock;
-#ifdef HAVE_WEAKREF
-    PyObject        *in_weakreflist; /* List of weak references */
-#endif
-} DBLockObject;
-
-#if (DBVER >= 43)
-typedef struct {
-    PyObject_HEAD
-    DB_SEQUENCE*     sequence;
-    DBObject*        mydb;
-#ifdef HAVE_WEAKREF
-    PyObject        *in_weakreflist; /* List of weak references */
-#endif
-} DBSequenceObject;
-staticforward PyTypeObject DBSequence_Type;
-#endif
 
 staticforward PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type, DBLock_Type;
 
@@ -545,12 +448,7 @@
                 strncat(errTxt, _db_errmsg, bytes_left);
             }
             _db_errmsg[0] = 0;
-#ifdef HAVE_WARNINGS
             exceptionRaised = PyErr_Warn(PyExc_RuntimeWarning, errTxt);
-#else
-            fprintf(stderr, errTxt);
-            fprintf(stderr, "\n");
-#endif
 
 #else  /* do an exception instead */
         errObj = DBIncompleteError;
@@ -804,9 +702,7 @@
     self->btCompareCallback = NULL;
     self->primaryDBType = 0;
 #endif
-#ifdef HAVE_WEAKREF
     self->in_weakreflist = NULL;
-#endif
 
     /* keep a reference to our python DBEnv object */
     if (arg) {
@@ -857,19 +753,15 @@
             MYDB_BEGIN_ALLOW_THREADS;
             self->db->close(self->db, 0);
             MYDB_END_ALLOW_THREADS;
-#ifdef HAVE_WARNINGS
         } else {
             PyErr_Warn(PyExc_RuntimeWarning,
                 "DB could not be closed in destructor: DBEnv already closed");
-#endif
         }
         self->db = NULL;
     }
-#ifdef HAVE_WEAKREF
     if (self->in_weakreflist != NULL) {
         PyObject_ClearWeakRefs((PyObject *) self);
     }
-#endif
     if (self->myenvobj) {
         Py_DECREF(self->myenvobj);
         self->myenvobj = NULL;
@@ -897,9 +789,7 @@
 
     self->dbc = dbc;
     self->mydb = db;
-#ifdef HAVE_WEAKREF
     self->in_weakreflist = NULL;
-#endif
     Py_INCREF(self->mydb);
     return self;
 }
@@ -910,11 +800,9 @@
 {
     int err;
 
-#ifdef HAVE_WEAKREF
     if (self->in_weakreflist != NULL) {
         PyObject_ClearWeakRefs((PyObject *) self);
     }
-#endif
 
     if (self->dbc != NULL) {
         MYDB_BEGIN_ALLOW_THREADS;
@@ -947,9 +835,7 @@
     self->flags = flags;
     self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
     self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
-#ifdef HAVE_WEAKREF
     self->in_weakreflist = NULL;
-#endif
 
     MYDB_BEGIN_ALLOW_THREADS;
     err = db_env_create(&self->db_env, flags);
@@ -968,11 +854,9 @@
 static void
 DBEnv_dealloc(DBEnvObject* self)
 {
-#ifdef HAVE_WEAKREF
     if (self->in_weakreflist != NULL) {
         PyObject_ClearWeakRefs((PyObject *) self);
     }
-#endif
 
     if (self->db_env && !self->closed) {
         MYDB_BEGIN_ALLOW_THREADS;
@@ -992,9 +876,7 @@
         return NULL;
     Py_INCREF(myenv);
     self->env = (PyObject*)myenv;
-#ifdef HAVE_WEAKREF
     self->in_weakreflist = NULL;
-#endif
 
     MYDB_BEGIN_ALLOW_THREADS;
 #if (DBVER >= 40)
@@ -1015,13 +897,10 @@
 static void
 DBTxn_dealloc(DBTxnObject* self)
 {
-#ifdef HAVE_WEAKREF
     if (self->in_weakreflist != NULL) {
         PyObject_ClearWeakRefs((PyObject *) self);
     }
-#endif
 
-#ifdef HAVE_WARNINGS
     if (self->txn) {
         /* it hasn't been finalized, abort it! */
         MYDB_BEGIN_ALLOW_THREADS;
@@ -1034,7 +913,6 @@
         PyErr_Warn(PyExc_RuntimeWarning,
             "DBTxn aborted in destructor.  No prior commit() or abort().");
     }
-#endif
 
     Py_DECREF(self->env);
     PyObject_Del(self);
@@ -1049,9 +927,7 @@
     DBLockObject* self = PyObject_New(DBLockObject, &DBLock_Type);
     if (self == NULL)
         return NULL;
-#ifdef HAVE_WEAKREF
     self->in_weakreflist = NULL;
-#endif
 
     MYDB_BEGIN_ALLOW_THREADS;
 #if (DBVER >= 40)
@@ -1073,11 +949,9 @@
 static void
 DBLock_dealloc(DBLockObject* self)
 {
-#ifdef HAVE_WEAKREF
     if (self->in_weakreflist != NULL) {
         PyObject_ClearWeakRefs((PyObject *) self);
     }
-#endif
     /* TODO: is this lock held? should we release it? */
 
     PyObject_Del(self);
@@ -1094,9 +968,7 @@
         return NULL;
     Py_INCREF(mydb);
     self->mydb = mydb;
-#ifdef HAVE_WEAKREF
     self->in_weakreflist = NULL;
-#endif
 
 
     MYDB_BEGIN_ALLOW_THREADS;
@@ -1115,11 +987,9 @@
 static void
 DBSequence_dealloc(DBSequenceObject* self)
 {
-#ifdef HAVE_WEAKREF
     if (self->in_weakreflist != NULL) {
         PyObject_ClearWeakRefs((PyObject *) self);
     }
-#endif
 
     Py_DECREF(self->mydb);
     PyObject_Del(self);
@@ -1201,13 +1071,7 @@
             Py_ssize_t size;
 
             CLEAR_DBT(*secKey);
-#if PYTHON_API_VERSION <= 1007
-            /* 1.5 compatibility */
-            size = PyString_Size(result);
-            data = PyString_AsString(result);
-#else
             PyString_AsStringAndSize(result, &data, &size);
-#endif
             secKey->flags = DB_DBT_APPMALLOC;   /* DB will free */
             secKey->data = malloc(size);        /* TODO, check this */
 	    if (secKey->data) {
@@ -1346,7 +1210,6 @@
 }
 
 
-#if (DBVER >= 32)
 static PyObject*
 _DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
 {
@@ -1414,8 +1277,6 @@
 {
     return _DB_consume(self, args, kwargs, DB_CONSUME_WAIT);
 }
-#endif
-
 
 
 static PyObject*
@@ -2423,7 +2284,6 @@
 }
 
 
-#if (DBVER >= 32)
 static PyObject*
 DB_set_q_extentsize(DBObject* self, PyObject* args)
 {
@@ -2440,7 +2300,6 @@
     RETURN_IF_ERR();
     RETURN_NONE();
 }
-#endif
 
 static PyObject*
 DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
@@ -4025,7 +3884,6 @@
 }
 
 
-#if (DBVER >= 32)
 static PyObject*
 DBEnv_set_flags(DBEnvObject* self, PyObject* args)
 {
@@ -4042,7 +3900,6 @@
     RETURN_IF_ERR();
     RETURN_NONE();
 }
-#endif
 
 
 static PyObject*
@@ -4169,7 +4026,6 @@
 #endif
 
 
-#if (DBVER >= 32)
 
 static PyObject*
 DBEnv_set_lk_max_locks(DBEnvObject* self, PyObject* args)
@@ -4221,8 +4077,6 @@
     RETURN_NONE();
 }
 
-#endif
-
 
 static PyObject*
 DBEnv_set_mp_mmapsize(DBEnvObject* self, PyObject* args)
@@ -4543,19 +4397,15 @@
     MAKE_ENTRY(lastid);
 #endif
     MAKE_ENTRY(nmodes);
-#if (DBVER >= 32)
     MAKE_ENTRY(maxlocks);
     MAKE_ENTRY(maxlockers);
     MAKE_ENTRY(maxobjects);
     MAKE_ENTRY(nlocks);
     MAKE_ENTRY(maxnlocks);
-#endif
     MAKE_ENTRY(nlockers);
     MAKE_ENTRY(maxnlockers);
-#if (DBVER >= 32)
     MAKE_ENTRY(nobjects);
     MAKE_ENTRY(maxnobjects);
-#endif
     MAKE_ENTRY(nrequests);
     MAKE_ENTRY(nreleases);
 #if (DBVER < 44)
@@ -5143,10 +4993,8 @@
     {"associate",       (PyCFunction)DB_associate,      METH_VARARGS|METH_KEYWORDS},
 #endif
     {"close",           (PyCFunction)DB_close,          METH_VARARGS},
-#if (DBVER >= 32)
     {"consume",         (PyCFunction)DB_consume,        METH_VARARGS|METH_KEYWORDS},
     {"consume_wait",    (PyCFunction)DB_consume_wait,   METH_VARARGS|METH_KEYWORDS},
-#endif
     {"cursor",          (PyCFunction)DB_cursor,         METH_VARARGS|METH_KEYWORDS},
     {"delete",          (PyCFunction)DB_delete,         METH_VARARGS|METH_KEYWORDS},
     {"fd",              (PyCFunction)DB_fd,             METH_VARARGS},
@@ -5184,9 +5032,7 @@
     {"set_re_len",      (PyCFunction)DB_set_re_len,     METH_VARARGS},
     {"set_re_pad",      (PyCFunction)DB_set_re_pad,     METH_VARARGS},
     {"set_re_source",   (PyCFunction)DB_set_re_source,  METH_VARARGS},
-#if (DBVER >= 32)
     {"set_q_extentsize",(PyCFunction)DB_set_q_extentsize,METH_VARARGS},
-#endif
     {"stat",            (PyCFunction)DB_stat,           METH_VARARGS|METH_KEYWORDS},
     {"sync",            (PyCFunction)DB_sync,           METH_VARARGS},
 #if (DBVER >= 33)
@@ -5254,9 +5100,7 @@
     {"set_shm_key",     (PyCFunction)DBEnv_set_shm_key,      METH_VARARGS},
     {"set_cachesize",   (PyCFunction)DBEnv_set_cachesize,    METH_VARARGS},
     {"set_data_dir",    (PyCFunction)DBEnv_set_data_dir,     METH_VARARGS},
-#if (DBVER >= 32)
     {"set_flags",       (PyCFunction)DBEnv_set_flags,        METH_VARARGS},
-#endif
     {"set_lg_bsize",    (PyCFunction)DBEnv_set_lg_bsize,     METH_VARARGS},
     {"set_lg_dir",      (PyCFunction)DBEnv_set_lg_dir,       METH_VARARGS},
     {"set_lg_max",      (PyCFunction)DBEnv_set_lg_max,       METH_VARARGS},
@@ -5267,11 +5111,9 @@
 #if (DBVER < 45)
     {"set_lk_max",      (PyCFunction)DBEnv_set_lk_max,       METH_VARARGS},
 #endif
-#if (DBVER >= 32)
     {"set_lk_max_locks", (PyCFunction)DBEnv_set_lk_max_locks, METH_VARARGS},
     {"set_lk_max_lockers", (PyCFunction)DBEnv_set_lk_max_lockers, METH_VARARGS},
     {"set_lk_max_objects", (PyCFunction)DBEnv_set_lk_max_objects, METH_VARARGS},
-#endif
     {"set_mp_mmapsize", (PyCFunction)DBEnv_set_mp_mmapsize,  METH_VARARGS},
     {"set_tmp_dir",     (PyCFunction)DBEnv_set_tmp_dir,      METH_VARARGS},
     {"txn_begin",       (PyCFunction)DBEnv_txn_begin,        METH_VARARGS|METH_KEYWORDS},
@@ -5391,7 +5233,6 @@
     0,          /*tp_as_sequence*/
     &DB_mapping,/*tp_as_mapping*/
     0,          /*tp_hash*/
-#ifdef HAVE_WEAKREF
     0,			/* tp_call */
     0,			/* tp_str */
     0,  		/* tp_getattro */
@@ -5403,7 +5244,6 @@
     0,			/* tp_clear */
     0,			/* tp_richcompare */
     offsetof(DBObject, in_weakreflist),   /* tp_weaklistoffset */
-#endif
 };
 
 
@@ -5424,7 +5264,6 @@
     0,                  /*tp_as_sequence*/
     0,                  /*tp_as_mapping*/
     0,                  /*tp_hash*/
-#ifdef HAVE_WEAKREF
     0,			/* tp_call */
     0,			/* tp_str */
     0,  		/* tp_getattro */
@@ -5436,7 +5275,6 @@
     0,			/* tp_clear */
     0,			/* tp_richcompare */
     offsetof(DBCursorObject, in_weakreflist),   /* tp_weaklistoffset */
-#endif
 };
 
 
@@ -5457,7 +5295,6 @@
     0,          /*tp_as_sequence*/
     0,          /*tp_as_mapping*/
     0,          /*tp_hash*/
-#ifdef HAVE_WEAKREF
     0,			/* tp_call */
     0,			/* tp_str */
     0,  		/* tp_getattro */
@@ -5469,7 +5306,6 @@
     0,			/* tp_clear */
     0,			/* tp_richcompare */
     offsetof(DBEnvObject, in_weakreflist),   /* tp_weaklistoffset */
-#endif
 };
 
 statichere PyTypeObject DBTxn_Type = {
@@ -5489,7 +5325,6 @@
     0,          /*tp_as_sequence*/
     0,          /*tp_as_mapping*/
     0,          /*tp_hash*/
-#ifdef HAVE_WEAKREF
     0,			/* tp_call */
     0,			/* tp_str */
     0,  		/* tp_getattro */
@@ -5501,7 +5336,6 @@
     0,			/* tp_clear */
     0,			/* tp_richcompare */
     offsetof(DBTxnObject, in_weakreflist),   /* tp_weaklistoffset */
-#endif
 };
 
 
@@ -5522,7 +5356,6 @@
     0,          /*tp_as_sequence*/
     0,          /*tp_as_mapping*/
     0,          /*tp_hash*/
-#ifdef HAVE_WEAKREF
     0,			/* tp_call */
     0,			/* tp_str */
     0,  		/* tp_getattro */
@@ -5534,7 +5367,6 @@
     0,			/* tp_clear */
     0,			/* tp_richcompare */
     offsetof(DBLockObject, in_weakreflist),   /* tp_weaklistoffset */
-#endif
 };
 
 #if (DBVER >= 43)
@@ -5555,7 +5387,6 @@
     0,          /*tp_as_sequence*/
     0,          /*tp_as_mapping*/
     0,          /*tp_hash*/
-#ifdef HAVE_WEAKREF
     0,			/* tp_call */
     0,			/* tp_str */
     0,  		/* tp_getattro */
@@ -5567,7 +5398,6 @@
     0,			/* tp_clear */
     0,			/* tp_richcompare */
     offsetof(DBSequenceObject, in_weakreflist),   /* tp_weaklistoffset */
-#endif
 };
 #endif
 
@@ -5649,6 +5479,9 @@
     {NULL,      NULL}       /* sentinel */
 };
 
+/* API structure */
+static BSDDB_api bsddb_api;
+
 
 /* --------------------------------------------------------------------- */
 /* Module initialization */
@@ -5669,6 +5502,7 @@
     PyObject* pybsddb_version_s = PyString_FromString( PY_BSDDB_VERSION );
     PyObject* db_version_s = PyString_FromString( DB_VERSION_STRING );
     PyObject* cvsid_s = PyString_FromString( rcs_id );
+    PyObject* py_api;
 
     /* Initialize the type of the new type objects here; doing it here
        is required for portability to Windows without requiring C++. */
@@ -5730,9 +5564,7 @@
     ADD_INT(d, DB_INIT_LOG);
     ADD_INT(d, DB_INIT_MPOOL);
     ADD_INT(d, DB_INIT_TXN);
-#if (DBVER >= 32)
     ADD_INT(d, DB_JOINENV);
-#endif
 
     ADD_INT(d, DB_RECOVER);
     ADD_INT(d, DB_RECOVER_FATAL);
@@ -5753,11 +5585,9 @@
     ADD_INT(d, DB_RDWRMASTER);
     ADD_INT(d, DB_RDONLY);
     ADD_INT(d, DB_TRUNCATE);
-#if (DBVER >= 32)
     ADD_INT(d, DB_EXTENT);
     ADD_INT(d, DB_CDB_ALLDB);
     ADD_INT(d, DB_VERIFY);
-#endif
     ADD_INT(d, DB_UPGRADE);
 
     ADD_INT(d, DB_AGGRESSIVE);
@@ -5801,9 +5631,7 @@
     ADD_INT(d, DB_LOCK_READ);
     ADD_INT(d, DB_LOCK_WRITE);
     ADD_INT(d, DB_LOCK_NOWAIT);
-#if (DBVER >= 32)
     ADD_INT(d, DB_LOCK_WAIT);
-#endif
     ADD_INT(d, DB_LOCK_IWRITE);
     ADD_INT(d, DB_LOCK_IREAD);
     ADD_INT(d, DB_LOCK_IWR);
@@ -5818,9 +5646,7 @@
 
     ADD_INT(d, DB_LOCK_RECORD);
     ADD_INT(d, DB_LOCK_UPGRADE);
-#if (DBVER >= 32)
     ADD_INT(d, DB_LOCK_SWITCH);
-#endif
 #if (DBVER >= 33)
     ADD_INT(d, DB_LOCK_UPGRADE_WRITE);
 #endif
@@ -5881,9 +5707,7 @@
     ADD_INT(d, DB_COMMIT);
 #endif
     ADD_INT(d, DB_CONSUME);
-#if (DBVER >= 32)
     ADD_INT(d, DB_CONSUME_WAIT);
-#endif
     ADD_INT(d, DB_CURRENT);
 #if (DBVER >= 33)
     ADD_INT(d, DB_FAST_STAT);
@@ -6061,6 +5885,19 @@
 
 #undef MAKE_EX
 
+    /* Initiliase the C API structure and add it to the module */
+    bsddb_api.db_type         = &DB_Type;
+    bsddb_api.dbcursor_type   = &DBCursor_Type;
+    bsddb_api.dbenv_type      = &DBEnv_Type;
+    bsddb_api.dbtxn_type      = &DBTxn_Type;
+    bsddb_api.dblock_type     = &DBLock_Type;
+    bsddb_api.dbsequence_type = &DBSequence_Type;
+    bsddb_api.makeDBError     = makeDBError;
+
+    py_api = PyCObject_FromVoidPtr((void*)&bsddb_api, NULL);
+    PyDict_SetItemString(d, "api", py_api);
+    Py_DECREF(py_api);
+
     /* Check for errors */
     if (PyErr_Occurred()) {
         PyErr_Print();

Added: python/trunk/Modules/bsddb.h
==============================================================================
--- (empty file)
+++ python/trunk/Modules/bsddb.h	Tue Oct  9 08:02:21 2007
@@ -0,0 +1,238 @@
+/*----------------------------------------------------------------------
+  Copyright (c) 1999-2001, Digital Creations, Fredericksburg, VA, USA
+  and Andrew Kuchling. All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are
+  met:
+
+    o Redistributions of source code must retain the above copyright
+      notice, this list of conditions, and the disclaimer that follows.
+
+    o Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions, and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+
+    o Neither the name of Digital Creations nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
+  IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+  PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL
+  CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+  DAMAGE.
+------------------------------------------------------------------------*/
+
+
+/*
+ * Handwritten code to wrap version 3.x of the Berkeley DB library,
+ * written to replace a SWIG-generated file.  It has since been updated
+ * to compile with BerkeleyDB versions 3.2 through 4.2.
+ *
+ * This module was started by Andrew Kuchling to remove the dependency
+ * on SWIG in a package by Gregory P. Smith who based his work on a
+ * similar package by Robin Dunn <robin at alldunn.com> which wrapped
+ * Berkeley DB 2.7.x.
+ *
+ * Development of this module then returned full circle back to Robin Dunn
+ * who worked on behalf of Digital Creations to complete the wrapping of
+ * the DB 3.x API and to build a solid unit test suite.  Robin has
+ * since gone onto other projects (wxPython).
+ *
+ * Gregory P. Smith <greg at krypto.org> is once again the maintainer.
+ *
+ * Use the pybsddb-users at lists.sf.net mailing list for all questions.
+ * Things can change faster than the header of this file is updated.  This
+ * file is shared with the PyBSDDB project at SourceForge:
+ *
+ * http://pybsddb.sf.net
+ *
+ * This file should remain backward compatible with Python 2.1, but see PEP
+ * 291 for the most current backward compatibility requirements:
+ *
+ * http://www.python.org/peps/pep-0291.html
+ *
+ * This module contains 6 types:
+ *
+ * DB           (Database)
+ * DBCursor     (Database Cursor)
+ * DBEnv        (database environment)
+ * DBTxn        (An explicit database transaction)
+ * DBLock       (A lock handle)
+ * DBSequence   (Sequence)
+ *
+ */
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Portions of this module, associated unit tests and build scripts are the
+ * result of a contract with The Written Word (http://thewrittenword.com/)
+ * Many thanks go out to them for causing me to raise the bar on quality and
+ * functionality, resulting in a better bsddb3 package for all of us to use.
+ *
+ * --Robin
+ */
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Work to split it up into a separate header and to add a C API was
+ * contributed by Duncan Grisby <duncan at tideway.com>.   See here:
+ *  http://sourceforge.net/tracker/index.php?func=detail&aid=1551895&group_id=13900&atid=313900
+ */
+
+/* --------------------------------------------------------------------- */
+
+#ifndef _BSDDB_H_
+#define _BSDDB_H_
+
+#include <db.h>
+
+
+/* 40 = 4.0, 33 = 3.3; this will break if the minor revision is > 9 */
+#define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
+#if DB_VERSION_MINOR > 9
+#error "eek! DBVER can't handle minor versions > 9"
+#endif
+
+#define PY_BSDDB_VERSION "4.6.0"
+
+/* Python object definitions */
+
+struct behaviourFlags {
+    /* What is the default behaviour when DB->get or DBCursor->get returns a
+       DB_NOTFOUND || DB_KEYEMPTY error?  Return None or raise an exception? */
+    unsigned int getReturnsNone : 1;
+    /* What is the default behaviour for DBCursor.set* methods when DBCursor->get
+     * returns a DB_NOTFOUND || DB_KEYEMPTY  error?  Return None or raise? */
+    unsigned int cursorSetReturnsNone : 1;
+};
+
+
+typedef struct {
+    PyObject_HEAD
+    DB_ENV*     db_env;
+    u_int32_t   flags;             /* saved flags from open() */
+    int         closed;
+    struct behaviourFlags moduleFlags;
+    PyObject        *in_weakreflist; /* List of weak references */
+} DBEnvObject;
+
+
+typedef struct {
+    PyObject_HEAD
+    DB*             db;
+    DBEnvObject*    myenvobj;  /* PyObject containing the DB_ENV */
+    u_int32_t       flags;     /* saved flags from open() */
+    u_int32_t       setflags;  /* saved flags from set_flags() */
+    int             haveStat;
+    struct behaviourFlags moduleFlags;
+#if (DBVER >= 33)
+    PyObject*       associateCallback;
+    PyObject*       btCompareCallback;
+    int             primaryDBType;
+#endif
+    PyObject        *in_weakreflist; /* List of weak references */
+} DBObject;
+
+
+typedef struct {
+    PyObject_HEAD
+    DBC*            dbc;
+    DBObject*       mydb;
+    PyObject        *in_weakreflist; /* List of weak references */
+} DBCursorObject;
+
+
+typedef struct {
+    PyObject_HEAD
+    DB_TXN*         txn;
+    PyObject        *env;
+    PyObject        *in_weakreflist; /* List of weak references */
+} DBTxnObject;
+
+
+typedef struct {
+    PyObject_HEAD
+    DB_LOCK         lock;
+    PyObject        *in_weakreflist; /* List of weak references */
+} DBLockObject;
+
+
+#if (DBVER >= 43)
+typedef struct {
+    PyObject_HEAD
+    DB_SEQUENCE*     sequence;
+    DBObject*        mydb;
+    PyObject        *in_weakreflist; /* List of weak references */
+} DBSequenceObject;
+staticforward PyTypeObject DBSequence_Type;
+#endif
+
+
+/* API structure for use by C code */
+
+/* To access the structure from an external module, use code like the
+   following (error checking missed out for clarity):
+
+     BSDDB_api* bsddb_api;
+     PyObject*  mod;
+     PyObject*  cobj;
+
+     mod  = PyImport_ImportModule("bsddb._bsddb");
+     // Use "bsddb3._pybsddb" if you're using the standalone pybsddb add-on.
+     cobj = PyObject_GetAttrString(mod, "api");
+     api  = (BSDDB_api*)PyCObject_AsVoidPtr(cobj);
+     Py_DECREF(cobj);
+     Py_DECREF(mod);
+
+   The structure's members must not be changed.
+*/
+
+typedef struct {
+    /* Type objects */
+    PyTypeObject* db_type;
+    PyTypeObject* dbcursor_type;
+    PyTypeObject* dbenv_type;
+    PyTypeObject* dbtxn_type;
+    PyTypeObject* dblock_type;
+#if (DBVER >= 43)
+    PyTypeObject* dbsequence_type;
+#endif
+
+    /* Functions */
+    int (*makeDBError)(int err);
+
+} BSDDB_api;
+
+
+#ifndef COMPILING_BSDDB_C
+
+/* If not inside _bsddb.c, define type check macros that use the api
+   structure.  The calling code must have a value named bsddb_api
+   pointing to the api structure.
+*/
+
+#define DBObject_Check(v)       ((v)->ob_type == bsddb_api->db_type)
+#define DBCursorObject_Check(v) ((v)->ob_type == bsddb_api->dbcursor_type)
+#define DBEnvObject_Check(v)    ((v)->ob_type == bsddb_api->dbenv_type)
+#define DBTxnObject_Check(v)    ((v)->ob_type == bsddb_api->dbtxn_type)
+#define DBLockObject_Check(v)   ((v)->ob_type == bsddb_api->dblock_type)
+#if (DBVER >= 43)
+#define DBSequenceObject_Check(v)  ((v)->ob_type == bsddb_api->dbsequence_type)
+#endif
+
+#endif // COMPILING_BSDDB_C
+
+
+#endif // _BSDDB_H_

Modified: python/trunk/setup.py
==============================================================================
--- python/trunk/setup.py	(original)
+++ python/trunk/setup.py	Tue Oct  9 08:02:21 2007
@@ -801,6 +801,7 @@
             # some unusual system configurations (e.g. the directory
             # is on an NFS server that goes away).
             exts.append(Extension('_bsddb', ['_bsddb.c'],
+                                  depends = ['bsddb.h'],
                                   library_dirs=dblib_dir,
                                   runtime_library_dirs=dblib_dir,
                                   include_dirs=db_incs,


More information about the Python-checkins mailing list