[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},