mirror of https://github.com/python/cpython
Splits Modules/_bsddb.c up into bsddb.h and _bsddb.c and adds a C API
object available as bsddb.db.api. This is based on the patch submitted by Duncan Grisby here: http://sourceforge.net/tracker/index.php?func=detail&aid=1551895&group_id=13900&atid=313900 See this thread for additional info: http://sourceforge.net/mailarchive/forum.php?thread_name=E1GAVDK-0002rk-Iw%40apasphere.com&forum_name=pybsddb-users It also cleans up the code a little by removing some ifdef/endifs for python prior to 2.1 and for unsupported Berkeley DB <= 3.2.
This commit is contained in:
parent
163f622c03
commit
392505391e
215
Modules/_bsddb.c
215
Modules/_bsddb.c
|
@ -87,21 +87,16 @@
|
|||
|
||||
#include <stddef.h> /* for offsetof() */
|
||||
#include <Python.h>
|
||||
#include <db.h>
|
||||
|
||||
#define COMPILING_BSDDB_C
|
||||
#include "bsddb.h"
|
||||
#undef COMPILING_BSDDB_C
|
||||
|
||||
static char *rcs_id = "$Id$";
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Various macro definitions */
|
||||
|
||||
/* 40 = 4.0, 33 = 3.3; this will break if the second number is > 9 */
|
||||
#define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
|
||||
#if DB_VERSION_MINOR > 9
|
||||
#error "eek! DBVER can't handle minor versions > 9"
|
||||
#endif
|
||||
|
||||
#define PY_BSDDB_VERSION "4.5.0"
|
||||
static char *rcs_id = "$Id$";
|
||||
|
||||
|
||||
#if (PY_VERSION_HEX < 0x02050000)
|
||||
typedef int Py_ssize_t;
|
||||
#endif
|
||||
|
@ -196,107 +191,15 @@ static PyObject* DBPermissionsError; /* EPERM */
|
|||
/* --------------------------------------------------------------------- */
|
||||
/* Structure definitions */
|
||||
|
||||
#if PYTHON_API_VERSION >= 1010 /* python >= 2.1 support weak references */
|
||||
#define HAVE_WEAKREF
|
||||
#else
|
||||
#undef HAVE_WEAKREF
|
||||
#if PYTHON_API_VERSION < 1010
|
||||
#error "Python 2.1 or later required"
|
||||
#endif
|
||||
|
||||
/* if Python >= 2.1 better support warnings */
|
||||
#if PYTHON_API_VERSION >= 1010
|
||||
#define HAVE_WARNINGS
|
||||
#else
|
||||
#undef HAVE_WARNINGS
|
||||
#endif
|
||||
|
||||
#if PYTHON_API_VERSION <= 1007
|
||||
/* 1.5 compatibility */
|
||||
#define PyObject_New PyObject_NEW
|
||||
#define PyObject_Del PyMem_DEL
|
||||
#endif
|
||||
|
||||
struct behaviourFlags {
|
||||
/* What is the default behaviour when DB->get or DBCursor->get returns a
|
||||
DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise an exception? */
|
||||
unsigned int getReturnsNone : 1;
|
||||
/* What is the default behaviour for DBCursor.set* methods when DBCursor->get
|
||||
* returns a DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise? */
|
||||
unsigned int cursorSetReturnsNone : 1;
|
||||
};
|
||||
|
||||
/* Defaults for moduleFlags in DBEnvObject and DBObject. */
|
||||
#define DEFAULT_GET_RETURNS_NONE 1
|
||||
#define DEFAULT_CURSOR_SET_RETURNS_NONE 1 /* 0 in pybsddb < 4.2, python < 2.4 */
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
DB_ENV* db_env;
|
||||
u_int32_t flags; /* saved flags from open() */
|
||||
int closed;
|
||||
struct behaviourFlags moduleFlags;
|
||||
#ifdef HAVE_WEAKREF
|
||||
PyObject *in_weakreflist; /* List of weak references */
|
||||
#endif
|
||||
} DBEnvObject;
|
||||
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
DB* db;
|
||||
DBEnvObject* myenvobj; /* PyObject containing the DB_ENV */
|
||||
u_int32_t flags; /* saved flags from open() */
|
||||
u_int32_t setflags; /* saved flags from set_flags() */
|
||||
int haveStat;
|
||||
struct behaviourFlags moduleFlags;
|
||||
#if (DBVER >= 33)
|
||||
PyObject* associateCallback;
|
||||
PyObject* btCompareCallback;
|
||||
int primaryDBType;
|
||||
#endif
|
||||
#ifdef HAVE_WEAKREF
|
||||
PyObject *in_weakreflist; /* List of weak references */
|
||||
#endif
|
||||
} DBObject;
|
||||
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
DBC* dbc;
|
||||
DBObject* mydb;
|
||||
#ifdef HAVE_WEAKREF
|
||||
PyObject *in_weakreflist; /* List of weak references */
|
||||
#endif
|
||||
} DBCursorObject;
|
||||
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
DB_TXN* txn;
|
||||
PyObject *env;
|
||||
#ifdef HAVE_WEAKREF
|
||||
PyObject *in_weakreflist; /* List of weak references */
|
||||
#endif
|
||||
} DBTxnObject;
|
||||
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
DB_LOCK lock;
|
||||
#ifdef HAVE_WEAKREF
|
||||
PyObject *in_weakreflist; /* List of weak references */
|
||||
#endif
|
||||
} DBLockObject;
|
||||
|
||||
#if (DBVER >= 43)
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
DB_SEQUENCE* sequence;
|
||||
DBObject* mydb;
|
||||
#ifdef HAVE_WEAKREF
|
||||
PyObject *in_weakreflist; /* List of weak references */
|
||||
#endif
|
||||
} DBSequenceObject;
|
||||
staticforward PyTypeObject DBSequence_Type;
|
||||
#endif
|
||||
|
||||
staticforward PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type, DBLock_Type;
|
||||
|
||||
|
@ -545,12 +448,7 @@ static int makeDBError(int err)
|
|||
strncat(errTxt, _db_errmsg, bytes_left);
|
||||
}
|
||||
_db_errmsg[0] = 0;
|
||||
#ifdef HAVE_WARNINGS
|
||||
exceptionRaised = PyErr_Warn(PyExc_RuntimeWarning, errTxt);
|
||||
#else
|
||||
fprintf(stderr, errTxt);
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
|
||||
#else /* do an exception instead */
|
||||
errObj = DBIncompleteError;
|
||||
|
@ -804,9 +702,7 @@ newDBObject(DBEnvObject* arg, int flags)
|
|||
self->btCompareCallback = NULL;
|
||||
self->primaryDBType = 0;
|
||||
#endif
|
||||
#ifdef HAVE_WEAKREF
|
||||
self->in_weakreflist = NULL;
|
||||
#endif
|
||||
|
||||
/* keep a reference to our python DBEnv object */
|
||||
if (arg) {
|
||||
|
@ -857,19 +753,15 @@ DB_dealloc(DBObject* self)
|
|||
MYDB_BEGIN_ALLOW_THREADS;
|
||||
self->db->close(self->db, 0);
|
||||
MYDB_END_ALLOW_THREADS;
|
||||
#ifdef HAVE_WARNINGS
|
||||
} else {
|
||||
PyErr_Warn(PyExc_RuntimeWarning,
|
||||
"DB could not be closed in destructor: DBEnv already closed");
|
||||
#endif
|
||||
}
|
||||
self->db = NULL;
|
||||
}
|
||||
#ifdef HAVE_WEAKREF
|
||||
if (self->in_weakreflist != NULL) {
|
||||
PyObject_ClearWeakRefs((PyObject *) self);
|
||||
}
|
||||
#endif
|
||||
if (self->myenvobj) {
|
||||
Py_DECREF(self->myenvobj);
|
||||
self->myenvobj = NULL;
|
||||
|
@ -897,9 +789,7 @@ newDBCursorObject(DBC* dbc, DBObject* db)
|
|||
|
||||
self->dbc = dbc;
|
||||
self->mydb = db;
|
||||
#ifdef HAVE_WEAKREF
|
||||
self->in_weakreflist = NULL;
|
||||
#endif
|
||||
Py_INCREF(self->mydb);
|
||||
return self;
|
||||
}
|
||||
|
@ -910,11 +800,9 @@ DBCursor_dealloc(DBCursorObject* self)
|
|||
{
|
||||
int err;
|
||||
|
||||
#ifdef HAVE_WEAKREF
|
||||
if (self->in_weakreflist != NULL) {
|
||||
PyObject_ClearWeakRefs((PyObject *) self);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (self->dbc != NULL) {
|
||||
MYDB_BEGIN_ALLOW_THREADS;
|
||||
|
@ -947,9 +835,7 @@ newDBEnvObject(int flags)
|
|||
self->flags = flags;
|
||||
self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
|
||||
self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
|
||||
#ifdef HAVE_WEAKREF
|
||||
self->in_weakreflist = NULL;
|
||||
#endif
|
||||
|
||||
MYDB_BEGIN_ALLOW_THREADS;
|
||||
err = db_env_create(&self->db_env, flags);
|
||||
|
@ -968,11 +854,9 @@ newDBEnvObject(int flags)
|
|||
static void
|
||||
DBEnv_dealloc(DBEnvObject* self)
|
||||
{
|
||||
#ifdef HAVE_WEAKREF
|
||||
if (self->in_weakreflist != NULL) {
|
||||
PyObject_ClearWeakRefs((PyObject *) self);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (self->db_env && !self->closed) {
|
||||
MYDB_BEGIN_ALLOW_THREADS;
|
||||
|
@ -992,9 +876,7 @@ newDBTxnObject(DBEnvObject* myenv, DB_TXN *parent, int flags)
|
|||
return NULL;
|
||||
Py_INCREF(myenv);
|
||||
self->env = (PyObject*)myenv;
|
||||
#ifdef HAVE_WEAKREF
|
||||
self->in_weakreflist = NULL;
|
||||
#endif
|
||||
|
||||
MYDB_BEGIN_ALLOW_THREADS;
|
||||
#if (DBVER >= 40)
|
||||
|
@ -1015,13 +897,10 @@ newDBTxnObject(DBEnvObject* myenv, DB_TXN *parent, int flags)
|
|||
static void
|
||||
DBTxn_dealloc(DBTxnObject* self)
|
||||
{
|
||||
#ifdef HAVE_WEAKREF
|
||||
if (self->in_weakreflist != NULL) {
|
||||
PyObject_ClearWeakRefs((PyObject *) self);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WARNINGS
|
||||
if (self->txn) {
|
||||
/* it hasn't been finalized, abort it! */
|
||||
MYDB_BEGIN_ALLOW_THREADS;
|
||||
|
@ -1034,7 +913,6 @@ DBTxn_dealloc(DBTxnObject* self)
|
|||
PyErr_Warn(PyExc_RuntimeWarning,
|
||||
"DBTxn aborted in destructor. No prior commit() or abort().");
|
||||
}
|
||||
#endif
|
||||
|
||||
Py_DECREF(self->env);
|
||||
PyObject_Del(self);
|
||||
|
@ -1049,9 +927,7 @@ newDBLockObject(DBEnvObject* myenv, u_int32_t locker, DBT* obj,
|
|||
DBLockObject* self = PyObject_New(DBLockObject, &DBLock_Type);
|
||||
if (self == NULL)
|
||||
return NULL;
|
||||
#ifdef HAVE_WEAKREF
|
||||
self->in_weakreflist = NULL;
|
||||
#endif
|
||||
|
||||
MYDB_BEGIN_ALLOW_THREADS;
|
||||
#if (DBVER >= 40)
|
||||
|
@ -1073,11 +949,9 @@ newDBLockObject(DBEnvObject* myenv, u_int32_t locker, DBT* obj,
|
|||
static void
|
||||
DBLock_dealloc(DBLockObject* self)
|
||||
{
|
||||
#ifdef HAVE_WEAKREF
|
||||
if (self->in_weakreflist != NULL) {
|
||||
PyObject_ClearWeakRefs((PyObject *) self);
|
||||
}
|
||||
#endif
|
||||
/* TODO: is this lock held? should we release it? */
|
||||
|
||||
PyObject_Del(self);
|
||||
|
@ -1094,9 +968,7 @@ newDBSequenceObject(DBObject* mydb, int flags)
|
|||
return NULL;
|
||||
Py_INCREF(mydb);
|
||||
self->mydb = mydb;
|
||||
#ifdef HAVE_WEAKREF
|
||||
self->in_weakreflist = NULL;
|
||||
#endif
|
||||
|
||||
|
||||
MYDB_BEGIN_ALLOW_THREADS;
|
||||
|
@ -1115,11 +987,9 @@ newDBSequenceObject(DBObject* mydb, int flags)
|
|||
static void
|
||||
DBSequence_dealloc(DBSequenceObject* self)
|
||||
{
|
||||
#ifdef HAVE_WEAKREF
|
||||
if (self->in_weakreflist != NULL) {
|
||||
PyObject_ClearWeakRefs((PyObject *) self);
|
||||
}
|
||||
#endif
|
||||
|
||||
Py_DECREF(self->mydb);
|
||||
PyObject_Del(self);
|
||||
|
@ -1201,13 +1071,7 @@ _db_associateCallback(DB* db, const DBT* priKey, const DBT* priData,
|
|||
Py_ssize_t size;
|
||||
|
||||
CLEAR_DBT(*secKey);
|
||||
#if PYTHON_API_VERSION <= 1007
|
||||
/* 1.5 compatibility */
|
||||
size = PyString_Size(result);
|
||||
data = PyString_AsString(result);
|
||||
#else
|
||||
PyString_AsStringAndSize(result, &data, &size);
|
||||
#endif
|
||||
secKey->flags = DB_DBT_APPMALLOC; /* DB will free */
|
||||
secKey->data = malloc(size); /* TODO, check this */
|
||||
if (secKey->data) {
|
||||
|
@ -1346,7 +1210,6 @@ DB_close(DBObject* self, PyObject* args)
|
|||
}
|
||||
|
||||
|
||||
#if (DBVER >= 32)
|
||||
static PyObject*
|
||||
_DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
|
||||
{
|
||||
|
@ -1414,8 +1277,6 @@ DB_consume_wait(DBObject* self, PyObject* args, PyObject* kwargs,
|
|||
{
|
||||
return _DB_consume(self, args, kwargs, DB_CONSUME_WAIT);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static PyObject*
|
||||
|
@ -2423,7 +2284,6 @@ DB_set_re_source(DBObject* self, PyObject* args)
|
|||
}
|
||||
|
||||
|
||||
#if (DBVER >= 32)
|
||||
static PyObject*
|
||||
DB_set_q_extentsize(DBObject* self, PyObject* args)
|
||||
{
|
||||
|
@ -2440,7 +2300,6 @@ DB_set_q_extentsize(DBObject* self, PyObject* args)
|
|||
RETURN_IF_ERR();
|
||||
RETURN_NONE();
|
||||
}
|
||||
#endif
|
||||
|
||||
static PyObject*
|
||||
DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
|
||||
|
@ -4025,7 +3884,6 @@ DBEnv_set_cachesize(DBEnvObject* self, PyObject* args)
|
|||
}
|
||||
|
||||
|
||||
#if (DBVER >= 32)
|
||||
static PyObject*
|
||||
DBEnv_set_flags(DBEnvObject* self, PyObject* args)
|
||||
{
|
||||
|
@ -4042,7 +3900,6 @@ DBEnv_set_flags(DBEnvObject* self, PyObject* args)
|
|||
RETURN_IF_ERR();
|
||||
RETURN_NONE();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static PyObject*
|
||||
|
@ -4169,7 +4026,6 @@ DBEnv_set_lk_max(DBEnvObject* self, PyObject* args)
|
|||
#endif
|
||||
|
||||
|
||||
#if (DBVER >= 32)
|
||||
|
||||
static PyObject*
|
||||
DBEnv_set_lk_max_locks(DBEnvObject* self, PyObject* args)
|
||||
|
@ -4221,8 +4077,6 @@ DBEnv_set_lk_max_objects(DBEnvObject* self, PyObject* args)
|
|||
RETURN_NONE();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static PyObject*
|
||||
DBEnv_set_mp_mmapsize(DBEnvObject* self, PyObject* args)
|
||||
|
@ -4543,19 +4397,15 @@ DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
|
|||
MAKE_ENTRY(lastid);
|
||||
#endif
|
||||
MAKE_ENTRY(nmodes);
|
||||
#if (DBVER >= 32)
|
||||
MAKE_ENTRY(maxlocks);
|
||||
MAKE_ENTRY(maxlockers);
|
||||
MAKE_ENTRY(maxobjects);
|
||||
MAKE_ENTRY(nlocks);
|
||||
MAKE_ENTRY(maxnlocks);
|
||||
#endif
|
||||
MAKE_ENTRY(nlockers);
|
||||
MAKE_ENTRY(maxnlockers);
|
||||
#if (DBVER >= 32)
|
||||
MAKE_ENTRY(nobjects);
|
||||
MAKE_ENTRY(maxnobjects);
|
||||
#endif
|
||||
MAKE_ENTRY(nrequests);
|
||||
MAKE_ENTRY(nreleases);
|
||||
#if (DBVER < 44)
|
||||
|
@ -5143,10 +4993,8 @@ static PyMethodDef DB_methods[] = {
|
|||
{"associate", (PyCFunction)DB_associate, METH_VARARGS|METH_KEYWORDS},
|
||||
#endif
|
||||
{"close", (PyCFunction)DB_close, METH_VARARGS},
|
||||
#if (DBVER >= 32)
|
||||
{"consume", (PyCFunction)DB_consume, METH_VARARGS|METH_KEYWORDS},
|
||||
{"consume_wait", (PyCFunction)DB_consume_wait, METH_VARARGS|METH_KEYWORDS},
|
||||
#endif
|
||||
{"cursor", (PyCFunction)DB_cursor, METH_VARARGS|METH_KEYWORDS},
|
||||
{"delete", (PyCFunction)DB_delete, METH_VARARGS|METH_KEYWORDS},
|
||||
{"fd", (PyCFunction)DB_fd, METH_VARARGS},
|
||||
|
@ -5184,9 +5032,7 @@ static PyMethodDef DB_methods[] = {
|
|||
{"set_re_len", (PyCFunction)DB_set_re_len, METH_VARARGS},
|
||||
{"set_re_pad", (PyCFunction)DB_set_re_pad, METH_VARARGS},
|
||||
{"set_re_source", (PyCFunction)DB_set_re_source, METH_VARARGS},
|
||||
#if (DBVER >= 32)
|
||||
{"set_q_extentsize",(PyCFunction)DB_set_q_extentsize,METH_VARARGS},
|
||||
#endif
|
||||
{"stat", (PyCFunction)DB_stat, METH_VARARGS|METH_KEYWORDS},
|
||||
{"sync", (PyCFunction)DB_sync, METH_VARARGS},
|
||||
#if (DBVER >= 33)
|
||||
|
@ -5254,9 +5100,7 @@ static PyMethodDef DBEnv_methods[] = {
|
|||
{"set_shm_key", (PyCFunction)DBEnv_set_shm_key, METH_VARARGS},
|
||||
{"set_cachesize", (PyCFunction)DBEnv_set_cachesize, METH_VARARGS},
|
||||
{"set_data_dir", (PyCFunction)DBEnv_set_data_dir, METH_VARARGS},
|
||||
#if (DBVER >= 32)
|
||||
{"set_flags", (PyCFunction)DBEnv_set_flags, METH_VARARGS},
|
||||
#endif
|
||||
{"set_lg_bsize", (PyCFunction)DBEnv_set_lg_bsize, METH_VARARGS},
|
||||
{"set_lg_dir", (PyCFunction)DBEnv_set_lg_dir, METH_VARARGS},
|
||||
{"set_lg_max", (PyCFunction)DBEnv_set_lg_max, METH_VARARGS},
|
||||
|
@ -5267,11 +5111,9 @@ static PyMethodDef DBEnv_methods[] = {
|
|||
#if (DBVER < 45)
|
||||
{"set_lk_max", (PyCFunction)DBEnv_set_lk_max, METH_VARARGS},
|
||||
#endif
|
||||
#if (DBVER >= 32)
|
||||
{"set_lk_max_locks", (PyCFunction)DBEnv_set_lk_max_locks, METH_VARARGS},
|
||||
{"set_lk_max_lockers", (PyCFunction)DBEnv_set_lk_max_lockers, METH_VARARGS},
|
||||
{"set_lk_max_objects", (PyCFunction)DBEnv_set_lk_max_objects, METH_VARARGS},
|
||||
#endif
|
||||
{"set_mp_mmapsize", (PyCFunction)DBEnv_set_mp_mmapsize, METH_VARARGS},
|
||||
{"set_tmp_dir", (PyCFunction)DBEnv_set_tmp_dir, METH_VARARGS},
|
||||
{"txn_begin", (PyCFunction)DBEnv_txn_begin, METH_VARARGS|METH_KEYWORDS},
|
||||
|
@ -5391,7 +5233,6 @@ statichere PyTypeObject DB_Type = {
|
|||
0, /*tp_as_sequence*/
|
||||
&DB_mapping,/*tp_as_mapping*/
|
||||
0, /*tp_hash*/
|
||||
#ifdef HAVE_WEAKREF
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
|
@ -5403,7 +5244,6 @@ statichere PyTypeObject DB_Type = {
|
|||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
offsetof(DBObject, in_weakreflist), /* tp_weaklistoffset */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -5424,7 +5264,6 @@ statichere PyTypeObject DBCursor_Type = {
|
|||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /*tp_hash*/
|
||||
#ifdef HAVE_WEAKREF
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
|
@ -5436,7 +5275,6 @@ statichere PyTypeObject DBCursor_Type = {
|
|||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
offsetof(DBCursorObject, in_weakreflist), /* tp_weaklistoffset */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -5457,7 +5295,6 @@ statichere PyTypeObject DBEnv_Type = {
|
|||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /*tp_hash*/
|
||||
#ifdef HAVE_WEAKREF
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
|
@ -5469,7 +5306,6 @@ statichere PyTypeObject DBEnv_Type = {
|
|||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
offsetof(DBEnvObject, in_weakreflist), /* tp_weaklistoffset */
|
||||
#endif
|
||||
};
|
||||
|
||||
statichere PyTypeObject DBTxn_Type = {
|
||||
|
@ -5489,7 +5325,6 @@ statichere PyTypeObject DBTxn_Type = {
|
|||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /*tp_hash*/
|
||||
#ifdef HAVE_WEAKREF
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
|
@ -5501,7 +5336,6 @@ statichere PyTypeObject DBTxn_Type = {
|
|||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
offsetof(DBTxnObject, in_weakreflist), /* tp_weaklistoffset */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -5522,7 +5356,6 @@ statichere PyTypeObject DBLock_Type = {
|
|||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /*tp_hash*/
|
||||
#ifdef HAVE_WEAKREF
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
|
@ -5534,7 +5367,6 @@ statichere PyTypeObject DBLock_Type = {
|
|||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
offsetof(DBLockObject, in_weakreflist), /* tp_weaklistoffset */
|
||||
#endif
|
||||
};
|
||||
|
||||
#if (DBVER >= 43)
|
||||
|
@ -5555,7 +5387,6 @@ statichere PyTypeObject DBSequence_Type = {
|
|||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /*tp_hash*/
|
||||
#ifdef HAVE_WEAKREF
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
|
@ -5567,7 +5398,6 @@ statichere PyTypeObject DBSequence_Type = {
|
|||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
offsetof(DBSequenceObject, in_weakreflist), /* tp_weaklistoffset */
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -5649,6 +5479,9 @@ static PyMethodDef bsddb_methods[] = {
|
|||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
/* API structure */
|
||||
static BSDDB_api bsddb_api;
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Module initialization */
|
||||
|
@ -5669,6 +5502,7 @@ DL_EXPORT(void) init_bsddb(void)
|
|||
PyObject* pybsddb_version_s = PyString_FromString( PY_BSDDB_VERSION );
|
||||
PyObject* db_version_s = PyString_FromString( DB_VERSION_STRING );
|
||||
PyObject* cvsid_s = PyString_FromString( rcs_id );
|
||||
PyObject* py_api;
|
||||
|
||||
/* Initialize the type of the new type objects here; doing it here
|
||||
is required for portability to Windows without requiring C++. */
|
||||
|
@ -5730,9 +5564,7 @@ DL_EXPORT(void) init_bsddb(void)
|
|||
ADD_INT(d, DB_INIT_LOG);
|
||||
ADD_INT(d, DB_INIT_MPOOL);
|
||||
ADD_INT(d, DB_INIT_TXN);
|
||||
#if (DBVER >= 32)
|
||||
ADD_INT(d, DB_JOINENV);
|
||||
#endif
|
||||
|
||||
ADD_INT(d, DB_RECOVER);
|
||||
ADD_INT(d, DB_RECOVER_FATAL);
|
||||
|
@ -5753,11 +5585,9 @@ DL_EXPORT(void) init_bsddb(void)
|
|||
ADD_INT(d, DB_RDWRMASTER);
|
||||
ADD_INT(d, DB_RDONLY);
|
||||
ADD_INT(d, DB_TRUNCATE);
|
||||
#if (DBVER >= 32)
|
||||
ADD_INT(d, DB_EXTENT);
|
||||
ADD_INT(d, DB_CDB_ALLDB);
|
||||
ADD_INT(d, DB_VERIFY);
|
||||
#endif
|
||||
ADD_INT(d, DB_UPGRADE);
|
||||
|
||||
ADD_INT(d, DB_AGGRESSIVE);
|
||||
|
@ -5801,9 +5631,7 @@ DL_EXPORT(void) init_bsddb(void)
|
|||
ADD_INT(d, DB_LOCK_READ);
|
||||
ADD_INT(d, DB_LOCK_WRITE);
|
||||
ADD_INT(d, DB_LOCK_NOWAIT);
|
||||
#if (DBVER >= 32)
|
||||
ADD_INT(d, DB_LOCK_WAIT);
|
||||
#endif
|
||||
ADD_INT(d, DB_LOCK_IWRITE);
|
||||
ADD_INT(d, DB_LOCK_IREAD);
|
||||
ADD_INT(d, DB_LOCK_IWR);
|
||||
|
@ -5818,9 +5646,7 @@ DL_EXPORT(void) init_bsddb(void)
|
|||
|
||||
ADD_INT(d, DB_LOCK_RECORD);
|
||||
ADD_INT(d, DB_LOCK_UPGRADE);
|
||||
#if (DBVER >= 32)
|
||||
ADD_INT(d, DB_LOCK_SWITCH);
|
||||
#endif
|
||||
#if (DBVER >= 33)
|
||||
ADD_INT(d, DB_LOCK_UPGRADE_WRITE);
|
||||
#endif
|
||||
|
@ -5881,9 +5707,7 @@ DL_EXPORT(void) init_bsddb(void)
|
|||
ADD_INT(d, DB_COMMIT);
|
||||
#endif
|
||||
ADD_INT(d, DB_CONSUME);
|
||||
#if (DBVER >= 32)
|
||||
ADD_INT(d, DB_CONSUME_WAIT);
|
||||
#endif
|
||||
ADD_INT(d, DB_CURRENT);
|
||||
#if (DBVER >= 33)
|
||||
ADD_INT(d, DB_FAST_STAT);
|
||||
|
@ -6061,6 +5885,19 @@ DL_EXPORT(void) init_bsddb(void)
|
|||
|
||||
#undef MAKE_EX
|
||||
|
||||
/* Initiliase the C API structure and add it to the module */
|
||||
bsddb_api.db_type = &DB_Type;
|
||||
bsddb_api.dbcursor_type = &DBCursor_Type;
|
||||
bsddb_api.dbenv_type = &DBEnv_Type;
|
||||
bsddb_api.dbtxn_type = &DBTxn_Type;
|
||||
bsddb_api.dblock_type = &DBLock_Type;
|
||||
bsddb_api.dbsequence_type = &DBSequence_Type;
|
||||
bsddb_api.makeDBError = makeDBError;
|
||||
|
||||
py_api = PyCObject_FromVoidPtr((void*)&bsddb_api, NULL);
|
||||
PyDict_SetItemString(d, "api", py_api);
|
||||
Py_DECREF(py_api);
|
||||
|
||||
/* Check for errors */
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
|
|
|
@ -0,0 +1,238 @@
|
|||
/*----------------------------------------------------------------------
|
||||
Copyright (c) 1999-2001, Digital Creations, Fredericksburg, VA, USA
|
||||
and Andrew Kuchling. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
o Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions, and the disclaimer that follows.
|
||||
|
||||
o Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions, and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
o Neither the name of Digital Creations nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
|
||||
IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
|
||||
CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*
|
||||
* Handwritten code to wrap version 3.x of the Berkeley DB library,
|
||||
* written to replace a SWIG-generated file. It has since been updated
|
||||
* to compile with BerkeleyDB versions 3.2 through 4.2.
|
||||
*
|
||||
* This module was started by Andrew Kuchling to remove the dependency
|
||||
* on SWIG in a package by Gregory P. Smith who based his work on a
|
||||
* similar package by Robin Dunn <robin@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
|
||||
*/
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Work to split it up into a separate header and to add a C API was
|
||||
* contributed by Duncan Grisby <duncan@tideway.com>. See here:
|
||||
* http://sourceforge.net/tracker/index.php?func=detail&aid=1551895&group_id=13900&atid=313900
|
||||
*/
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#ifndef _BSDDB_H_
|
||||
#define _BSDDB_H_
|
||||
|
||||
#include <db.h>
|
||||
|
||||
|
||||
/* 40 = 4.0, 33 = 3.3; this will break if the minor revision is > 9 */
|
||||
#define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
|
||||
#if DB_VERSION_MINOR > 9
|
||||
#error "eek! DBVER can't handle minor versions > 9"
|
||||
#endif
|
||||
|
||||
#define PY_BSDDB_VERSION "4.6.0"
|
||||
|
||||
/* Python object definitions */
|
||||
|
||||
struct behaviourFlags {
|
||||
/* What is the default behaviour when DB->get or DBCursor->get returns a
|
||||
DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise an exception? */
|
||||
unsigned int getReturnsNone : 1;
|
||||
/* What is the default behaviour for DBCursor.set* methods when DBCursor->get
|
||||
* returns a DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise? */
|
||||
unsigned int cursorSetReturnsNone : 1;
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
DB_ENV* db_env;
|
||||
u_int32_t flags; /* saved flags from open() */
|
||||
int closed;
|
||||
struct behaviourFlags moduleFlags;
|
||||
PyObject *in_weakreflist; /* List of weak references */
|
||||
} DBEnvObject;
|
||||
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
DB* db;
|
||||
DBEnvObject* myenvobj; /* PyObject containing the DB_ENV */
|
||||
u_int32_t flags; /* saved flags from open() */
|
||||
u_int32_t setflags; /* saved flags from set_flags() */
|
||||
int haveStat;
|
||||
struct behaviourFlags moduleFlags;
|
||||
#if (DBVER >= 33)
|
||||
PyObject* associateCallback;
|
||||
PyObject* btCompareCallback;
|
||||
int primaryDBType;
|
||||
#endif
|
||||
PyObject *in_weakreflist; /* List of weak references */
|
||||
} DBObject;
|
||||
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
DBC* dbc;
|
||||
DBObject* mydb;
|
||||
PyObject *in_weakreflist; /* List of weak references */
|
||||
} DBCursorObject;
|
||||
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
DB_TXN* txn;
|
||||
PyObject *env;
|
||||
PyObject *in_weakreflist; /* List of weak references */
|
||||
} DBTxnObject;
|
||||
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
DB_LOCK lock;
|
||||
PyObject *in_weakreflist; /* List of weak references */
|
||||
} DBLockObject;
|
||||
|
||||
|
||||
#if (DBVER >= 43)
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
DB_SEQUENCE* sequence;
|
||||
DBObject* mydb;
|
||||
PyObject *in_weakreflist; /* List of weak references */
|
||||
} DBSequenceObject;
|
||||
staticforward PyTypeObject DBSequence_Type;
|
||||
#endif
|
||||
|
||||
|
||||
/* API structure for use by C code */
|
||||
|
||||
/* To access the structure from an external module, use code like the
|
||||
following (error checking missed out for clarity):
|
||||
|
||||
BSDDB_api* bsddb_api;
|
||||
PyObject* mod;
|
||||
PyObject* cobj;
|
||||
|
||||
mod = PyImport_ImportModule("bsddb._bsddb");
|
||||
// Use "bsddb3._pybsddb" if you're using the standalone pybsddb add-on.
|
||||
cobj = PyObject_GetAttrString(mod, "api");
|
||||
api = (BSDDB_api*)PyCObject_AsVoidPtr(cobj);
|
||||
Py_DECREF(cobj);
|
||||
Py_DECREF(mod);
|
||||
|
||||
The structure's members must not be changed.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/* Type objects */
|
||||
PyTypeObject* db_type;
|
||||
PyTypeObject* dbcursor_type;
|
||||
PyTypeObject* dbenv_type;
|
||||
PyTypeObject* dbtxn_type;
|
||||
PyTypeObject* dblock_type;
|
||||
#if (DBVER >= 43)
|
||||
PyTypeObject* dbsequence_type;
|
||||
#endif
|
||||
|
||||
/* Functions */
|
||||
int (*makeDBError)(int err);
|
||||
|
||||
} BSDDB_api;
|
||||
|
||||
|
||||
#ifndef COMPILING_BSDDB_C
|
||||
|
||||
/* If not inside _bsddb.c, define type check macros that use the api
|
||||
structure. The calling code must have a value named bsddb_api
|
||||
pointing to the api structure.
|
||||
*/
|
||||
|
||||
#define DBObject_Check(v) ((v)->ob_type == bsddb_api->db_type)
|
||||
#define DBCursorObject_Check(v) ((v)->ob_type == bsddb_api->dbcursor_type)
|
||||
#define DBEnvObject_Check(v) ((v)->ob_type == bsddb_api->dbenv_type)
|
||||
#define DBTxnObject_Check(v) ((v)->ob_type == bsddb_api->dbtxn_type)
|
||||
#define DBLockObject_Check(v) ((v)->ob_type == bsddb_api->dblock_type)
|
||||
#if (DBVER >= 43)
|
||||
#define DBSequenceObject_Check(v) ((v)->ob_type == bsddb_api->dbsequence_type)
|
||||
#endif
|
||||
|
||||
#endif // COMPILING_BSDDB_C
|
||||
|
||||
|
||||
#endif // _BSDDB_H_
|
1
setup.py
1
setup.py
|
@ -801,6 +801,7 @@ class PyBuildExt(build_ext):
|
|||
# some unusual system configurations (e.g. the directory
|
||||
# is on an NFS server that goes away).
|
||||
exts.append(Extension('_bsddb', ['_bsddb.c'],
|
||||
depends = ['bsddb.h'],
|
||||
library_dirs=dblib_dir,
|
||||
runtime_library_dirs=dblib_dir,
|
||||
include_dirs=db_incs,
|
||||
|
|
Loading…
Reference in New Issue