opt/python/python-2.4.2-bsddb.patch
2006-02-24 08:54:10 +00:00

1025 lines
35 KiB
Diff

diff -Nru Python-2.4.2.orig/Lib/bsddb/__init__.py Python-2.4.2/Lib/bsddb/__init__.py
--- Python-2.4.2.orig/Lib/bsddb/__init__.py 2006-02-13 18:18:16.000000000 +0100
+++ Python-2.4.2/Lib/bsddb/__init__.py 2006-01-27 07:17:25.000000000 +0100
@@ -372,6 +372,8 @@
try:
import thread
del thread
+ if db.version() < (3, 3, 0):
+ db.DB_THREAD = 0
except ImportError:
db.DB_THREAD = 0
diff -Nru Python-2.4.2.orig/Lib/bsddb/db.py Python-2.4.2/Lib/bsddb/db.py
--- Python-2.4.2.orig/Lib/bsddb/db.py 2006-02-13 18:18:16.000000000 +0100
+++ Python-2.4.2/Lib/bsddb/db.py 2006-01-27 07:17:25.000000000 +0100
@@ -37,7 +37,7 @@
# case we ever want to augment the stuff in _db in any way. For now
# it just simply imports everything from _db.
-if __name__[:len('bsddb3.')] == 'bsddb3.':
+if __name__.startswith('bsddb3.'):
# import _pybsddb binary as it should be the more recent version from
# a standalone pybsddb addon package than the version included with
# python as bsddb._bsddb.
diff -Nru Python-2.4.2.orig/Lib/bsddb/dbobj.py Python-2.4.2/Lib/bsddb/dbobj.py
--- Python-2.4.2.orig/Lib/bsddb/dbobj.py 2006-02-13 18:18:16.000000000 +0100
+++ Python-2.4.2/Lib/bsddb/dbobj.py 2006-01-27 07:28:12.000000000 +0100
@@ -77,6 +77,8 @@
return apply(self._cobj.txn_stat, args, kwargs)
def set_tx_max(self, *args, **kwargs):
return apply(self._cobj.set_tx_max, args, kwargs)
+ def set_tx_timestamp(self, *args, **kwargs):
+ return apply(self._cobj.set_tx_timestamp, args, kwargs)
def lock_detect(self, *args, **kwargs):
return apply(self._cobj.lock_detect, args, kwargs)
def lock_get(self, *args, **kwargs):
@@ -164,6 +166,8 @@
return apply(self._cobj.rename, args, kwargs)
def set_bt_minkey(self, *args, **kwargs):
return apply(self._cobj.set_bt_minkey, args, kwargs)
+ def set_bt_compare(self, *args, **kwargs):
+ return apply(self._cobj.set_bt_compare, args, kwargs)
def set_cachesize(self, *args, **kwargs):
return apply(self._cobj.set_cachesize, args, kwargs)
def set_flags(self, *args, **kwargs):
diff -Nru Python-2.4.2.orig/Lib/bsddb/dbtables.py Python-2.4.2/Lib/bsddb/dbtables.py
--- Python-2.4.2.orig/Lib/bsddb/dbtables.py 2006-02-13 18:18:16.000000000 +0100
+++ Python-2.4.2/Lib/bsddb/dbtables.py 2006-01-27 07:17:25.000000000 +0100
@@ -15,7 +15,7 @@
# This provides a simple database table interface built on top of
# the Python BerkeleyDB 3 interface.
#
-_cvsid = '$Id: dbtables.py,v 1.11 2004/08/08 00:54:20 tim_one Exp $'
+_cvsid = '$Id: dbtables.py 36901 2004-08-08 00:54:21Z tim_one $'
import re
import sys
diff -Nru Python-2.4.2.orig/Modules/_bsddb.c Python-2.4.2/Modules/_bsddb.c
--- Python-2.4.2.orig/Modules/_bsddb.c 2006-02-13 18:18:17.000000000 +0100
+++ Python-2.4.2/Modules/_bsddb.c 2006-01-30 01:22:16.000000000 +0100
@@ -97,8 +97,8 @@
#error "eek! DBVER can't handle minor versions > 9"
#endif
-#define PY_BSDDB_VERSION "4.3.0"
-static char *rcs_id = "$Id: _bsddb.c,v 1.38.2.1 2004/12/16 09:48:37 greg Exp $";
+#define PY_BSDDB_VERSION "4.4.2"
+static char *rcs_id = "$Id: _bsddb.c 42205 2006-01-30 00:22:08Z gregory.p.smith $";
#ifdef WITH_THREAD
@@ -153,7 +153,7 @@
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 */
+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 */
@@ -212,10 +212,10 @@
struct behaviourFlags {
/* What is the default behaviour when DB->get or DBCursor->get returns a
- DB_NOTFOUND error? Return None or raise an exception? */
+ 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 error? Return None or raise an exception? */
+ * returns a DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise? */
unsigned int cursorSetReturnsNone : 1;
};
@@ -244,6 +244,7 @@
struct behaviourFlags moduleFlags;
#if (DBVER >= 33)
PyObject* associateCallback;
+ PyObject* btCompareCallback;
int primaryDBType;
#endif
#ifdef HAVE_WEAKREF
@@ -265,6 +266,7 @@
typedef struct {
PyObject_HEAD
DB_TXN* txn;
+ PyObject *env;
#ifdef HAVE_WEAKREF
PyObject *in_weakreflist; /* List of weak references */
#endif
@@ -649,7 +651,7 @@
int dlen = -1;
int doff = -1;
int flags = 0;
- char* kwnames[] = { "flags", "dlen", "doff", NULL };
+ static const char* kwnames[] = { "flags", "dlen", "doff", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, kwnames,
&flags, &dlen, &doff))
@@ -672,7 +674,8 @@
err = self->dbc->c_get(self->dbc, &key, &data, flags);
MYDB_END_ALLOW_THREADS;
- if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.getReturnsNone) {
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->mydb->moduleFlags.getReturnsNone) {
Py_INCREF(Py_None);
retval = Py_None;
}
@@ -741,6 +744,7 @@
self->myenvobj = NULL;
#if (DBVER >= 33)
self->associateCallback = NULL;
+ self->btCompareCallback = NULL;
self->primaryDBType = 0;
#endif
#ifdef HAVE_WEAKREF
@@ -815,6 +819,10 @@
Py_DECREF(self->associateCallback);
self->associateCallback = NULL;
}
+ if (self->btCompareCallback != NULL) {
+ Py_DECREF(self->btCompareCallback);
+ self->btCompareCallback = NULL;
+ }
#endif
PyObject_Del(self);
}
@@ -905,7 +913,7 @@
}
#endif
- if (self->db_env) {
+ if (self->db_env && !self->closed) {
MYDB_BEGIN_ALLOW_THREADS;
self->db_env->close(self->db_env, 0);
MYDB_END_ALLOW_THREADS;
@@ -921,6 +929,8 @@
DBTxnObject* self = PyObject_New(DBTxnObject, &DBTxn_Type);
if (self == NULL)
return NULL;
+ Py_INCREF(myenv);
+ self->env = (PyObject*)myenv;
#ifdef HAVE_WEAKREF
self->in_weakreflist = NULL;
#endif
@@ -931,11 +941,10 @@
#else
err = txn_begin(myenv->db_env, parent, &(self->txn), flags);
#endif
- /* 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
- * open DBTxns and closing any open DBs first. */
MYDB_END_ALLOW_THREADS;
if (makeDBError(err)) {
+ Py_DECREF(self->env);
+ PyObject_Del(self);
self = NULL;
}
return self;
@@ -966,6 +975,7 @@
}
#endif
+ Py_DECREF(self->env);
PyObject_Del(self);
}
@@ -1140,9 +1150,10 @@
#if (DBVER >= 41)
PyObject *txnobj = NULL;
DB_TXN *txn = NULL;
- char* kwnames[] = {"secondaryDB", "callback", "flags", "txn", NULL};
+ static const char* kwnames[] = {"secondaryDB", "callback", "flags", "txn",
+ NULL};
#else
- char* kwnames[] = {"secondaryDB", "callback", "flags", NULL};
+ static const char* kwnames[] = {"secondaryDB", "callback", "flags", NULL};
#endif
#if (DBVER >= 41)
@@ -1165,6 +1176,7 @@
makeTypeError("DB", (PyObject*)secondaryDB);
return NULL;
}
+ CHECK_DB_NOT_CLOSED(secondaryDB);
if (callback == Py_None) {
callback = NULL;
}
@@ -1174,9 +1186,7 @@
}
/* Save a reference to the callback in the secondary DB. */
- if (self->associateCallback != NULL) {
- Py_DECREF(self->associateCallback);
- }
+ Py_XDECREF(secondaryDB->associateCallback);
Py_INCREF(callback);
secondaryDB->associateCallback = callback;
secondaryDB->primaryDBType = _DB_get_type(self);
@@ -1210,8 +1220,8 @@
MYDB_END_ALLOW_THREADS;
if (err) {
- Py_DECREF(self->associateCallback);
- self->associateCallback = NULL;
+ Py_XDECREF(secondaryDB->associateCallback);
+ secondaryDB->associateCallback = NULL;
secondaryDB->primaryDBType = 0;
}
@@ -1249,7 +1259,7 @@
PyObject* retval = NULL;
DBT key, data;
DB_TXN *txn = NULL;
- char* kwnames[] = { "txn", "flags", NULL };
+ static const char* kwnames[] = { "txn", "flags", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:consume", kwnames,
&txnobj, &flags))
@@ -1279,7 +1289,8 @@
err = self->db->get(self->db, txn, &key, &data, flags|consume_flag);
MYDB_END_ALLOW_THREADS;
- if ((err == DB_NOTFOUND) && self->moduleFlags.getReturnsNone) {
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->moduleFlags.getReturnsNone) {
err = 0;
Py_INCREF(Py_None);
retval = Py_None;
@@ -1318,7 +1329,7 @@
DBC* dbc;
PyObject* txnobj = NULL;
DB_TXN *txn = NULL;
- char* kwnames[] = { "txn", "flags", NULL };
+ static const char* kwnames[] = { "txn", "flags", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
&txnobj, &flags))
@@ -1343,7 +1354,7 @@
PyObject* keyobj;
DBT key;
DB_TXN *txn = NULL;
- char* kwnames[] = { "key", "txn", "flags", NULL };
+ static const char* kwnames[] = { "key", "txn", "flags", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:delete", kwnames,
&keyobj, &txnobj, &flags))
@@ -1395,7 +1406,8 @@
int doff = -1;
DBT key, data;
DB_TXN *txn = NULL;
- char* kwnames[] = {"key", "default", "txn", "flags", "dlen", "doff", NULL};
+ static const char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
+ "doff", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:get", kwnames,
&keyobj, &dfltobj, &txnobj, &flags, &dlen,
@@ -1424,12 +1436,13 @@
err = self->db->get(self->db, txn, &key, &data, flags);
MYDB_END_ALLOW_THREADS;
- if ((err == DB_NOTFOUND) && (dfltobj != NULL)) {
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
err = 0;
Py_INCREF(dfltobj);
retval = dfltobj;
}
- else if ((err == DB_NOTFOUND) && self->moduleFlags.getReturnsNone) {
+ else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->moduleFlags.getReturnsNone) {
err = 0;
Py_INCREF(Py_None);
retval = Py_None;
@@ -1461,7 +1474,8 @@
int doff = -1;
DBT key, pkey, data;
DB_TXN *txn = NULL;
- char* kwnames[] = {"key", "default", "txn", "flags", "dlen", "doff", NULL};
+ static const char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
+ "doff", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:pget", kwnames,
&keyobj, &dfltobj, &txnobj, &flags, &dlen,
@@ -1493,12 +1507,13 @@
err = self->db->pget(self->db, txn, &key, &pkey, &data, flags);
MYDB_END_ALLOW_THREADS;
- if ((err == DB_NOTFOUND) && (dfltobj != NULL)) {
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
err = 0;
Py_INCREF(dfltobj);
retval = dfltobj;
}
- else if ((err == DB_NOTFOUND) && self->moduleFlags.getReturnsNone) {
+ else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->moduleFlags.getReturnsNone) {
err = 0;
Py_INCREF(Py_None);
retval = Py_None;
@@ -1510,7 +1525,7 @@
if (self->primaryDBType == DB_RECNO ||
self->primaryDBType == DB_QUEUE)
- pkeyObj = PyInt_FromLong(*(long *)pkey.data);
+ pkeyObj = PyInt_FromLong(*(int *)pkey.data);
else
pkeyObj = PyString_FromStringAndSize(pkey.data, pkey.size);
@@ -1519,14 +1534,22 @@
PyObject *keyObj;
int type = _DB_get_type(self);
if (type == DB_RECNO || type == DB_QUEUE)
- keyObj = PyInt_FromLong(*(long *)key.data);
+ keyObj = PyInt_FromLong(*(int *)key.data);
else
keyObj = PyString_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
}
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
}
FREE_DBT(pkey);
FREE_DBT(data);
@@ -1549,7 +1572,7 @@
PyObject* retval = NULL;
DBT key, data;
DB_TXN *txn = NULL;
- char* kwnames[] = { "key", "txn", NULL };
+ static const char* kwnames[] = { "key", "txn", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:get_size", kwnames,
&keyobj, &txnobj))
@@ -1592,7 +1615,7 @@
PyObject* retval = NULL;
DBT key, data;
DB_TXN *txn = NULL;
- char* kwnames[] = { "key", "data", "txn", "flags", NULL };
+ static const char* kwnames[] = { "key", "data", "txn", "flags", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oi:get_both", kwnames,
@@ -1623,7 +1646,8 @@
err = self->db->get(self->db, txn, &key, &data, flags);
MYDB_END_ALLOW_THREADS;
- if ((err == DB_NOTFOUND) && self->moduleFlags.getReturnsNone) {
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->moduleFlags.getReturnsNone) {
err = 0;
Py_INCREF(Py_None);
retval = Py_None;
@@ -1742,7 +1766,7 @@
DBT key;
DB_TXN *txn = NULL;
DB_KEY_RANGE range;
- char* kwnames[] = { "key", "txn", "flags", NULL };
+ static const char* kwnames[] = { "key", "txn", "flags", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:key_range", kwnames,
&keyobj, &txnobj, &flags))
@@ -1773,17 +1797,17 @@
PyObject *txnobj = NULL;
DB_TXN *txn = NULL;
/* with dbname */
- char* kwnames[] = {
+ static const char* kwnames[] = {
"filename", "dbname", "dbtype", "flags", "mode", "txn", NULL};
/* without dbname */
- char* kwnames_basic[] = {
+ static const char* kwnames_basic[] = {
"filename", "dbtype", "flags", "mode", "txn", NULL};
#else
/* with dbname */
- char* kwnames[] = {
+ static const char* kwnames[] = {
"filename", "dbname", "dbtype", "flags", "mode", NULL};
/* without dbname */
- char* kwnames_basic[] = {
+ static const char* kwnames_basic[] = {
"filename", "dbtype", "flags", "mode", NULL};
#endif
@@ -1867,7 +1891,8 @@
PyObject* keyobj, *dataobj, *retval;
DBT key, data;
DB_TXN *txn = NULL;
- char* kwnames[] = { "key", "data", "txn", "flags", "dlen", "doff", NULL };
+ static const char* kwnames[] = { "key", "data", "txn", "flags", "dlen",
+ "doff", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oiii:put", kwnames,
&keyobj, &dataobj, &txnobj, &flags, &dlen, &doff))
@@ -1907,7 +1932,7 @@
char* filename;
char* database = NULL;
int err, flags=0;
- char* kwnames[] = { "filename", "dbname", "flags", NULL};
+ static const char* kwnames[] = { "filename", "dbname", "flags", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zi:remove", kwnames,
&filename, &database, &flags))
@@ -1959,6 +1984,160 @@
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;
+ PyObject *leftObject;
+ PyObject *rightObject;
+ 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;
+
+ leftObject = PyString_FromStringAndSize (leftKey->data, leftKey->size);
+ rightObject = PyString_FromStringAndSize (rightKey->data, rightKey->size);
+
+ args = PyTuple_New (2);
+ Py_INCREF (self);
+ PyTuple_SET_ITEM (args, 0, leftObject); /* steals reference */
+ PyTuple_SET_ITEM (args, 1, rightObject); /* steals reference */
+
+ result = PyEval_CallObject (self->btCompareCallback, args);
+ if (result == 0) {
+ /* we're in a callback within the DB code, we can't raise */
+ PyErr_Print ();
+ res = _default_cmp (leftKey, rightKey);
+ }
+ else if (PyInt_Check (result)) {
+ res = PyInt_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_DECREF (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, *emptyStr, *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 = PyTuple_New (2);
+
+ emptyStr = PyString_FromStringAndSize (NULL, 0);
+ Py_INCREF(emptyStr);
+ PyTuple_SET_ITEM (tuple, 0, emptyStr);
+ PyTuple_SET_ITEM (tuple, 1, emptyStr); /* steals reference */
+ result = PyEval_CallObject (comparator, tuple);
+ Py_DECREF (tuple);
+ if (result == 0 || !PyInt_Check(result)) {
+ PyErr_SetString (PyExc_TypeError,
+ "callback MUST return an int");
+ return NULL;
+ }
+ else if (PyInt_AsLong(result) != 0) {
+ PyErr_SetString (PyExc_TypeError,
+ "callback failed to return 0 on two empty strings");
+ return NULL;
+ }
+
+ /* 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,
+ (comparator != NULL ?
+ _db_compareCallback : NULL));
+
+ 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)
@@ -2171,9 +2350,9 @@
#if (DBVER >= 43)
PyObject* txnobj = NULL;
DB_TXN *txn = NULL;
- char* kwnames[] = { "txn", "flags", NULL };
+ static const char* kwnames[] = { "txn", "flags", NULL };
#else
- char* kwnames[] = { "flags", NULL };
+ static const char* kwnames[] = { "flags", NULL };
#endif
#if (DBVER >= 43)
@@ -2313,7 +2492,7 @@
u_int32_t count=0;
PyObject* txnobj = NULL;
DB_TXN *txn = NULL;
- char* kwnames[] = { "txn", "flags", NULL };
+ static const char* kwnames[] = { "txn", "flags", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
&txnobj, &flags))
@@ -2357,7 +2536,8 @@
char* dbName=NULL;
char* outFileName=NULL;
FILE* outFile=NULL;
- char* kwnames[] = { "filename", "dbname", "outfile", "flags", NULL };
+ static const char* kwnames[] = { "filename", "dbname", "outfile", "flags",
+ NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zzi:verify", kwnames,
&fileName, &dbName, &outFileName, &flags))
@@ -2414,7 +2594,7 @@
int err;
u_int32_t flags=0;
char *passwd = NULL;
- char* kwnames[] = { "passwd", "flags", NULL };
+ static const char* kwnames[] = { "passwd", "flags", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
&passwd, &flags)) {
@@ -2584,7 +2764,15 @@
err = self->db->get(self->db, txn, &key, &data, 0);
MYDB_END_ALLOW_THREADS;
FREE_DBT(key);
- return PyInt_FromLong((err == DB_BUFFER_SMALL) || (err == 0));
+
+ if (err == DB_BUFFER_SMALL || err == 0) {
+ return PyInt_FromLong(1);
+ } else if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
+ return PyInt_FromLong(0);
+ }
+
+ makeDBError(err);
+ return NULL;
}
@@ -2682,8 +2870,8 @@
Py_DECREF(item);
}
- /* DB_NOTFOUND is okay, it just means we got to the end */
- if (err != DB_NOTFOUND && makeDBError(err)) {
+ /* 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;
}
@@ -2846,7 +3034,8 @@
int dlen = -1;
int doff = -1;
DBT key, data;
- char* kwnames[] = { "key","data", "flags", "dlen", "doff", NULL };
+ static const char* kwnames[] = { "key","data", "flags", "dlen", "doff",
+ NULL };
CLEAR_DBT(key);
CLEAR_DBT(data);
@@ -2890,7 +3079,8 @@
err = self->dbc->c_get(self->dbc, &key, &data, flags);
MYDB_END_ALLOW_THREADS;
- if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.getReturnsNone) {
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->mydb->moduleFlags.getReturnsNone) {
Py_INCREF(Py_None);
retval = Py_None;
}
@@ -2931,7 +3121,8 @@
int dlen = -1;
int doff = -1;
DBT key, pkey, data;
- char* kwnames[] = { "key","data", "flags", "dlen", "doff", NULL };
+ static const char* kwnames[] = { "key","data", "flags", "dlen", "doff",
+ NULL };
CLEAR_DBT(key);
CLEAR_DBT(data);
@@ -2977,7 +3168,8 @@
err = self->dbc->c_pget(self->dbc, &key, &pkey, &data, flags);
MYDB_END_ALLOW_THREADS;
- if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.getReturnsNone) {
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->mydb->moduleFlags.getReturnsNone) {
Py_INCREF(Py_None);
retval = Py_None;
}
@@ -2991,24 +3183,32 @@
if (self->mydb->primaryDBType == DB_RECNO ||
self->mydb->primaryDBType == DB_QUEUE)
- pkeyObj = PyInt_FromLong(*(long *)pkey.data);
+ pkeyObj = PyInt_FromLong(*(int *)pkey.data);
else
pkeyObj = PyString_FromStringAndSize(pkey.data, pkey.size);
- if (flags & DB_SET_RECNO) /* return key, pkey and data */
+ 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 = PyInt_FromLong(*(long *)key.data);
+ keyObj = PyInt_FromLong(*(int *)key.data);
else
keyObj = PyString_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
FREE_DBT(key);
}
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
}
FREE_DBT(pkey);
FREE_DBT(data);
@@ -3083,7 +3283,8 @@
int err, flags = 0;
PyObject* keyobj, *dataobj;
DBT key, data;
- char* kwnames[] = { "key", "data", "flags", "dlen", "doff", NULL };
+ static const char* kwnames[] = { "key", "data", "flags", "dlen", "doff",
+ NULL };
int dlen = -1;
int doff = -1;
@@ -3118,7 +3319,7 @@
int err, flags = 0;
DBT key, data;
PyObject* retval, *keyobj;
- char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
+ static const char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
int dlen = -1;
int doff = -1;
@@ -3144,7 +3345,8 @@
MYDB_BEGIN_ALLOW_THREADS;
err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET);
MYDB_END_ALLOW_THREADS;
- if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.cursorSetReturnsNone) {
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->mydb->moduleFlags.cursorSetReturnsNone) {
Py_INCREF(Py_None);
retval = Py_None;
}
@@ -3187,7 +3389,7 @@
int err, flags = 0;
DBT key, data;
PyObject* retval, *keyobj;
- char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
+ static const char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
int dlen = -1;
int doff = -1;
@@ -3216,7 +3418,8 @@
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) && self->mydb->moduleFlags.cursorSetReturnsNone) {
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->mydb->moduleFlags.cursorSetReturnsNone) {
Py_INCREF(Py_None);
retval = Py_None;
}
@@ -3271,7 +3474,7 @@
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) && returnsNone) {
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && returnsNone) {
Py_INCREF(Py_None);
retval = Py_None;
}
@@ -3376,7 +3579,7 @@
PyObject* retval;
int dlen = -1;
int doff = -1;
- char* kwnames[] = { "recno","flags", "dlen", "doff", NULL };
+ static const char* kwnames[] = { "recno","flags", "dlen", "doff", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|iii:set_recno", kwnames,
&irecno, &flags, &dlen, &doff))
@@ -3411,7 +3614,8 @@
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) && self->mydb->moduleFlags.cursorSetReturnsNone) {
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->mydb->moduleFlags.cursorSetReturnsNone) {
Py_INCREF(Py_None);
retval = Py_None;
}
@@ -3479,7 +3683,8 @@
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) && self->mydb->moduleFlags.getReturnsNone) {
+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+ && self->mydb->moduleFlags.getReturnsNone) {
Py_INCREF(Py_None);
retval = Py_None;
}
@@ -3568,7 +3773,8 @@
char *database = NULL;
PyObject *txnobj = NULL;
DB_TXN *txn = NULL;
- char* kwnames[] = { "file", "database", "txn", "flags", NULL };
+ static const char* kwnames[] = { "file", "database", "txn", "flags",
+ NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss|Oi:dbremove", kwnames,
&file, &database, &txnobj, &flags)) {
@@ -3595,7 +3801,8 @@
char *newname = NULL;
PyObject *txnobj = NULL;
DB_TXN *txn = NULL;
- char* kwnames[] = { "file", "database", "newname", "txn", "flags", NULL };
+ static const char* kwnames[] = { "file", "database", "newname", "txn",
+ "flags", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sss|Oi:dbrename", kwnames,
&file, &database, &newname, &txnobj, &flags)) {
@@ -3619,7 +3826,7 @@
int err;
u_int32_t flags=0;
char *passwd = NULL;
- char* kwnames[] = { "passwd", "flags", NULL };
+ static const char* kwnames[] = { "passwd", "flags", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
&passwd, &flags)) {
@@ -3642,7 +3849,7 @@
int err;
u_int32_t flags=0;
u_int32_t timeout = 0;
- char* kwnames[] = { "timeout", "flags", NULL };
+ static const char* kwnames[] = { "timeout", "flags", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
&timeout, &flags)) {
@@ -3780,6 +3987,25 @@
}
+#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)
{
@@ -3910,7 +4136,7 @@
int flags = 0;
PyObject* txnobj = NULL;
DB_TXN *txn = NULL;
- char* kwnames[] = { "parent", "flags", NULL };
+ static const char* kwnames[] = { "parent", "flags", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:txn_begin", kwnames,
&txnobj, &flags))
@@ -3954,9 +4180,23 @@
return NULL;
CHECK_ENV_NOT_CLOSED(self);
- MYDB_BEGIN_ALLOW_THREADS;
err = self->db_env->set_tx_max(self->db_env, max);
- MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+
+static PyObject*
+DBEnv_set_tx_timestamp(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ time_t stamp;
+
+ if (!PyArg_ParseTuple(args, "i:set_tx_timestamp", &stamp))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ err = self->db_env->set_tx_timestamp(self->db_env, &stamp);
RETURN_IF_ERR();
RETURN_NONE();
}
@@ -4101,8 +4341,13 @@
#endif
MAKE_ENTRY(nrequests);
MAKE_ENTRY(nreleases);
- MAKE_ENTRY(nnowaits);
+#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);
@@ -4400,6 +4645,9 @@
{"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},
@@ -4489,6 +4737,9 @@
{"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},
{"set_lk_max", (PyCFunction)DBEnv_set_lk_max, METH_VARARGS},
#if (DBVER >= 32)
@@ -4502,6 +4753,7 @@
{"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},
@@ -4734,7 +4986,7 @@
{
PyObject* dbenvobj = NULL;
int flags = 0;
- char* kwnames[] = { "dbEnv", "flags", NULL};
+ static const char* kwnames[] = { "dbEnv", "flags", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:DB", kwnames,
&dbenvobj, &flags))
@@ -4821,6 +5073,8 @@
/* Create the module and add the functions */
m = Py_InitModule(_bsddbModuleName, bsddb_methods);
+ if (m == NULL)
+ return;
/* Add some symbolic constants to the module */
d = PyModule_GetDict(m);
@@ -4938,7 +5192,11 @@
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
@@ -5040,6 +5298,11 @@
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);
#endif
@@ -5117,12 +5380,15 @@
DBError = PyErr_NewException("bsddb._db.DBError", NULL, NULL);
PyDict_SetItemString(d, "DBError", DBError);
- /* Some magic to make DBNotFoundError derive from both DBError and
- KeyError, since the API only supports using one base class. */
+ /* 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);
- PyRun_String("class DBNotFoundError(DBError, KeyError): pass",
+ 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");