diff options
Diffstat (limited to 'Modules/_bsddb.c')
-rw-r--r-- | Modules/_bsddb.c | 211 |
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(); |