aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Modules/_bsddb.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_bsddb.c')
-rw-r--r--Modules/_bsddb.c211
1 files changed, 28 insertions, 183 deletions
diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c
index 175dec3d49d..befdd7b6b80 100644
--- a/Modules/_bsddb.c
+++ b/Modules/_bsddb.c
@@ -87,20 +87,15 @@
#include <stddef.h> /* for offsetof() */
#include <Python.h>
-#include <db.h>
-/* --------------------------------------------------------------------- */
-/* Various macro definitions */
+#define COMPILING_BSDDB_C
+#include "bsddb.h"
+#undef COMPILING_BSDDB_C
-/* 40 = 4.0, 33 = 3.3; this will break if the second number is > 9 */
-#define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
-#if DB_VERSION_MINOR > 9
-#error "eek! DBVER can't handle minor versions > 9"
-#endif
-
-#define PY_BSDDB_VERSION "4.5.0"
static char *svn_id = "$Id$";
+/* --------------------------------------------------------------------- */
+/* Various macro definitions */
#if (PY_VERSION_HEX < 0x02050000)
typedef int Py_ssize_t;
@@ -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
-#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
+#if PYTHON_API_VERSION < 1010
+#error "Python 2.1 or later required"
#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;
-static PyTypeObject DBSequence_Type;
-#endif
static PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type, DBLock_Type;
@@ -628,12 +531,7 @@ static int makeDBError(int err)
strncat(errTxt, _db_errmsg, bytes_left);
}
_db_errmsg[0] = 0;
-#ifdef HAVE_WARNINGS
exceptionRaised = PyErr_WarnEx(PyExc_RuntimeWarning, errTxt, 1);
-#else
- fprintf(stderr, errTxt);
- fprintf(stderr, "\n");
-#endif
#else /* do an exception instead */
errObj = DBIncompleteError;
@@ -887,9 +785,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) {
@@ -940,21 +836,17 @@ DB_dealloc(DBObject* self)
MYDB_BEGIN_ALLOW_THREADS;
self->db->close(self->db, 0);
MYDB_END_ALLOW_THREADS;
-#ifdef HAVE_WARNINGS
} else {
PyErr_WarnEx(PyExc_RuntimeWarning,
"DB could not be closed in destructor:"
" DBEnv already closed",
1);
-#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;
@@ -982,9 +874,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;
}
@@ -995,11 +885,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;
@@ -1032,9 +920,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);
@@ -1053,11 +939,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;
@@ -1077,9 +961,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)
@@ -1100,13 +982,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;
@@ -1121,7 +1000,6 @@ DBTxn_dealloc(DBTxnObject* self)
" No prior commit() or abort().",
1);
}
-#endif
Py_DECREF(self->env);
PyObject_Del(self);
@@ -1136,9 +1014,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)
@@ -1160,11 +1036,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);
@@ -1181,9 +1055,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;
@@ -1202,11 +1074,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);
@@ -1432,7 +1302,6 @@ DB_close(DBObject* self, PyObject* args)
}
-#if (DBVER >= 32)
static PyObject*
_DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
{
@@ -1500,8 +1369,6 @@ DB_consume_wait(DBObject* self, PyObject* args, PyObject* kwargs,
{
return _DB_consume(self, args, kwargs, DB_CONSUME_WAIT);
}
-#endif
-
static PyObject*
@@ -2526,7 +2393,6 @@ DB_set_re_source(DBObject* self, PyObject* args)
}
-#if (DBVER >= 32)
static PyObject*
DB_set_q_extentsize(DBObject* self, PyObject* args)
{
@@ -2543,7 +2409,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)
@@ -4144,7 +4009,6 @@ DBEnv_set_cachesize(DBEnvObject* self, PyObject* args)
}
-#if (DBVER >= 32)
static PyObject*
DBEnv_set_flags(DBEnvObject* self, PyObject* args)
{
@@ -4161,7 +4025,6 @@ DBEnv_set_flags(DBEnvObject* self, PyObject* args)
RETURN_IF_ERR();
RETURN_NONE();
}
-#endif
static PyObject*
@@ -4288,7 +4151,6 @@ DBEnv_set_lk_max(DBEnvObject* self, PyObject* args)
#endif
-#if (DBVER >= 32)
static PyObject*
DBEnv_set_lk_max_locks(DBEnvObject* self, PyObject* args)
@@ -4340,8 +4202,6 @@ DBEnv_set_lk_max_objects(DBEnvObject* self, PyObject* args)
RETURN_NONE();
}
-#endif
-
static PyObject*
DBEnv_set_mp_mmapsize(DBEnvObject* self, PyObject* args)
@@ -4664,19 +4524,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)
@@ -5024,7 +4880,7 @@ DBSequence_get_key(DBSequenceObject* self, PyObject* args)
{
int err;
DBT key;
- PyObject *retval;
+ PyObject *retval = NULL;
key.flags = DB_DBT_MALLOC;
CHECK_SEQUENCE_NOT_CLOSED(self)
MYDB_BEGIN_ALLOW_THREADS
@@ -5265,10 +5121,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},
@@ -5306,9 +5160,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)
@@ -5376,9 +5228,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},
@@ -5389,11 +5239,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},
@@ -5512,7 +5360,6 @@ static 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 */
@@ -5524,7 +5371,6 @@ static PyTypeObject DB_Type = {
0, /* tp_clear */
0, /* tp_richcompare */
offsetof(DBObject, in_weakreflist), /* tp_weaklistoffset */
-#endif
};
@@ -5544,7 +5390,6 @@ static 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 */
@@ -5556,7 +5401,6 @@ static PyTypeObject DBCursor_Type = {
0, /* tp_clear */
0, /* tp_richcompare */
offsetof(DBCursorObject, in_weakreflist), /* tp_weaklistoffset */
-#endif
};
@@ -5576,7 +5420,6 @@ static 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 */
@@ -5588,7 +5431,6 @@ static PyTypeObject DBEnv_Type = {
0, /* tp_clear */
0, /* tp_richcompare */
offsetof(DBEnvObject, in_weakreflist), /* tp_weaklistoffset */
-#endif
};
static PyTypeObject DBTxn_Type = {
@@ -5607,7 +5449,6 @@ static 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 */
@@ -5619,7 +5460,6 @@ static PyTypeObject DBTxn_Type = {
0, /* tp_clear */
0, /* tp_richcompare */
offsetof(DBTxnObject, in_weakreflist), /* tp_weaklistoffset */
-#endif
};
@@ -5639,7 +5479,6 @@ static 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 */
@@ -5651,7 +5490,6 @@ static PyTypeObject DBLock_Type = {
0, /* tp_clear */
0, /* tp_richcompare */
offsetof(DBLockObject, in_weakreflist), /* tp_weaklistoffset */
-#endif
};
#if (DBVER >= 43)
@@ -5671,7 +5509,6 @@ static 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 */
@@ -5683,7 +5520,6 @@ static PyTypeObject DBSequence_Type = {
0, /* tp_clear */
0, /* tp_richcompare */
offsetof(DBSequenceObject, in_weakreflist), /* tp_weaklistoffset */
-#endif
};
#endif
@@ -5765,6 +5601,9 @@ static PyMethodDef bsddb_methods[] = {
{NULL, NULL} /* sentinel */
};
+/* API structure */
+static BSDDB_api bsddb_api;
+
/* --------------------------------------------------------------------- */
/* Module initialization */
@@ -5785,6 +5624,7 @@ PyMODINIT_FUNC init_bsddb(void)
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 the type of the new type objects here; doing it here
is required for portability to Windows without requiring C++. */
@@ -5846,9 +5686,7 @@ PyMODINIT_FUNC 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);
@@ -5869,11 +5707,9 @@ PyMODINIT_FUNC 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);
@@ -5917,9 +5753,7 @@ PyMODINIT_FUNC 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);
@@ -5934,9 +5768,7 @@ PyMODINIT_FUNC 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
@@ -5997,9 +5829,7 @@ PyMODINIT_FUNC 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);
@@ -6182,6 +6012,21 @@ PyMODINIT_FUNC 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;
+#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();