/*----------------------------------------------------------------------
  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@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@krypto.org> is once again the maintainer.
 *
 * Use the pybsddb-users@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
 */

/* --------------------------------------------------------------------- */

#include <stddef.h>   /* for offsetof() */
#include <Python.h>

#define COMPILING_BSDDB_C
#include "bsddb.h"
#undef COMPILING_BSDDB_C

static char *svn_id = "$Id$";

/* --------------------------------------------------------------------- */
/* Various macro definitions */

#if (PY_VERSION_HEX < 0x02050000)
typedef int Py_ssize_t;
#endif

#ifdef WITH_THREAD

/* These are for when calling Python --> C */
#define MYDB_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS;
#define MYDB_END_ALLOW_THREADS Py_END_ALLOW_THREADS;

/* For 2.3, use the PyGILState_ calls */
#if (PY_VERSION_HEX >= 0x02030000)
#define MYDB_USE_GILSTATE
#endif

/* and these are for calling C --> Python */
#if defined(MYDB_USE_GILSTATE)
#define MYDB_BEGIN_BLOCK_THREADS \
		PyGILState_STATE __savestate = PyGILState_Ensure();
#define MYDB_END_BLOCK_THREADS \
		PyGILState_Release(__savestate);
#else /* MYDB_USE_GILSTATE */
/* Pre GILState API - do it the long old way */
static PyInterpreterState* _db_interpreterState = NULL;
#define MYDB_BEGIN_BLOCK_THREADS {                              \
        PyThreadState* prevState;                               \
        PyThreadState* newState;                                \
        PyEval_AcquireLock();                                   \
        newState  = PyThreadState_New(_db_interpreterState);    \
        prevState = PyThreadState_Swap(newState);

#define MYDB_END_BLOCK_THREADS                                  \
        newState = PyThreadState_Swap(prevState);               \
        PyThreadState_Clear(newState);                          \
        PyEval_ReleaseLock();                                   \
        PyThreadState_Delete(newState);                         \
        }
#endif /* MYDB_USE_GILSTATE */

#else
/* Compiled without threads - avoid all this cruft */
#define MYDB_BEGIN_ALLOW_THREADS
#define MYDB_END_ALLOW_THREADS
#define MYDB_BEGIN_BLOCK_THREADS
#define MYDB_END_BLOCK_THREADS

#endif

/* Should DB_INCOMPLETE be turned into a warning or an exception? */
#define INCOMPLETE_IS_WARNING 1

/* --------------------------------------------------------------------- */
/* Exceptions */

static PyObject* DBError;               /* Base class, all others derive from this */
static PyObject* DBCursorClosedError;   /* raised when trying to use a closed cursor object */
static PyObject* DBKeyEmptyError;       /* DB_KEYEMPTY: also derives from KeyError */
static PyObject* DBKeyExistError;       /* DB_KEYEXIST */
static PyObject* DBLockDeadlockError;   /* DB_LOCK_DEADLOCK */
static PyObject* DBLockNotGrantedError; /* DB_LOCK_NOTGRANTED */
static PyObject* DBNotFoundError;       /* DB_NOTFOUND: also derives from KeyError */
static PyObject* DBOldVersionError;     /* DB_OLD_VERSION */
static PyObject* DBRunRecoveryError;    /* DB_RUNRECOVERY */
static PyObject* DBVerifyBadError;      /* DB_VERIFY_BAD */
static PyObject* DBNoServerError;       /* DB_NOSERVER */
static PyObject* DBNoServerHomeError;   /* DB_NOSERVER_HOME */
static PyObject* DBNoServerIDError;     /* DB_NOSERVER_ID */
#if (DBVER >= 33)
static PyObject* DBPageNotFoundError;   /* DB_PAGE_NOTFOUND */
static PyObject* DBSecondaryBadError;   /* DB_SECONDARY_BAD */
#endif

#if !INCOMPLETE_IS_WARNING
static PyObject* DBIncompleteError;     /* DB_INCOMPLETE */
#endif

static PyObject* DBInvalidArgError;     /* EINVAL */
static PyObject* DBAccessError;         /* EACCES */
static PyObject* DBNoSpaceError;        /* ENOSPC */
static PyObject* DBNoMemoryError;       /* DB_BUFFER_SMALL (ENOMEM when < 4.3) */
static PyObject* DBAgainError;          /* EAGAIN */
static PyObject* DBBusyError;           /* EBUSY  */
static PyObject* DBFileExistsError;     /* EEXIST */
static PyObject* DBNoSuchFileError;     /* ENOENT */
static PyObject* DBPermissionsError;    /* EPERM  */

#if (DBVER < 43)
#define	DB_BUFFER_SMALL		ENOMEM
#endif


/* --------------------------------------------------------------------- */
/* Structure definitions */

#if PYTHON_API_VERSION < 1010
#error "Python 2.1 or later required"
#endif


/* 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 */


static PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type, DBLock_Type;

#define DBObject_Check(v)           (Py_TYPE(v) == &DB_Type)
#define DBCursorObject_Check(v)     (Py_TYPE(v) == &DBCursor_Type)
#define DBEnvObject_Check(v)        (Py_TYPE(v) == &DBEnv_Type)
#define DBTxnObject_Check(v)        (Py_TYPE(v) == &DBTxn_Type)
#define DBLockObject_Check(v)       (Py_TYPE(v) == &DBLock_Type)
#if (DBVER >= 43)
#define DBSequenceObject_Check(v)   (Py_TYPE(v) == &DBSequence_Type)
#endif


/* --------------------------------------------------------------------- */
/* Utility macros and functions */

#define RETURN_IF_ERR()          \
    if (makeDBError(err)) {      \
        return NULL;             \
    }

#define RETURN_NONE()  Py_INCREF(Py_None); return Py_None;

#define _CHECK_OBJECT_NOT_CLOSED(nonNull, pyErrObj, name) \
    if ((nonNull) == NULL) {          \
        PyObject *errTuple = NULL;    \
        errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
        PyErr_SetObject((pyErrObj), errTuple);  \
	Py_DECREF(errTuple);          \
        return NULL;                  \
    }

#define CHECK_DB_NOT_CLOSED(dbobj) \
        _CHECK_OBJECT_NOT_CLOSED(dbobj->db, DBError, DB)

#define CHECK_ENV_NOT_CLOSED(env) \
        _CHECK_OBJECT_NOT_CLOSED(env->db_env, DBError, DBEnv)

#define CHECK_CURSOR_NOT_CLOSED(curs) \
        _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)

#if (DBVER >= 43)
#define CHECK_SEQUENCE_NOT_CLOSED(curs) \
        _CHECK_OBJECT_NOT_CLOSED(curs->sequence, DBError, DBSequence)
#endif

#define CHECK_DBFLAG(mydb, flag)    (((mydb)->flags & (flag)) || \
                                     (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))

#define CLEAR_DBT(dbt)              (memset(&(dbt), 0, sizeof(dbt)))


static int makeDBError(int err);


/* Return the access method type of the DBObject */
static int _DB_get_type(DBObject* self)
{
#if (DBVER >= 33)
    DBTYPE type;
    int err;
    err = self->db->get_type(self->db, &type);
    if (makeDBError(err)) {
        return -1;
    }
    return type;
#else
    return self->db->get_type(self->db);
#endif
}


/* Handy function to free a DBT and any self-allocated data within.
   To be used on self created DBTs.  The make_dbt and make_key_dbt
   functions have their own free routines that do more that this. */
static void free_dbt(DBT *dbt)
{
    if ((dbt->flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && dbt->data != NULL) {
         free(dbt->data);
         dbt->data = NULL;
    }
}


/* Cleanup a Python buffer API view created by make_dbt() */
static void free_buf_view(PyObject *obj, Py_buffer *view)
{
    if (view) {
        PyBuffer_Release(view);
        PyMem_Free(view);
    }
}


/* Cleanup a DBT and an associated Python buffer API view
   created by make_key_dbt() */
#define FREE_DBT_VIEW(dbt, obj, view)    \
            do { \
                free_dbt(&(dbt)); \
                free_buf_view((obj), (view)); \
            } while(0);


static Py_buffer * _malloc_view(PyObject *obj)
{
    Py_buffer *view;

    if (!(view = PyMem_Malloc(sizeof(Py_buffer)))) {
        PyErr_SetString(PyExc_MemoryError,
                        "Py_buffer malloc failed");
        return NULL;
    }

    if (PyObject_GetBuffer(obj, view, PyBUF_SIMPLE))
        return NULL;

    if (view->ndim > 1) {
        PyErr_SetString(PyExc_BufferError,
                        "buffers must be single dimension");
        PyBuffer_Release(view);
        PyMem_Free(view);
        return NULL;
    }
    return view;
}


/* Create a DBT structure (containing key and data values) from Python
   strings.  Returns >= 1 on success, 0 on an error.  The returned_view_p
   may be filled with a newly allocated Py_buffer view on success.
   The caller MUST call free_buf_view() on any returned Py_buffer. */
static int make_dbt(PyObject* obj, DBT* dbt, Py_buffer** returned_view_p)
{
    Py_buffer *view;

    /* simple way to ensure the caller can detect if we've returned a
       new buffer view or not: require their pointer to start out NULL. */
    assert(*returned_view_p == NULL);

    CLEAR_DBT(*dbt);
    if (obj == Py_None) {
        /* no need to do anything, the structure has already been zeroed */
        return 1;
    }
    if (!PyObject_CheckBuffer(obj)) {
        PyErr_SetString(PyExc_TypeError,
                        "Data values must support the buffer API or be None.");
        return 0;
    }

    if ( !(view = _malloc_view(obj)) )
        return 0;

    dbt->data = view->buf;
    dbt->size = Py_SAFE_DOWNCAST(view->len, Py_ssize_t, u_int32_t);
    *returned_view_p = view;
    return 1;
}


/* Recno and Queue DBs can have integer keys.  This function figures out
   what's been given, verifies that it's allowed, and then makes the DBT.

   Caller MUST call FREE_DBT_VIEW(keydbt, keyobj, key_view) with all
   returned DBT and Py_buffer values when done. */
static int
make_key_dbt(DBObject* self, PyObject* keyobj, DBT* key, int* pflags,
             Py_buffer** returned_view_p)
{
    db_recno_t recno;
    int type;
    Py_buffer *view;

    /* simple way to ensure the caller can detect if we've returned a
       new buffer view or not: require their pointer to start out NULL. */
    assert(*returned_view_p == NULL);

    CLEAR_DBT(*key);
    if (keyobj == Py_None) {
        type = _DB_get_type(self);
        if (type == -1)
            return 0;
        if (type == DB_RECNO || type == DB_QUEUE) {
            PyErr_SetString(
                PyExc_TypeError,
                "None keys not allowed for Recno and Queue DB's");
            return 0;
        }
        /* no need to do anything, the structure has already been zeroed */
    }

    else if (PyLong_Check(keyobj)) {
        /* verify access method type */
        type = _DB_get_type(self);
        if (type == -1)
            return 0;
        if (type == DB_BTREE && pflags != NULL) {
            /* if BTREE then an Integer key is allowed with the
             * DB_SET_RECNO flag */
            *pflags |= DB_SET_RECNO;
        }
        else if (type != DB_RECNO && type != DB_QUEUE) {
            PyErr_SetString(
                PyExc_TypeError,
                "Integer keys only allowed for Recno and Queue DB's");
            return 0;
        }

        /* Make a key out of the requested recno, use allocated space so DB
         * will be able to realloc room for the real key if needed. */
        recno = PyLong_AS_LONG(keyobj);
        key->data = malloc(sizeof(db_recno_t));
        if (key->data == NULL) {
            PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
            return 0;
        }
        key->ulen = key->size = sizeof(db_recno_t);
        memcpy(key->data, &recno, sizeof(db_recno_t));
        key->flags = DB_DBT_REALLOC;
    }

    else if (PyObject_CheckBuffer(keyobj)) {
        /* verify access method type */
        type = _DB_get_type(self);
        if (type == -1)
            return 0;
        if (type == DB_RECNO || type == DB_QUEUE) {
            PyErr_SetString(
                PyExc_TypeError,
                "Non-integer keys not allowed for Recno and Queue DB's");
            return 0;
        }

        if ( !(view = _malloc_view(keyobj)) )
            return 0;

        /*
         * NOTE(gps): I don't like doing a data copy here, it seems
         * wasteful.  But without a clean way to tell FREE_DBT if it
         * should free key->data or not we have to.  Other places in
         * the code check for DB_THREAD and forceably set DBT_MALLOC
         * when we otherwise would leave flags 0 to indicate that.
         */
        key->size = Py_SAFE_DOWNCAST(view->len, Py_ssize_t, u_int32_t);
        key->data = malloc(key->size);
        if (key->data == NULL) {
            PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
            key->size = 0;
            return 0;
        }
        memcpy(key->data, view->buf, key->size);
        key->flags = DB_DBT_REALLOC;
        *returned_view_p = view;
    }

    else {
        PyErr_Format(PyExc_TypeError,
                     "buffer or int object expected for key, %s found",
                     Py_TYPE(keyobj)->tp_name);
        return 0;
    }

    return 1;
}


/* Add partial record access to an existing DBT data struct.
   If dlen and doff are set, then the DB_DBT_PARTIAL flag will be set
   and the data storage/retrieval will be done using dlen and doff. */
static int add_partial_dbt(DBT* d, int dlen, int doff) {
    /* if neither were set we do nothing (-1 is the default value) */
    if ((dlen == -1) && (doff == -1)) {
        return 1;
    }

    if ((dlen < 0) || (doff < 0)) {
        PyErr_SetString(PyExc_TypeError, "dlen and doff must both be >= 0");
        return 0;
    }

    d->flags = d->flags | DB_DBT_PARTIAL;
    d->dlen = (unsigned int) dlen;
    d->doff = (unsigned int) doff;
    return 1;
}

/* a safe strcpy() without the zeroing behaviour and semantics of strncpy. */
/* TODO: make this use the native libc strlcpy() when available (BSD)      */
unsigned int our_strlcpy(char* dest, const char* src, unsigned int n)
{
    unsigned int srclen, copylen;

    srclen = strlen(src);
    if (n <= 0)
	return srclen;
    copylen = (srclen > n-1) ? n-1 : srclen;
    /* populate dest[0] thru dest[copylen-1] */
    memcpy(dest, src, copylen);
    /* guarantee null termination */
    dest[copylen] = 0;

    return srclen;
}

/* Callback used to save away more information about errors from the DB
 * library. */
static char _db_errmsg[1024];
#if (DBVER <= 42)
static void _db_errorCallback(const char* prefix, char* msg)
#else
static void _db_errorCallback(const DB_ENV *db_env,
	const char* prefix, const char* msg)
#endif
{
    our_strlcpy(_db_errmsg, msg, sizeof(_db_errmsg));
}


/* make a nice exception object to raise for errors. */
static int makeDBError(int err)
{
    char errTxt[2048];  /* really big, just in case... */
    PyObject *errObj = NULL;
    PyObject *errTuple = NULL;
    int exceptionRaised = 0;
    unsigned int bytes_left;

    switch (err) {
        case 0:                     /* successful, no error */      break;

#if (DBVER < 41)
        case DB_INCOMPLETE:
#if INCOMPLETE_IS_WARNING
            bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
            /* Ensure that bytes_left never goes negative */
            if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) {
                bytes_left = sizeof(errTxt) - bytes_left - 4 - 1;
		assert(bytes_left >= 0);
                strcat(errTxt, " -- ");
                strncat(errTxt, _db_errmsg, bytes_left);
            }
            _db_errmsg[0] = 0;
            exceptionRaised = PyErr_WarnEx(PyExc_RuntimeWarning, errTxt, 1);

#else  /* do an exception instead */
        errObj = DBIncompleteError;
#endif
        break;
#endif /* DBVER < 41 */

        case DB_KEYEMPTY:           errObj = DBKeyEmptyError;       break;
        case DB_KEYEXIST:           errObj = DBKeyExistError;       break;
        case DB_LOCK_DEADLOCK:      errObj = DBLockDeadlockError;   break;
        case DB_LOCK_NOTGRANTED:    errObj = DBLockNotGrantedError; break;
        case DB_NOTFOUND:           errObj = DBNotFoundError;       break;
        case DB_OLD_VERSION:        errObj = DBOldVersionError;     break;
        case DB_RUNRECOVERY:        errObj = DBRunRecoveryError;    break;
        case DB_VERIFY_BAD:         errObj = DBVerifyBadError;      break;
        case DB_NOSERVER:           errObj = DBNoServerError;       break;
        case DB_NOSERVER_HOME:      errObj = DBNoServerHomeError;   break;
        case DB_NOSERVER_ID:        errObj = DBNoServerIDError;     break;
#if (DBVER >= 33)
        case DB_PAGE_NOTFOUND:      errObj = DBPageNotFoundError;   break;
        case DB_SECONDARY_BAD:      errObj = DBSecondaryBadError;   break;
#endif
        case DB_BUFFER_SMALL:       errObj = DBNoMemoryError;       break;

#if (DBVER >= 43)
	/* ENOMEM and DB_BUFFER_SMALL were one and the same until 4.3 */
	case ENOMEM:  errObj = PyExc_MemoryError;   break;
#endif
        case EINVAL:  errObj = DBInvalidArgError;   break;
        case EACCES:  errObj = DBAccessError;       break;
        case ENOSPC:  errObj = DBNoSpaceError;      break;
        case EAGAIN:  errObj = DBAgainError;        break;
        case EBUSY :  errObj = DBBusyError;         break;
        case EEXIST:  errObj = DBFileExistsError;   break;
        case ENOENT:  errObj = DBNoSuchFileError;   break;
        case EPERM :  errObj = DBPermissionsError;  break;

        default:      errObj = DBError;             break;
    }

    if (errObj != NULL) {
        bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
        /* Ensure that bytes_left never goes negative */
        if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) {
            bytes_left = sizeof(errTxt) - bytes_left - 4 - 1;
            assert(bytes_left >= 0);
            strcat(errTxt, " -- ");
            strncat(errTxt, _db_errmsg, bytes_left);
        }
        _db_errmsg[0] = 0;

	errTuple = Py_BuildValue("(is)", err, errTxt);
        PyErr_SetObject(errObj, errTuple);
	Py_DECREF(errTuple);
    }

    return ((errObj != NULL) || exceptionRaised);
}



/* set a type exception */
static void makeTypeError(char* expected, PyObject* found)
{
    PyErr_Format(PyExc_TypeError, "Expected %s argument, %s found.",
                 expected, Py_TYPE(found)->tp_name);
}


/* verify that an obj is either None or a DBTxn, and set the txn pointer */
static int checkTxnObj(PyObject* txnobj, DB_TXN** txn)
{
    if (txnobj == Py_None || txnobj == NULL) {
        *txn = NULL;
        return 1;
    }
    if (DBTxnObject_Check(txnobj)) {
        *txn = ((DBTxnObject*)txnobj)->txn;
        return 1;
    }
    else
        makeTypeError("DBTxn", txnobj);
    return 0;
}


/* Delete a key from a database
  Returns 0 on success, -1 on an error.  */
static int _DB_delete(DBObject* self, DB_TXN *txn, DBT *key, int flags)
{
    int err;

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->del(self->db, txn, key, 0);
    MYDB_END_ALLOW_THREADS;
    if (makeDBError(err)) {
        return -1;
    }
    self->haveStat = 0;
    return 0;
}


/* Store a key into a database
   Returns 0 on success, -1 on an error.  */
static int _DB_put(DBObject* self, DB_TXN *txn, DBT *key, DBT *data, int flags)
{
    int err;

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->put(self->db, txn, key, data, flags);
    MYDB_END_ALLOW_THREADS;
    if (makeDBError(err)) {
        return -1;
    }
    self->haveStat = 0;
    return 0;
}

/* Get a key/data pair from a cursor */
static PyObject* _DBCursor_get(DBCursorObject* self, int extra_flags,
			       PyObject *args, PyObject *kwargs, char *format)
{
    int err;
    PyObject* retval = NULL;
    DBT key, data;
    int dlen = -1;
    int doff = -1;
    int flags = 0;
    static char* kwnames[] = { "flags", "dlen", "doff", NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, kwnames,
				     &flags, &dlen, &doff)) 
      return NULL;

    CHECK_CURSOR_NOT_CLOSED(self);

    flags |= extra_flags;
    CLEAR_DBT(key);
    CLEAR_DBT(data);
    if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
        /* Tell BerkeleyDB to malloc the return value (thread safe) */
        data.flags = DB_DBT_MALLOC;
        key.flags = DB_DBT_MALLOC;
    }
    if (!add_partial_dbt(&data, dlen, doff))
        return NULL;

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->dbc->c_get(self->dbc, &key, &data, flags);
    MYDB_END_ALLOW_THREADS;

    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
	    && self->mydb->moduleFlags.getReturnsNone) {
        Py_INCREF(Py_None);
        retval = Py_None;
    }
    else if (makeDBError(err)) {
        retval = NULL;
    }
    else {  /* otherwise, success! */

        /* if Recno or Queue, return the key as an Int */
        switch (_DB_get_type(self->mydb)) {
        case -1:
            retval = NULL;
            break;

        case DB_RECNO:
        case DB_QUEUE:
            retval = Py_BuildValue("iy#", *((db_recno_t*)key.data),
                                   data.data, data.size);
            break;
        case DB_HASH:
        case DB_BTREE:
        default:
            retval = Py_BuildValue("y#y#", key.data, key.size,
                                   data.data, data.size);
            break;
        }
    }
    if (!err) {
        free_dbt(&key);
        free_dbt(&data);
    }
    return retval;
}


/* add an integer to a dictionary using the given name as a key */
static void _addIntToDict(PyObject* dict, char *name, int value)
{
    PyObject* v = PyLong_FromLong((long) value);
    if (!v || PyDict_SetItemString(dict, name, v))
        PyErr_Clear();

    Py_XDECREF(v);
}

/* The same, when the value is a time_t */
static void _addTimeTToDict(PyObject* dict, char *name, time_t value)
{
    PyObject* v;
	/* if the value fits in regular int, use that. */
#ifdef HAVE_LONG_LONG
	if (sizeof(time_t) > sizeof(long))
		v = PyLong_FromLongLong((PY_LONG_LONG) value);
	else
#endif
		v = PyLong_FromLong((long) value);
    if (!v || PyDict_SetItemString(dict, name, v))
        PyErr_Clear();

    Py_XDECREF(v);
}

#if (DBVER >= 43)
/* add an db_seq_t to a dictionary using the given name as a key */
static void _addDb_seq_tToDict(PyObject* dict, char *name, db_seq_t value)
{
    PyObject* v = PyLong_FromLongLong(value);
    if (!v || PyDict_SetItemString(dict, name, v))
        PyErr_Clear();

    Py_XDECREF(v);
}
#endif



/* --------------------------------------------------------------------- */
/* Allocators and deallocators */

static DBObject*
newDBObject(DBEnvObject* arg, int flags)
{
    DBObject* self;
    DB_ENV* db_env = NULL;
    int err;

    self = PyObject_New(DBObject, &DB_Type);
    if (self == NULL)
        return NULL;

    self->haveStat = 0;
    self->flags = 0;
    self->setflags = 0;
    self->myenvobj = NULL;
#if (DBVER >= 33)
    self->associateCallback = NULL;
    self->btCompareCallback = NULL;
    self->primaryDBType = 0;
#endif
    self->in_weakreflist = NULL;

    /* keep a reference to our python DBEnv object */
    if (arg) {
        Py_INCREF(arg);
        self->myenvobj = arg;
        db_env = arg->db_env;
    }

    if (self->myenvobj)
        self->moduleFlags = self->myenvobj->moduleFlags;
    else
        self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
        self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;

    MYDB_BEGIN_ALLOW_THREADS;
    err = db_create(&self->db, db_env, flags);
    if (self->db != NULL) {
        self->db->set_errcall(self->db, _db_errorCallback);
#if (DBVER >= 33)
        self->db->app_private = (void*)self;
#endif
    }
    MYDB_END_ALLOW_THREADS;
    /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
     * list so that a DBEnv can refuse to close without aborting any open
     * DBTxns and closing any open DBs first. */
    if (makeDBError(err)) {
        if (self->myenvobj) {
            Py_DECREF(self->myenvobj);
            self->myenvobj = NULL;
        }
        PyObject_Del(self);
        self = NULL;
    }
    return self;
}


static void
DB_dealloc(DBObject* self)
{
    if (self->db != NULL) {
        /* avoid closing a DB when its DBEnv has been closed out from under
         * it */
        if (!self->myenvobj ||
            (self->myenvobj && self->myenvobj->db_env))
        {
            MYDB_BEGIN_ALLOW_THREADS;
            self->db->close(self->db, 0);
            MYDB_END_ALLOW_THREADS;
        } else {
            PyErr_WarnEx(PyExc_RuntimeWarning,
			 "DB could not be closed in destructor:"
			 " DBEnv already closed",
			 1);
        }
        self->db = NULL;
    }
    if (self->in_weakreflist != NULL) {
        PyObject_ClearWeakRefs((PyObject *) self);
    }
    if (self->myenvobj) {
        Py_DECREF(self->myenvobj);
        self->myenvobj = NULL;
    }
#if (DBVER >= 33)
    if (self->associateCallback != NULL) {
        Py_DECREF(self->associateCallback);
        self->associateCallback = NULL;
    }
    if (self->btCompareCallback != NULL) {
        Py_DECREF(self->btCompareCallback);
        self->btCompareCallback = NULL;
    }
#endif
    PyObject_Del(self);
}


static DBCursorObject*
newDBCursorObject(DBC* dbc, DBObject* db)
{
    DBCursorObject* self = PyObject_New(DBCursorObject, &DBCursor_Type);
    if (self == NULL)
        return NULL;

    self->dbc = dbc;
    self->mydb = db;
    self->in_weakreflist = NULL;
    Py_INCREF(self->mydb);
    return self;
}


static void
DBCursor_dealloc(DBCursorObject* self)
{
    int err;

    if (self->in_weakreflist != NULL) {
        PyObject_ClearWeakRefs((PyObject *) self);
    }

    if (self->dbc != NULL) {
	/* If the underlying database has been closed, we don't
	   need to do anything. If the environment has been closed
	   we need to leak, as BerkeleyDB will crash trying to access
	   the environment. There was an exception when the 
	   user closed the environment even though there still was
	   a database open. */
	if (self->mydb->db && self->mydb->myenvobj &&
	    !self->mydb->myenvobj->closed)
        /* test for: open db + no environment or non-closed environment */
	if (self->mydb->db && (!self->mydb->myenvobj || (self->mydb->myenvobj &&
	    !self->mydb->myenvobj->closed))) {
            MYDB_BEGIN_ALLOW_THREADS;
            err = self->dbc->c_close(self->dbc);
            MYDB_END_ALLOW_THREADS;
        }
        self->dbc = NULL;
    }
    Py_XDECREF( self->mydb );
    PyObject_Del(self);
}


static DBEnvObject*
newDBEnvObject(int flags)
{
    int err;
    DBEnvObject* self = PyObject_New(DBEnvObject, &DBEnv_Type);
    if (self == NULL)
        return NULL;

    self->closed = 1;
    self->flags = flags;
    self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
    self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
    self->in_weakreflist = NULL;

    MYDB_BEGIN_ALLOW_THREADS;
    err = db_env_create(&self->db_env, flags);
    MYDB_END_ALLOW_THREADS;
    if (makeDBError(err)) {
        PyObject_Del(self);
        self = NULL;
    }
    else {
        self->db_env->set_errcall(self->db_env, _db_errorCallback);
    }
    return self;
}


static void
DBEnv_dealloc(DBEnvObject* self)
{
    if (self->in_weakreflist != NULL) {
        PyObject_ClearWeakRefs((PyObject *) self);
    }

    if (self->db_env && !self->closed) {
        MYDB_BEGIN_ALLOW_THREADS;
        self->db_env->close(self->db_env, 0);
        MYDB_END_ALLOW_THREADS;
    }
    PyObject_Del(self);
}


static DBTxnObject*
newDBTxnObject(DBEnvObject* myenv, DB_TXN *parent, int flags)
{
    int err;
    DBTxnObject* self = PyObject_New(DBTxnObject, &DBTxn_Type);
    if (self == NULL)
        return NULL;
    Py_INCREF(myenv);
    self->env = (PyObject*)myenv;
    self->in_weakreflist = NULL;

    MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
    err = myenv->db_env->txn_begin(myenv->db_env, parent, &(self->txn), flags);
#else
    err = txn_begin(myenv->db_env, parent, &(self->txn), flags);
#endif
    MYDB_END_ALLOW_THREADS;
    if (makeDBError(err)) {
        Py_DECREF(self->env);
        PyObject_Del(self);
        self = NULL;
    }
    return self;
}


static void
DBTxn_dealloc(DBTxnObject* self)
{
    if (self->in_weakreflist != NULL) {
        PyObject_ClearWeakRefs((PyObject *) self);
    }

    if (self->txn) {
        /* it hasn't been finalized, abort it! */
        MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
        self->txn->abort(self->txn);
#else
        txn_abort(self->txn);
#endif
        MYDB_END_ALLOW_THREADS;
        PyErr_WarnEx(PyExc_RuntimeWarning,
		     "DBTxn aborted in destructor. "
		     " No prior commit() or abort().",
		     1);
    }

    Py_DECREF(self->env);
    PyObject_Del(self);
}


static DBLockObject*
newDBLockObject(DBEnvObject* myenv, u_int32_t locker, DBT* obj,
                db_lockmode_t lock_mode, int flags)
{
    int err;
    DBLockObject* self = PyObject_New(DBLockObject, &DBLock_Type);
    if (self == NULL)
        return NULL;
    self->in_weakreflist = NULL;

    MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
    err = myenv->db_env->lock_get(myenv->db_env, locker, flags, obj, lock_mode,
                                  &self->lock);
#else
    err = lock_get(myenv->db_env, locker, flags, obj, lock_mode, &self->lock);
#endif
    MYDB_END_ALLOW_THREADS;
    if (makeDBError(err)) {
        PyObject_Del(self);
        self = NULL;
    }

    return self;
}


static void
DBLock_dealloc(DBLockObject* self)
{
    if (self->in_weakreflist != NULL) {
        PyObject_ClearWeakRefs((PyObject *) self);
    }
    /* TODO: is this lock held? should we release it? */

    PyObject_Del(self);
}


#if (DBVER >= 43)
static DBSequenceObject*
newDBSequenceObject(DBObject* mydb,  int flags)
{
    int err;
    DBSequenceObject* self = PyObject_New(DBSequenceObject, &DBSequence_Type);
    if (self == NULL)
        return NULL;
    Py_INCREF(mydb);
    self->mydb = mydb;
    self->in_weakreflist = NULL;


    MYDB_BEGIN_ALLOW_THREADS;
    err = db_sequence_create(&self->sequence, self->mydb->db, flags);
    MYDB_END_ALLOW_THREADS;
    if (makeDBError(err)) {
        Py_DECREF(self->mydb);
        PyObject_Del(self);
        self = NULL;
    }

    return self;
}


static void
DBSequence_dealloc(DBSequenceObject* self)
{
    if (self->in_weakreflist != NULL) {
        PyObject_ClearWeakRefs((PyObject *) self);
    }

    Py_DECREF(self->mydb);
    PyObject_Del(self);
}
#endif

/* --------------------------------------------------------------------- */
/* DB methods */

static PyObject*
DB_append(DBObject* self, PyObject* args)
{
    PyObject* txnobj = NULL;
    PyObject* dataobj;
    Py_buffer* data_buf_view = NULL;
    db_recno_t recno;
    DBT key, data;
    DB_TXN *txn = NULL;

    if (!PyArg_UnpackTuple(args, "append", 1, 2, &dataobj, &txnobj))
        return NULL;

    CHECK_DB_NOT_CLOSED(self);

    /* make a dummy key out of a recno */
    recno = 0;
    CLEAR_DBT(key);
    key.data = &recno;
    key.size = sizeof(recno);
    key.ulen = key.size;
    key.flags = DB_DBT_USERMEM;

    if (!checkTxnObj(txnobj, &txn)) return NULL;
    if (!make_dbt(dataobj, &data, &data_buf_view)) return NULL;

    if (-1 == _DB_put(self, txn, &key, &data, DB_APPEND)) {
        free_buf_view(dataobj, data_buf_view);
        return NULL;
    }

    free_buf_view(dataobj, data_buf_view);
    return PyLong_FromLong(recno);
}


#if (DBVER >= 33)

static int
_db_associateCallback(DB* db, const DBT* priKey, const DBT* priData,
                      DBT* secKey)
{
    int       retval = DB_DONOTINDEX;
    DBObject* secondaryDB = (DBObject*)db->app_private;
    PyObject* callback = secondaryDB->associateCallback;
    int       type = secondaryDB->primaryDBType;
    PyObject* args;
    PyObject* result = NULL;


    if (callback != NULL) {
        MYDB_BEGIN_BLOCK_THREADS;

        if (type == DB_RECNO || type == DB_QUEUE)
            args = Py_BuildValue("(ly#)", *((db_recno_t*)priKey->data),
                                 priData->data, priData->size);
        else
            args = Py_BuildValue("(y#y#)", priKey->data, priKey->size,
                                 priData->data, priData->size);
        if (args != NULL) {
                result = PyEval_CallObject(callback, args);
        }
        if (args == NULL || result == NULL) {
            PyErr_Print();
        }
        else if (result == Py_None) {
            retval = DB_DONOTINDEX;
        }
        else if (PyLong_Check(result)) {
            retval = PyLong_AsLong(result);
        }
        else if (PyByteArray_Check(result) || PyBytes_Check(result)) {
            char* data;
            Py_ssize_t size;

            CLEAR_DBT(*secKey);
            size = Py_SIZE(result);
            if (PyByteArray_Check(result))
                data = PyByteArray_AS_STRING(result);
            else
                data = PyBytes_AS_STRING(result);
            secKey->flags = DB_DBT_APPMALLOC;   /* DB will free */
            secKey->data = malloc(size);        /* TODO, check this */
	    if (secKey->data) {
		memcpy(secKey->data, data, size);
		secKey->size = size;
		retval = 0;
	    }
	    else {
		PyErr_SetString(PyExc_MemoryError,
                                "malloc failed in _db_associateCallback");
		PyErr_Print();
	    }
        }
        else {
            PyErr_SetString(
               PyExc_TypeError,
               "DB associate callback should return DB_DONOTINDEX or bytes.");
            PyErr_Print();
        }

        Py_XDECREF(args);
        Py_XDECREF(result);

        MYDB_END_BLOCK_THREADS;
    }
    return retval;
}


static PyObject*
DB_associate(DBObject* self, PyObject* args, PyObject* kwargs)
{
    int err, flags=0;
    DBObject* secondaryDB;
    PyObject* callback;
#if (DBVER >= 41)
    PyObject *txnobj = NULL;
    DB_TXN *txn = NULL;
    static char* kwnames[] = {"secondaryDB", "callback", "flags", "txn",
                                    NULL};
#else
    static char* kwnames[] = {"secondaryDB", "callback", "flags", NULL};
#endif

#if (DBVER >= 41)
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iO:associate", kwnames,
                                     &secondaryDB, &callback, &flags,
                                     &txnobj)) {
#else
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:associate", kwnames,
                                     &secondaryDB, &callback, &flags)) {
#endif
        return NULL;
    }

#if (DBVER >= 41)
    if (!checkTxnObj(txnobj, &txn)) return NULL;
#endif

    CHECK_DB_NOT_CLOSED(self);
    if (!DBObject_Check(secondaryDB)) {
        makeTypeError("DB", (PyObject*)secondaryDB);
        return NULL;
    }
    CHECK_DB_NOT_CLOSED(secondaryDB);
    if (callback == Py_None) {
        callback = NULL;
    }
    else if (!PyCallable_Check(callback)) {
        makeTypeError("Callable", callback);
        return NULL;
    }

    /* Save a reference to the callback in the secondary DB. */
    Py_XDECREF(secondaryDB->associateCallback);
    Py_XINCREF(callback);
    secondaryDB->associateCallback = callback;
    secondaryDB->primaryDBType = _DB_get_type(self);

    /* PyEval_InitThreads is called here due to a quirk in python 1.5
     * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
     * The global interepreter lock is not initialized until the first
     * thread is created using thread.start_new_thread() or fork() is
     * called.  that would cause the ALLOW_THREADS here to segfault due
     * to a null pointer reference if no threads or child processes
     * have been created.  This works around that and is a no-op if
     * threads have already been initialized.
     *  (see pybsddb-users mailing list post on 2002-08-07)
     */
#ifdef WITH_THREAD
    PyEval_InitThreads();
#endif
    MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 41)
    err = self->db->associate(self->db,
	                      txn,
                              secondaryDB->db,
                              _db_associateCallback,
                              flags);
#else
    err = self->db->associate(self->db,
                              secondaryDB->db,
                              _db_associateCallback,
                              flags);
#endif
    MYDB_END_ALLOW_THREADS;

    if (err) {
        Py_XDECREF(secondaryDB->associateCallback);
        secondaryDB->associateCallback = NULL;
        secondaryDB->primaryDBType = 0;
    }

    RETURN_IF_ERR();
    RETURN_NONE();
}


#endif


static PyObject*
DB_close(DBObject* self, PyObject* args)
{
    int err, flags=0;
    if (!PyArg_ParseTuple(args,"|i:close", &flags))
        return NULL;
    if (self->db != NULL) {
        if (self->myenvobj)
            CHECK_ENV_NOT_CLOSED(self->myenvobj);
        err = self->db->close(self->db, flags);
        self->db = NULL;
        RETURN_IF_ERR();
    }
    RETURN_NONE();
}


static PyObject*
_DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
{
    int err, flags=0, type;
    PyObject* txnobj = NULL;
    PyObject* retval = NULL;
    DBT key, data;
    DB_TXN *txn = NULL;
    static char* kwnames[] = { "txn", "flags", NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:consume", kwnames,
                                     &txnobj, &flags))
        return NULL;

    CHECK_DB_NOT_CLOSED(self);
    type = _DB_get_type(self);
    if (type == -1)
        return NULL;
    if (type != DB_QUEUE) {
        PyErr_SetString(PyExc_TypeError,
                        "Consume methods only allowed for Queue DB's");
        return NULL;
    }
    if (!checkTxnObj(txnobj, &txn))
        return NULL;

    CLEAR_DBT(key);
    CLEAR_DBT(data);
    if (CHECK_DBFLAG(self, DB_THREAD)) {
        /* Tell BerkeleyDB to malloc the return value (thread safe) */
        data.flags = DB_DBT_MALLOC;
        key.flags = DB_DBT_MALLOC;
    }

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->get(self->db, txn, &key, &data, flags|consume_flag);
    MYDB_END_ALLOW_THREADS;

    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
	    && self->moduleFlags.getReturnsNone) {
        err = 0;
        Py_INCREF(Py_None);
        retval = Py_None;
    }
    else if (!err) {
        retval = Py_BuildValue("y#y#", key.data, key.size, data.data,
                               data.size);
        free_dbt(&key);
        free_dbt(&data);
    }

    RETURN_IF_ERR();
    return retval;
}

static PyObject*
DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
{
    return _DB_consume(self, args, kwargs, DB_CONSUME);
}

static PyObject*
DB_consume_wait(DBObject* self, PyObject* args, PyObject* kwargs,
                int consume_flag)
{
    return _DB_consume(self, args, kwargs, DB_CONSUME_WAIT);
}


static PyObject*
DB_cursor(DBObject* self, PyObject* args, PyObject* kwargs)
{
    int err, flags=0;
    DBC* dbc;
    PyObject* txnobj = NULL;
    DB_TXN *txn = NULL;
    static char* kwnames[] = { "txn", "flags", NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
                                     &txnobj, &flags))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);
    if (!checkTxnObj(txnobj, &txn))
        return NULL;

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->cursor(self->db, txn, &dbc, flags);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    return (PyObject*) newDBCursorObject(dbc, self);
}


static PyObject*
DB_delete(DBObject* self, PyObject* args, PyObject* kwargs)
{
    PyObject* txnobj = NULL;
    int flags = 0;
    PyObject* keyobj;
    Py_buffer* key_buf_view = NULL;
    DBT key;
    DB_TXN *txn = NULL;
    static char* kwnames[] = { "key", "txn", "flags", NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:delete", kwnames,
                                     &keyobj, &txnobj, &flags))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);
    if (!make_key_dbt(self, keyobj, &key, NULL, &key_buf_view))
        return NULL;
    if (!checkTxnObj(txnobj, &txn)) {
        FREE_DBT_VIEW(key, keyobj, key_buf_view);
        return NULL;
    }

    if (-1 == _DB_delete(self, txn, &key, 0)) {
        FREE_DBT_VIEW(key, keyobj, key_buf_view);
        return NULL;
    }

    FREE_DBT_VIEW(key, keyobj, key_buf_view);
    RETURN_NONE();
}


static PyObject*
DB_fd(DBObject* self, PyObject* args)
{
    int err, the_fd;

    if (!PyArg_ParseTuple(args,":fd"))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->fd(self->db, &the_fd);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    return PyLong_FromLong(the_fd);
}


static PyObject*
DB_get(DBObject* self, PyObject* args, PyObject* kwargs)
{
    int err, flags=0;
    PyObject* txnobj = NULL;
    PyObject* keyobj;
    PyObject* dfltobj = NULL;
    PyObject* retval = NULL;
    Py_buffer* key_buf_view = NULL;
    int dlen = -1;
    int doff = -1;
    DBT key, data;
    DB_TXN *txn = NULL;
    static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
                                    "doff", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:get", kwnames,
                                     &keyobj, &dfltobj, &txnobj, &flags, &dlen,
                                     &doff))
        return NULL;

    CHECK_DB_NOT_CLOSED(self);
    if (!make_key_dbt(self, keyobj, &key, &flags, &key_buf_view))
        return NULL;
    if (!checkTxnObj(txnobj, &txn)) {
        FREE_DBT_VIEW(key, keyobj, key_buf_view);
        return NULL;
    }

    CLEAR_DBT(data);
    if (CHECK_DBFLAG(self, DB_THREAD)) {
        /* Tell BerkeleyDB to malloc the return value (thread safe) */
        data.flags = DB_DBT_MALLOC;
    }
    if (!add_partial_dbt(&data, dlen, doff)) {
        FREE_DBT_VIEW(key, keyobj, key_buf_view);
        return NULL;
    }

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->get(self->db, txn, &key, &data, flags);
    MYDB_END_ALLOW_THREADS;

    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
        err = 0;
        Py_INCREF(dfltobj);
        retval = dfltobj;
    }
    else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
	     && self->moduleFlags.getReturnsNone) {
        err = 0;
        Py_INCREF(Py_None);
        retval = Py_None;
    }
    else if (!err) {
        if (flags & DB_SET_RECNO) /* return both key and data */
            retval = Py_BuildValue("y#y#", key.data, key.size, data.data,
                                   data.size);
        else /* return just the data */
            retval = PyBytes_FromStringAndSize((char*)data.data, data.size);
        free_dbt(&data);
    }
    FREE_DBT_VIEW(key, keyobj, key_buf_view);

    RETURN_IF_ERR();
    return retval;
}

#if (DBVER >= 33)
static PyObject*
DB_pget(DBObject* self, PyObject* args, PyObject* kwargs)
{
    int err, flags=0;
    PyObject* txnobj = NULL;
    PyObject* keyobj;
    PyObject* dfltobj = NULL;
    PyObject* retval = NULL;
    Py_buffer* key_buf_view = NULL;
    int dlen = -1;
    int doff = -1;
    DBT key, pkey, data;
    DB_TXN *txn = NULL;
    static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
                                    "doff", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:pget", kwnames,
                                     &keyobj, &dfltobj, &txnobj, &flags, &dlen,
                                     &doff))
        return NULL;

    CHECK_DB_NOT_CLOSED(self);
    if (!make_key_dbt(self, keyobj, &key, &flags, &key_buf_view))
        return NULL;
    if (!checkTxnObj(txnobj, &txn)) {
        FREE_DBT_VIEW(key, keyobj, key_buf_view);
        return NULL;
    }

    CLEAR_DBT(data);
    if (CHECK_DBFLAG(self, DB_THREAD)) {
        /* Tell BerkeleyDB to malloc the return value (thread safe) */
        data.flags = DB_DBT_MALLOC;
    }
    if (!add_partial_dbt(&data, dlen, doff)) {
        FREE_DBT_VIEW(key, keyobj, key_buf_view);
        return NULL;
    }

    CLEAR_DBT(pkey);
    pkey.flags = DB_DBT_MALLOC;
    
    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->pget(self->db, txn, &key, &pkey, &data, flags);
    MYDB_END_ALLOW_THREADS;

    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
        err = 0;
        Py_INCREF(dfltobj);
        retval = dfltobj;
    }
    else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
	     && self->moduleFlags.getReturnsNone) {
        err = 0;
        Py_INCREF(Py_None);
        retval = Py_None;
    }
    else if (!err) {
        PyObject *pkeyObj;
        PyObject *dataObj;
        dataObj = PyBytes_FromStringAndSize(data.data, data.size);

        if (self->primaryDBType == DB_RECNO ||
            self->primaryDBType == DB_QUEUE)
            pkeyObj = PyLong_FromLong(*(int *)pkey.data);
        else
            pkeyObj = PyBytes_FromStringAndSize(pkey.data, pkey.size);

        if (flags & DB_SET_RECNO) /* return key , pkey and data */
        {
            PyObject *keyObj;
            int type = _DB_get_type(self);
            if (type == DB_RECNO || type == DB_QUEUE)
                keyObj = PyLong_FromLong(*(int *)key.data);
            else
                keyObj = PyBytes_FromStringAndSize(key.data, key.size);
#if (PY_VERSION_HEX >= 0x02040000)
            retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
#else
            retval = Py_BuildValue("OOO", keyObj, pkeyObj, dataObj);
#endif
            Py_DECREF(keyObj);
        }
        else /* return just the pkey and data */
        {
#if (PY_VERSION_HEX >= 0x02040000)
            retval = PyTuple_Pack(2, pkeyObj, dataObj);
#else
            retval = Py_BuildValue("OO", pkeyObj, dataObj);
#endif
        }
        Py_DECREF(dataObj);
        Py_DECREF(pkeyObj);
	free_dbt(&pkey);
        free_dbt(&data);
    }
    FREE_DBT_VIEW(key, keyobj, key_buf_view);

    RETURN_IF_ERR();
    return retval;
}
#endif


/* Return size of entry */
static PyObject*
DB_get_size(DBObject* self, PyObject* args, PyObject* kwargs)
{
    int err, flags=0;
    PyObject* txnobj = NULL;
    PyObject* keyobj;
    PyObject* retval = NULL;
    Py_buffer* key_buf_view = NULL;
    DBT key, data;
    DB_TXN *txn = NULL;
    static char* kwnames[] = { "key", "txn", NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:get_size", kwnames,
                                     &keyobj, &txnobj))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);
    if (!make_key_dbt(self, keyobj, &key, &flags, &key_buf_view))
        return NULL;
    if (!checkTxnObj(txnobj, &txn)) {
        FREE_DBT_VIEW(key, keyobj, key_buf_view);
        return NULL;
    }
    CLEAR_DBT(data);

    /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
       thus getting the record size. */
    data.flags = DB_DBT_USERMEM;
    data.ulen = 0;
    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->get(self->db, txn, &key, &data, flags);
    MYDB_END_ALLOW_THREADS;
    if (err == DB_BUFFER_SMALL) {
        retval = PyLong_FromLong((long)data.size);
        err = 0;
    }

    FREE_DBT_VIEW(key, keyobj, key_buf_view);
    free_dbt(&data);
    RETURN_IF_ERR();
    return retval;
}


static PyObject*
DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
{
    int err, flags=0;
    PyObject* txnobj = NULL;
    PyObject* keyobj;
    PyObject* dataobj;
    PyObject* retval = NULL;
    Py_buffer* data_buf_view = NULL;
    Py_buffer* key_buf_view = NULL;
    DBT key, data;
    void *orig_data;
    DB_TXN *txn = NULL;
    static char* kwnames[] = { "key", "data", "txn", "flags", NULL };


    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oi:get_both", kwnames,
                                     &keyobj, &dataobj, &txnobj, &flags))
        return NULL;

    CHECK_DB_NOT_CLOSED(self);
    if (!make_key_dbt(self, keyobj, &key, NULL, &key_buf_view))
        return NULL;
    if ( !checkTxnObj(txnobj, &txn) ||
         !make_dbt(dataobj, &data, &data_buf_view) )
    {
        FREE_DBT_VIEW(key, keyobj, key_buf_view);
        return NULL;
    }

    flags |= DB_GET_BOTH;
    orig_data = data.data;

    if (CHECK_DBFLAG(self, DB_THREAD)) {
        /* Tell BerkeleyDB to malloc the return value (thread safe) */
        /* XXX(nnorwitz): At least 4.4.20 and 4.5.20 require this flag. */
        data.flags = DB_DBT_MALLOC;
    }

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->get(self->db, txn, &key, &data, flags);
    MYDB_END_ALLOW_THREADS;

    free_buf_view(dataobj, data_buf_view);

    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
	    && self->moduleFlags.getReturnsNone) {
        err = 0;
        Py_INCREF(Py_None);
        retval = Py_None;
    }
    else if (!err) {
        /* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */
        /* XXX(gps) I think not: buffer API input vs. bytes object output. */
        /* XXX(guido) But what if the input is PyString? */
        retval = PyBytes_FromStringAndSize((char*)data.data, data.size);

        /* Even though the flags require DB_DBT_MALLOC, data is not always
           allocated.  4.4: allocated, 4.5: *not* allocated. :-( */
        if (data.data != orig_data)
            free_dbt(&data);
    }

    FREE_DBT_VIEW(key, keyobj, key_buf_view);
    RETURN_IF_ERR();
    return retval;
}


static PyObject*
DB_get_byteswapped(DBObject* self, PyObject* args)
{
#if (DBVER >= 33)
    int err = 0;
#endif
    int retval = -1;

    if (!PyArg_ParseTuple(args,":get_byteswapped"))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);

#if (DBVER >= 33)
    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->get_byteswapped(self->db, &retval);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
#else
    MYDB_BEGIN_ALLOW_THREADS;
    retval = self->db->get_byteswapped(self->db);
    MYDB_END_ALLOW_THREADS;
#endif
    return PyLong_FromLong(retval);
}


static PyObject*
DB_get_type(DBObject* self, PyObject* args)
{
    int type;

    if (!PyArg_ParseTuple(args,":get_type"))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);

    type = _DB_get_type(self);
    if (type == -1)
        return NULL;
    return PyLong_FromLong(type);
}


static PyObject*
DB_join(DBObject* self, PyObject* args)
{
    int err, flags=0;
    int length, x;
    PyObject* cursorsObj;
    DBC** cursors;
    DBC*  dbc;

    if (!PyArg_ParseTuple(args,"O|i:join", &cursorsObj, &flags))
        return NULL;

    CHECK_DB_NOT_CLOSED(self);

    if (!PySequence_Check(cursorsObj)) {
        PyErr_SetString(PyExc_TypeError,
                        "Sequence of DBCursor objects expected");
        return NULL;
    }

    length = PyObject_Length(cursorsObj);
    cursors = malloc((length+1) * sizeof(DBC*));
    if (!cursors) {
	PyErr_NoMemory();
	return NULL;
    }

    cursors[length] = NULL;
    for (x=0; x<length; x++) {
        PyObject* item = PySequence_GetItem(cursorsObj, x);
        if (item == NULL) {
            free(cursors);
            return NULL;
        }
        if (!DBCursorObject_Check(item)) {
            PyErr_SetString(PyExc_TypeError,
                            "Sequence of DBCursor objects expected");
            free(cursors);
            return NULL;
        }
        cursors[x] = ((DBCursorObject*)item)->dbc;
        Py_DECREF(item);
    }

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->join(self->db, cursors, &dbc, flags);
    MYDB_END_ALLOW_THREADS;
    free(cursors);
    RETURN_IF_ERR();

    /* FIXME: this is a buggy interface.  The returned cursor
       contains internal references to the passed in cursors
       but does not hold python references to them or prevent
       them from being closed prematurely.  This can cause
       python to crash when things are done in the wrong order. */
    return (PyObject*) newDBCursorObject(dbc, self);
}


static PyObject*
DB_key_range(DBObject* self, PyObject* args, PyObject* kwargs)
{
    int err, flags=0;
    PyObject* txnobj = NULL;
    PyObject* keyobj;
    Py_buffer* key_buf_view = NULL;
    DBT key;
    DB_TXN *txn = NULL;
    DB_KEY_RANGE range;
    static char* kwnames[] = { "key", "txn", "flags", NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:key_range", kwnames,
                                     &keyobj, &txnobj, &flags))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);
    if (!checkTxnObj(txnobj, &txn))
        return NULL;
    if (!make_dbt(keyobj, &key, &key_buf_view))
        /* BTree only, don't need to allow for an int key */
        return NULL;

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->key_range(self->db, txn, &key, &range, flags);
    MYDB_END_ALLOW_THREADS;

    free_buf_view(keyobj, key_buf_view);

    RETURN_IF_ERR();
    return Py_BuildValue("ddd", range.less, range.equal, range.greater);
}


static PyObject*
DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
{
    int err, type = DB_UNKNOWN, flags=0, mode=0660;
    char* filename = NULL;
    char* dbname = NULL;
#if (DBVER >= 41)
    PyObject *txnobj = NULL;
    DB_TXN *txn = NULL;
    /* with dbname */
    static char* kwnames[] = {
        "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL};
    /* without dbname */
    static char* kwnames_basic[] = {
        "filename", "dbtype", "flags", "mode", "txn", NULL};
#else
    /* with dbname */
    static char* kwnames[] = {
        "filename", "dbname", "dbtype", "flags", "mode", NULL};
    /* without dbname */
    static char* kwnames_basic[] = {
        "filename", "dbtype", "flags", "mode", NULL};
#endif

#if (DBVER >= 41)
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziiiO:open", kwnames,
				     &filename, &dbname, &type, &flags, &mode,
                                     &txnobj))
#else
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziii:open", kwnames,
				     &filename, &dbname, &type, &flags,
                                     &mode))
#endif
    {
	PyErr_Clear();
	type = DB_UNKNOWN; flags = 0; mode = 0660;
	filename = NULL; dbname = NULL;
#if (DBVER >= 41)
	if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iiiO:open",
                                         kwnames_basic,
					 &filename, &type, &flags, &mode,
                                         &txnobj))
	    return NULL;
#else
	if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iii:open",
                                         kwnames_basic,
					 &filename, &type, &flags, &mode))
	    return NULL;
#endif
    }

#if (DBVER >= 41)
    if (!checkTxnObj(txnobj, &txn)) return NULL;
#endif

    if (NULL == self->db) {
        PyObject *t = Py_BuildValue("(is)", 0,
                                "Cannot call open() twice for DB object");
        PyErr_SetObject(DBError, t);
        Py_DECREF(t);
        return NULL;
    }

    MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 41)
    err = self->db->open(self->db, txn, filename, dbname, type, flags, mode);
#else
    err = self->db->open(self->db, filename, dbname, type, flags, mode);
#endif
    MYDB_END_ALLOW_THREADS;
    if (makeDBError(err)) {
        self->db->close(self->db, 0);
        self->db = NULL;
        return NULL;
    }

#if (DBVER >= 42)
    self->db->get_flags(self->db, &self->setflags);
#endif

    self->flags = flags;
    RETURN_NONE();
}


static PyObject*
DB_put(DBObject* self, PyObject* args, PyObject* kwargs)
{
    int flags=0;
    PyObject* txnobj = NULL;
    int dlen = -1;
    int doff = -1;
    PyObject *keyobj, *dataobj, *retval;
    Py_buffer *data_buf_view = NULL;
    Py_buffer *key_buf_view = NULL;
    DBT key, data;
    DB_TXN *txn = NULL;
    static char* kwnames[] = { "key", "data", "txn", "flags", "dlen",
                                     "doff", NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oiii:put", kwnames,
                         &keyobj, &dataobj, &txnobj, &flags, &dlen, &doff))
        return NULL;

    CHECK_DB_NOT_CLOSED(self);
    if (!make_key_dbt(self, keyobj, &key, NULL, &key_buf_view))
        return NULL;
    if ( !make_dbt(dataobj, &data, &data_buf_view) ||
         !add_partial_dbt(&data, dlen, doff) ||
         !checkTxnObj(txnobj, &txn) )
    {
        FREE_DBT_VIEW(key, keyobj, key_buf_view);
        free_buf_view(dataobj, data_buf_view);
        return NULL;
    }

    if (-1 == _DB_put(self, txn, &key, &data, flags)) {
        FREE_DBT_VIEW(key, keyobj, key_buf_view);
        free_buf_view(dataobj, data_buf_view);
        return NULL;
    }

    if (flags & DB_APPEND)
        retval = PyLong_FromLong(*((db_recno_t*)key.data));
    else {
        retval = Py_None;
        Py_INCREF(retval);
    }
    FREE_DBT_VIEW(key, keyobj, key_buf_view);
    free_buf_view(dataobj, data_buf_view);
    return retval;
}



static PyObject*
DB_remove(DBObject* self, PyObject* args, PyObject* kwargs)
{
    char* filename;
    char* database = NULL;
    int err, flags=0;
    static char* kwnames[] = { "filename", "dbname", "flags", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zi:remove", kwnames,
                                     &filename, &database, &flags))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);

    err = self->db->remove(self->db, filename, database, flags);
    self->db = NULL;
    RETURN_IF_ERR();
    RETURN_NONE();
}



static PyObject*
DB_rename(DBObject* self, PyObject* args)
{
    char* filename;
    char* database;
    char* newname;
    int err, flags=0;

    if (!PyArg_ParseTuple(args, "sss|i:rename", &filename, &database, &newname,
                          &flags))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->rename(self->db, filename, database, newname, flags);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DB_set_bt_minkey(DBObject* self, PyObject* args)
{
    int err, minkey;

    if (!PyArg_ParseTuple(args,"i:set_bt_minkey", &minkey ))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->set_bt_minkey(self->db, minkey);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}

#if (DBVER >= 33)
static int 
_default_cmp(const DBT *leftKey,
	     const DBT *rightKey)
{
  int res;
  int lsize = leftKey->size, rsize = rightKey->size;

  res = memcmp(leftKey->data, rightKey->data, 
	       lsize < rsize ? lsize : rsize);
  
  if (res == 0) {
      if (lsize < rsize) {
	  res = -1;
      }
      else if (lsize > rsize) {
	  res = 1;
      }
  }
  return res;
}

static int
_db_compareCallback(DB* db, 
		    const DBT *leftKey,
		    const DBT *rightKey)
{
    int res = 0;
    PyObject *args;
    PyObject *result = NULL;
    DBObject *self = (DBObject *)db->app_private;

    if (self == NULL || self->btCompareCallback == NULL) {
	MYDB_BEGIN_BLOCK_THREADS;
	PyErr_SetString(PyExc_TypeError,
			(self == 0
			 ? "DB_bt_compare db is NULL."
			 : "DB_bt_compare callback is NULL."));
	/* we're in a callback within the DB code, we can't raise */
	PyErr_Print();
	res = _default_cmp(leftKey, rightKey);
	MYDB_END_BLOCK_THREADS;
    } else {
	MYDB_BEGIN_BLOCK_THREADS;

	args = Py_BuildValue("y#y#", leftKey->data, leftKey->size,
			     rightKey->data, rightKey->size);
	if (args != NULL) {
		/* XXX(twouters) I highly doubt this INCREF is correct */
		Py_INCREF(self);
		result = PyEval_CallObject(self->btCompareCallback, args);
	}
	if (args == NULL || result == NULL) {
	    /* we're in a callback within the DB code, we can't raise */
	    PyErr_Print();
	    res = _default_cmp(leftKey, rightKey);
	} else if (PyLong_Check(result)) {
	    res = PyLong_AsLong(result);
	} else {
	    PyErr_SetString(PyExc_TypeError,
			    "DB_bt_compare callback MUST return an int.");
	    /* we're in a callback within the DB code, we can't raise */
	    PyErr_Print();
	    res = _default_cmp(leftKey, rightKey);
	}
    
	Py_XDECREF(args);
	Py_XDECREF(result);

	MYDB_END_BLOCK_THREADS;
    }
    return res;
}

static PyObject*
DB_set_bt_compare(DBObject* self, PyObject* args)
{
    int err;
    PyObject *comparator;
    PyObject *tuple, *result;

    if (!PyArg_ParseTuple(args, "O:set_bt_compare", &comparator))
	return NULL;

    CHECK_DB_NOT_CLOSED(self);

    if (!PyCallable_Check(comparator)) {
	makeTypeError("Callable", comparator);
	return NULL;
    }

    /* 
     * Perform a test call of the comparator function with two empty
     * string objects here.  verify that it returns an int (0).
     * err if not.
     */
    tuple = Py_BuildValue("(ss)", "", "");
    result = PyEval_CallObject(comparator, tuple);
    Py_DECREF(tuple);
    if (result == NULL)
        return NULL;
    if (!PyLong_Check(result)) {
	PyErr_SetString(PyExc_TypeError,
		        "callback MUST return an int");
	return NULL;
    } else if (PyLong_AsLong(result) != 0) {
	PyErr_SetString(PyExc_TypeError,
		        "callback failed to return 0 on two empty strings");
	return NULL;
    }
    Py_DECREF(result);

    /* We don't accept multiple set_bt_compare operations, in order to
     * simplify the code. This would have no real use, as one cannot
     * change the function once the db is opened anyway */
    if (self->btCompareCallback != NULL) {
	PyErr_SetString(PyExc_RuntimeError, "set_bt_compare() cannot be called more than once");
	return NULL;
    }

    Py_INCREF(comparator);
    self->btCompareCallback = comparator;

    /* This is to workaround a problem with un-initialized threads (see
       comment in DB_associate) */
#ifdef WITH_THREAD
    PyEval_InitThreads();
#endif

    err = self->db->set_bt_compare(self->db, _db_compareCallback);

    if (err) {
	/* restore the old state in case of error */
	Py_DECREF(comparator);
	self->btCompareCallback = NULL;
    }

    RETURN_IF_ERR();
    RETURN_NONE();
}
#endif /* DBVER >= 33 */


static PyObject*
DB_set_cachesize(DBObject* self, PyObject* args)
{
    int err;
    int gbytes = 0, bytes = 0, ncache = 0;

    if (!PyArg_ParseTuple(args,"ii|i:set_cachesize",
                          &gbytes,&bytes,&ncache))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->set_cachesize(self->db, gbytes, bytes, ncache);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DB_set_flags(DBObject* self, PyObject* args)
{
    int err, flags;

    if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->set_flags(self->db, flags);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();

    self->setflags |= flags;
    RETURN_NONE();
}


static PyObject*
DB_set_h_ffactor(DBObject* self, PyObject* args)
{
    int err, ffactor;

    if (!PyArg_ParseTuple(args,"i:set_h_ffactor", &ffactor))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->set_h_ffactor(self->db, ffactor);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DB_set_h_nelem(DBObject* self, PyObject* args)
{
    int err, nelem;

    if (!PyArg_ParseTuple(args,"i:set_h_nelem", &nelem))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->set_h_nelem(self->db, nelem);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DB_set_lorder(DBObject* self, PyObject* args)
{
    int err, lorder;

    if (!PyArg_ParseTuple(args,"i:set_lorder", &lorder))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->set_lorder(self->db, lorder);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DB_set_pagesize(DBObject* self, PyObject* args)
{
    int err, pagesize;

    if (!PyArg_ParseTuple(args,"i:set_pagesize", &pagesize))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->set_pagesize(self->db, pagesize);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DB_set_re_delim(DBObject* self, PyObject* args)
{
    int err;
    char delim;

    if (!PyArg_ParseTuple(args,"b:set_re_delim", &delim)) {
        PyErr_Clear();
        if (!PyArg_ParseTuple(args,"c:set_re_delim", &delim))
            return NULL;
    }

    CHECK_DB_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->set_re_delim(self->db, delim);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}

static PyObject*
DB_set_re_len(DBObject* self, PyObject* args)
{
    int err, len;

    if (!PyArg_ParseTuple(args,"i:set_re_len", &len))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->set_re_len(self->db, len);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DB_set_re_pad(DBObject* self, PyObject* args)
{
    int err;
    char pad;

    if (!PyArg_ParseTuple(args,"b:set_re_pad", &pad)) {
        PyErr_Clear();
        if (!PyArg_ParseTuple(args,"c:set_re_pad", &pad))
            return NULL;
    }
    CHECK_DB_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->set_re_pad(self->db, pad);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DB_set_re_source(DBObject* self, PyObject* args)
{
    int err;
    char *re_source;

    if (!PyArg_ParseTuple(args,"s:set_re_source", &re_source))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->set_re_source(self->db, re_source);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DB_set_q_extentsize(DBObject* self, PyObject* args)
{
    int err;
    int extentsize;

    if (!PyArg_ParseTuple(args,"i:set_q_extentsize", &extentsize))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->set_q_extentsize(self->db, extentsize);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}

static PyObject*
DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
{
    int err, flags = 0, type;
    void* sp;
    PyObject* d;
#if (DBVER >= 43)
    PyObject* txnobj = NULL;
    DB_TXN *txn = NULL;
    static char* kwnames[] = { "flags", "txn", NULL };
#else
    static char* kwnames[] = { "flags", NULL };
#endif

#if (DBVER >= 43)
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:stat", kwnames,
                                     &flags, &txnobj))
        return NULL;
    if (!checkTxnObj(txnobj, &txn))
        return NULL;
#else
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat", kwnames, &flags))
        return NULL;
#endif
    CHECK_DB_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 43)
    err = self->db->stat(self->db, txn, &sp, flags);
#elif (DBVER >= 33)
    err = self->db->stat(self->db, &sp, flags);
#else
    err = self->db->stat(self->db, &sp, NULL, flags);
#endif
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();

    self->haveStat = 1;

    /* Turn the stat structure into a dictionary */
    type = _DB_get_type(self);
    if ((type == -1) || ((d = PyDict_New()) == NULL)) {
        free(sp);
        return NULL;
    }

#define MAKE_HASH_ENTRY(name)  _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
#define MAKE_BT_ENTRY(name)    _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
#define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)

    switch (type) {
    case DB_HASH:
        MAKE_HASH_ENTRY(magic);
        MAKE_HASH_ENTRY(version);
        MAKE_HASH_ENTRY(nkeys);
        MAKE_HASH_ENTRY(ndata);
        MAKE_HASH_ENTRY(pagesize);
#if (DBVER < 41)
        MAKE_HASH_ENTRY(nelem);
#endif
        MAKE_HASH_ENTRY(ffactor);
        MAKE_HASH_ENTRY(buckets);
        MAKE_HASH_ENTRY(free);
        MAKE_HASH_ENTRY(bfree);
        MAKE_HASH_ENTRY(bigpages);
        MAKE_HASH_ENTRY(big_bfree);
        MAKE_HASH_ENTRY(overflows);
        MAKE_HASH_ENTRY(ovfl_free);
        MAKE_HASH_ENTRY(dup);
        MAKE_HASH_ENTRY(dup_free);
        break;

    case DB_BTREE:
    case DB_RECNO:
        MAKE_BT_ENTRY(magic);
        MAKE_BT_ENTRY(version);
        MAKE_BT_ENTRY(nkeys);
        MAKE_BT_ENTRY(ndata);
        MAKE_BT_ENTRY(pagesize);
        MAKE_BT_ENTRY(minkey);
        MAKE_BT_ENTRY(re_len);
        MAKE_BT_ENTRY(re_pad);
        MAKE_BT_ENTRY(levels);
        MAKE_BT_ENTRY(int_pg);
        MAKE_BT_ENTRY(leaf_pg);
        MAKE_BT_ENTRY(dup_pg);
        MAKE_BT_ENTRY(over_pg);
        MAKE_BT_ENTRY(free);
        MAKE_BT_ENTRY(int_pgfree);
        MAKE_BT_ENTRY(leaf_pgfree);
        MAKE_BT_ENTRY(dup_pgfree);
        MAKE_BT_ENTRY(over_pgfree);
        break;

    case DB_QUEUE:
        MAKE_QUEUE_ENTRY(magic);
        MAKE_QUEUE_ENTRY(version);
        MAKE_QUEUE_ENTRY(nkeys);
        MAKE_QUEUE_ENTRY(ndata);
        MAKE_QUEUE_ENTRY(pagesize);
        MAKE_QUEUE_ENTRY(pages);
        MAKE_QUEUE_ENTRY(re_len);
        MAKE_QUEUE_ENTRY(re_pad);
        MAKE_QUEUE_ENTRY(pgfree);
#if (DBVER == 31)
        MAKE_QUEUE_ENTRY(start);
#endif
        MAKE_QUEUE_ENTRY(first_recno);
        MAKE_QUEUE_ENTRY(cur_recno);
        break;

    default:
        PyErr_SetString(PyExc_TypeError, "Unknown DB type, unable to stat");
        Py_DECREF(d);
        d = NULL;
    }

#undef MAKE_HASH_ENTRY
#undef MAKE_BT_ENTRY
#undef MAKE_QUEUE_ENTRY

    free(sp);
    return d;
}

static PyObject*
DB_sync(DBObject* self, PyObject* args)
{
    int err;
    int flags = 0;

    if (!PyArg_ParseTuple(args,"|i:sync", &flags ))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->sync(self->db, flags);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


#if (DBVER >= 33)
static PyObject*
DB_truncate(DBObject* self, PyObject* args, PyObject* kwargs)
{
    int err, flags=0;
    u_int32_t count=0;
    PyObject* txnobj = NULL;
    DB_TXN *txn = NULL;
    static char* kwnames[] = { "txn", "flags", NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
                                     &txnobj, &flags))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);
    if (!checkTxnObj(txnobj, &txn))
        return NULL;

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->truncate(self->db, txn, &count, flags);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    return PyLong_FromLong(count);
}
#endif


static PyObject*
DB_upgrade(DBObject* self, PyObject* args)
{
    int err, flags=0;
    char *filename;

    if (!PyArg_ParseTuple(args,"s|i:upgrade", &filename, &flags))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->upgrade(self->db, filename, flags);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DB_verify(DBObject* self, PyObject* args, PyObject* kwargs)
{
    int err, flags=0;
    char* fileName;
    char* dbName=NULL;
    char* outFileName=NULL;
    FILE* outFile=NULL;
    static char* kwnames[] = { "filename", "dbname", "outfile", "flags",
                                     NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zzi:verify", kwnames,
                                     &fileName, &dbName, &outFileName, &flags))
        return NULL;

    CHECK_DB_NOT_CLOSED(self);
    if (outFileName)
        outFile = fopen(outFileName, "w");
	/* XXX(nnorwitz): it should probably be an exception if outFile
	   can't be opened. */

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->verify(self->db, fileName, dbName, outFile, flags);
    MYDB_END_ALLOW_THREADS;
    if (outFile)
        fclose(outFile);

    /* DB.verify acts as a DB handle destructor (like close); this was
     * documented in BerkeleyDB 4.2 but had the undocumented effect
     * of not being safe in prior versions while still requiring an explicit
     * DB.close call afterwards.  Lets call close for the user to emulate
     * the safe 4.2 behaviour. */
#if (DBVER <= 41)
    self->db->close(self->db, 0);
#endif
    self->db = NULL;

    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DB_set_get_returns_none(DBObject* self, PyObject* args)
{
    int flags=0;
    int oldValue=0;

    if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);

    if (self->moduleFlags.getReturnsNone)
        ++oldValue;
    if (self->moduleFlags.cursorSetReturnsNone)
        ++oldValue;
    self->moduleFlags.getReturnsNone = (flags >= 1);
    self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
    return PyLong_FromLong(oldValue);
}

#if (DBVER >= 41)
static PyObject*
DB_set_encrypt(DBObject* self, PyObject* args, PyObject* kwargs)
{
    int err;
    u_int32_t flags=0;
    char *passwd = NULL;
    static char* kwnames[] = { "passwd", "flags", NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
		&passwd, &flags)) {
	return NULL;
    }

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->set_encrypt(self->db, passwd, flags);
    MYDB_END_ALLOW_THREADS;

    RETURN_IF_ERR();
    RETURN_NONE();
}
#endif /* DBVER >= 41 */


/*-------------------------------------------------------------- */
/* Mapping and Dictionary-like access routines */

Py_ssize_t DB_length(PyObject* _self)
{
    int err;
    Py_ssize_t size = 0;
    int flags = 0;
    void* sp;
    DBObject* self = (DBObject*)_self;

    if (self->db == NULL) {
        PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
        PyErr_SetObject(DBError, t);
        Py_DECREF(t);
        return -1;
    }

    if (self->haveStat) {  /* Has the stat function been called recently?  If
                              so, we can use the cached value. */
        flags = DB_FAST_STAT;
    }

    MYDB_BEGIN_ALLOW_THREADS;
redo_stat_for_length:
#if (DBVER >= 43)
    err = self->db->stat(self->db, /*txnid*/ NULL, &sp, flags);
#elif (DBVER >= 33)
    err = self->db->stat(self->db, &sp, flags);
#else
    err = self->db->stat(self->db, &sp, NULL, flags);
#endif

    /* All the stat structures have matching fields upto the ndata field,
       so we can use any of them for the type cast */
    size = ((DB_BTREE_STAT*)sp)->bt_ndata;

    /* A size of 0 could mean that BerkeleyDB no longer had the stat values cached.
     * redo a full stat to make sure.
     *   Fixes SF python bug 1493322, pybsddb bug 1184012
     */
    if (size == 0 && (flags & DB_FAST_STAT)) {
        flags = 0;
        if (!err)
            free(sp);
        goto redo_stat_for_length;
    }

    MYDB_END_ALLOW_THREADS;

    if (err)
        return -1;

    self->haveStat = 1;

    free(sp);
    return size;
}


PyObject* DB_subscript(DBObject* self, PyObject* keyobj)
{
    int err;
    PyObject* retval;
    Py_buffer* key_buf_view = NULL;
    DBT key;
    DBT data;

    CHECK_DB_NOT_CLOSED(self);
    if (!make_key_dbt(self, keyobj, &key, NULL, &key_buf_view))
        return NULL;

    CLEAR_DBT(data);
    if (CHECK_DBFLAG(self, DB_THREAD)) {
        /* Tell BerkeleyDB to malloc the return value (thread safe) */
        data.flags = DB_DBT_MALLOC;
    }
    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->get(self->db, NULL, &key, &data, 0);
    MYDB_END_ALLOW_THREADS;
    if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
        PyErr_SetObject(PyExc_KeyError, keyobj);
        retval = NULL;
    }
    else if (makeDBError(err)) {
        retval = NULL;
    }
    else {
        retval = PyBytes_FromStringAndSize((char*)data.data, data.size);
        free_dbt(&data);
    }

    FREE_DBT_VIEW(key, keyobj, key_buf_view);
    return retval;
}


static int
DB_ass_sub(DBObject* self, PyObject* keyobj, PyObject* dataobj)
{
    DBT key, data;
    int retval;
    int flags = 0;
    Py_buffer *data_buf_view = NULL;
    Py_buffer *key_buf_view = NULL;

    if (self->db == NULL) {
        PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
        PyErr_SetObject(DBError, t);
        Py_DECREF(t);
        return -1;
    }

    if (!make_key_dbt(self, keyobj, &key, NULL, &key_buf_view))
        return -1;

    if (dataobj != NULL) {
        if (!make_dbt(dataobj, &data, &data_buf_view))
            retval =  -1;
        else {
            if (self->setflags & (DB_DUP|DB_DUPSORT))
                /* dictionaries shouldn't have duplicate keys */
                flags = DB_NOOVERWRITE;
            retval = _DB_put(self, NULL, &key, &data, flags);

            if ((retval == -1) &&  (self->setflags & (DB_DUP|DB_DUPSORT))) {
                /* try deleting any old record that matches and then PUT it
                 * again... */
                _DB_delete(self, NULL, &key, 0);
                PyErr_Clear();
                retval = _DB_put(self, NULL, &key, &data, flags);
            }
        }
    }
    else {
        /* dataobj == NULL, so delete the key */
        retval = _DB_delete(self, NULL, &key, 0);
    }
    FREE_DBT_VIEW(key, keyobj, key_buf_view);
    free_buf_view(dataobj, data_buf_view);
    return retval;
}


static PyObject*
DB_has_key(DBObject* self, PyObject* args)
{
    int err;
    PyObject* keyobj;
    Py_buffer* key_buf_view = NULL;
    DBT key, data;
    PyObject* txnobj = NULL;
    DB_TXN *txn = NULL;

    if (!PyArg_ParseTuple(args,"O|O:has_key", &keyobj, &txnobj))
        return NULL;
    CHECK_DB_NOT_CLOSED(self);
    if (!make_key_dbt(self, keyobj, &key, NULL, &key_buf_view))
        return NULL;
    if (!checkTxnObj(txnobj, &txn)) {
        FREE_DBT_VIEW(key, keyobj, key_buf_view);
        return NULL;
    }

    /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
       it has a record but can't allocate a buffer for the data.  This saves
       having to deal with data we won't be using.
     */
    CLEAR_DBT(data);
    data.flags = DB_DBT_USERMEM;

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->get(self->db, txn, &key, &data, 0);
    MYDB_END_ALLOW_THREADS;
    FREE_DBT_VIEW(key, keyobj, key_buf_view);

    if (err == DB_BUFFER_SMALL || err == 0) {
        return PyLong_FromLong(1);
    } else if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
        return PyLong_FromLong(0);
    }

    makeDBError(err);
    return NULL;
}


#define _KEYS_LIST      1
#define _VALUES_LIST    2
#define _ITEMS_LIST     3

static PyObject*
_DB_make_list(DBObject* self, DB_TXN* txn, int type)
{
    int err, dbtype;
    DBT key;
    DBT data;
    DBC *cursor;
    PyObject* list;
    PyObject* item = NULL;

    CHECK_DB_NOT_CLOSED(self);
    CLEAR_DBT(key);
    CLEAR_DBT(data);

    dbtype = _DB_get_type(self);
    if (dbtype == -1)
        return NULL;

    list = PyList_New(0);
    if (list == NULL)
        return NULL;

    /* get a cursor */
    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db->cursor(self->db, txn, &cursor, 0);
    MYDB_END_ALLOW_THREADS;
    if (makeDBError(err)) {
        Py_DECREF(list);
        return NULL;
    }

    if (CHECK_DBFLAG(self, DB_THREAD)) {
        key.flags = DB_DBT_REALLOC;
        data.flags = DB_DBT_REALLOC;
    }

    while (1) { /* use the cursor to traverse the DB, collecting items */
        MYDB_BEGIN_ALLOW_THREADS;
        err = cursor->c_get(cursor, &key, &data, DB_NEXT);
        MYDB_END_ALLOW_THREADS;

        if (err) {
            /* for any error, break out of the loop */
            break;
        }

        switch (type) {
        case _KEYS_LIST:
            switch(dbtype) {
            case DB_BTREE:
            case DB_HASH:
            default:
                item = PyBytes_FromStringAndSize((char*)key.data, key.size);
                break;
            case DB_RECNO:
            case DB_QUEUE:
                item = PyLong_FromLong(*((db_recno_t*)key.data));
                break;
            }
            break;

        case _VALUES_LIST:
            item = PyBytes_FromStringAndSize((char*)data.data, data.size);
            break;

        case _ITEMS_LIST:
            switch(dbtype) {
            case DB_BTREE:
            case DB_HASH:
            default:
                item = Py_BuildValue("y#y#", key.data, key.size, data.data,
                                     data.size);
                break;
            case DB_RECNO:
            case DB_QUEUE:
                item = Py_BuildValue("iy#", *((db_recno_t*)key.data),
                                     data.data, data.size);
                break;
            }
            break;
        default:
            PyErr_Format(PyExc_ValueError, "Unknown key type 0x%x", type);
            item = NULL;
            break;
        }
        if (item == NULL) {
            Py_DECREF(list);
            list = NULL;
            goto done;
        }
        PyList_Append(list, item);
        Py_DECREF(item);
    }

    /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
    if (err != DB_NOTFOUND && err != DB_KEYEMPTY && makeDBError(err)) {
        Py_DECREF(list);
        list = NULL;
    }

 done:
    free_dbt(&key);
    free_dbt(&data);
    MYDB_BEGIN_ALLOW_THREADS;
    cursor->c_close(cursor);
    MYDB_END_ALLOW_THREADS;
    return list;
}


static PyObject*
DB_keys(DBObject* self, PyObject* args)
{
    PyObject* txnobj = NULL;
    DB_TXN *txn = NULL;

    if (!PyArg_UnpackTuple(args, "keys", 0, 1, &txnobj))
        return NULL;
    if (!checkTxnObj(txnobj, &txn))
        return NULL;
    return _DB_make_list(self, txn, _KEYS_LIST);
}


static PyObject*
DB_items(DBObject* self, PyObject* args)
{
    PyObject* txnobj = NULL;
    DB_TXN *txn = NULL;

    if (!PyArg_UnpackTuple(args, "items", 0, 1, &txnobj))
        return NULL;
    if (!checkTxnObj(txnobj, &txn))
        return NULL;
    return _DB_make_list(self, txn, _ITEMS_LIST);
}


static PyObject*
DB_values(DBObject* self, PyObject* args)
{
    PyObject* txnobj = NULL;
    DB_TXN *txn = NULL;

    if (!PyArg_UnpackTuple(args, "values", 0, 1, &txnobj))
        return NULL;
    if (!checkTxnObj(txnobj, &txn))
        return NULL;
    return _DB_make_list(self, txn, _VALUES_LIST);
}

/* --------------------------------------------------------------------- */
/* DBCursor methods */


static PyObject*
DBC_close(DBCursorObject* self, PyObject* args)
{
    int err = 0;

    if (!PyArg_ParseTuple(args, ":close"))
        return NULL;

    if (self->dbc != NULL) {
        MYDB_BEGIN_ALLOW_THREADS;
        err = self->dbc->c_close(self->dbc);
        self->dbc = NULL;
        MYDB_END_ALLOW_THREADS;
    }
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DBC_count(DBCursorObject* self, PyObject* args)
{
    int err = 0;
    db_recno_t count;
    int flags = 0;

    if (!PyArg_ParseTuple(args, "|i:count", &flags))
        return NULL;

    CHECK_CURSOR_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->dbc->c_count(self->dbc, &count, flags);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();

    return PyLong_FromLong(count);
}


static PyObject*
DBC_current(DBCursorObject* self, PyObject* args, PyObject *kwargs)
{
    return _DBCursor_get(self,DB_CURRENT,args,kwargs,"|iii:current");
}


static PyObject*
DBC_delete(DBCursorObject* self, PyObject* args)
{
    int err, flags=0;

    if (!PyArg_ParseTuple(args, "|i:delete", &flags))
        return NULL;

    CHECK_CURSOR_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->dbc->c_del(self->dbc, flags);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();

    self->mydb->haveStat = 0;
    RETURN_NONE();
}


static PyObject*
DBC_dup(DBCursorObject* self, PyObject* args)
{
    int err, flags =0;
    DBC* dbc = NULL;

    if (!PyArg_ParseTuple(args, "|i:dup", &flags))
        return NULL;

    CHECK_CURSOR_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->dbc->c_dup(self->dbc, &dbc, flags);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();

    return (PyObject*) newDBCursorObject(dbc, self->mydb);
}

static PyObject*
DBC_first(DBCursorObject* self, PyObject* args, PyObject* kwargs)
{
    return _DBCursor_get(self,DB_FIRST,args,kwargs,"|iii:first");
}


static PyObject*
DBC_get(DBCursorObject* self, PyObject* args, PyObject *kwargs)
{
    int err, flags=0;
    PyObject* keyobj = NULL;
    PyObject* dataobj = NULL;
    PyObject* retval = NULL;
    Py_buffer* data_buf_view = NULL;
    Py_buffer* key_buf_view = NULL;
    int dlen = -1;
    int doff = -1;
    DBT key, data;
    static char* kwnames[] = { "key","data", "flags", "dlen", "doff",
                                     NULL };

    CLEAR_DBT(key);
    CLEAR_DBT(data);
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:get", &kwnames[2],
				     &flags, &dlen, &doff))
    {
        PyErr_Clear();
        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:get",
                                         &kwnames[1], 
					 &keyobj, &flags, &dlen, &doff))
        {
            PyErr_Clear();
            if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:get",
                                             kwnames, &keyobj, &dataobj,
                                             &flags, &dlen, &doff))
            {
                return NULL;
	    }
	}
    }

    CHECK_CURSOR_NOT_CLOSED(self);

    if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL, &key_buf_view))
        return NULL;
    if ( (dataobj && !make_dbt(dataobj, &data, &data_buf_view)) ||
         (!add_partial_dbt(&data, dlen, doff)) )
    {
        FREE_DBT_VIEW(key, keyobj, key_buf_view);
        free_buf_view(dataobj, data_buf_view);
        return NULL;
    }

    if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
        data.flags = DB_DBT_MALLOC;
        if (!(key.flags & DB_DBT_REALLOC)) {
            key.flags |= DB_DBT_MALLOC;
        }
    }

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->dbc->c_get(self->dbc, &key, &data, flags);
    MYDB_END_ALLOW_THREADS;

    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
	    && self->mydb->moduleFlags.getReturnsNone) {
        Py_INCREF(Py_None);
        retval = Py_None;
    }
    else if (makeDBError(err)) {
        retval = NULL;
    }
    else {
        switch (_DB_get_type(self->mydb)) {
        case -1:
            retval = NULL;
            break;
        case DB_BTREE:
        case DB_HASH:
        default:
            retval = Py_BuildValue("y#y#", key.data, key.size,
                                   data.data, data.size);
            break;
        case DB_RECNO:
        case DB_QUEUE:
            retval = Py_BuildValue("iy#", *((db_recno_t*)key.data),
                                   data.data, data.size);
            break;
        }
        free_dbt(&data);
    }
    FREE_DBT_VIEW(key, keyobj, key_buf_view);
    free_buf_view(dataobj, data_buf_view);
    return retval;
}

#if (DBVER >= 33)
static PyObject*
DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
{
    int err, flags=0;
    PyObject* keyobj = NULL;
    PyObject* dataobj = NULL;
    PyObject* retval = NULL;
    Py_buffer* data_buf_view = NULL;
    Py_buffer* key_buf_view = NULL;
    int dlen = -1;
    int doff = -1;
    DBT key, pkey, data;
    static char* kwnames_keyOnly[] = { "key", "flags", "dlen", "doff", NULL };
    static char* kwnames[] = { "key", "data", "flags", "dlen", "doff", NULL };

    CLEAR_DBT(key);
    CLEAR_DBT(data);
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:pget", &kwnames[2],
				     &flags, &dlen, &doff))
    {
        PyErr_Clear();
        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:pget",
                                         kwnames_keyOnly, 
					 &keyobj, &flags, &dlen, &doff))
        {
            PyErr_Clear();
            if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:pget",
                                             kwnames, &keyobj, &dataobj,
                                             &flags, &dlen, &doff))
            {
                return NULL;
	    }
	}
    }

    CHECK_CURSOR_NOT_CLOSED(self);

    if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL, &key_buf_view))
        return NULL;
    if ( (dataobj && !make_dbt(dataobj, &data, &data_buf_view)) ||
         (!add_partial_dbt(&data, dlen, doff)) ) {
        FREE_DBT_VIEW(key, keyobj, key_buf_view);
        free_buf_view(dataobj, data_buf_view);
        return NULL;
    }

    if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
        data.flags = DB_DBT_MALLOC;
        if (!(key.flags & DB_DBT_REALLOC)) {
            key.flags |= DB_DBT_MALLOC;
        }
    }

    CLEAR_DBT(pkey);
    pkey.flags = DB_DBT_MALLOC;

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->dbc->c_pget(self->dbc, &key, &pkey, &data, flags);
    MYDB_END_ALLOW_THREADS;

    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
	    && self->mydb->moduleFlags.getReturnsNone) {
        Py_INCREF(Py_None);
        retval = Py_None;
    }
    else if (makeDBError(err)) {
        retval = NULL;
    }
    else {
        PyObject *pkeyObj;
        PyObject *dataObj;
        dataObj = PyBytes_FromStringAndSize(data.data, data.size);

        if (self->mydb->primaryDBType == DB_RECNO ||
            self->mydb->primaryDBType == DB_QUEUE)
            pkeyObj = PyLong_FromLong(*(int *)pkey.data);
        else
            pkeyObj = PyBytes_FromStringAndSize(pkey.data, pkey.size);

        if (key.data && key.size) /* return key, pkey and data */
        {
            PyObject *keyObj;
            int type = _DB_get_type(self->mydb);
            if (type == DB_RECNO || type == DB_QUEUE)
                keyObj = PyLong_FromLong(*(int *)key.data);
            else
                keyObj = PyBytes_FromStringAndSize(key.data, key.size);
            retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
            Py_DECREF(keyObj);
        }
        else /* return just the pkey and data */
        {
            retval = PyTuple_Pack(2, pkeyObj, dataObj);
        }
        Py_DECREF(dataObj);
        Py_DECREF(pkeyObj);
        free_dbt(&pkey);
        free_dbt(&data);
    }
    /* the only time REALLOC should be set is if we used an integer
     * key that make_key_dbt malloc'd for us.  always free these. */
    if (key.flags & DB_DBT_REALLOC) {
        free_dbt(&key);
    }
    free_buf_view(keyobj, key_buf_view);
    free_buf_view(dataobj, data_buf_view);
    return retval;
}
#endif


static PyObject*
DBC_get_recno(DBCursorObject* self, PyObject* args)
{
    int err;
    db_recno_t recno;
    DBT key;
    DBT data;

    if (!PyArg_ParseTuple(args, ":get_recno"))
        return NULL;

    CHECK_CURSOR_NOT_CLOSED(self);

    CLEAR_DBT(key);
    CLEAR_DBT(data);
    if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
        /* Tell BerkeleyDB to malloc the return value (thread safe) */
        data.flags = DB_DBT_MALLOC;
        key.flags = DB_DBT_MALLOC;
    }

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->dbc->c_get(self->dbc, &key, &data, DB_GET_RECNO);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();

    recno = *((db_recno_t*)data.data);
    free_dbt(&key);
    free_dbt(&data);
    return PyLong_FromLong(recno);
}


static PyObject*
DBC_last(DBCursorObject* self, PyObject* args, PyObject *kwargs)
{
    return _DBCursor_get(self,DB_LAST,args,kwargs,"|iii:last");
}


static PyObject*
DBC_next(DBCursorObject* self, PyObject* args, PyObject *kwargs)
{
    return _DBCursor_get(self,DB_NEXT,args,kwargs,"|iii:next");
}


static PyObject*
DBC_prev(DBCursorObject* self, PyObject* args, PyObject *kwargs)
{
    return _DBCursor_get(self,DB_PREV,args,kwargs,"|iii:prev");
}


static PyObject*
DBC_put(DBCursorObject* self, PyObject* args, PyObject* kwargs)
{
    int err, flags = 0;
    PyObject *keyobj, *dataobj;
    Py_buffer *data_buf_view = NULL;
    Py_buffer *key_buf_view = NULL;
    DBT key, data;
    static char* kwnames[] = { "key", "data", "flags", "dlen", "doff",
                                     NULL };
    int dlen = -1;
    int doff = -1;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iii:put", kwnames,
				     &keyobj, &dataobj, &flags, &dlen, &doff))
        return NULL;

    CHECK_CURSOR_NOT_CLOSED(self);

    if (!make_key_dbt(self->mydb, keyobj, &key, NULL, &key_buf_view))
        return NULL;
    if (!make_dbt(dataobj, &data, &data_buf_view) ||
        !add_partial_dbt(&data, dlen, doff) )
    {
        FREE_DBT_VIEW(key, keyobj, key_buf_view);
        free_buf_view(dataobj, data_buf_view);
        return NULL;
    }

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->dbc->c_put(self->dbc, &key, &data, flags);
    MYDB_END_ALLOW_THREADS;
    FREE_DBT_VIEW(key, keyobj, key_buf_view);
    free_buf_view(dataobj, data_buf_view);
    RETURN_IF_ERR();
    self->mydb->haveStat = 0;
    RETURN_NONE();
}


static PyObject*
DBC_set(DBCursorObject* self, PyObject* args, PyObject *kwargs)
{
    int err, flags = 0;
    DBT key, data;
    PyObject *retval, *keyobj;
    Py_buffer *key_buf_view = NULL;
    static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
    int dlen = -1;
    int doff = -1;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set", kwnames,
				     &keyobj, &flags, &dlen, &doff))
        return NULL;

    CHECK_CURSOR_NOT_CLOSED(self);

    if (!make_key_dbt(self->mydb, keyobj, &key, NULL, &key_buf_view))
        return NULL;

    CLEAR_DBT(data);
    if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
        /* Tell BerkeleyDB to malloc the return value (thread safe) */
        data.flags = DB_DBT_MALLOC;
    }
    if (!add_partial_dbt(&data, dlen, doff)) {
        FREE_DBT_VIEW(key, keyobj, key_buf_view);
        return NULL;
    }

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET);
    MYDB_END_ALLOW_THREADS;
    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
	    && self->mydb->moduleFlags.cursorSetReturnsNone) {
        Py_INCREF(Py_None);
        retval = Py_None;
    }
    else if (makeDBError(err)) {
        retval = NULL;
    }
    else {
        switch (_DB_get_type(self->mydb)) {
        case -1:
            retval = NULL;
            break;
        case DB_BTREE:
        case DB_HASH:
        default:
            retval = Py_BuildValue("y#y#", key.data, key.size,
                                   data.data, data.size);
            break;
        case DB_RECNO:
        case DB_QUEUE:
            retval = Py_BuildValue("iy#", *((db_recno_t*)key.data),
                                   data.data, data.size);
            break;
        }
        free_dbt(&data);
        free_dbt(&key);
    }
    /* the only time REALLOC should be set is if we used an integer
     * key that make_key_dbt malloc'd for us.  always free these. */
    if (key.flags & DB_DBT_REALLOC) {
        free_dbt(&key);
    }
    free_buf_view(keyobj, key_buf_view);

    return retval;
}


static PyObject*
DBC_set_range(DBCursorObject* self, PyObject* args, PyObject* kwargs)
{
    int err, flags = 0;
    DBT key, data;
    PyObject *retval, *keyobj;
    Py_buffer *key_buf_view = NULL;
    static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
    int dlen = -1;
    int doff = -1;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set_range", kwnames,
				     &keyobj, &flags, &dlen, &doff))
        return NULL;

    CHECK_CURSOR_NOT_CLOSED(self);

    if (!make_key_dbt(self->mydb, keyobj, &key, NULL, &key_buf_view))
        return NULL;

    CLEAR_DBT(data);
    if (!add_partial_dbt(&data, dlen, doff)) {
        FREE_DBT_VIEW(key, keyobj, key_buf_view);
        return NULL;
    }
    if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
        /* Tell BerkeleyDB to malloc the return value (thread safe) */
        data.flags |= DB_DBT_MALLOC;
        /* only BTREE databases will return anything in the key */
        if (!(key.flags & DB_DBT_REALLOC) && _DB_get_type(self->mydb) == DB_BTREE) {
            key.flags |= DB_DBT_MALLOC;
        }
    }
    MYDB_BEGIN_ALLOW_THREADS;
    err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET_RANGE);
    MYDB_END_ALLOW_THREADS;
    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
	    && self->mydb->moduleFlags.cursorSetReturnsNone) {
        Py_INCREF(Py_None);
        retval = Py_None;
    }
    else if (makeDBError(err)) {
        retval = NULL;
    }
    else {
        switch (_DB_get_type(self->mydb)) {
        case -1:
            retval = NULL;
            break;
        case DB_BTREE:
        case DB_HASH:
        default:
            retval = Py_BuildValue("y#y#", key.data, key.size,
                                   data.data, data.size);
            break;
        case DB_RECNO:
        case DB_QUEUE:
            retval = Py_BuildValue("iy#", *((db_recno_t*)key.data),
                                   data.data, data.size);
            break;
        }
        free_dbt(&key);
        free_dbt(&data);
    }
    /* the only time REALLOC should be set is if we used an integer
     * key that make_key_dbt malloc'd for us.  always free these. */
    if (key.flags & DB_DBT_REALLOC) {
        free_dbt(&key);
    }
    free_buf_view(keyobj, key_buf_view);

    return retval;
}

static PyObject*
_DBC_get_set_both(DBCursorObject* self, PyObject* keyobj, PyObject* dataobj,
                  int flags, unsigned int returnsNone)
{
    int err;
    DBT key, data;
    PyObject *retval;
    Py_buffer *data_buf_view = NULL;
    Py_buffer *key_buf_view = NULL;

    /* the caller did this:  CHECK_CURSOR_NOT_CLOSED(self); */
    if (!make_key_dbt(self->mydb, keyobj, &key, NULL, &key_buf_view))
        return NULL;
    if (!make_dbt(dataobj, &data, &data_buf_view)) {
        FREE_DBT_VIEW(key, keyobj, key_buf_view);
        return NULL;
    }

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_GET_BOTH);
    MYDB_END_ALLOW_THREADS;
    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && returnsNone) {
        Py_INCREF(Py_None);
        retval = Py_None;
    }
    else if (makeDBError(err)) {
        retval = NULL;
    }
    else {
        switch (_DB_get_type(self->mydb)) {
        case -1:
            retval = NULL;
            break;
        case DB_BTREE:
        case DB_HASH:
        default:
            retval = Py_BuildValue("y#y#", key.data, key.size,
                                   data.data, data.size);
            break;
        case DB_RECNO:
        case DB_QUEUE:
            retval = Py_BuildValue("iy#", *((db_recno_t*)key.data),
                                   data.data, data.size);
            break;
        }
    }

    FREE_DBT_VIEW(key, keyobj, key_buf_view);
    free_buf_view(dataobj, data_buf_view);
    return retval;
}

static PyObject*
DBC_get_both(DBCursorObject* self, PyObject* args)
{
    int flags=0;
    PyObject *keyobj, *dataobj;

    if (!PyArg_ParseTuple(args, "OO|i:get_both", &keyobj, &dataobj, &flags))
        return NULL;

    /* if the cursor is closed, self->mydb may be invalid */
    CHECK_CURSOR_NOT_CLOSED(self);

    return _DBC_get_set_both(self, keyobj, dataobj, flags,
                self->mydb->moduleFlags.getReturnsNone);
}

/* Return size of entry */
static PyObject*
DBC_get_current_size(DBCursorObject* self, PyObject* args)
{
    int err, flags=DB_CURRENT;
    PyObject* retval = NULL;
    DBT key, data;

    if (!PyArg_ParseTuple(args, ":get_current_size"))
        return NULL;
    CHECK_CURSOR_NOT_CLOSED(self);
    CLEAR_DBT(key);
    CLEAR_DBT(data);

    /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
       getting the record size. */
    data.flags = DB_DBT_USERMEM;
    data.ulen = 0;
    MYDB_BEGIN_ALLOW_THREADS;
    err = self->dbc->c_get(self->dbc, &key, &data, flags);
    MYDB_END_ALLOW_THREADS;
    if (err == DB_BUFFER_SMALL || !err) {
        /* DB_BUFFER_SMALL means positive size, !err means zero length value */
        retval = PyLong_FromLong((long)data.size);
        err = 0;
    }

    free_dbt(&key);
    free_dbt(&data);
    RETURN_IF_ERR();
    return retval;
}

static PyObject*
DBC_set_both(DBCursorObject* self, PyObject* args)
{
    int flags=0;
    PyObject *keyobj, *dataobj;

    if (!PyArg_ParseTuple(args, "OO|i:set_both", &keyobj, &dataobj, &flags))
        return NULL;

    /* if the cursor is closed, self->mydb may be invalid */
    CHECK_CURSOR_NOT_CLOSED(self);

    return _DBC_get_set_both(self, keyobj, dataobj, flags,
                self->mydb->moduleFlags.cursorSetReturnsNone);
}


static PyObject*
DBC_set_recno(DBCursorObject* self, PyObject* args, PyObject *kwargs)
{
    int err, irecno, flags=0;
    db_recno_t recno;
    DBT key, data;
    PyObject* retval;
    int dlen = -1;
    int doff = -1;
    static char* kwnames[] = { "recno","flags", "dlen", "doff", NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|iii:set_recno", kwnames,
				     &irecno, &flags, &dlen, &doff))
      return NULL;

    CHECK_CURSOR_NOT_CLOSED(self);

    CLEAR_DBT(key);
    recno = (db_recno_t) irecno;
    /* use allocated space so DB will be able to realloc room for the real
     * key */
    key.data = malloc(sizeof(db_recno_t));
    if (key.data == NULL) {
        PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
        return NULL;
    }
    key.size = sizeof(db_recno_t);
    key.ulen = key.size;
    memcpy(key.data, &recno, sizeof(db_recno_t));
    key.flags = DB_DBT_REALLOC;

    CLEAR_DBT(data);
    if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
        /* Tell BerkeleyDB to malloc the return value (thread safe) */
        data.flags = DB_DBT_MALLOC;
    }
    if (!add_partial_dbt(&data, dlen, doff)) {
        free_dbt(&key);
        return NULL;
    }

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET_RECNO);
    MYDB_END_ALLOW_THREADS;
    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
	    && self->mydb->moduleFlags.cursorSetReturnsNone) {
        Py_INCREF(Py_None);
        retval = Py_None;
    }
    else if (makeDBError(err)) {
        retval = NULL;
    }
    else {  /* Can only be used for BTrees, so no need to return int key */
        retval = Py_BuildValue("y#y#", key.data, key.size,
                               data.data, data.size);
        free_dbt(&data);
    }
    free_dbt(&key);

    return retval;
}


static PyObject*
DBC_consume(DBCursorObject* self, PyObject* args, PyObject *kwargs)
{
    return _DBCursor_get(self,DB_CONSUME,args,kwargs,"|iii:consume");
}


static PyObject*
DBC_next_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
{
    return _DBCursor_get(self,DB_NEXT_DUP,args,kwargs,"|iii:next_dup");
}


static PyObject*
DBC_next_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
{
    return _DBCursor_get(self,DB_NEXT_NODUP,args,kwargs,"|iii:next_nodup");
}


static PyObject*
DBC_prev_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
{
    return _DBCursor_get(self,DB_PREV_NODUP,args,kwargs,"|iii:prev_nodup");
}


static PyObject*
DBC_join_item(DBCursorObject* self, PyObject* args)
{
    int err, flags=0;
    DBT key, data;
    PyObject* retval;

    if (!PyArg_ParseTuple(args, "|i:join_item", &flags))
        return NULL;

    CHECK_CURSOR_NOT_CLOSED(self);

    CLEAR_DBT(key);
    CLEAR_DBT(data);
    if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
        /* Tell BerkeleyDB to malloc the return value (thread safe) */
        key.flags = DB_DBT_MALLOC;
    }

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->dbc->c_get(self->dbc, &key, &data, flags | DB_JOIN_ITEM);
    MYDB_END_ALLOW_THREADS;
    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
	    && self->mydb->moduleFlags.getReturnsNone) {
        Py_INCREF(Py_None);
        retval = Py_None;
    }
    else if (makeDBError(err)) {
        retval = NULL;
    }
    else {
        retval = Py_BuildValue("y#", key.data, key.size);
        free_dbt(&key);
    }

    return retval;
}



/* --------------------------------------------------------------------- */
/* DBEnv methods */


static PyObject*
DBEnv_close(DBEnvObject* self, PyObject* args)
{
    int err, flags = 0;

    if (!PyArg_ParseTuple(args, "|i:close", &flags))
        return NULL;
    if (!self->closed) {      /* Don't close more than once */
        MYDB_BEGIN_ALLOW_THREADS;
        err = self->db_env->close(self->db_env, flags);
        MYDB_END_ALLOW_THREADS;
        /* after calling DBEnv->close, regardless of error, this DBEnv
         * may not be accessed again (BerkeleyDB docs). */
        self->closed = 1;
        self->db_env = NULL;
        RETURN_IF_ERR();
    }
    RETURN_NONE();
}


static PyObject*
DBEnv_open(DBEnvObject* self, PyObject* args)
{
    int err, flags=0, mode=0660;
    char *db_home;

    if (!PyArg_ParseTuple(args, "z|ii:open", &db_home, &flags, &mode))
        return NULL;

    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->open(self->db_env, db_home, flags, mode);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    self->closed = 0;
    self->flags = flags;
    RETURN_NONE();
}


static PyObject*
DBEnv_remove(DBEnvObject* self, PyObject* args)
{
    int err, flags=0;
    char *db_home;

    if (!PyArg_ParseTuple(args, "s|i:remove", &db_home, &flags))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);
    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->remove(self->db_env, db_home, flags);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}

#if (DBVER >= 41)
static PyObject*
DBEnv_dbremove(DBEnvObject* self, PyObject* args, PyObject* kwargs)
{
    int err;
    u_int32_t flags=0;
    char *file = NULL;
    char *database = NULL;
    PyObject *txnobj = NULL;
    DB_TXN *txn = NULL;
    static char* kwnames[] = { "file", "database", "txn", "flags",
                                     NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zOi:dbremove", kwnames,
		&file, &database, &txnobj, &flags)) {
	return NULL;
    }
    if (!checkTxnObj(txnobj, &txn)) {
        return NULL;
    }
    CHECK_ENV_NOT_CLOSED(self);
    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->dbremove(self->db_env, txn, file, database, flags);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}

static PyObject*
DBEnv_dbrename(DBEnvObject* self, PyObject* args, PyObject* kwargs)
{
    int err;
    u_int32_t flags=0;
    char *file = NULL;
    char *database = NULL;
    char *newname = NULL;
    PyObject *txnobj = NULL;
    DB_TXN *txn = NULL;
    static char* kwnames[] = { "file", "database", "newname", "txn",
                                     "flags", NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "szs|Oi:dbrename", kwnames,
		&file, &database, &newname, &txnobj, &flags)) {
	return NULL;
    }
    if (!checkTxnObj(txnobj, &txn)) {
        return NULL;
    }
    CHECK_ENV_NOT_CLOSED(self);
    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->dbrename(self->db_env, txn, file, database, newname,
                                 flags);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}

static PyObject*
DBEnv_set_encrypt(DBEnvObject* self, PyObject* args, PyObject* kwargs)
{
    int err;
    u_int32_t flags=0;
    char *passwd = NULL;
    static char* kwnames[] = { "passwd", "flags", NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
		&passwd, &flags)) {
	return NULL;
    }

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->set_encrypt(self->db_env, passwd, flags);
    MYDB_END_ALLOW_THREADS;

    RETURN_IF_ERR();
    RETURN_NONE();
}
#endif /* DBVER >= 41 */

#if (DBVER >= 40)
static PyObject*
DBEnv_set_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
{
    int err;
    u_int32_t flags=0;
    u_int32_t timeout = 0;
    static char* kwnames[] = { "timeout", "flags", NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
		&timeout, &flags)) {
	return NULL;
    }

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->set_timeout(self->db_env, (db_timeout_t)timeout, flags);
    MYDB_END_ALLOW_THREADS;

    RETURN_IF_ERR();
    RETURN_NONE();
}
#endif /* DBVER >= 40 */

static PyObject*
DBEnv_set_shm_key(DBEnvObject* self, PyObject* args)
{
    int err;
    long shm_key = 0;

    if (!PyArg_ParseTuple(args, "l:set_shm_key", &shm_key))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    err = self->db_env->set_shm_key(self->db_env, shm_key);
    RETURN_IF_ERR();
    RETURN_NONE();
}

static PyObject*
DBEnv_set_cachesize(DBEnvObject* self, PyObject* args)
{
    int err, gbytes=0, bytes=0, ncache=0;

    if (!PyArg_ParseTuple(args, "ii|i:set_cachesize",
                          &gbytes, &bytes, &ncache))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->set_cachesize(self->db_env, gbytes, bytes, ncache);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DBEnv_set_flags(DBEnvObject* self, PyObject* args)
{
    int err, flags=0, onoff=0;

    if (!PyArg_ParseTuple(args, "ii:set_flags",
                          &flags, &onoff))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->set_flags(self->db_env, flags, onoff);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DBEnv_set_data_dir(DBEnvObject* self, PyObject* args)
{
    int err;
    char *dir;

    if (!PyArg_ParseTuple(args, "s:set_data_dir", &dir))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->set_data_dir(self->db_env, dir);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DBEnv_set_lg_bsize(DBEnvObject* self, PyObject* args)
{
    int err, lg_bsize;

    if (!PyArg_ParseTuple(args, "i:set_lg_bsize", &lg_bsize))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->set_lg_bsize(self->db_env, lg_bsize);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DBEnv_set_lg_dir(DBEnvObject* self, PyObject* args)
{
    int err;
    char *dir;

    if (!PyArg_ParseTuple(args, "s:set_lg_dir", &dir))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->set_lg_dir(self->db_env, dir);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}

static PyObject*
DBEnv_set_lg_max(DBEnvObject* self, PyObject* args)
{
    int err, lg_max;

    if (!PyArg_ParseTuple(args, "i:set_lg_max", &lg_max))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->set_lg_max(self->db_env, lg_max);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


#if (DBVER >= 33)
static PyObject*
DBEnv_set_lg_regionmax(DBEnvObject* self, PyObject* args)
{
    int err, lg_max;

    if (!PyArg_ParseTuple(args, "i:set_lg_regionmax", &lg_max))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->set_lg_regionmax(self->db_env, lg_max);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}
#endif


static PyObject*
DBEnv_set_lk_detect(DBEnvObject* self, PyObject* args)
{
    int err, lk_detect;

    if (!PyArg_ParseTuple(args, "i:set_lk_detect", &lk_detect))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->set_lk_detect(self->db_env, lk_detect);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


#if (DBVER < 45)
static PyObject*
DBEnv_set_lk_max(DBEnvObject* self, PyObject* args)
{
    int err, max;

    if (!PyArg_ParseTuple(args, "i:set_lk_max", &max))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->set_lk_max(self->db_env, max);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}
#endif



static PyObject*
DBEnv_set_lk_max_locks(DBEnvObject* self, PyObject* args)
{
    int err, max;

    if (!PyArg_ParseTuple(args, "i:set_lk_max_locks", &max))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->set_lk_max_locks(self->db_env, max);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DBEnv_set_lk_max_lockers(DBEnvObject* self, PyObject* args)
{
    int err, max;

    if (!PyArg_ParseTuple(args, "i:set_lk_max_lockers", &max))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->set_lk_max_lockers(self->db_env, max);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DBEnv_set_lk_max_objects(DBEnvObject* self, PyObject* args)
{
    int err, max;

    if (!PyArg_ParseTuple(args, "i:set_lk_max_objects", &max))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->set_lk_max_objects(self->db_env, max);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DBEnv_set_mp_mmapsize(DBEnvObject* self, PyObject* args)
{
    int err, mp_mmapsize;

    if (!PyArg_ParseTuple(args, "i:set_mp_mmapsize", &mp_mmapsize))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->set_mp_mmapsize(self->db_env, mp_mmapsize);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DBEnv_set_tmp_dir(DBEnvObject* self, PyObject* args)
{
    int err;
    char *dir;

    if (!PyArg_ParseTuple(args, "s:set_tmp_dir", &dir))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->set_tmp_dir(self->db_env, dir);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DBEnv_txn_begin(DBEnvObject* self, PyObject* args, PyObject* kwargs)
{
    int flags = 0;
    PyObject* txnobj = NULL;
    DB_TXN *txn = NULL;
    static char* kwnames[] = { "parent", "flags", NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:txn_begin", kwnames,
                                     &txnobj, &flags))
        return NULL;

    if (!checkTxnObj(txnobj, &txn))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    return (PyObject*)newDBTxnObject(self, txn, flags);
}


static PyObject*
DBEnv_txn_checkpoint(DBEnvObject* self, PyObject* args)
{
    int err, kbyte=0, min=0, flags=0;

    if (!PyArg_ParseTuple(args, "|iii:txn_checkpoint", &kbyte, &min, &flags))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
    err = self->db_env->txn_checkpoint(self->db_env, kbyte, min, flags);
#else
    err = txn_checkpoint(self->db_env, kbyte, min, flags);
#endif
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DBEnv_set_tx_max(DBEnvObject* self, PyObject* args)
{
    int err, max;

    if (!PyArg_ParseTuple(args, "i:set_tx_max", &max))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    err = self->db_env->set_tx_max(self->db_env, max);
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DBEnv_set_tx_timestamp(DBEnvObject* self, PyObject* args)
{
    int err;
    long stamp;
    time_t timestamp;

    if (!PyArg_ParseTuple(args, "l:set_tx_timestamp", &stamp))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);
    timestamp = (time_t)stamp;
    err = self->db_env->set_tx_timestamp(self->db_env, &timestamp);
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DBEnv_lock_detect(DBEnvObject* self, PyObject* args)
{
    int err, atype, flags=0;
    int aborted = 0;

    if (!PyArg_ParseTuple(args, "i|i:lock_detect", &atype, &flags))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
    err = self->db_env->lock_detect(self->db_env, flags, atype, &aborted);
#else
    err = lock_detect(self->db_env, flags, atype, &aborted);
#endif
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    return PyLong_FromLong(aborted);
}


static PyObject*
DBEnv_lock_get(DBEnvObject* self, PyObject* args)
{
    int flags=0;
    int locker, lock_mode;
    DBT obj;
    PyObject *objobj, *retval;
    Py_buffer *obj_buf_view = NULL;

    if (!PyArg_ParseTuple(args, "iOi|i:lock_get", &locker, &objobj, &lock_mode, &flags))
        return NULL;

    if (!make_dbt(objobj, &obj, &obj_buf_view))
        return NULL;

    retval = (PyObject*)newDBLockObject(self, locker, &obj, lock_mode, flags);
    free_buf_view(objobj, obj_buf_view);
    return retval;
}


static PyObject*
DBEnv_lock_id(DBEnvObject* self, PyObject* args)
{
    int err;
    u_int32_t theID;

    if (!PyArg_ParseTuple(args, ":lock_id"))
        return NULL;

    CHECK_ENV_NOT_CLOSED(self);
    MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
    err = self->db_env->lock_id(self->db_env, &theID);
#else
    err = lock_id(self->db_env, &theID);
#endif
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();

    return PyLong_FromLong((long)theID);
}

#if (DBVER >= 40)
static PyObject*
DBEnv_lock_id_free(DBEnvObject* self, PyObject* args)
{
    int err;
    u_int32_t theID;

    if (!PyArg_ParseTuple(args, "I:lock_id_free", &theID))
        return NULL;

    CHECK_ENV_NOT_CLOSED(self);
    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->lock_id_free(self->db_env, theID);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}
#endif

static PyObject*
DBEnv_lock_put(DBEnvObject* self, PyObject* args)
{
    int err;
    DBLockObject* dblockobj;

    if (!PyArg_ParseTuple(args, "O!:lock_put", &DBLock_Type, &dblockobj))
        return NULL;

    CHECK_ENV_NOT_CLOSED(self);
    MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
    err = self->db_env->lock_put(self->db_env, &dblockobj->lock);
#else
    err = lock_put(self->db_env, &dblockobj->lock);
#endif
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}

#if (DBVER >= 44)
static PyObject*
DBEnv_lsn_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
{
    int err;
    char *file;
    u_int32_t flags = 0;
    static char* kwnames[] = { "file", "flags", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:lsn_reset", kwnames,
                                     &file, &flags))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->lsn_reset(self->db_env, file, flags);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}
#endif /* DBVER >= 4.4 */

#if (DBVER >= 40)
static PyObject*
DBEnv_log_stat(DBEnvObject* self, PyObject* args)
{
    int err;
    DB_LOG_STAT* statp = NULL;
    PyObject* d = NULL;
    u_int32_t flags = 0;

    if (!PyArg_ParseTuple(args, "|i:log_stat", &flags))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->db_env->log_stat(self->db_env, &statp, flags);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();

    /* Turn the stat structure into a dictionary */
    d = PyDict_New();
    if (d == NULL) {
        if (statp)
            free(statp);
        return NULL;
    }

#define MAKE_ENTRY(name)  _addIntToDict(d, #name, statp->st_##name)

    MAKE_ENTRY(magic);
    MAKE_ENTRY(version);
    MAKE_ENTRY(mode);
    MAKE_ENTRY(lg_bsize);
#if (DBVER >= 44)
    MAKE_ENTRY(lg_size);
    MAKE_ENTRY(record);
#endif
#if (DBVER <= 40)
    MAKE_ENTRY(lg_max);
#endif
    MAKE_ENTRY(w_mbytes);
    MAKE_ENTRY(w_bytes);
    MAKE_ENTRY(wc_mbytes);
    MAKE_ENTRY(wc_bytes);
    MAKE_ENTRY(wcount);
    MAKE_ENTRY(wcount_fill);
#if (DBVER >= 44)
    MAKE_ENTRY(rcount);
#endif
    MAKE_ENTRY(scount);
    MAKE_ENTRY(cur_file);
    MAKE_ENTRY(cur_offset);
    MAKE_ENTRY(disk_file);
    MAKE_ENTRY(disk_offset);
    MAKE_ENTRY(maxcommitperflush);
    MAKE_ENTRY(mincommitperflush);
    MAKE_ENTRY(regsize);
    MAKE_ENTRY(region_wait);
    MAKE_ENTRY(region_nowait);

#undef MAKE_ENTRY
    free(statp);
    return d;
} /* DBEnv_log_stat */
#endif /* DBVER >= 4.0 for log_stat method */


static PyObject*
DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
{
    int err;
    DB_LOCK_STAT* sp;
    PyObject* d = NULL;
    u_int32_t flags = 0;

    if (!PyArg_ParseTuple(args, "|i:lock_stat", &flags))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
    err = self->db_env->lock_stat(self->db_env, &sp, flags);
#else
#if (DBVER >= 33)
    err = lock_stat(self->db_env, &sp);
#else
    err = lock_stat(self->db_env, &sp, NULL);
#endif
#endif
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();

    /* Turn the stat structure into a dictionary */
    d = PyDict_New();
    if (d == NULL) {
        free(sp);
        return NULL;
    }

#define MAKE_ENTRY(name)  _addIntToDict(d, #name, sp->st_##name)

#if (DBVER < 41)
    MAKE_ENTRY(lastid);
#endif
    MAKE_ENTRY(nmodes);
    MAKE_ENTRY(maxlocks);
    MAKE_ENTRY(maxlockers);
    MAKE_ENTRY(maxobjects);
    MAKE_ENTRY(nlocks);
    MAKE_ENTRY(maxnlocks);
    MAKE_ENTRY(nlockers);
    MAKE_ENTRY(maxnlockers);
    MAKE_ENTRY(nobjects);
    MAKE_ENTRY(maxnobjects);
    MAKE_ENTRY(nrequests);
    MAKE_ENTRY(nreleases);
#if (DBVER < 44)
    MAKE_ENTRY(nnowaits);       /* these were renamed in 4.4 */
    MAKE_ENTRY(nconflicts);
#else
    MAKE_ENTRY(lock_nowait);
    MAKE_ENTRY(lock_wait);
#endif
    MAKE_ENTRY(ndeadlocks);
    MAKE_ENTRY(regsize);
    MAKE_ENTRY(region_wait);
    MAKE_ENTRY(region_nowait);

#undef MAKE_ENTRY
    free(sp);
    return d;
}


static PyObject*
DBEnv_log_archive(DBEnvObject* self, PyObject* args)
{
    int flags=0;
    int err;
    char **log_list = NULL;
    PyObject* list;
    PyObject* item = NULL;

    if (!PyArg_ParseTuple(args, "|i:log_archive", &flags))
        return NULL;

    CHECK_ENV_NOT_CLOSED(self);
    MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
    err = self->db_env->log_archive(self->db_env, &log_list, flags);
#elif (DBVER == 33)
    err = log_archive(self->db_env, &log_list, flags);
#else
    err = log_archive(self->db_env, &log_list, flags, NULL);
#endif
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();

    list = PyList_New(0);
    if (list == NULL) {
        if (log_list)
            free(log_list);
        return NULL;
    }

    if (log_list) {
        char **log_list_start;
        for (log_list_start = log_list; *log_list != NULL; ++log_list) {
            item = PyUnicode_FromString (*log_list);
            if (item == NULL) {
                Py_DECREF(list);
                list = NULL;
                break;
            }
            PyList_Append(list, item);
            Py_DECREF(item);
        }
        free(log_list_start);
    }
    return list;
}


static PyObject*
DBEnv_txn_stat(DBEnvObject* self, PyObject* args)
{
    int err;
    DB_TXN_STAT* sp;
    PyObject* d = NULL;
    u_int32_t flags=0;

    if (!PyArg_ParseTuple(args, "|i:txn_stat", &flags))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
    err = self->db_env->txn_stat(self->db_env, &sp, flags);
#elif (DBVER == 33)
    err = txn_stat(self->db_env, &sp);
#else
    err = txn_stat(self->db_env, &sp, NULL);
#endif
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();

    /* Turn the stat structure into a dictionary */
    d = PyDict_New();
    if (d == NULL) {
        free(sp);
        return NULL;
    }

#define MAKE_ENTRY(name)  _addIntToDict(d, #name, sp->st_##name)
#define MAKE_TIME_T_ENTRY(name)_addTimeTToDict(d, #name, sp->st_##name)

    MAKE_TIME_T_ENTRY(time_ckp);
    MAKE_ENTRY(last_txnid);
    MAKE_ENTRY(maxtxns);
    MAKE_ENTRY(nactive);
    MAKE_ENTRY(maxnactive);
    MAKE_ENTRY(nbegins);
    MAKE_ENTRY(naborts);
    MAKE_ENTRY(ncommits);
    MAKE_ENTRY(regsize);
    MAKE_ENTRY(region_wait);
    MAKE_ENTRY(region_nowait);

#undef MAKE_ENTRY
#undef MAKE_TIME_T_ENTRY
    free(sp);
    return d;
}


static PyObject*
DBEnv_set_get_returns_none(DBEnvObject* self, PyObject* args)
{
    int flags=0;
    int oldValue=0;

    if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
        return NULL;
    CHECK_ENV_NOT_CLOSED(self);

    if (self->moduleFlags.getReturnsNone)
        ++oldValue;
    if (self->moduleFlags.cursorSetReturnsNone)
        ++oldValue;
    self->moduleFlags.getReturnsNone = (flags >= 1);
    self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
    return PyLong_FromLong(oldValue);
}


/* --------------------------------------------------------------------- */
/* DBTxn methods */


static PyObject*
DBTxn_commit(DBTxnObject* self, PyObject* args)
{
    int flags=0, err;
    DB_TXN *txn;

    if (!PyArg_ParseTuple(args, "|i:commit", &flags))
        return NULL;

    if (!self->txn) {
        PyObject *t =  Py_BuildValue("(is)", 0, "DBTxn must not be used "
                                     "after txn_commit or txn_abort");
        PyErr_SetObject(DBError, t);
        Py_DECREF(t);
        return NULL;
    }
    txn = self->txn;
    self->txn = NULL;   /* this DB_TXN is no longer valid after this call */
    MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
    err = txn->commit(txn, flags);
#else
    err = txn_commit(txn, flags);
#endif
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}

static PyObject*
DBTxn_prepare(DBTxnObject* self, PyObject* args)
{
#if (DBVER >= 33)
    int err;
    char* gid=NULL;
    int   gid_size=0;

    if (!PyArg_ParseTuple(args, "y#:prepare", &gid, &gid_size))
        return NULL;

    if (gid_size != DB_XIDDATASIZE) {
        PyErr_SetString(PyExc_TypeError,
                        "gid must be DB_XIDDATASIZE bytes long");
        return NULL;
    }

    if (!self->txn) {
        PyObject *t = Py_BuildValue("(is)", 0,"DBTxn must not be used "
                                    "after txn_commit or txn_abort");
        PyErr_SetObject(DBError, t);
        Py_DECREF(t);
        return NULL;
    }
    MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
    err = self->txn->prepare(self->txn, (u_int8_t*)gid);
#else
    err = txn_prepare(self->txn, (u_int8_t*)gid);
#endif
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
#else
    int err;

    if (!PyArg_ParseTuple(args, ":prepare"))
        return NULL;

    if (!self->txn) {
        PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
                                    "after txn_commit or txn_abort");
        PyErr_SetObject(DBError, t);
        Py_DECREF(t);
        return NULL;
    }
    MYDB_BEGIN_ALLOW_THREADS;
    err = txn_prepare(self->txn);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
#endif
}


static PyObject*
DBTxn_abort(DBTxnObject* self, PyObject* args)
{
    int err;
    DB_TXN *txn;

    if (!PyArg_ParseTuple(args, ":abort"))
        return NULL;

    if (!self->txn) {
        PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
                                    "after txn_commit or txn_abort");
        PyErr_SetObject(DBError, t);
        Py_DECREF(t);
        return NULL;
    }
    txn = self->txn;
    self->txn = NULL;   /* this DB_TXN is no longer valid after this call */
    MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
    err = txn->abort(txn);
#else
    err = txn_abort(txn);
#endif
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();
    RETURN_NONE();
}


static PyObject*
DBTxn_id(DBTxnObject* self, PyObject* args)
{
    int id;

    if (!PyArg_ParseTuple(args, ":id"))
        return NULL;

    if (!self->txn) {
        PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
                                    "after txn_commit or txn_abort");
        PyErr_SetObject(DBError, t);
        Py_DECREF(t);
        return NULL;
    }
    MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
    id = self->txn->id(self->txn);
#else
    id = txn_id(self->txn);
#endif
    MYDB_END_ALLOW_THREADS;
    return PyLong_FromLong(id);
}

#if (DBVER >= 43)
/* --------------------------------------------------------------------- */
/* DBSequence methods */


static PyObject*
DBSequence_close(DBSequenceObject* self, PyObject* args)
{
    int err, flags=0;
    if (!PyArg_ParseTuple(args,"|i:close", &flags))
        return NULL;
    CHECK_SEQUENCE_NOT_CLOSED(self)

    MYDB_BEGIN_ALLOW_THREADS
    err = self->sequence->close(self->sequence, flags);
    self->sequence = NULL;
    MYDB_END_ALLOW_THREADS

    RETURN_IF_ERR();

    RETURN_NONE();
}

static PyObject*
DBSequence_get(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
{
    int err, flags = 0;
    int delta = 1;
    db_seq_t value;
    PyObject *txnobj = NULL;
    DB_TXN *txn = NULL;
    static char* kwnames[] = {"delta", "txn", "flags", NULL };
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iOi:get", kwnames, &delta, &txnobj, &flags))
        return NULL;
    CHECK_SEQUENCE_NOT_CLOSED(self)

    if (!checkTxnObj(txnobj, &txn))
        return NULL;

    MYDB_BEGIN_ALLOW_THREADS
    err = self->sequence->get(self->sequence, txn, delta, &value, flags);
    MYDB_END_ALLOW_THREADS

    RETURN_IF_ERR();
    return PyLong_FromLongLong(value);

}

static PyObject*
DBSequence_get_dbp(DBSequenceObject* self, PyObject* args)
{
    if (!PyArg_ParseTuple(args,":get_dbp"))
        return NULL;
    CHECK_SEQUENCE_NOT_CLOSED(self)
    Py_INCREF(self->mydb);
    return (PyObject* )self->mydb;
}

static PyObject*
DBSequence_get_key(DBSequenceObject* self, PyObject* args)
{
    int err;
    DBT key;
    PyObject *retval = NULL;
    key.flags = DB_DBT_MALLOC;
    CHECK_SEQUENCE_NOT_CLOSED(self)
    MYDB_BEGIN_ALLOW_THREADS
    err = self->sequence->get_key(self->sequence, &key);
    MYDB_END_ALLOW_THREADS

    if (!err)
        retval = PyBytes_FromStringAndSize(key.data, key.size);

    free_dbt(&key);
    RETURN_IF_ERR();

    return retval;
}

static PyObject*
DBSequence_init_value(DBSequenceObject* self, PyObject* args)
{
    int err;
    db_seq_t value;
    if (!PyArg_ParseTuple(args,"L:init_value", &value))
        return NULL;
    CHECK_SEQUENCE_NOT_CLOSED(self)

    MYDB_BEGIN_ALLOW_THREADS
    err = self->sequence->initial_value(self->sequence, value);
    MYDB_END_ALLOW_THREADS

    RETURN_IF_ERR();

    RETURN_NONE();
}

static PyObject*
DBSequence_open(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
{
    int err, flags = 0;
    PyObject *keyobj;
    Py_buffer *key_buf_view = NULL;
    PyObject *txnobj = NULL;
    DB_TXN *txn = NULL;
    DBT key;

    static char* kwnames[] = {"key", "txn", "flags", NULL };
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:open", kwnames, &keyobj, &txnobj, &flags))
        return NULL;

    if (!checkTxnObj(txnobj, &txn))
        return NULL;

    if (!make_key_dbt(self->mydb, keyobj, &key, NULL, &key_buf_view))
        return NULL;

    MYDB_BEGIN_ALLOW_THREADS
    err = self->sequence->open(self->sequence, txn, &key, flags);
    MYDB_END_ALLOW_THREADS

    FREE_DBT_VIEW(key, keyobj, key_buf_view);
    RETURN_IF_ERR();

    RETURN_NONE();
}

static PyObject*
DBSequence_remove(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
{
    int err, flags = 0;
    PyObject *txnobj = NULL;
    DB_TXN *txn = NULL;

    static char* kwnames[] = {"txn", "flags", NULL };
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:remove", kwnames, &txnobj, &flags))
        return NULL;

    if (!checkTxnObj(txnobj, &txn))
        return NULL;

    CHECK_SEQUENCE_NOT_CLOSED(self)

    MYDB_BEGIN_ALLOW_THREADS
    err = self->sequence->remove(self->sequence, txn, flags);
    MYDB_END_ALLOW_THREADS

    RETURN_IF_ERR();
    RETURN_NONE();
}

static PyObject*
DBSequence_set_cachesize(DBSequenceObject* self, PyObject* args)
{
    int err, size;
    if (!PyArg_ParseTuple(args,"i:set_cachesize", &size))
        return NULL;
    CHECK_SEQUENCE_NOT_CLOSED(self)

    MYDB_BEGIN_ALLOW_THREADS
    err = self->sequence->set_cachesize(self->sequence, size);
    MYDB_END_ALLOW_THREADS

    RETURN_IF_ERR();
    RETURN_NONE();
}

static PyObject*
DBSequence_get_cachesize(DBSequenceObject* self, PyObject* args)
{
    int err, size;
    if (!PyArg_ParseTuple(args,":get_cachesize"))
        return NULL;
    CHECK_SEQUENCE_NOT_CLOSED(self)

    MYDB_BEGIN_ALLOW_THREADS
    err = self->sequence->get_cachesize(self->sequence, &size);
    MYDB_END_ALLOW_THREADS

    RETURN_IF_ERR();
    return PyLong_FromLong(size);
}

static PyObject*
DBSequence_set_flags(DBSequenceObject* self, PyObject* args)
{
    int err, flags = 0;
    if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
        return NULL;
    CHECK_SEQUENCE_NOT_CLOSED(self)

    MYDB_BEGIN_ALLOW_THREADS
    err = self->sequence->set_flags(self->sequence, flags);
    MYDB_END_ALLOW_THREADS

    RETURN_IF_ERR();
    RETURN_NONE();

}

static PyObject*
DBSequence_get_flags(DBSequenceObject* self, PyObject* args)
{
    unsigned int flags;
    int err;
    if (!PyArg_ParseTuple(args,":get_flags"))
        return NULL;
    CHECK_SEQUENCE_NOT_CLOSED(self)

    MYDB_BEGIN_ALLOW_THREADS
    err = self->sequence->get_flags(self->sequence, &flags);
    MYDB_END_ALLOW_THREADS

    RETURN_IF_ERR();
    return PyLong_FromLong((int)flags);
}

static PyObject*
DBSequence_set_range(DBSequenceObject* self, PyObject* args)
{
    int err;
    db_seq_t min, max;
    if (!PyArg_ParseTuple(args,"(LL):set_range", &min, &max))
        return NULL;
    CHECK_SEQUENCE_NOT_CLOSED(self)

    MYDB_BEGIN_ALLOW_THREADS
    err = self->sequence->set_range(self->sequence, min, max);
    MYDB_END_ALLOW_THREADS

    RETURN_IF_ERR();
    RETURN_NONE();
}

static PyObject*
DBSequence_get_range(DBSequenceObject* self, PyObject* args)
{
    int err;
    db_seq_t min, max;
    if (!PyArg_ParseTuple(args,":get_range"))
        return NULL;
    CHECK_SEQUENCE_NOT_CLOSED(self)

    MYDB_BEGIN_ALLOW_THREADS
    err = self->sequence->get_range(self->sequence, &min, &max);
    MYDB_END_ALLOW_THREADS

    RETURN_IF_ERR();
    return Py_BuildValue("(LL)", min, max);
}

static PyObject*
DBSequence_stat(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
{
    int err, flags = 0;
    DB_SEQUENCE_STAT* sp = NULL;
    PyObject* dict_stat;
    static char* kwnames[] = {"flags", NULL };
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat", kwnames, &flags))
        return NULL;
    CHECK_SEQUENCE_NOT_CLOSED(self);

    MYDB_BEGIN_ALLOW_THREADS;
    err = self->sequence->stat(self->sequence, &sp, flags);
    MYDB_END_ALLOW_THREADS;
    RETURN_IF_ERR();

    if ((dict_stat = PyDict_New()) == NULL) {
        free(sp);
        return NULL;
    }


#define MAKE_INT_ENTRY(name)  _addIntToDict(dict_stat, #name, sp->st_##name)
#define MAKE_LONG_LONG_ENTRY(name)  _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)

    MAKE_INT_ENTRY(wait);
    MAKE_INT_ENTRY(nowait);
    MAKE_LONG_LONG_ENTRY(current);
    MAKE_LONG_LONG_ENTRY(value);
    MAKE_LONG_LONG_ENTRY(last_value);
    MAKE_LONG_LONG_ENTRY(min);
    MAKE_LONG_LONG_ENTRY(max);
    MAKE_INT_ENTRY(cache_size);
    MAKE_INT_ENTRY(flags);

#undef MAKE_INT_ENTRY
#undef MAKE_LONG_LONG_ENTRY

    free(sp);
    return dict_stat;
}
#endif


/* --------------------------------------------------------------------- */
/* Method definition tables and type objects */

static PyMethodDef DB_methods[] = {
    {"append",          (PyCFunction)DB_append,         METH_VARARGS},
#if (DBVER >= 33)
    {"associate",       (PyCFunction)DB_associate,      METH_VARARGS|METH_KEYWORDS},
#endif
    {"close",           (PyCFunction)DB_close,          METH_VARARGS},
    {"consume",         (PyCFunction)DB_consume,        METH_VARARGS|METH_KEYWORDS},
    {"consume_wait",    (PyCFunction)DB_consume_wait,   METH_VARARGS|METH_KEYWORDS},
    {"cursor",          (PyCFunction)DB_cursor,         METH_VARARGS|METH_KEYWORDS},
    {"delete",          (PyCFunction)DB_delete,         METH_VARARGS|METH_KEYWORDS},
    {"fd",              (PyCFunction)DB_fd,             METH_VARARGS},
    {"get",             (PyCFunction)DB_get,            METH_VARARGS|METH_KEYWORDS},
#if (DBVER >= 33)
    {"pget",            (PyCFunction)DB_pget,           METH_VARARGS|METH_KEYWORDS},
#endif
    {"get_both",        (PyCFunction)DB_get_both,       METH_VARARGS|METH_KEYWORDS},
    {"get_byteswapped", (PyCFunction)DB_get_byteswapped,METH_VARARGS},
    {"get_size",        (PyCFunction)DB_get_size,       METH_VARARGS|METH_KEYWORDS},
    {"get_type",        (PyCFunction)DB_get_type,       METH_VARARGS},
    {"join",            (PyCFunction)DB_join,           METH_VARARGS},
    {"key_range",       (PyCFunction)DB_key_range,      METH_VARARGS|METH_KEYWORDS},
    {"has_key",         (PyCFunction)DB_has_key,        METH_VARARGS},
    {"items",           (PyCFunction)DB_items,          METH_VARARGS},
    {"keys",            (PyCFunction)DB_keys,           METH_VARARGS},
    {"open",            (PyCFunction)DB_open,           METH_VARARGS|METH_KEYWORDS},
    {"put",             (PyCFunction)DB_put,            METH_VARARGS|METH_KEYWORDS},
    {"remove",          (PyCFunction)DB_remove,         METH_VARARGS|METH_KEYWORDS},
    {"rename",          (PyCFunction)DB_rename,         METH_VARARGS},
    {"set_bt_minkey",   (PyCFunction)DB_set_bt_minkey,  METH_VARARGS},
#if (DBVER >= 33)
    {"set_bt_compare",  (PyCFunction)DB_set_bt_compare, METH_VARARGS},
#endif
    {"set_cachesize",   (PyCFunction)DB_set_cachesize,  METH_VARARGS},
#if (DBVER >= 41)
    {"set_encrypt",     (PyCFunction)DB_set_encrypt,    METH_VARARGS|METH_KEYWORDS},
#endif
    {"set_flags",       (PyCFunction)DB_set_flags,      METH_VARARGS},
    {"set_h_ffactor",   (PyCFunction)DB_set_h_ffactor,  METH_VARARGS},
    {"set_h_nelem",     (PyCFunction)DB_set_h_nelem,    METH_VARARGS},
    {"set_lorder",      (PyCFunction)DB_set_lorder,     METH_VARARGS},
    {"set_pagesize",    (PyCFunction)DB_set_pagesize,   METH_VARARGS},
    {"set_re_delim",    (PyCFunction)DB_set_re_delim,   METH_VARARGS},
    {"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},
    {"set_q_extentsize",(PyCFunction)DB_set_q_extentsize,METH_VARARGS},
    {"stat",            (PyCFunction)DB_stat,           METH_VARARGS|METH_KEYWORDS},
    {"sync",            (PyCFunction)DB_sync,           METH_VARARGS},
#if (DBVER >= 33)
    {"truncate",        (PyCFunction)DB_truncate,       METH_VARARGS|METH_KEYWORDS},
#endif
    {"type",            (PyCFunction)DB_get_type,       METH_VARARGS},
    {"upgrade",         (PyCFunction)DB_upgrade,        METH_VARARGS},
    {"values",          (PyCFunction)DB_values,         METH_VARARGS},
    {"verify",          (PyCFunction)DB_verify,         METH_VARARGS|METH_KEYWORDS},
    {"set_get_returns_none",(PyCFunction)DB_set_get_returns_none,      METH_VARARGS},
    {NULL,      NULL}       /* sentinel */
};


static PyMappingMethods DB_mapping = {
        DB_length,                   /*mp_length*/
        (binaryfunc)DB_subscript,    /*mp_subscript*/
        (objobjargproc)DB_ass_sub,   /*mp_ass_subscript*/
};


static PyMethodDef DBCursor_methods[] = {
    {"close",           (PyCFunction)DBC_close,         METH_VARARGS},
    {"count",           (PyCFunction)DBC_count,         METH_VARARGS},
    {"current",         (PyCFunction)DBC_current,       METH_VARARGS|METH_KEYWORDS},
    {"delete",          (PyCFunction)DBC_delete,        METH_VARARGS},
    {"dup",             (PyCFunction)DBC_dup,           METH_VARARGS},
    {"first",           (PyCFunction)DBC_first,         METH_VARARGS|METH_KEYWORDS},
    {"get",             (PyCFunction)DBC_get,           METH_VARARGS|METH_KEYWORDS},
#if (DBVER >= 33)
    {"pget",            (PyCFunction)DBC_pget,          METH_VARARGS|METH_KEYWORDS},
#endif
    {"get_recno",       (PyCFunction)DBC_get_recno,     METH_VARARGS},
    {"last",            (PyCFunction)DBC_last,          METH_VARARGS|METH_KEYWORDS},
    {"next",            (PyCFunction)DBC_next,          METH_VARARGS|METH_KEYWORDS},
    {"prev",            (PyCFunction)DBC_prev,          METH_VARARGS|METH_KEYWORDS},
    {"put",             (PyCFunction)DBC_put,           METH_VARARGS|METH_KEYWORDS},
    {"set",             (PyCFunction)DBC_set,           METH_VARARGS|METH_KEYWORDS},
    {"set_range",       (PyCFunction)DBC_set_range,     METH_VARARGS|METH_KEYWORDS},
    {"get_both",        (PyCFunction)DBC_get_both,      METH_VARARGS},
    {"get_current_size",(PyCFunction)DBC_get_current_size, METH_VARARGS},
    {"set_both",        (PyCFunction)DBC_set_both,      METH_VARARGS},
    {"set_recno",       (PyCFunction)DBC_set_recno,     METH_VARARGS|METH_KEYWORDS},
    {"consume",         (PyCFunction)DBC_consume,       METH_VARARGS|METH_KEYWORDS},
    {"next_dup",        (PyCFunction)DBC_next_dup,      METH_VARARGS|METH_KEYWORDS},
    {"next_nodup",      (PyCFunction)DBC_next_nodup,    METH_VARARGS|METH_KEYWORDS},
    {"prev_nodup",      (PyCFunction)DBC_prev_nodup,    METH_VARARGS|METH_KEYWORDS},
    {"join_item",       (PyCFunction)DBC_join_item,     METH_VARARGS},
    {NULL,      NULL}       /* sentinel */
};


static PyMethodDef DBEnv_methods[] = {
    {"close",           (PyCFunction)DBEnv_close,            METH_VARARGS},
    {"open",            (PyCFunction)DBEnv_open,             METH_VARARGS},
    {"remove",          (PyCFunction)DBEnv_remove,           METH_VARARGS},
#if (DBVER >= 41)
    {"dbremove",        (PyCFunction)DBEnv_dbremove,         METH_VARARGS|METH_KEYWORDS},
    {"dbrename",        (PyCFunction)DBEnv_dbrename,         METH_VARARGS|METH_KEYWORDS},
    {"set_encrypt",     (PyCFunction)DBEnv_set_encrypt,      METH_VARARGS|METH_KEYWORDS},
#endif
#if (DBVER >= 40)
    {"set_timeout",     (PyCFunction)DBEnv_set_timeout,      METH_VARARGS|METH_KEYWORDS},
#endif
    {"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},
    {"set_flags",       (PyCFunction)DBEnv_set_flags,        METH_VARARGS},
    {"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},
#if (DBVER >= 33)
    {"set_lg_regionmax",(PyCFunction)DBEnv_set_lg_regionmax, METH_VARARGS},
#endif
    {"set_lk_detect",   (PyCFunction)DBEnv_set_lk_detect,    METH_VARARGS},
#if (DBVER < 45)
    {"set_lk_max",      (PyCFunction)DBEnv_set_lk_max,       METH_VARARGS},
#endif
    {"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},
    {"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},
    {"txn_checkpoint",  (PyCFunction)DBEnv_txn_checkpoint,   METH_VARARGS},
    {"txn_stat",        (PyCFunction)DBEnv_txn_stat,         METH_VARARGS},
    {"set_tx_max",      (PyCFunction)DBEnv_set_tx_max,       METH_VARARGS},
    {"set_tx_timestamp", (PyCFunction)DBEnv_set_tx_timestamp, METH_VARARGS},
    {"lock_detect",     (PyCFunction)DBEnv_lock_detect,      METH_VARARGS},
    {"lock_get",        (PyCFunction)DBEnv_lock_get,         METH_VARARGS},
    {"lock_id",         (PyCFunction)DBEnv_lock_id,          METH_VARARGS},
#if (DBVER >= 40)
    {"lock_id_free",    (PyCFunction)DBEnv_lock_id_free,     METH_VARARGS},
#endif
    {"lock_put",        (PyCFunction)DBEnv_lock_put,         METH_VARARGS},
    {"lock_stat",       (PyCFunction)DBEnv_lock_stat,        METH_VARARGS},
    {"log_archive",     (PyCFunction)DBEnv_log_archive,      METH_VARARGS},
#if (DBVER >= 40)
    {"log_stat",        (PyCFunction)DBEnv_log_stat,         METH_VARARGS},
#endif
#if (DBVER >= 44)
    {"lsn_reset",       (PyCFunction)DBEnv_lsn_reset,        METH_VARARGS|METH_KEYWORDS},
#endif
    {"set_get_returns_none",(PyCFunction)DBEnv_set_get_returns_none, METH_VARARGS},
    {NULL,      NULL}       /* sentinel */
};


static PyMethodDef DBTxn_methods[] = {
    {"commit",          (PyCFunction)DBTxn_commit,      METH_VARARGS},
    {"prepare",         (PyCFunction)DBTxn_prepare,     METH_VARARGS},
    {"abort",           (PyCFunction)DBTxn_abort,       METH_VARARGS},
    {"id",              (PyCFunction)DBTxn_id,          METH_VARARGS},
    {NULL,      NULL}       /* sentinel */
};


#if (DBVER >= 43)
static PyMethodDef DBSequence_methods[] = {
    {"close",           (PyCFunction)DBSequence_close,          METH_VARARGS},
    {"get",             (PyCFunction)DBSequence_get,            METH_VARARGS|METH_KEYWORDS},
    {"get_dbp",         (PyCFunction)DBSequence_get_dbp,        METH_VARARGS},
    {"get_key",         (PyCFunction)DBSequence_get_key,        METH_VARARGS},
    {"init_value",      (PyCFunction)DBSequence_init_value,     METH_VARARGS},
    {"open",            (PyCFunction)DBSequence_open,           METH_VARARGS|METH_KEYWORDS},
    {"remove",          (PyCFunction)DBSequence_remove,         METH_VARARGS|METH_KEYWORDS},
    {"set_cachesize",   (PyCFunction)DBSequence_set_cachesize,  METH_VARARGS},
    {"get_cachesize",   (PyCFunction)DBSequence_get_cachesize,  METH_VARARGS},
    {"set_flags",       (PyCFunction)DBSequence_set_flags,      METH_VARARGS},
    {"get_flags",       (PyCFunction)DBSequence_get_flags,      METH_VARARGS},
    {"set_range",       (PyCFunction)DBSequence_set_range,      METH_VARARGS},
    {"get_range",       (PyCFunction)DBSequence_get_range,      METH_VARARGS},
    {"stat",            (PyCFunction)DBSequence_stat,           METH_VARARGS|METH_KEYWORDS},
    {NULL,      NULL}       /* sentinel */
};
#endif

static PyObject*
DBEnv_db_home_get(DBEnvObject* self)
{
    CHECK_ENV_NOT_CLOSED(self);
    if (self->db_env->db_home == NULL) {
        RETURN_NONE();
    }
    return PyUnicode_FromString(self->db_env->db_home);
}

static PyGetSetDef DBEnv_getsets[] = {
    {"db_home", (getter)DBEnv_db_home_get, NULL,},
    {NULL}
};


static PyTypeObject DB_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "DB",               /*tp_name*/
    sizeof(DBObject),   /*tp_basicsize*/
    0,                  /*tp_itemsize*/
    /* methods */
    (destructor)DB_dealloc, /*tp_dealloc*/
    0,                  /*tp_print*/
    0,                  /*tp_getattr*/
    0,                  /*tp_setattr*/
    0,          /*tp_compare*/
    0,          /*tp_repr*/
    0,          /*tp_as_number*/
    0,          /*tp_as_sequence*/
    &DB_mapping,/*tp_as_mapping*/
    0,          /*tp_hash*/
    0,			/* tp_call */
    0,			/* tp_str */
    0,  		/* tp_getattro */
    0,                  /* tp_setattro */
    0,			/* tp_as_buffer */
    Py_TPFLAGS_DEFAULT, /* tp_flags */
    0,                  /* tp_doc */
    0,		        /* tp_traverse */
    0,			/* tp_clear */
    0,			/* tp_richcompare */
    offsetof(DBObject, in_weakreflist),   /* tp_weaklistoffset */
    0,			/* tp_iter */
    0,			/* tp_iternext */
    DB_methods,		/* tp_methods */
};


static PyTypeObject DBCursor_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "DBCursor",         /*tp_name*/
    sizeof(DBCursorObject),  /*tp_basicsize*/
    0,                  /*tp_itemsize*/
    /* methods */
    (destructor)DBCursor_dealloc,/*tp_dealloc*/
    0,                  /*tp_print*/
    0,                  /*tp_getattr*/
    0,                  /*tp_setattr*/
    0,                  /*tp_compare*/
    0,                  /*tp_repr*/
    0,                  /*tp_as_number*/
    0,                  /*tp_as_sequence*/
    0,                  /*tp_as_mapping*/
    0,                  /*tp_hash*/
    0,			/* tp_call */
    0,			/* tp_str */
    0,  		/* tp_getattro */
    0,                  /* tp_setattro */
    0,			/* tp_as_buffer */
    Py_TPFLAGS_DEFAULT, /* tp_flags */
    0,                  /* tp_doc */
    0,		        /* tp_traverse */
    0,			/* tp_clear */
    0,			/* tp_richcompare */
    offsetof(DBCursorObject, in_weakreflist),   /* tp_weaklistoffset */
    0,			/* tp_iter */
    0,			/* tp_iternext */
    DBCursor_methods,	/* tp_methods */
};


static PyTypeObject DBEnv_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "DBEnv",            /*tp_name*/
    sizeof(DBEnvObject),    /*tp_basicsize*/
    0,          /*tp_itemsize*/
    /* methods */
    (destructor)DBEnv_dealloc, /*tp_dealloc*/
    0,          /*tp_print*/
    0,          /*tp_getattr*/
    0,          /*tp_setattr*/
    0,          /*tp_compare*/
    0,          /*tp_repr*/
    0,          /*tp_as_number*/
    0,          /*tp_as_sequence*/
    0,          /*tp_as_mapping*/
    0,          /*tp_hash*/
    0,			/* tp_call */
    0,			/* tp_str */
    0,  		/* tp_getattro */
    0,                  /* tp_setattro */
    0,			/* tp_as_buffer */
    Py_TPFLAGS_DEFAULT, /* tp_flags */
    0,                  /* tp_doc */
    0,		        /* tp_traverse */
    0,			/* tp_clear */
    0,			/* tp_richcompare */
    offsetof(DBEnvObject, in_weakreflist),   /* tp_weaklistoffset */
    0,                  /* tp_iter */
    0,                  /* tp_iternext */
    DBEnv_methods,      /* tp_methods */
    0,                  /* tp_members */
    DBEnv_getsets,      /* tp_getsets */
};

static PyTypeObject DBTxn_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "DBTxn",    /*tp_name*/
    sizeof(DBTxnObject),  /*tp_basicsize*/
    0,          /*tp_itemsize*/
    /* methods */
    (destructor)DBTxn_dealloc, /*tp_dealloc*/
    0,          /*tp_print*/
    0,          /*tp_getattr*/
    0,          /*tp_setattr*/
    0,          /*tp_compare*/
    0,          /*tp_repr*/
    0,          /*tp_as_number*/
    0,          /*tp_as_sequence*/
    0,          /*tp_as_mapping*/
    0,          /*tp_hash*/
    0,			/* tp_call */
    0,			/* tp_str */
    0,  		/* tp_getattro */
    0,                  /* tp_setattro */
    0,			/* tp_as_buffer */
    Py_TPFLAGS_DEFAULT, /* tp_flags */
    0,                  /* tp_doc */
    0,		        /* tp_traverse */
    0,			/* tp_clear */
    0,			/* tp_richcompare */
    offsetof(DBTxnObject, in_weakreflist),   /* tp_weaklistoffset */
    0,			/* tp_iter */
    0,			/* tp_iternext */
    DBTxn_methods,	/* tp_methods */
};


static PyTypeObject DBLock_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "DBLock",   /*tp_name*/
    sizeof(DBLockObject),  /*tp_basicsize*/
    0,          /*tp_itemsize*/
    /* methods */
    (destructor)DBLock_dealloc, /*tp_dealloc*/
    0,          /*tp_print*/
    0,          /*tp_getattr*/
    0,          /*tp_setattr*/
    0,          /*tp_compare*/
    0,          /*tp_repr*/
    0,          /*tp_as_number*/
    0,          /*tp_as_sequence*/
    0,          /*tp_as_mapping*/
    0,          /*tp_hash*/
    0,			/* tp_call */
    0,			/* tp_str */
    0,  		/* tp_getattro */
    0,                  /* tp_setattro */
    0,			/* tp_as_buffer */
    Py_TPFLAGS_DEFAULT, /* tp_flags */
    0,                  /* tp_doc */
    0,		        /* tp_traverse */
    0,			/* tp_clear */
    0,			/* tp_richcompare */
    offsetof(DBLockObject, in_weakreflist),   /* tp_weaklistoffset */
};

#if (DBVER >= 43)
static PyTypeObject DBSequence_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "DBSequence",                   /*tp_name*/
    sizeof(DBSequenceObject),       /*tp_basicsize*/
    0,          /*tp_itemsize*/
    /* methods */
    (destructor)DBSequence_dealloc, /*tp_dealloc*/
    0,          /*tp_print*/
    0,          /*tp_getattr*/
    0,          /*tp_setattr*/
    0,          /*tp_compare*/
    0,          /*tp_repr*/
    0,          /*tp_as_number*/
    0,          /*tp_as_sequence*/
    0,          /*tp_as_mapping*/
    0,          /*tp_hash*/
    0,			/* tp_call */
    0,			/* tp_str */
    0,  		/* tp_getattro */
    0,          /* tp_setattro */
    0,			/* tp_as_buffer */
    Py_TPFLAGS_DEFAULT, /* tp_flags */
    0,          /* tp_doc */
    0,		    /* tp_traverse */
    0,			/* tp_clear */
    0,			/* tp_richcompare */
    offsetof(DBSequenceObject, in_weakreflist),   /* tp_weaklistoffset */
    0,			/* tp_iter */
    0,			/* tp_iternext */
    DBSequence_methods,	/* tp_methods */
};
#endif

/* --------------------------------------------------------------------- */
/* Module-level functions */

static PyObject*
DB_construct(PyObject* self, PyObject* args, PyObject* kwargs)
{
    PyObject* dbenvobj = NULL;
    int flags = 0;
    static char* kwnames[] = { "dbEnv", "flags", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:DB", kwnames,
                                     &dbenvobj, &flags))
        return NULL;
    if (dbenvobj == Py_None)
        dbenvobj = NULL;
    else if (dbenvobj && !DBEnvObject_Check(dbenvobj)) {
        makeTypeError("DBEnv", dbenvobj);
        return NULL;
    }

    return (PyObject* )newDBObject((DBEnvObject*)dbenvobj, flags);
}


static PyObject*
DBEnv_construct(PyObject* self, PyObject* args)
{
    int flags = 0;
    if (!PyArg_ParseTuple(args, "|i:DbEnv", &flags)) return NULL;
    return (PyObject* )newDBEnvObject(flags);
}

#if (DBVER >= 43)
static PyObject*
DBSequence_construct(PyObject* self, PyObject* args, PyObject* kwargs)
{
    PyObject* dbobj;
    int flags = 0;
    static char* kwnames[] = { "db", "flags", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:DBSequence", kwnames, &dbobj, &flags))
        return NULL;
    if (!DBObject_Check(dbobj)) {
        makeTypeError("DB", dbobj);
        return NULL;
    }
    return (PyObject* )newDBSequenceObject((DBObject*)dbobj, flags);
}
#endif

static char bsddb_version_doc[] =
"Returns a tuple of major, minor, and patch release numbers of the\n\
underlying DB library.";

static PyObject*
bsddb_version(PyObject* self, PyObject* args)
{
    int major, minor, patch;

        if (!PyArg_ParseTuple(args, ":version"))
        return NULL;
        db_version(&major, &minor, &patch);
        return Py_BuildValue("(iii)", major, minor, patch);
}


/* List of functions defined in the module */

static PyMethodDef bsddb_methods[] = {
    {"DB",          (PyCFunction)DB_construct,          METH_VARARGS | METH_KEYWORDS },
    {"DBEnv",       (PyCFunction)DBEnv_construct,       METH_VARARGS},
#if (DBVER >= 43)    
    {"DBSequence",  (PyCFunction)DBSequence_construct,  METH_VARARGS | METH_KEYWORDS },
#endif    
    {"version",     (PyCFunction)bsddb_version,         METH_VARARGS, bsddb_version_doc},
    {NULL,      NULL}       /* sentinel */
};

/* API structure */
static BSDDB_api bsddb_api;


/* --------------------------------------------------------------------- */
/* Module initialization */


/* Convenience routine to export an integer value.
 * Errors are silently ignored, for better or for worse...
 */
#define ADD_INT(dict, NAME)         _addIntToDict(dict, #NAME, NAME)

#define MODULE_NAME_MAX_LEN     11
static char _bsddbModuleName[MODULE_NAME_MAX_LEN+1] = "_bsddb";


static struct PyModuleDef _bsddbmodule = {
	PyModuleDef_HEAD_INIT,
	_bsddbModuleName,
	NULL,
	-1,
	bsddb_methods,
	NULL,
	NULL,
	NULL,
	NULL
};

PyMODINIT_FUNC PyInit__bsddb(void)
{
    PyObject* m;
    PyObject* d;
    PyObject* pybsddb_version_s = PyUnicode_FromString(PY_BSDDB_VERSION);
    PyObject* db_version_s = PyUnicode_FromString(DB_VERSION_STRING);
    PyObject* svnid_s = PyUnicode_FromString(svn_id);
    PyObject* py_api;

    /* Initialize object types */
    if (PyType_Ready(&DB_Type) < 0)
        return NULL;
    if (PyType_Ready(&DBCursor_Type) < 0)
        return NULL;
    if (PyType_Ready(&DBEnv_Type) < 0)
        return NULL;
    if (PyType_Ready(&DBTxn_Type) < 0)
        return NULL;
    if (PyType_Ready(&DBLock_Type) < 0)
        return NULL;
#if (DBVER >= 43)
    if (PyType_Ready(&DBSequence_Type) < 0)
        return NULL;
#endif


#if defined(WITH_THREAD) && !defined(MYDB_USE_GILSTATE)
    /* Save the current interpreter, so callbacks can do the right thing. */
    _db_interpreterState = PyThreadState_GET()->interp;
#endif

    /* Create the module and add the functions */
    m = PyModule_Create(&_bsddbmodule);
    if (m == NULL)
    	return NULL;

    /* Add some symbolic constants to the module */
    d = PyModule_GetDict(m);
    PyDict_SetItemString(d, "__version__", pybsddb_version_s);
    PyDict_SetItemString(d, "cvsid", svnid_s);
    PyDict_SetItemString(d, "DB_VERSION_STRING", db_version_s);
    Py_DECREF(pybsddb_version_s);
    pybsddb_version_s = NULL;
    Py_DECREF(svnid_s);
    svnid_s = NULL;
    Py_DECREF(db_version_s);
    db_version_s = NULL;

    ADD_INT(d, DB_VERSION_MAJOR);
    ADD_INT(d, DB_VERSION_MINOR);
    ADD_INT(d, DB_VERSION_PATCH);

    ADD_INT(d, DB_MAX_PAGES);
    ADD_INT(d, DB_MAX_RECORDS);

#if (DBVER >= 42)
    ADD_INT(d, DB_RPCCLIENT);
#else
    ADD_INT(d, DB_CLIENT);
    /* allow apps to be written using DB_RPCCLIENT on older BerkeleyDB */
    _addIntToDict(d, "DB_RPCCLIENT", DB_CLIENT);
#endif
    ADD_INT(d, DB_XA_CREATE);

    ADD_INT(d, DB_CREATE);
    ADD_INT(d, DB_NOMMAP);
    ADD_INT(d, DB_THREAD);

    ADD_INT(d, DB_FORCE);
    ADD_INT(d, DB_INIT_CDB);
    ADD_INT(d, DB_INIT_LOCK);
    ADD_INT(d, DB_INIT_LOG);
    ADD_INT(d, DB_INIT_MPOOL);
    ADD_INT(d, DB_INIT_TXN);
    ADD_INT(d, DB_JOINENV);

    ADD_INT(d, DB_RECOVER);
    ADD_INT(d, DB_RECOVER_FATAL);
    ADD_INT(d, DB_TXN_NOSYNC);
    ADD_INT(d, DB_USE_ENVIRON);
    ADD_INT(d, DB_USE_ENVIRON_ROOT);

    ADD_INT(d, DB_LOCKDOWN);
    ADD_INT(d, DB_PRIVATE);
    ADD_INT(d, DB_SYSTEM_MEM);

    ADD_INT(d, DB_TXN_SYNC);
    ADD_INT(d, DB_TXN_NOWAIT);

    ADD_INT(d, DB_EXCL);
    ADD_INT(d, DB_FCNTL_LOCKING);
    ADD_INT(d, DB_ODDFILESIZE);
    ADD_INT(d, DB_RDWRMASTER);
    ADD_INT(d, DB_RDONLY);
    ADD_INT(d, DB_TRUNCATE);
    ADD_INT(d, DB_EXTENT);
    ADD_INT(d, DB_CDB_ALLDB);
    ADD_INT(d, DB_VERIFY);
    ADD_INT(d, DB_UPGRADE);

    ADD_INT(d, DB_AGGRESSIVE);
    ADD_INT(d, DB_NOORDERCHK);
    ADD_INT(d, DB_ORDERCHKONLY);
    ADD_INT(d, DB_PR_PAGE);
#if ! (DBVER >= 33)
    ADD_INT(d, DB_VRFY_FLAGMASK);
    ADD_INT(d, DB_PR_HEADERS);
#endif
    ADD_INT(d, DB_PR_RECOVERYTEST);
    ADD_INT(d, DB_SALVAGE);

    ADD_INT(d, DB_LOCK_NORUN);
    ADD_INT(d, DB_LOCK_DEFAULT);
    ADD_INT(d, DB_LOCK_OLDEST);
    ADD_INT(d, DB_LOCK_RANDOM);
    ADD_INT(d, DB_LOCK_YOUNGEST);
#if (DBVER >= 33)
    ADD_INT(d, DB_LOCK_MAXLOCKS);
    ADD_INT(d, DB_LOCK_MINLOCKS);
    ADD_INT(d, DB_LOCK_MINWRITE);
#endif


#if (DBVER >= 33)
    /* docs say to use zero instead */
    _addIntToDict(d, "DB_LOCK_CONFLICT", 0);
#else
    ADD_INT(d, DB_LOCK_CONFLICT);
#endif

    ADD_INT(d, DB_LOCK_DUMP);
    ADD_INT(d, DB_LOCK_GET);
    ADD_INT(d, DB_LOCK_INHERIT);
    ADD_INT(d, DB_LOCK_PUT);
    ADD_INT(d, DB_LOCK_PUT_ALL);
    ADD_INT(d, DB_LOCK_PUT_OBJ);

    ADD_INT(d, DB_LOCK_NG);
    ADD_INT(d, DB_LOCK_READ);
    ADD_INT(d, DB_LOCK_WRITE);
    ADD_INT(d, DB_LOCK_NOWAIT);
    ADD_INT(d, DB_LOCK_WAIT);
    ADD_INT(d, DB_LOCK_IWRITE);
    ADD_INT(d, DB_LOCK_IREAD);
    ADD_INT(d, DB_LOCK_IWR);
#if (DBVER >= 33)
#if (DBVER < 44)
    ADD_INT(d, DB_LOCK_DIRTY);
#else
    ADD_INT(d, DB_LOCK_READ_UNCOMMITTED);  /* renamed in 4.4 */
#endif
    ADD_INT(d, DB_LOCK_WWRITE);
#endif

    ADD_INT(d, DB_LOCK_RECORD);
    ADD_INT(d, DB_LOCK_UPGRADE);
    ADD_INT(d, DB_LOCK_SWITCH);
#if (DBVER >= 33)
    ADD_INT(d, DB_LOCK_UPGRADE_WRITE);
#endif

    ADD_INT(d, DB_LOCK_NOWAIT);
    ADD_INT(d, DB_LOCK_RECORD);
    ADD_INT(d, DB_LOCK_UPGRADE);

#if (DBVER >= 33)
    ADD_INT(d, DB_LSTAT_ABORTED);
#if (DBVER < 43)
    ADD_INT(d, DB_LSTAT_ERR);
#endif
    ADD_INT(d, DB_LSTAT_FREE);
    ADD_INT(d, DB_LSTAT_HELD);
#if (DBVER == 33)
    ADD_INT(d, DB_LSTAT_NOGRANT);
#endif
    ADD_INT(d, DB_LSTAT_PENDING);
    ADD_INT(d, DB_LSTAT_WAITING);
#endif

    ADD_INT(d, DB_ARCH_ABS);
    ADD_INT(d, DB_ARCH_DATA);
    ADD_INT(d, DB_ARCH_LOG);
#if (DBVER >= 42)
    ADD_INT(d, DB_ARCH_REMOVE);
#endif

    ADD_INT(d, DB_BTREE);
    ADD_INT(d, DB_HASH);
    ADD_INT(d, DB_RECNO);
    ADD_INT(d, DB_QUEUE);
    ADD_INT(d, DB_UNKNOWN);

    ADD_INT(d, DB_DUP);
    ADD_INT(d, DB_DUPSORT);
    ADD_INT(d, DB_RECNUM);
    ADD_INT(d, DB_RENUMBER);
    ADD_INT(d, DB_REVSPLITOFF);
    ADD_INT(d, DB_SNAPSHOT);

    ADD_INT(d, DB_JOIN_NOSORT);

    ADD_INT(d, DB_AFTER);
    ADD_INT(d, DB_APPEND);
    ADD_INT(d, DB_BEFORE);
#if (DBVER < 45)
    ADD_INT(d, DB_CACHED_COUNTS);
#endif
#if (DBVER >= 41)
    _addIntToDict(d, "DB_CHECKPOINT", 0);
#else
    ADD_INT(d, DB_CHECKPOINT);
    ADD_INT(d, DB_CURLSN);
#endif
#if ((DBVER >= 33) && (DBVER <= 41))
    ADD_INT(d, DB_COMMIT);
#endif
    ADD_INT(d, DB_CONSUME);
    ADD_INT(d, DB_CONSUME_WAIT);
    ADD_INT(d, DB_CURRENT);
#if (DBVER >= 33)
    ADD_INT(d, DB_FAST_STAT);
#endif
    ADD_INT(d, DB_FIRST);
    ADD_INT(d, DB_FLUSH);
    ADD_INT(d, DB_GET_BOTH);
    ADD_INT(d, DB_GET_RECNO);
    ADD_INT(d, DB_JOIN_ITEM);
    ADD_INT(d, DB_KEYFIRST);
    ADD_INT(d, DB_KEYLAST);
    ADD_INT(d, DB_LAST);
    ADD_INT(d, DB_NEXT);
    ADD_INT(d, DB_NEXT_DUP);
    ADD_INT(d, DB_NEXT_NODUP);
    ADD_INT(d, DB_NODUPDATA);
    ADD_INT(d, DB_NOOVERWRITE);
    ADD_INT(d, DB_NOSYNC);
    ADD_INT(d, DB_POSITION);
    ADD_INT(d, DB_PREV);
    ADD_INT(d, DB_PREV_NODUP);
#if (DBVER < 45)
    ADD_INT(d, DB_RECORDCOUNT);
#endif
    ADD_INT(d, DB_SET);
    ADD_INT(d, DB_SET_RANGE);
    ADD_INT(d, DB_SET_RECNO);
    ADD_INT(d, DB_WRITECURSOR);

    ADD_INT(d, DB_OPFLAGS_MASK);
    ADD_INT(d, DB_RMW);
#if (DBVER >= 33)
    ADD_INT(d, DB_DIRTY_READ);
    ADD_INT(d, DB_MULTIPLE);
    ADD_INT(d, DB_MULTIPLE_KEY);
#endif

#if (DBVER >= 44)
    ADD_INT(d, DB_READ_UNCOMMITTED);    /* replaces DB_DIRTY_READ in 4.4 */
    ADD_INT(d, DB_READ_COMMITTED);
#endif

#if (DBVER >= 33)
    ADD_INT(d, DB_DONOTINDEX);
    ADD_INT(d, DB_XIDDATASIZE);
#endif

#if (DBVER >= 41)
    _addIntToDict(d, "DB_INCOMPLETE", 0);
#else
    ADD_INT(d, DB_INCOMPLETE);
#endif
    ADD_INT(d, DB_KEYEMPTY);
    ADD_INT(d, DB_KEYEXIST);
    ADD_INT(d, DB_LOCK_DEADLOCK);
    ADD_INT(d, DB_LOCK_NOTGRANTED);
    ADD_INT(d, DB_NOSERVER);
    ADD_INT(d, DB_NOSERVER_HOME);
    ADD_INT(d, DB_NOSERVER_ID);
    ADD_INT(d, DB_NOTFOUND);
    ADD_INT(d, DB_OLD_VERSION);
    ADD_INT(d, DB_RUNRECOVERY);
    ADD_INT(d, DB_VERIFY_BAD);
#if (DBVER >= 33)
    ADD_INT(d, DB_PAGE_NOTFOUND);
    ADD_INT(d, DB_SECONDARY_BAD);
#endif
#if (DBVER >= 40)
    ADD_INT(d, DB_STAT_CLEAR);
    ADD_INT(d, DB_REGION_INIT);
    ADD_INT(d, DB_NOLOCKING);
    ADD_INT(d, DB_YIELDCPU);
    ADD_INT(d, DB_PANIC_ENVIRONMENT);
    ADD_INT(d, DB_NOPANIC);
#endif

#ifdef DB_REGISTER
    ADD_INT(d, DB_REGISTER);
#endif

#if (DBVER >= 42)
    ADD_INT(d, DB_TIME_NOTGRANTED);
    ADD_INT(d, DB_TXN_NOT_DURABLE);
    ADD_INT(d, DB_TXN_WRITE_NOSYNC);
    ADD_INT(d, DB_LOG_AUTOREMOVE);
    ADD_INT(d, DB_DIRECT_LOG);
    ADD_INT(d, DB_DIRECT_DB);
    ADD_INT(d, DB_INIT_REP);
    ADD_INT(d, DB_ENCRYPT);
    ADD_INT(d, DB_CHKSUM);
#endif

#if (DBVER >= 43)
    ADD_INT(d, DB_LOG_INMEMORY);
    ADD_INT(d, DB_BUFFER_SMALL);
    ADD_INT(d, DB_SEQ_DEC);
    ADD_INT(d, DB_SEQ_INC);
    ADD_INT(d, DB_SEQ_WRAP);
#endif

#if (DBVER >= 41)
    ADD_INT(d, DB_ENCRYPT_AES);
    ADD_INT(d, DB_AUTO_COMMIT);
#else
    /* allow berkeleydb 4.1 aware apps to run on older versions */
    _addIntToDict(d, "DB_AUTO_COMMIT", 0);
#endif

    ADD_INT(d, EINVAL);
    ADD_INT(d, EACCES);
    ADD_INT(d, ENOSPC);
    ADD_INT(d, ENOMEM);
    ADD_INT(d, EAGAIN);
    ADD_INT(d, EBUSY);
    ADD_INT(d, EEXIST);
    ADD_INT(d, ENOENT);
    ADD_INT(d, EPERM);

#if (DBVER >= 40)
    ADD_INT(d, DB_SET_LOCK_TIMEOUT);
    ADD_INT(d, DB_SET_TXN_TIMEOUT);
#endif

    /* The exception name must be correct for pickled exception *
     * objects to unpickle properly.                            */
#ifdef PYBSDDB_STANDALONE  /* different value needed for standalone pybsddb */
#define PYBSDDB_EXCEPTION_BASE  "bsddb3.db."
#else
#define PYBSDDB_EXCEPTION_BASE  "bsddb.db."
#endif

    /* All the rest of the exceptions derive only from DBError */
#define MAKE_EX(name)   name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
                        PyDict_SetItemString(d, #name, name)

    /* The base exception class is DBError */
    DBError = NULL;     /* used in MAKE_EX so that it derives from nothing */
    MAKE_EX(DBError);

    /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
     * from both DBError and KeyError, since the API only supports
     * using one base class. */
    PyDict_SetItemString(d, "KeyError", PyExc_KeyError);
    { 
	    PyObject *builtin_mod = PyImport_ImportModule("builtins");
	    PyDict_SetItemString(d, "__builtins__", builtin_mod);
    }
    PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
	         "class DBKeyEmptyError(DBError, KeyError): pass",
                 Py_file_input, d, d);
    DBNotFoundError = PyDict_GetItemString(d, "DBNotFoundError");
    DBKeyEmptyError = PyDict_GetItemString(d, "DBKeyEmptyError");
    PyDict_DelItemString(d, "KeyError");


#if !INCOMPLETE_IS_WARNING
    MAKE_EX(DBIncompleteError);
#endif
    MAKE_EX(DBCursorClosedError);
    MAKE_EX(DBKeyEmptyError);
    MAKE_EX(DBKeyExistError);
    MAKE_EX(DBLockDeadlockError);
    MAKE_EX(DBLockNotGrantedError);
    MAKE_EX(DBOldVersionError);
    MAKE_EX(DBRunRecoveryError);
    MAKE_EX(DBVerifyBadError);
    MAKE_EX(DBNoServerError);
    MAKE_EX(DBNoServerHomeError);
    MAKE_EX(DBNoServerIDError);
#if (DBVER >= 33)
    MAKE_EX(DBPageNotFoundError);
    MAKE_EX(DBSecondaryBadError);
#endif

    MAKE_EX(DBInvalidArgError);
    MAKE_EX(DBAccessError);
    MAKE_EX(DBNoSpaceError);
    MAKE_EX(DBNoMemoryError);
    MAKE_EX(DBAgainError);
    MAKE_EX(DBBusyError);
    MAKE_EX(DBFileExistsError);
    MAKE_EX(DBNoSuchFileError);
    MAKE_EX(DBPermissionsError);

#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;
#if (DBVER >= 43)
    bsddb_api.dbsequence_type = &DBSequence_Type;
#endif
    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();
        Py_FatalError("can't initialize module _bsddb");
	Py_DECREF(m);
	m = NULL;
    }
    return m;
}

/* allow this module to be named _pybsddb so that it can be installed
 * and imported on top of python >= 2.3 that includes its own older
 * copy of the library named _bsddb without importing the old version. */
PyMODINIT_FUNC init_pybsddb(void)
{
    strncpy(_bsddbModuleName, "_pybsddb", MODULE_NAME_MAX_LEN);
    return PyInit__bsddb();
}
