[Python-checkins] python/dist/src/Modules _bsddb.c,1.15,1.16
greg@users.sourceforge.net
greg@users.sourceforge.net
Tue, 08 Jul 2003 21:46:01 -0700
Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1:/tmp/cvs-serv26130/extsrc
Modified Files:
_bsddb.c
Log Message:
bsddb 4.1.6:
* Extended DB & DBEnv set_get_returns_none functionality to take a
"level" instead of a boolean flag. The boolean 0 and 1 values still
have the same effect. A value of 2 extends the "return None instead
of raising an exception" behaviour to the DBCursor set methods.
This will become the default behaviour in pybsddb 4.2.
* Fixed a typo in DBCursor.join_item method that made it crash instead
of returning a value. Obviously nobody uses it. Wrote a test case
for join and join_item.
Index: _bsddb.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_bsddb.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -C2 -d -r1.15 -r1.16
*** _bsddb.c 7 Jul 2003 19:06:45 -0000 1.15
--- _bsddb.c 9 Jul 2003 04:45:59 -0000 1.16
***************
*** 94,98 ****
#define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
! #define PY_BSDDB_VERSION "4.1.5"
static char *rcs_id = "$Id$";
--- 94,98 ----
#define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
! #define PY_BSDDB_VERSION "4.1.6"
static char *rcs_id = "$Id$";
***************
*** 142,151 ****
#endif
-
- /* What is the default behaviour when DB->get or DBCursor->get returns a
- DB_NOTFOUND error? Return None or raise an exception? */
- #define GET_RETURNS_NONE_DEFAULT 1
-
-
/* Should DB_INCOMPLETE be turned into a warning or an exception? */
#define INCOMPLETE_IS_WARNING 1
--- 142,145 ----
***************
*** 190,193 ****
--- 184,199 ----
/* Structure definitions */
+ struct behaviourFlags {
+ /* What is the default behaviour when DB->get or DBCursor->get returns a
+ DB_NOTFOUND 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? */
+ unsigned int cursorSetReturnsNone : 1;
+ };
+
+ #define DEFAULT_GET_RETURNS_NONE 1
+ #define DEFAULT_CURSOR_SET_RETURNS_NONE 0 /* 0 in pybsddb < 4.2, python < 2.4 */
+
typedef struct {
PyObject_HEAD
***************
*** 195,199 ****
u_int32_t flags; /* saved flags from open() */
int closed;
! int getReturnsNone;
} DBEnvObject;
--- 201,205 ----
u_int32_t flags; /* saved flags from open() */
int closed;
! struct behaviourFlags moduleFlags;
} DBEnvObject;
***************
*** 206,210 ****
u_int32_t setflags; /* saved flags from set_flags() */
int haveStat;
! int getReturnsNone;
#if (DBVER >= 33)
PyObject* associateCallback;
--- 212,216 ----
u_int32_t setflags; /* saved flags from set_flags() */
int haveStat;
! struct behaviourFlags moduleFlags;
#if (DBVER >= 33)
PyObject* associateCallback;
***************
*** 596,600 ****
MYDB_END_ALLOW_THREADS;
! if ((err == DB_NOTFOUND) && self->mydb->getReturnsNone) {
Py_INCREF(Py_None);
retval = Py_None;
--- 602,606 ----
MYDB_END_ALLOW_THREADS;
! if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.getReturnsNone) {
Py_INCREF(Py_None);
retval = Py_None;
***************
*** 682,688 ****
if (self->myenvobj)
! self->getReturnsNone = self->myenvobj->getReturnsNone;
else
! self->getReturnsNone = GET_RETURNS_NONE_DEFAULT;
MYDB_BEGIN_ALLOW_THREADS;
--- 688,695 ----
if (self->myenvobj)
! self->moduleFlags = self->myenvobj->moduleFlags;
else
! self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
! self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
MYDB_BEGIN_ALLOW_THREADS;
***************
*** 798,802 ****
self->closed = 1;
self->flags = flags;
! self->getReturnsNone = GET_RETURNS_NONE_DEFAULT;
MYDB_BEGIN_ALLOW_THREADS;
--- 805,810 ----
self->closed = 1;
self->flags = flags;
! self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
! self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
MYDB_BEGIN_ALLOW_THREADS;
***************
*** 1183,1187 ****
MYDB_END_ALLOW_THREADS;
! if ((err == DB_NOTFOUND) && self->getReturnsNone) {
err = 0;
Py_INCREF(Py_None);
--- 1191,1195 ----
MYDB_END_ALLOW_THREADS;
! if ((err == DB_NOTFOUND) && self->moduleFlags.getReturnsNone) {
err = 0;
Py_INCREF(Py_None);
***************
*** 1325,1329 ****
retval = dfltobj;
}
! else if ((err == DB_NOTFOUND) && self->getReturnsNone) {
err = 0;
Py_INCREF(Py_None);
--- 1333,1337 ----
retval = dfltobj;
}
! else if ((err == DB_NOTFOUND) && self->moduleFlags.getReturnsNone) {
err = 0;
Py_INCREF(Py_None);
***************
*** 1425,1429 ****
MYDB_END_ALLOW_THREADS;
! if ((err == DB_NOTFOUND) && self->getReturnsNone) {
err = 0;
Py_INCREF(Py_None);
--- 1433,1437 ----
MYDB_END_ALLOW_THREADS;
! if ((err == DB_NOTFOUND) && self->moduleFlags.getReturnsNone) {
err = 0;
Py_INCREF(Py_None);
***************
*** 1526,1529 ****
--- 1534,1542 ----
RETURN_IF_ERR();
+ // FIXME: this is a buggy interface. The returned cursor
+ // contains internal references to the passed in cursors
+ // but does not hold python references to them or prevent
+ // them from being closed prematurely. This can cause
+ // python to crash when things are done in the wrong order.
return (PyObject*) newDBCursorObject(dbc, self);
}
***************
*** 2157,2161 ****
{
int flags=0;
! int oldValue;
if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
--- 2170,2174 ----
{
int flags=0;
! int oldValue=0;
if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
***************
*** 2163,2168 ****
CHECK_DB_NOT_CLOSED(self);
! oldValue = self->getReturnsNone;
! self->getReturnsNone = flags;
return PyInt_FromLong(oldValue);
}
--- 2176,2185 ----
CHECK_DB_NOT_CLOSED(self);
! if (self->moduleFlags.getReturnsNone)
! ++oldValue;
! if (self->moduleFlags.cursorSetReturnsNone)
! ++oldValue;
! self->moduleFlags.getReturnsNone = (flags >= 1);
! self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
return PyInt_FromLong(oldValue);
}
***************
*** 2644,2648 ****
! if ((err == DB_NOTFOUND) && self->mydb->getReturnsNone) {
Py_INCREF(Py_None);
retval = Py_None;
--- 2661,2665 ----
! if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.getReturnsNone) {
Py_INCREF(Py_None);
retval = Py_None;
***************
*** 2791,2795 ****
err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET);
MYDB_END_ALLOW_THREADS;
! if (makeDBError(err)) {
retval = NULL;
}
--- 2808,2816 ----
err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET);
MYDB_END_ALLOW_THREADS;
! if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.cursorSetReturnsNone) {
! Py_INCREF(Py_None);
! retval = Py_None;
! }
! else if (makeDBError(err)) {
retval = NULL;
}
***************
*** 2849,2853 ****
err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET_RANGE);
MYDB_END_ALLOW_THREADS;
! if (makeDBError(err)) {
retval = NULL;
}
--- 2870,2878 ----
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) {
! Py_INCREF(Py_None);
! retval = Py_None;
! }
! else if (makeDBError(err)) {
retval = NULL;
}
***************
*** 2876,2892 ****
}
-
static PyObject*
! DBC_get_both(DBCursorObject* self, PyObject* args)
{
! int err, flags=0;
DBT key, data;
! PyObject* retval, *keyobj, *dataobj;
!
! if (!PyArg_ParseTuple(args, "OO|i:get_both", &keyobj, &dataobj, &flags))
! return NULL;
!
! CHECK_CURSOR_NOT_CLOSED(self);
if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
return NULL;
--- 2901,2913 ----
}
static PyObject*
! _DBC_get_set_both(DBCursorObject* self, PyObject* keyobj, PyObject* dataobj,
! int flags, unsigned int returnsNone)
{
! int err;
DBT key, data;
! PyObject* retval;
+ // the caller did this: CHECK_CURSOR_NOT_CLOSED(self);
if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
return NULL;
***************
*** 2897,2901 ****
err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_GET_BOTH);
MYDB_END_ALLOW_THREADS;
! if (makeDBError(err)) {
retval = NULL;
}
--- 2918,2926 ----
err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_GET_BOTH);
MYDB_END_ALLOW_THREADS;
! if ((err == DB_NOTFOUND) && returnsNone) {
! Py_INCREF(Py_None);
! retval = Py_None;
! }
! else if (makeDBError(err)) {
retval = NULL;
}
***************
*** 2923,2926 ****
--- 2948,2983 ----
}
+ static PyObject*
+ DBC_get_both(DBCursorObject* self, PyObject* args)
+ {
+ int flags=0;
+ PyObject *keyobj, *dataobj;
+
+ if (!PyArg_ParseTuple(args, "OO|i:get_both", &keyobj, &dataobj, &flags))
+ return NULL;
+
+ // if the cursor is closed, self->mydb may be invalid
+ CHECK_CURSOR_NOT_CLOSED(self);
+
+ return _DBC_get_set_both(self, keyobj, dataobj, flags,
+ self->mydb->moduleFlags.getReturnsNone);
+ }
+
+ static PyObject*
+ DBC_set_both(DBCursorObject* self, PyObject* args)
+ {
+ int flags=0;
+ PyObject *keyobj, *dataobj;
+
+ if (!PyArg_ParseTuple(args, "OO|i:set_both", &keyobj, &dataobj, &flags))
+ return NULL;
+
+ // if the cursor is closed, self->mydb may be invalid
+ CHECK_CURSOR_NOT_CLOSED(self);
+
+ return _DBC_get_set_both(self, keyobj, dataobj, flags,
+ self->mydb->moduleFlags.cursorSetReturnsNone);
+ }
+
static PyObject*
***************
*** 2966,2970 ****
err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET_RECNO);
MYDB_END_ALLOW_THREADS;
! if (makeDBError(err)) {
retval = NULL;
}
--- 3023,3031 ----
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) {
! Py_INCREF(Py_None);
! retval = Py_None;
! }
! else if (makeDBError(err)) {
retval = NULL;
}
***************
*** 3011,3019 ****
DBC_join_item(DBCursorObject* self, PyObject* args)
{
! int err;
DBT key, data;
PyObject* retval;
! if (!PyArg_ParseTuple(args, ":join_item"))
return NULL;
--- 3072,3080 ----
DBC_join_item(DBCursorObject* self, PyObject* args)
{
! int err, flags=0;
DBT key, data;
PyObject* retval;
! if (!PyArg_ParseTuple(args, "|i:join_item", &flags))
return NULL;
***************
*** 3028,3034 ****
MYDB_BEGIN_ALLOW_THREADS;
! err = self->dbc->c_get(self->dbc, &key, &data, DB_JOIN_ITEM);
MYDB_END_ALLOW_THREADS;
! if (makeDBError(err)) {
retval = NULL;
}
--- 3089,3099 ----
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) {
! Py_INCREF(Py_None);
! retval = Py_None;
! }
! else if (makeDBError(err)) {
retval = NULL;
}
***************
*** 3749,3753 ****
{
int flags=0;
! int oldValue;
if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
--- 3814,3818 ----
{
int flags=0;
! int oldValue=0;
if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
***************
*** 3755,3760 ****
CHECK_ENV_NOT_CLOSED(self);
! oldValue = self->getReturnsNone;
! self->getReturnsNone = flags;
return PyInt_FromLong(oldValue);
}
--- 3820,3829 ----
CHECK_ENV_NOT_CLOSED(self);
! if (self->moduleFlags.getReturnsNone)
! ++oldValue;
! if (self->moduleFlags.cursorSetReturnsNone)
! ++oldValue;
! self->moduleFlags.getReturnsNone = (flags >= 1);
! self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
return PyInt_FromLong(oldValue);
}
***************
*** 3978,3982 ****
{"set_range", (PyCFunction)DBC_set_range, METH_VARARGS|METH_KEYWORDS},
{"get_both", (PyCFunction)DBC_get_both, METH_VARARGS},
! {"set_both", (PyCFunction)DBC_get_both, METH_VARARGS},
{"set_recno", (PyCFunction)DBC_set_recno, METH_VARARGS|METH_KEYWORDS},
{"consume", (PyCFunction)DBC_consume, METH_VARARGS|METH_KEYWORDS},
--- 4047,4051 ----
{"set_range", (PyCFunction)DBC_set_range, METH_VARARGS|METH_KEYWORDS},
{"get_both", (PyCFunction)DBC_get_both, METH_VARARGS},
! {"set_both", (PyCFunction)DBC_set_both, METH_VARARGS},
{"set_recno", (PyCFunction)DBC_set_recno, METH_VARARGS|METH_KEYWORDS},
{"consume", (PyCFunction)DBC_consume, METH_VARARGS|METH_KEYWORDS},