summaryrefslogtreecommitdiffstats
path: root/Modules/_bsddb.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_bsddb.c')
-rw-r--r--Modules/_bsddb.c407
1 files changed, 333 insertions, 74 deletions
diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c
index 5834d51..9bb339c 100644
--- a/Modules/_bsddb.c
+++ b/Modules/_bsddb.c
@@ -35,16 +35,23 @@
/*
* Handwritten code to wrap version 3.x of the Berkeley DB library,
- * written to replace a SWIG-generated file.
+ * written to replace a SWIG-generated file. It has since been updated
+ * to compile with BerkeleyDB versions 3.2 through 4.1.
*
* This module was started by Andrew Kuchling to remove the dependency
* on SWIG in a package by Gregory P. Smith <greg@electricrain.com> 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 has now returned full circle back to
- * Robin Dunn who is working in behalf of Digital Creations to complete
- * the wrapping of the DB 3.x API and to build a solid unit test suite.
+ * 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@electricrain.com> 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 module contains 5 types:
*
@@ -75,12 +82,10 @@
/* --------------------------------------------------------------------- */
/* Various macro definitions */
-#define PY_BSDDB_VERSION "3.4.2"
-
/* 40 = 4.0, 33 = 3.3; this will break if the second number is > 9 */
#define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
-static char *orig_rcs_id = "/Id: _db.c,v 1.48 2002/11/21 19:11:19 greg Exp /";
+#define PY_BSDDB_VERSION "4.1.1"
static char *rcs_id = "$Id$";
@@ -166,7 +171,7 @@ static PyObject* DBPermissionsError; /* EPERM */
typedef struct {
PyObject_HEAD
DB_ENV* db_env;
- int flags; /* saved flags from open() */
+ u_int32_t flags; /* saved flags from open() */
int closed;
int getReturnsNone;
} DBEnvObject;
@@ -176,8 +181,8 @@ typedef struct {
PyObject_HEAD
DB* db;
DBEnvObject* myenvobj; /* PyObject containing the DB_ENV */
- int flags; /* saved flags from open() */
- int setflags; /* saved flags from set_flags() */
+ u_int32_t flags; /* saved flags from open() */
+ u_int32_t setflags; /* saved flags from set_flags() */
int haveStat;
int getReturnsNone;
#if (DBVER >= 33)
@@ -299,7 +304,8 @@ static int make_dbt(PyObject* obj, DBT* dbt)
what's been given, verifies that it's allowed, and then makes the DBT.
Caller should call FREE_DBT(key) when done. */
-static int make_key_dbt(DBObject* self, PyObject* keyobj, DBT* key, int* pflags)
+static int
+make_key_dbt(DBObject* self, PyObject* keyobj, DBT* key, int* pflags)
{
db_recno_t recno;
int type;
@@ -315,7 +321,9 @@ static int make_key_dbt(DBObject* self, PyObject* keyobj, DBT* key, int* pflags)
if (type == -1)
return 0;
if (type == DB_RECNO || type == DB_QUEUE) {
- PyErr_SetString(PyExc_TypeError, "String keys not allowed for Recno and Queue DB's");
+ PyErr_SetString(
+ PyExc_TypeError,
+ "String keys not allowed for Recno and Queue DB's");
return 0;
}
@@ -329,16 +337,19 @@ static int make_key_dbt(DBObject* self, PyObject* keyobj, DBT* key, int* pflags)
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 */
+ /* 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");
+ 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. */
+ /* 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 = PyInt_AS_LONG(keyobj);
key->data = malloc(sizeof(db_recno_t));
if (key->data == NULL) {
@@ -381,7 +392,8 @@ static int add_partial_dbt(DBT* d, int dlen, int doff) {
}
-/* Callback used to save away more information about errors from the DB library. */
+/* Callback used to save away more information about errors from the DB
+ * library. */
static char _db_errmsg[1024];
static void _db_errorCallback(const char* prefix, char* msg)
{
@@ -393,12 +405,14 @@ static void _db_errorCallback(const char* prefix, char* msg)
static int makeDBError(int err)
{
char errTxt[2048]; /* really big, just in case... */
- PyObject* errObj = NULL;
+ PyObject *errObj = NULL;
+ PyObject *errTuple = NULL;
int exceptionRaised = 0;
switch (err) {
case 0: /* successful, no error */ break;
+#if (DBVER < 41)
case DB_INCOMPLETE:
#if INCOMPLETE_IS_WARNING
strcpy(errTxt, db_strerror(err));
@@ -407,7 +421,8 @@ static int makeDBError(int err)
strcat(errTxt, _db_errmsg);
_db_errmsg[0] = 0;
}
-#if PYTHON_API_VERSION >= 1010 /* if Python 2.1 or better use warning framework */
+/* if Python 2.1 or better use warning framework */
+#if PYTHON_API_VERSION >= 1010
exceptionRaised = PyErr_Warn(PyExc_RuntimeWarning, errTxt);
#else
fprintf(stderr, errTxt);
@@ -418,6 +433,7 @@ static int makeDBError(int err)
errObj = DBIncompleteError;
#endif
break;
+#endif /* DBVER < 41 */
case DB_KEYEMPTY: errObj = DBKeyEmptyError; break;
case DB_KEYEXIST: errObj = DBKeyExistError; break;
@@ -455,7 +471,10 @@ static int makeDBError(int err)
strcat(errTxt, _db_errmsg);
_db_errmsg[0] = 0;
}
- PyErr_SetObject(errObj, Py_BuildValue("(is)", err, errTxt));
+
+ errTuple = Py_BuildValue("(is)", err, errTxt);
+ PyErr_SetObject(errObj, errTuple);
+ Py_DECREF(errTuple);
}
return ((errObj != NULL) || exceptionRaised);
@@ -666,13 +685,16 @@ static void
DB_dealloc(DBObject* self)
{
if (self->db != NULL) {
- /* avoid closing a DB when its DBEnv has been closed out from under it */
+ /* avoid closing a DB when its DBEnv has been closed out from under
+ * it */
if (!self->myenvobj ||
- (self->myenvobj && self->myenvobj->db_env)) {
+ (self->myenvobj && self->myenvobj->db_env))
+ {
MYDB_BEGIN_ALLOW_THREADS;
self->db->close(self->db, 0);
MYDB_END_ALLOW_THREADS;
-#if PYTHON_API_VERSION >= 1010 /* if Python 2.1 or better use warning framework */
+ /* if Python 2.1 or better use warning framework */
+#if PYTHON_API_VERSION >= 1010
} else {
PyErr_Warn(PyExc_RuntimeWarning,
"DB could not be closed in destructor: DBEnv already closed");
@@ -843,7 +865,8 @@ newDBLockObject(DBEnvObject* myenv, u_int32_t locker, DBT* obj,
MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
- err = myenv->db_env->lock_get(myenv->db_env, locker, flags, obj, lock_mode, &self->lock);
+ 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
@@ -907,7 +930,8 @@ DB_append(DBObject* self, PyObject* args)
#if (DBVER >= 33)
static int
-_db_associateCallback(DB* db, const DBT* priKey, const DBT* priData, DBT* secKey)
+_db_associateCallback(DB* db, const DBT* priKey, const DBT* priData,
+ DBT* secKey)
{
int retval = DB_DONOTINDEX;
DBObject* secondaryDB = (DBObject*)db->app_private;
@@ -958,13 +982,21 @@ _db_associateCallback(DB* db, const DBT* priKey, const DBT* priData, DBT* secKey
#endif
secKey->flags = DB_DBT_APPMALLOC; /* DB will free */
secKey->data = malloc(size); /* TODO, check this */
- memcpy(secKey->data, data, size);
- secKey->size = size;
- retval = 0;
+ 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 a string.");
+ PyErr_SetString(
+ PyExc_TypeError,
+ "DB associate callback should return DB_DONOTINDEX or string.");
PyErr_Print();
}
@@ -985,11 +1017,28 @@ 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;
+ char* kwnames[] = {"secondaryDB", "callback", "flags", "txn", NULL};
+#else
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))
+ &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)) {
@@ -1024,10 +1073,18 @@ DB_associate(DBObject* self, PyObject* args, PyObject* kwargs)
*/
PyEval_InitThreads();
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) {
@@ -1083,7 +1140,8 @@ _DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
if (type == -1)
return NULL;
if (type != DB_QUEUE) {
- PyErr_SetString(PyExc_TypeError, "Consume methods only allowed for Queue DB's");
+ PyErr_SetString(PyExc_TypeError,
+ "Consume methods only allowed for Queue DB's");
return NULL;
}
if (!checkTxnObj(txnobj, &txn))
@@ -1107,7 +1165,8 @@ _DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
retval = Py_None;
}
else if (!err) {
- retval = Py_BuildValue("s#s#", key.data, key.size, data.data, data.size);
+ retval = Py_BuildValue("s#s#", key.data, key.size, data.data,
+ data.size);
FREE_DBT(key);
FREE_DBT(data);
}
@@ -1123,7 +1182,8 @@ DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
}
static PyObject*
-DB_consume_wait(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
+DB_consume_wait(DBObject* self, PyObject* args, PyObject* kwargs,
+ int consume_flag)
{
return _DB_consume(self, args, kwargs, DB_CONSUME_WAIT);
}
@@ -1211,10 +1271,11 @@ DB_get(DBObject* self, PyObject* args, PyObject* kwargs)
int doff = -1;
DBT key, data;
DB_TXN *txn = NULL;
- char* kwnames[] = { "key", "default", "txn", "flags", "dlen", "doff", NULL };
+ char* kwnames[] = {"key", "default", "txn", "flags", "dlen", "doff", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:get", kwnames,
- &keyobj, &dfltobj, &txnobj, &flags, &dlen, &doff))
+ &keyobj, &dfltobj, &txnobj, &flags, &dlen,
+ &doff))
return NULL;
CHECK_DB_NOT_CLOSED(self);
@@ -1247,7 +1308,8 @@ DB_get(DBObject* self, PyObject* args, PyObject* kwargs)
}
else if (!err) {
if (flags & DB_SET_RECNO) /* return both key and data */
- retval = Py_BuildValue("s#s#", key.data, key.size, data.data, data.size);
+ retval = Py_BuildValue("s#s#", key.data, key.size, data.data,
+ data.size);
else /* return just the data */
retval = PyString_FromStringAndSize((char*)data.data, data.size);
FREE_DBT(key);
@@ -1415,7 +1477,8 @@ DB_join(DBObject* self, PyObject* args)
CHECK_DB_NOT_CLOSED(self);
if (!PySequence_Check(cursorsObj)) {
- PyErr_SetString(PyExc_TypeError, "Sequence of DBCursor objects expected");
+ PyErr_SetString(PyExc_TypeError,
+ "Sequence of DBCursor objects expected");
return NULL;
}
@@ -1425,7 +1488,8 @@ DB_join(DBObject* self, PyObject* args)
for (x=0; x<length; x++) {
PyObject* item = PySequence_GetItem(cursorsObj, x);
if (!DBCursorObject_Check(item)) {
- PyErr_SetString(PyExc_TypeError, "Sequence of DBCursor objects expected");
+ PyErr_SetString(PyExc_TypeError,
+ "Sequence of DBCursor objects expected");
free(cursors);
return NULL;
}
@@ -1457,7 +1521,8 @@ DB_key_range(DBObject* self, PyObject* args, PyObject* kwargs)
&keyobj, &txnobj, &flags))
return NULL;
CHECK_DB_NOT_CLOSED(self);
- if (!make_dbt(keyobj, &key)) /* BTree only, don't need to allow for an int key */
+ if (!make_dbt(keyobj, &key))
+ /* BTree only, don't need to allow for an int key */
return NULL;
if (!checkTxnObj(txnobj, &txn))
return NULL;
@@ -1477,27 +1542,82 @@ DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
int err, type = DB_UNKNOWN, flags=0, mode=0660;
char* filename = NULL;
char* dbname = NULL;
- char* kwnames[] = { "filename", "dbname", "dbtype", "flags", "mode", NULL };
- char* kwnames2[] = { "filename", "dbtype", "flags", "mode", NULL };
+#if (DBVER >= 41)
+ PyObject *txnobj = NULL;
+ DB_TXN *txn = NULL;
+ /* with dbname */
+ char* kwnames[] = {
+ "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL};
+ /* without dbname */
+ char* kwnames_basic[] = {
+ "filename", "dbtype", "flags", "mode", "txn", NULL};
+#else
+ /* with dbname */
+ char* kwnames[] = {
+ "filename", "dbname", "dbtype", "flags", "mode", NULL};
+ /* without dbname */
+ 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)) {
- PyErr_Clear();
- type = DB_UNKNOWN; flags = 0; mode = 0660;
- filename = NULL; dbname = NULL;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iii:open", kwnames2,
- &filename, &type, &flags, &mode))
- return NULL;
+ &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) {
PyErr_SetObject(DBError, Py_BuildValue("(is)", 0,
"Cannot call open() twice for DB object"));
return NULL;
}
+#if 0 && (DBVER >= 41)
+ if ((!txn) && (txnobj != Py_None) && self->myenvobj
+ && (self->myenvobj->flags & DB_INIT_TXN))
+ {
+ /* If no 'txn' parameter was supplied (no DbTxn object and None was not
+ * explicitly passed) but we are in a transaction ready environment:
+ * add DB_AUTO_COMMIT to allow for older pybsddb apps using transactions
+ * to work on BerkeleyDB 4.1 without needing to modify their
+ * DBEnv or DB open calls.
+ * TODO make this behaviour of the library configurable.
+ */
+ flags |= DB_AUTO_COMMIT;
+ }
+#endif
+
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 = NULL;
@@ -1578,7 +1698,8 @@ DB_rename(DBObject* self, PyObject* args)
char* newname;
int err, flags=0;
- if (!PyArg_ParseTuple(args, "sss|i:rename", &filename, &database, &newname, &flags))
+ if (!PyArg_ParseTuple(args, "sss|i:rename", &filename, &database, &newname,
+ &flags))
return NULL;
CHECK_DB_NOT_CLOSED(self);
@@ -1850,7 +1971,9 @@ DB_stat(DBObject* self, PyObject* args)
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);
@@ -2021,6 +2144,29 @@ DB_set_get_returns_none(DBObject* self, PyObject* args)
return PyInt_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;
+ 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 */
@@ -2033,7 +2179,8 @@ int DB_length(DBObject* self)
void* sp;
if (self->db == NULL) {
- PyErr_SetObject(DBError, Py_BuildValue("(is)", 0, "DB object has been closed"));
+ PyErr_SetObject(DBError,
+ Py_BuildValue("(is)", 0, "DB object has been closed"));
return -1;
}
@@ -2107,7 +2254,8 @@ DB_ass_sub(DBObject* self, PyObject* keyobj, PyObject* dataobj)
int flags = 0;
if (self->db == NULL) {
- PyErr_SetObject(DBError, Py_BuildValue("(is)", 0, "DB object has been closed"));
+ PyErr_SetObject(DBError,
+ Py_BuildValue("(is)", 0, "DB object has been closed"));
return -1;
}
@@ -2119,11 +2267,13 @@ DB_ass_sub(DBObject* self, PyObject* keyobj, PyObject* dataobj)
retval = -1;
else {
if (self->setflags & (DB_DUP|DB_DUPSORT))
- flags = DB_NOOVERWRITE; /* dictionaries shouldn't have duplicate keys */
+ /* 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... */
+ /* 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);
@@ -2148,7 +2298,7 @@ DB_has_key(DBObject* self, PyObject* args)
PyObject* txnobj = NULL;
DB_TXN *txn = NULL;
- if (!PyArg_ParseTuple(args,"O|O:has_key", &keyobj, &txnobj ))
+ 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))
@@ -2244,11 +2394,13 @@ _DB_make_list(DBObject* self, DB_TXN* txn, int type)
case DB_BTREE:
case DB_HASH:
default:
- item = Py_BuildValue("s#s#", key.data, key.size, data.data, data.size);
+ item = Py_BuildValue("s#s#", key.data, key.size, data.data,
+ data.size);
break;
case DB_RECNO:
case DB_QUEUE:
- item = Py_BuildValue("is#", *((db_recno_t*)key.data), data.data, data.size);
+ item = Py_BuildValue("is#", *((db_recno_t*)key.data),
+ data.data, data.size);
break;
}
break;
@@ -2320,7 +2472,6 @@ DB_values(DBObject* self, PyObject* args)
return _DB_make_list(self, txn, _VALUES_LIST);
}
-
/* --------------------------------------------------------------------- */
/* DBCursor methods */
@@ -2433,13 +2584,18 @@ DBC_get(DBCursorObject* self, PyObject* args, PyObject *kwargs)
CLEAR_DBT(key);
CLEAR_DBT(data);
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:get", &kwnames[2],
- &flags, &dlen, &doff)) {
+ &flags, &dlen, &doff))
+ {
PyErr_Clear();
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:get", &kwnames[1],
- &keyobj, &flags, &dlen, &doff)) {
+ 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)) {
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:get",
+ kwnames, &keyobj, &dataobj,
+ &flags, &dlen, &doff))
+ {
return NULL;
}
}
@@ -2763,7 +2919,8 @@ DBC_set_recno(DBCursorObject* self, PyObject* args, PyObject *kwargs)
CLEAR_DBT(key);
recno = (db_recno_t) irecno;
- /* use allocated space so DB will be able to realloc room for the real key */
+ /* 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");
@@ -2924,6 +3081,82 @@ DBEnv_remove(DBEnvObject* self, PyObject* args)
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;
+ char* kwnames[] = { "file", "database", "txn", "flags", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss|Oi: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;
+ char* kwnames[] = { "file", "database", "newname", "txn", "flags", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sss|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;
+ 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 */
static PyObject*
DBEnv_set_cachesize(DBEnvObject* self, PyObject* args)
@@ -3334,7 +3567,9 @@ DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
+#if (DBVER < 41)
MAKE_ENTRY(lastid);
+#endif
MAKE_ENTRY(nmodes);
#if (DBVER >= 32)
MAKE_ENTRY(maxlocks);
@@ -3399,7 +3634,8 @@ DBEnv_log_archive(DBEnvObject* self, PyObject* args)
item = PyString_FromString (*log_list);
if (item == NULL) {
Py_DECREF(list);
- PyErr_SetString(PyExc_MemoryError, "List item creation failed");
+ PyErr_SetString(PyExc_MemoryError,
+ "List item creation failed");
list = NULL;
break;
}
@@ -3612,6 +3848,9 @@ static PyMethodDef DB_methods[] = {
{"rename", (PyCFunction)DB_rename, METH_VARARGS},
{"set_bt_minkey", (PyCFunction)DB_set_bt_minkey, METH_VARARGS},
{"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},
@@ -3676,6 +3915,11 @@ 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
{"set_cachesize", (PyCFunction)DBEnv_set_cachesize, METH_VARARGS},
{"set_data_dir", (PyCFunction)DBEnv_set_data_dir, METH_VARARGS},
#if (DBVER >= 32)
@@ -3866,7 +4110,8 @@ DB_construct(PyObject* self, PyObject* args, PyObject* kwargs)
int flags = 0;
char* kwnames[] = { "dbEnv", "flags", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:DB", kwnames, &dbenvobj, &flags))
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:DB", kwnames,
+ &dbenvobj, &flags))
return NULL;
if (dbenvobj == Py_None)
dbenvobj = NULL;
@@ -4036,7 +4281,8 @@ DL_EXPORT(void) init_bsddb(void)
#if (DBVER >= 33)
- _addIntToDict(d, "DB_LOCK_CONFLICT", 0); /* docs say to use zero instead */
+ /* docs say to use zero instead */
+ _addIntToDict(d, "DB_LOCK_CONFLICT", 0);
#else
ADD_INT(d, DB_LOCK_CONFLICT);
#endif
@@ -4111,7 +4357,12 @@ DL_EXPORT(void) init_bsddb(void)
ADD_INT(d, DB_APPEND);
ADD_INT(d, DB_BEFORE);
ADD_INT(d, DB_CACHED_COUNTS);
+#if (DBVER >= 41)
+ _addIntToDict(d, "DB_CHECKPOINT", 0);
+#else
ADD_INT(d, DB_CHECKPOINT);
+ ADD_INT(d, DB_CURLSN);
+#endif
#if (DBVER >= 33)
ADD_INT(d, DB_COMMIT);
#endif
@@ -4119,7 +4370,6 @@ DL_EXPORT(void) init_bsddb(void)
#if (DBVER >= 32)
ADD_INT(d, DB_CONSUME_WAIT);
#endif
- ADD_INT(d, DB_CURLSN);
ADD_INT(d, DB_CURRENT);
#if (DBVER >= 33)
ADD_INT(d, DB_FAST_STAT);
@@ -4159,7 +4409,11 @@ DL_EXPORT(void) init_bsddb(void)
ADD_INT(d, DB_DONOTINDEX);
#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);
@@ -4184,6 +4438,14 @@ DL_EXPORT(void) init_bsddb(void)
ADD_INT(d, DB_NOPANIC);
#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);
@@ -4197,7 +4459,7 @@ DL_EXPORT(void) init_bsddb(void)
/* The base exception class is DBError */
- DBError = PyErr_NewException("bsddb3._db.DBError", NULL, NULL);
+ DBError = PyErr_NewException("bsddb._db.DBError", NULL, NULL);
PyDict_SetItemString(d, "DBError", DBError);
/* Some magic to make DBNotFoundError derive from both DBError and
@@ -4210,7 +4472,7 @@ DL_EXPORT(void) init_bsddb(void)
/* All the rest of the exceptions derive only from DBError */
-#define MAKE_EX(name) name = PyErr_NewException("bsddb3._db." #name, DBError, NULL); \
+#define MAKE_EX(name) name = PyErr_NewException("bsddb._db." #name, DBError, NULL); \
PyDict_SetItemString(d, #name, name)
#if !INCOMPLETE_IS_WARNING
@@ -4246,9 +4508,6 @@ DL_EXPORT(void) init_bsddb(void)
/* Check for errors */
if (PyErr_Occurred()) {
PyErr_Print();
- Py_FatalError("can't initialize module _db");
+ Py_FatalError("can't initialize module _bsddb");
}
}
-
-
-