[Python-checkins] CVS: python/dist/src/Modules bsddbmodule.c,1.27,1.28

Fred L. Drake fdrake@users.sourceforge.net
Tue, 27 Feb 2001 10:56:49 -0800


Update of /cvsroot/python/python/dist/src/Modules
In directory usw-pr-cvs1:/tmp/cvs-serv26276/Modules

Modified Files:
	bsddbmodule.c 
Log Message:

Gustavo Niemeyer <niemeyer@conectiva.com>:
Fixed recno support (keys are integers rather than strings).
Work around DB bug that cause stdin to be closed by rnopen() when the
DB file needed to exist but did not (no longer segfaults).

This closes SF tracker patch #403445.

Also wrapped some long lines and added whitespace around operators -- FLD.


Index: bsddbmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/bsddbmodule.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -C2 -r1.27 -r1.28
*** bsddbmodule.c	2001/02/19 21:16:00	1.27
--- bsddbmodule.c	2001/02/27 18:56:46	1.28
***************
*** 3,9 ****
     Hacked: Guido van Rossum
     Btree and Recno additions plus sequence methods: David Ely
  
     XXX To do:
-    - provide interface to the B-tree and record libraries too
     - provide a way to access the various hash functions
     - support more open flags
--- 3,10 ----
     Hacked: Guido van Rossum
     Btree and Recno additions plus sequence methods: David Ely
+    Hacked by Gustavo Niemeyer <niemeyer@conectiva.com> fixing recno
+    support.
  
     XXX To do:
     - provide a way to access the various hash functions
     - support more open flags
***************
*** 18,21 ****
--- 19,26 ----
  #endif
  
+ #ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+ #endif
+ 
  #include <sys/types.h>
  #include <sys/stat.h>
***************
*** 33,36 ****
--- 38,42 ----
  	DB *di_bsddb;
  	int di_size;	/* -1 means recompute */
+ 	int di_type;
  #ifdef WITH_THREAD
  	PyThread_type_lock di_lock;
***************
*** 41,48 ****
  
  #define is_bsddbobject(v) ((v)->ob_type == &Bsddbtype)
! #define check_bsddbobject_open(v) if ((v)->di_bsddb == NULL) \
                 { PyErr_SetString(BsddbError, \
  				 "BSDDB object has already been closed"); \
!                  return NULL; }
  
  static PyObject *BsddbError;
--- 47,54 ----
  
  #define is_bsddbobject(v) ((v)->ob_type == &Bsddbtype)
! #define check_bsddbobject_open(v, r) if ((v)->di_bsddb == NULL) \
                 { PyErr_SetString(BsddbError, \
  				 "BSDDB object has already been closed"); \
!                  return r; }
  
  static PyObject *BsddbError;
***************
*** 82,85 ****
--- 88,93 ----
  
  	dp->di_size = -1;
+ 	dp->di_type = DB_HASH;
+ 
  #ifdef WITH_THREAD
  	dp->di_lock = PyThread_allocate_lock();
***************
*** 130,133 ****
--- 138,143 ----
  
  	dp->di_size = -1;
+ 	dp->di_type = DB_BTREE;
+ 
  #ifdef WITH_THREAD
  	dp->di_lock = PyThread_allocate_lock();
***************
*** 149,152 ****
--- 159,163 ----
  	bsddbobject *dp;
  	RECNOINFO info;
+ 	int fd;
  
  	if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
***************
*** 164,170 ****
  	flags |= O_BINARY;
  #endif
! 	Py_BEGIN_ALLOW_THREADS
! 	dp->di_bsddb = dbopen(file, flags, mode, DB_RECNO, &info);
! 	Py_END_ALLOW_THREADS
  	if (dp->di_bsddb == NULL) {
  		PyErr_SetFromErrno(BsddbError);
--- 175,190 ----
  	flags |= O_BINARY;
  #endif
! 	/* This is a hack to avoid a dbopen() bug that happens when
! 	 * it fails. */
! 	fd = open(file, flags);
! 	if (fd == -1) {
! 		dp->di_bsddb = NULL;
! 	}
! 	else {
! 		close(fd);
! 		Py_BEGIN_ALLOW_THREADS
! 		dp->di_bsddb = dbopen(file, flags, mode, DB_RECNO, &info);
! 		Py_END_ALLOW_THREADS
! 	}
  	if (dp->di_bsddb == NULL) {
  		PyErr_SetFromErrno(BsddbError);
***************
*** 177,180 ****
--- 197,202 ----
  
  	dp->di_size = -1;
+ 	dp->di_type = DB_RECNO;
+ 
  #ifdef WITH_THREAD
  	dp->di_lock = PyThread_allocate_lock();
***************
*** 226,234 ****
  bsddb_length(bsddbobject *dp)
  {
!         if (dp->di_bsddb == NULL) {
!                  PyErr_SetString(BsddbError,
! 				 "BSDDB object has already been closed"); 
!                  return -1; 
!         }
  	if (dp->di_size < 0) {
  		DBT krec, drec;
--- 248,252 ----
  bsddb_length(bsddbobject *dp)
  {
! 	check_bsddbobject_open(dp, -1);
  	if (dp->di_size < 0) {
  		DBT krec, drec;
***************
*** 260,270 ****
  	int size;
  	PyObject *result;
! 
! 	if (!PyArg_Parse(key, "s#", &data, &size))
! 		return NULL;
!         check_bsddbobject_open(dp);
  	
! 	krec.data = data;
! 	krec.size = size;
  
  	BSDDB_BGN_SAVE(dp)
--- 278,302 ----
  	int size;
  	PyObject *result;
! 	recno_t recno;
  	
! 	if (dp->di_type == DB_RECNO) {
! 		if (!PyArg_Parse(key, "i", &recno)) {
! 			PyErr_SetString(PyExc_TypeError,
! 					"key type must be integer");
! 			return NULL;
! 		}
! 		krec.data = &recno;
! 		krec.size = sizeof(recno);
! 	}
! 	else {
! 		if (!PyArg_Parse(key, "s#", &data, &size)) {
! 			PyErr_SetString(PyExc_TypeError,
! 					"key type must be string");
! 			return NULL;
! 		}
! 		krec.data = data;
! 		krec.size = size;
! 	}
!         check_bsddbobject_open(dp, NULL);
  
  	BSDDB_BGN_SAVE(dp)
***************
*** 297,313 ****
  	char *data;
  	int size;
  
! 	if (!PyArg_Parse(key, "s#", &data, &size)) {
! 		PyErr_SetString(PyExc_TypeError,
! 				"bsddb key type must be string");
! 		return -1;
  	}
!         if (dp->di_bsddb == NULL) {
!                  PyErr_SetString(BsddbError,
! 				 "BSDDB object has already been closed"); 
!                  return -1; 
!         }
! 	krec.data = data;
! 	krec.size = size;
  	dp->di_size = -1;
  	if (value == NULL) {
--- 329,353 ----
  	char *data;
  	int size;
+ 	recno_t recno;
  
! 	if (dp->di_type == DB_RECNO) {
! 		if (!PyArg_Parse(key, "i", &recno)) {
! 			PyErr_SetString(PyExc_TypeError,
! 					"bsddb key type must be integer");
! 			return -1;
! 		}
! 		krec.data = &recno;
! 		krec.size = sizeof(recno);
  	}
! 	else {
! 		if (!PyArg_Parse(key, "s#", &data, &size)) {
! 			PyErr_SetString(PyExc_TypeError,
! 					"bsddb key type must be string");
! 			return -1;
! 		}
! 		krec.data = data;
! 		krec.size = size;
! 	}
! 	check_bsddbobject_open(dp, -1);
  	dp->di_size = -1;
  	if (value == NULL) {
***************
*** 324,338 ****
  		drec.data = data;
  		drec.size = size;
- #if 0
- 		/* For RECNO, put fails with 'No space left on device'
- 		   after a few short records are added??  Looks fine
- 		   to this point... linked with 1.85 on Solaris Intel
- 		   Roger E. Masse 1/16/97
- 		 */
- 		printf("before put data: '%s', size: %d\n",
- 		       drec.data, drec.size);
- 		printf("before put key= '%s', size= %d\n",
- 		       krec.data, krec.size);
- #endif
  		BSDDB_BGN_SAVE(dp)
  		status = (dp->di_bsddb->put)(dp->di_bsddb, &krec, &drec, 0);
--- 364,367 ----
***************
*** 379,383 ****
  bsddb_keys(bsddbobject *dp, PyObject *args)
  {
! 	PyObject *list, *item;
  	DBT krec, drec;
  	char *data=NULL,buf[4096];
--- 408,412 ----
  bsddb_keys(bsddbobject *dp, PyObject *args)
  {
! 	PyObject *list, *item=NULL;
  	DBT krec, drec;
  	char *data=NULL,buf[4096];
***************
*** 387,391 ****
  	if (!PyArg_NoArgs(args))
  		return NULL;
! 	check_bsddbobject_open(dp);
  	list = PyList_New(0);
  	if (list == NULL)
--- 416,420 ----
  	if (!PyArg_NoArgs(args))
  		return NULL;
! 	check_bsddbobject_open(dp, NULL);
  	list = PyList_New(0);
  	if (list == NULL)
***************
*** 396,405 ****
  		if (krec.size > sizeof(buf)) data = malloc(krec.size);
  		else data = buf;
! 		if (data!=NULL) memcpy(data,krec.data,krec.size);
  	}
  	BSDDB_END_SAVE(dp)
  	if (data==NULL) return PyErr_NoMemory();
  	while (status == 0) {
! 		item = PyString_FromStringAndSize(data, (int)krec.size);
  		if (data != buf) free(data);
  		if (item == NULL) {
--- 425,438 ----
  		if (krec.size > sizeof(buf)) data = malloc(krec.size);
  		else data = buf;
! 		if (data != NULL) memcpy(data,krec.data,krec.size);
  	}
  	BSDDB_END_SAVE(dp)
  	if (data==NULL) return PyErr_NoMemory();
  	while (status == 0) {
! 		if (dp->di_type == DB_RECNO)
! 			item = PyInt_FromLong(*((int*)data));
! 		else
! 			item = PyString_FromStringAndSize(data,
! 							  (int)krec.size);
  		if (data != buf) free(data);
  		if (item == NULL) {
***************
*** 443,452 ****
  	char *data;
  	int size;
  
! 	if (!PyArg_Parse(args, "s#", &data, &size))
! 		return NULL;
! 	check_bsddbobject_open(dp);
! 	krec.data = data;
! 	krec.size = size;
  
  	BSDDB_BGN_SAVE(dp)
--- 476,500 ----
  	char *data;
  	int size;
+ 	recno_t recno;
  
! 	if (dp->di_type == DB_RECNO) {
! 		if (!PyArg_Parse(args, "i", &recno)) {
! 			PyErr_SetString(PyExc_TypeError,
! 					"key type must be integer");
! 			return NULL;
! 		}
! 		krec.data = &recno;
! 		krec.size = sizeof(recno);
! 	}
! 	else {
! 		if (!PyArg_Parse(args, "s#", &data, &size)) {
! 			PyErr_SetString(PyExc_TypeError,
! 					"key type must be string");
! 			return NULL;
! 		}
! 		krec.data = data;
! 		krec.size = size;
! 	}
! 	check_bsddbobject_open(dp, NULL);
  
  	BSDDB_BGN_SAVE(dp)
***************
*** 469,478 ****
  	int size;
  	PyObject *result;
  
! 	if (!PyArg_Parse(key, "s#", &data, &size))
! 		return NULL;
! 	check_bsddbobject_open(dp);
! 	krec.data = data;
! 	krec.size = size;
  
  	BSDDB_BGN_SAVE(dp)
--- 517,541 ----
  	int size;
  	PyObject *result;
+ 	recno_t recno;
  
! 	if (dp->di_type == DB_RECNO) {
! 		if (!PyArg_Parse(key, "i", &recno)) {
! 			PyErr_SetString(PyExc_TypeError,
! 					"key type must be integer");
! 			return NULL;
! 		}
! 		krec.data = &recno;
! 		krec.size = sizeof(recno);
! 	}
! 	else {
! 		if (!PyArg_Parse(key, "s#", &data, &size)) {
! 			PyErr_SetString(PyExc_TypeError,
! 					"key type must be string");
! 			return NULL;
! 		}
! 		krec.data = data;
! 		krec.size = size;
! 	}
! 	check_bsddbobject_open(dp, NULL);
  
  	BSDDB_BGN_SAVE(dp)
***************
*** 493,497 ****
  	}
  
! 	result = Py_BuildValue("s#s#", krec.data, krec.size, data, drec.size);
  	if (data != buf) free(data);
  	return result;
--- 556,565 ----
  	}
  
! 	if (dp->di_type == DB_RECNO)
! 		result = Py_BuildValue("is#", *((int*)krec.data),
! 				       data, drec.size);
! 	else
! 		result = Py_BuildValue("s#s#", krec.data, krec.size,
! 				       data, drec.size);
  	if (data != buf) free(data);
  	return result;
***************
*** 510,514 ****
  		return NULL;
  
! 	check_bsddbobject_open(dp);
  	krec.data = 0;
  	krec.size = 0;
--- 578,582 ----
  		return NULL;
  
! 	check_bsddbobject_open(dp, NULL);
  	krec.data = 0;
  	krec.size = 0;
***************
*** 520,531 ****
  		if (krec.size > sizeof(kbuf)) kdata = malloc(krec.size);
  		else kdata = kbuf;
! 		if (kdata!=NULL) memcpy(kdata,krec.data,krec.size);
  		if (drec.size > sizeof(dbuf)) ddata = malloc(drec.size);
  		else ddata = dbuf;
! 		if (ddata!=NULL) memcpy(ddata,drec.data,drec.size);
  	}
  	BSDDB_END_SAVE(dp)
  	if (status == 0) {
! 		if ((kdata==NULL) || (ddata==NULL)) 
  			return PyErr_NoMemory();
  	}
--- 588,599 ----
  		if (krec.size > sizeof(kbuf)) kdata = malloc(krec.size);
  		else kdata = kbuf;
! 		if (kdata != NULL) memcpy(kdata,krec.data,krec.size);
  		if (drec.size > sizeof(dbuf)) ddata = malloc(drec.size);
  		else ddata = dbuf;
! 		if (ddata != NULL) memcpy(ddata,drec.data,drec.size);
  	}
  	BSDDB_END_SAVE(dp)
  	if (status == 0) {
! 		if ((kdata == NULL) || (ddata == NULL)) 
  			return PyErr_NoMemory();
  	}
***************
*** 539,543 ****
  	}
  
! 	result = Py_BuildValue("s#s#", kdata, krec.size, ddata, drec.size);
  	if (kdata != kbuf) free(kdata);
  	if (ddata != dbuf) free(ddata);
--- 607,617 ----
  	}
  
! 	
! 	if (dp->di_type == DB_RECNO)
! 		result = Py_BuildValue("is#", *((int*)kdata),
! 				       ddata, drec.size);
! 	else
! 		result = Py_BuildValue("s#s#", kdata, krec.size,
! 				       ddata, drec.size);
  	if (kdata != kbuf) free(kdata);
  	if (ddata != dbuf) free(ddata);
***************
*** 572,576 ****
  	if (!PyArg_NoArgs(args))
  		return NULL;
! 	check_bsddbobject_open(dp);
  	BSDDB_BGN_SAVE(dp)
  	status = (dp->di_bsddb->sync)(dp->di_bsddb, 0);
--- 646,650 ----
  	if (!PyArg_NoArgs(args))
  		return NULL;
! 	check_bsddbobject_open(dp, NULL);
  	BSDDB_BGN_SAVE(dp)
  	status = (dp->di_bsddb->sync)(dp->di_bsddb, 0);
***************
*** 742,758 ****
  		return NULL;
  
- # if 0
- 	printf("file: %s\n", file);
- 	printf("flag: %s\n", flag);
- 	printf("mode: %d\n", mode);
- 	printf("rnflags: 0x%x\n", rnflags);
- 	printf("cachesize: %d\n", cachesize);
- 	printf("psize: %d\n", psize);
- 	printf("lorder: %d\n", 0);
- 	printf("reclen: %d\n", reclen);
- 	printf("bval: %c\n", bval[0]);
- 	printf("bfname %s\n", bfname);
- #endif
- 	
  	if (flag != NULL) {
  		/* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
--- 816,819 ----