| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* DBM module using dictionary interface */ | 
					
						
							| 
									
										
										
										
											1998-03-03 22:02:24 +00:00
										 |  |  | /* Author: Anthony Baxter, after dbmmodule.c */ | 
					
						
							|  |  |  | /* Doc strings: Mitch Chapman */ | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 19:55:33 +00:00
										 |  |  | #include "Python.h"
 | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <sys/types.h>
 | 
					
						
							|  |  |  | #include <sys/stat.h>
 | 
					
						
							|  |  |  | #include <fcntl.h>
 | 
					
						
							|  |  |  | #include "gdbm.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-02-28 16:44:18 +00:00
										 |  |  | #if defined(WIN32) && !defined(__CYGWIN__)
 | 
					
						
							| 
									
										
										
										
											1998-10-03 05:13:27 +00:00
										 |  |  | #include "gdbmerrno.h"
 | 
					
						
							|  |  |  | extern const char * gdbm_strerror(gdbm_error); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-03 22:02:24 +00:00
										 |  |  | static char gdbmmodule__doc__[] = "\
 | 
					
						
							|  |  |  | This module provides an interface to the GNU DBM (GDBM) library.\n\ | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | This module is quite similar to the dbm module, but uses GDBM instead to\n\ | 
					
						
							|  |  |  | provide some additional functionality. Please note that the file formats\n\ | 
					
						
							|  |  |  | created by GDBM and dbm are incompatible. \n\ | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | GDBM objects behave like mappings (dictionaries), except that keys and\n\ | 
					
						
							|  |  |  | values are always strings. Printing a GDBM object doesn't print the\n\ | 
					
						
							|  |  |  | keys and values, and the items() and values() methods are not\n\ | 
					
						
							|  |  |  | supported."; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     PyObject_HEAD | 
					
						
							|  |  |  |     int di_size;	/* -1 means recompute */ | 
					
						
							|  |  |  |     GDBM_FILE di_dbm; | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | } dbmobject; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 19:55:33 +00:00
										 |  |  | staticforward PyTypeObject Dbmtype; | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define is_dbmobject(v) ((v)->ob_type == &Dbmtype)
 | 
					
						
							| 
									
										
										
										
											1997-07-17 22:56:01 +00:00
										 |  |  | #define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \
 | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     { PyErr_SetString(DbmError, "GDBM object has already been closed"); \ | 
					
						
							|  |  |  |       return NULL; } | 
					
						
							| 
									
										
										
										
											1997-07-17 22:56:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 19:55:33 +00:00
										 |  |  | static PyObject *DbmError; | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-03 22:02:24 +00:00
										 |  |  | static char gdbm_object__doc__[] = "\
 | 
					
						
							|  |  |  | This object represents a GDBM database.\n\ | 
					
						
							|  |  |  | GDBM objects behave like mappings (dictionaries), except that keys and\n\ | 
					
						
							|  |  |  | values are always strings. Printing a GDBM object doesn't print the\n\ | 
					
						
							|  |  |  | keys and values, and the items() and values() methods are not\n\ | 
					
						
							|  |  |  | supported.\n\ | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | GDBM objects also support additional operations such as firstkey,\n\ | 
					
						
							|  |  |  | nextkey, reorganize, and sync."; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 19:55:33 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  | newdbmobject(char *file, int flags, int mode) | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     dbmobject *dp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dp = PyObject_New(dbmobject, &Dbmtype); | 
					
						
							|  |  |  |     if (dp == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     dp->di_size = -1; | 
					
						
							|  |  |  |     errno = 0; | 
					
						
							|  |  |  |     if ((dp->di_dbm = gdbm_open(file, 0, flags, mode, NULL)) == 0) { | 
					
						
							|  |  |  |         if (errno != 0) | 
					
						
							|  |  |  |             PyErr_SetFromErrno(DbmError); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno)); | 
					
						
							|  |  |  |         Py_DECREF(dp); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return (PyObject *)dp; | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Methods */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  | dbm_dealloc(register dbmobject *dp) | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     if (dp->di_dbm) | 
					
						
							|  |  |  |         gdbm_close(dp->di_dbm); | 
					
						
							|  |  |  |     PyObject_Del(dp); | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  | dbm_length(dbmobject *dp) | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     if (dp->di_dbm == NULL) { | 
					
						
							|  |  |  |         PyErr_SetString(DbmError, "GDBM object has already been closed");  | 
					
						
							|  |  |  |         return -1;  | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (dp->di_size < 0) { | 
					
						
							|  |  |  |         datum key,okey; | 
					
						
							|  |  |  |         int size; | 
					
						
							|  |  |  |         okey.dsize=0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         size = 0; | 
					
						
							|  |  |  |         for (key=gdbm_firstkey(dp->di_dbm); key.dptr; | 
					
						
							|  |  |  |              key = gdbm_nextkey(dp->di_dbm,okey)) { | 
					
						
							|  |  |  |             size++; | 
					
						
							|  |  |  |             if(okey.dsize) free(okey.dptr); | 
					
						
							|  |  |  |             okey=key; | 
					
						
							| 
									
										
										
										
											1997-07-17 22:56:01 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |         dp->di_size = size; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return dp->di_size; | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 19:55:33 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  | dbm_subscript(dbmobject *dp, register PyObject *key) | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     PyObject *v; | 
					
						
							|  |  |  |     datum drec, krec; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_Parse(key, "s#", &krec.dptr, &krec.dsize) ) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (dp->di_dbm == NULL) { | 
					
						
							|  |  |  |         PyErr_SetString(DbmError, | 
					
						
							|  |  |  |                         "GDBM object has already been closed"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     drec = gdbm_fetch(dp->di_dbm, krec); | 
					
						
							|  |  |  |     if (drec.dptr == 0) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_KeyError, | 
					
						
							|  |  |  |                         PyString_AS_STRING((PyStringObject *)key)); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     v = PyString_FromStringAndSize(drec.dptr, drec.dsize); | 
					
						
							|  |  |  |     free(drec.dptr); | 
					
						
							|  |  |  |     return v; | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  | dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w) | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     datum krec, drec; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_Parse(v, "s#", &krec.dptr, &krec.dsize) ) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                         "gdbm mappings have string indices only"); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (dp->di_dbm == NULL) { | 
					
						
							|  |  |  |         PyErr_SetString(DbmError, | 
					
						
							|  |  |  |                         "GDBM object has already been closed");  | 
					
						
							|  |  |  |         return -1;  | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     dp->di_size = -1; | 
					
						
							|  |  |  |     if (w == NULL) { | 
					
						
							|  |  |  |         if (gdbm_delete(dp->di_dbm, krec) < 0) { | 
					
						
							|  |  |  |             PyErr_SetString(PyExc_KeyError, | 
					
						
							|  |  |  |                             PyString_AS_STRING((PyStringObject *)v)); | 
					
						
							|  |  |  |             return -1; | 
					
						
							| 
									
										
										
										
											1997-07-17 22:56:01 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         if (!PyArg_Parse(w, "s#", &drec.dptr, &drec.dsize)) { | 
					
						
							|  |  |  |             PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                             "gdbm mappings have string elements only"); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         errno = 0; | 
					
						
							|  |  |  |         if (gdbm_store(dp->di_dbm, krec, drec, GDBM_REPLACE) < 0) { | 
					
						
							|  |  |  |             if (errno != 0) | 
					
						
							|  |  |  |                 PyErr_SetFromErrno(DbmError); | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 PyErr_SetString(DbmError, | 
					
						
							|  |  |  |                                 gdbm_strerror(gdbm_errno)); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 19:55:33 +00:00
										 |  |  | static PyMappingMethods dbm_as_mapping = { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     (inquiry)dbm_length,		/*mp_length*/ | 
					
						
							|  |  |  |     (binaryfunc)dbm_subscript,          /*mp_subscript*/ | 
					
						
							|  |  |  |     (objobjargproc)dbm_ass_sub,         /*mp_ass_subscript*/ | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-03 22:02:24 +00:00
										 |  |  | static char dbm_close__doc__[] = "\
 | 
					
						
							|  |  |  | close() -> None\n\ | 
					
						
							| 
									
										
										
										
											1998-04-13 18:11:55 +00:00
										 |  |  | Closes the database."; | 
					
						
							| 
									
										
										
										
											1998-03-03 22:02:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 19:55:33 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  | dbm_close(register dbmobject *dp, PyObject *args) | 
					
						
							| 
									
										
										
										
											1995-07-07 22:37:11 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     if (!PyArg_ParseTuple(args, ":close")) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     if (dp->di_dbm) | 
					
						
							|  |  |  |         gdbm_close(dp->di_dbm); | 
					
						
							|  |  |  |     dp->di_dbm = NULL; | 
					
						
							|  |  |  |     Py_INCREF(Py_None); | 
					
						
							|  |  |  |     return Py_None; | 
					
						
							| 
									
										
										
										
											1995-07-07 22:37:11 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-03 22:02:24 +00:00
										 |  |  | static char dbm_keys__doc__[] = "\
 | 
					
						
							|  |  |  | keys() -> list_of_keys\n\ | 
					
						
							|  |  |  | Get a list of all keys in the database."; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 19:55:33 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  | dbm_keys(register dbmobject *dp, PyObject *args) | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     register PyObject *v, *item; | 
					
						
							|  |  |  |     datum key, nextkey; | 
					
						
							|  |  |  |     int err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (dp == NULL || !is_dbmobject(dp)) { | 
					
						
							|  |  |  |         PyErr_BadInternalCall(); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, ":keys")) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     check_dbmobject_open(dp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     v = PyList_New(0); | 
					
						
							|  |  |  |     if (v == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = gdbm_firstkey(dp->di_dbm); | 
					
						
							|  |  |  |     while (key.dptr) { | 
					
						
							|  |  |  |         item = PyString_FromStringAndSize(key.dptr, key.dsize); | 
					
						
							|  |  |  |         if (item == NULL) { | 
					
						
							|  |  |  |             free(key.dptr); | 
					
						
							|  |  |  |             Py_DECREF(v); | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         err = PyList_Append(v, item); | 
					
						
							|  |  |  |         Py_DECREF(item); | 
					
						
							|  |  |  |         if (err != 0) { | 
					
						
							|  |  |  |             free(key.dptr); | 
					
						
							|  |  |  |             Py_DECREF(v); | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         nextkey = gdbm_nextkey(dp->di_dbm, key); | 
					
						
							|  |  |  |         free(key.dptr); | 
					
						
							|  |  |  |         key = nextkey; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return v; | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-03 22:02:24 +00:00
										 |  |  | static char dbm_has_key__doc__[] = "\
 | 
					
						
							|  |  |  | has_key(key) -> boolean\n\ | 
					
						
							|  |  |  | Find out whether or not the database contains a given key."; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 19:55:33 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  | dbm_has_key(register dbmobject *dp, PyObject *args) | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     datum key; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "s#:has_key", &key.dptr, &key.dsize)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     check_dbmobject_open(dp); | 
					
						
							|  |  |  |     return PyInt_FromLong((long) gdbm_exists(dp->di_dbm, key)); | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-03 22:02:24 +00:00
										 |  |  | static char dbm_firstkey__doc__[] = "\
 | 
					
						
							|  |  |  | firstkey() -> key\n\ | 
					
						
							|  |  |  | It's possible to loop over every key in the database using this method\n\ | 
					
						
							|  |  |  | and the nextkey() method. The traversal is ordered by GDBM's internal\n\ | 
					
						
							|  |  |  | hash values, and won't be sorted by the key values. This method\n\ | 
					
						
							|  |  |  | returns the starting key."; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 19:55:33 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  | dbm_firstkey(register dbmobject *dp, PyObject *args) | 
					
						
							| 
									
										
										
										
											1995-03-16 16:07:34 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     register PyObject *v; | 
					
						
							|  |  |  |     datum key; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, ":firstkey")) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     check_dbmobject_open(dp); | 
					
						
							|  |  |  |     key = gdbm_firstkey(dp->di_dbm); | 
					
						
							|  |  |  |     if (key.dptr) { | 
					
						
							|  |  |  |         v = PyString_FromStringAndSize(key.dptr, key.dsize); | 
					
						
							|  |  |  |         free(key.dptr); | 
					
						
							|  |  |  |         return v; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         Py_INCREF(Py_None); | 
					
						
							|  |  |  |         return Py_None; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											1995-03-16 16:07:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-03 22:02:24 +00:00
										 |  |  | static char dbm_nextkey__doc__[] = "\
 | 
					
						
							|  |  |  | nextkey(key) -> next_key\n\ | 
					
						
							|  |  |  | Returns the key that follows key in the traversal.\n\ | 
					
						
							|  |  |  | The following code prints every key in the database db, without having\n\ | 
					
						
							|  |  |  | to create a list in memory that contains them all:\n\ | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  |       k = db.firstkey()\n\ | 
					
						
							|  |  |  |       while k != None:\n\ | 
					
						
							|  |  |  |           print k\n\ | 
					
						
							|  |  |  |           k = db.nextkey(k)"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 19:55:33 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  | dbm_nextkey(register dbmobject *dp, PyObject *args) | 
					
						
							| 
									
										
										
										
											1995-03-16 16:07:34 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     register PyObject *v; | 
					
						
							|  |  |  |     datum key, nextkey; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "s#:nextkey", &key.dptr, &key.dsize)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     check_dbmobject_open(dp); | 
					
						
							|  |  |  |     nextkey = gdbm_nextkey(dp->di_dbm, key); | 
					
						
							|  |  |  |     if (nextkey.dptr) { | 
					
						
							|  |  |  |         v = PyString_FromStringAndSize(nextkey.dptr, nextkey.dsize); | 
					
						
							|  |  |  |         free(nextkey.dptr); | 
					
						
							|  |  |  |         return v; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         Py_INCREF(Py_None); | 
					
						
							|  |  |  |         return Py_None; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											1995-03-16 16:07:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-03 22:02:24 +00:00
										 |  |  | static char dbm_reorganize__doc__[] = "\
 | 
					
						
							|  |  |  | reorganize() -> None\n\ | 
					
						
							|  |  |  | If you have carried out a lot of deletions and would like to shrink\n\ | 
					
						
							|  |  |  | the space used by the GDBM file, this routine will reorganize the\n\ | 
					
						
							|  |  |  | database. GDBM will not shorten the length of a database file except\n\ | 
					
						
							|  |  |  | by using this reorganization; otherwise, deleted file space will be\n\ | 
					
						
							|  |  |  | kept and reused as new (key,value) pairs are added."; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 19:55:33 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  | dbm_reorganize(register dbmobject *dp, PyObject *args) | 
					
						
							| 
									
										
										
										
											1995-03-16 16:07:34 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     if (!PyArg_ParseTuple(args, ":reorganize")) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     check_dbmobject_open(dp); | 
					
						
							|  |  |  |     errno = 0; | 
					
						
							|  |  |  |     if (gdbm_reorganize(dp->di_dbm) < 0) { | 
					
						
							|  |  |  |         if (errno != 0) | 
					
						
							|  |  |  |             PyErr_SetFromErrno(DbmError); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno)); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     Py_INCREF(Py_None); | 
					
						
							|  |  |  |     return Py_None; | 
					
						
							| 
									
										
										
										
											1995-03-16 16:07:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-03 22:02:24 +00:00
										 |  |  | static char dbm_sync__doc__[] = "\
 | 
					
						
							|  |  |  | sync() -> None\n\ | 
					
						
							|  |  |  | When the database has been opened in fast mode, this method forces\n\ | 
					
						
							|  |  |  | any unwritten data to be written to the disk."; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-03-25 17:39:56 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  | dbm_sync(register dbmobject *dp, PyObject *args) | 
					
						
							| 
									
										
										
										
											1997-03-25 17:39:56 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     if (!PyArg_ParseTuple(args, ":sync")) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     check_dbmobject_open(dp); | 
					
						
							|  |  |  |     gdbm_sync(dp->di_dbm); | 
					
						
							|  |  |  |     Py_INCREF(Py_None); | 
					
						
							|  |  |  |     return Py_None; | 
					
						
							| 
									
										
										
										
											1997-03-25 17:39:56 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 19:55:33 +00:00
										 |  |  | static PyMethodDef dbm_methods[] = { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     {"close",	  (PyCFunction)dbm_close,   METH_VARARGS, dbm_close__doc__}, | 
					
						
							|  |  |  |     {"keys",	  (PyCFunction)dbm_keys,    METH_VARARGS, dbm_keys__doc__}, | 
					
						
							|  |  |  |     {"has_key",   (PyCFunction)dbm_has_key, METH_VARARGS, dbm_has_key__doc__}, | 
					
						
							|  |  |  |     {"firstkey",  (PyCFunction)dbm_firstkey,METH_VARARGS, dbm_firstkey__doc__}, | 
					
						
							|  |  |  |     {"nextkey",	  (PyCFunction)dbm_nextkey, METH_VARARGS, dbm_nextkey__doc__}, | 
					
						
							|  |  |  |     {"reorganize",(PyCFunction)dbm_reorganize,METH_VARARGS, dbm_reorganize__doc__}, | 
					
						
							|  |  |  |     {"sync",      (PyCFunction)dbm_sync,    METH_VARARGS, dbm_sync__doc__}, | 
					
						
							|  |  |  |     {NULL,		NULL}		/* sentinel */ | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 19:55:33 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  | dbm_getattr(dbmobject *dp, char *name) | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     return Py_FindMethod(dbm_methods, (PyObject *)dp, name); | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 19:55:33 +00:00
										 |  |  | static PyTypeObject Dbmtype = { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     PyObject_HEAD_INIT(0) | 
					
						
							|  |  |  |     0, | 
					
						
							|  |  |  |     "gdbm", | 
					
						
							|  |  |  |     sizeof(dbmobject), | 
					
						
							|  |  |  |     0, | 
					
						
							|  |  |  |     (destructor)dbm_dealloc,            /*tp_dealloc*/ | 
					
						
							|  |  |  |     0,                                  /*tp_print*/ | 
					
						
							|  |  |  |     (getattrfunc)dbm_getattr,           /*tp_getattr*/ | 
					
						
							|  |  |  |     0,                                  /*tp_setattr*/ | 
					
						
							|  |  |  |     0,                                  /*tp_compare*/ | 
					
						
							|  |  |  |     0,                                  /*tp_repr*/ | 
					
						
							|  |  |  |     0,                                  /*tp_as_number*/ | 
					
						
							|  |  |  |     0,                                  /*tp_as_sequence*/ | 
					
						
							|  |  |  |     &dbm_as_mapping,                    /*tp_as_mapping*/ | 
					
						
							|  |  |  |     0,                                  /*tp_hash*/ | 
					
						
							|  |  |  |     0,                                  /*tp_call*/ | 
					
						
							|  |  |  |     0,                                  /*tp_str*/ | 
					
						
							|  |  |  |     0,                                  /*tp_getattro*/ | 
					
						
							|  |  |  |     0,                                  /*tp_setattro*/ | 
					
						
							|  |  |  |     0,                                  /*tp_as_buffer*/ | 
					
						
							|  |  |  |     0,                                  /*tp_xxx4*/ | 
					
						
							|  |  |  |     gdbm_object__doc__,                 /*tp_doc*/ | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ----------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-03 22:02:24 +00:00
										 |  |  | static char dbmopen__doc__[] = "\
 | 
					
						
							| 
									
										
										
										
											2000-12-17 07:14:13 +00:00
										 |  |  | open(filename, [flags, [mode]])  -> dbm_object\n\ | 
					
						
							| 
									
										
										
										
											1998-03-03 22:02:24 +00:00
										 |  |  | Open a dbm database and return a dbm object. The filename argument is\n\ | 
					
						
							|  |  |  | the name of the database file.\n\ | 
					
						
							|  |  |  | \n\ | 
					
						
							| 
									
										
										
										
											2000-12-17 07:14:13 +00:00
										 |  |  | The optional flags argument can be 'r' (to open an existing database\n\ | 
					
						
							| 
									
										
										
										
											1998-03-03 22:02:24 +00:00
										 |  |  | for reading only -- default), 'w' (to open an existing database for\n\ | 
					
						
							|  |  |  | reading and writing), 'c' (which creates the database if it doesn't\n\ | 
					
						
							|  |  |  | exist), or 'n' (which always creates a new empty database).\n\ | 
					
						
							|  |  |  | \n\ | 
					
						
							| 
									
										
										
										
											2000-12-17 07:14:13 +00:00
										 |  |  | Some versions of gdbm support additional flags which must be\n\ | 
					
						
							|  |  |  | appended to one of the flags described above. The module constant\n\ | 
					
						
							|  |  |  | 'open_flags' is a string of valid additional flags. The 'f' flag\n\ | 
					
						
							|  |  |  | opens the database in fast mode; altered data will not automatically\n\ | 
					
						
							|  |  |  | be written to the disk after every change. This results in faster\n\ | 
					
						
							|  |  |  | writes to the database, but may result in an inconsistent database\n\ | 
					
						
							|  |  |  | if the program crashes while the database is still open. Use the\n\ | 
					
						
							|  |  |  | sync() method to force any unwritten data to be written to the disk.\n\ | 
					
						
							|  |  |  | The 's' flag causes all database operations to be synchronized to\n\ | 
					
						
							|  |  |  | disk. The 'u' flag disables locking of the database file.\n\ | 
					
						
							| 
									
										
										
										
											1998-03-03 22:02:24 +00:00
										 |  |  | \n\ | 
					
						
							|  |  |  | The optional mode argument is the Unix mode of the file, used only\n\ | 
					
						
							|  |  |  | when the database has to be created. It defaults to octal 0666. "; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 19:55:33 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  | dbmopen(PyObject *self, PyObject *args) | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     char *name; | 
					
						
							|  |  |  |     char *flags = "r "; | 
					
						
							|  |  |  |     int iflags; | 
					
						
							|  |  |  |     int mode = 0666; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "s|si:open", &name, &flags, &mode)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     switch (flags[0]) { | 
					
						
							|  |  |  |     case 'r': | 
					
						
							|  |  |  |         iflags = GDBM_READER; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 'w': | 
					
						
							|  |  |  |         iflags = GDBM_WRITER; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 'c': | 
					
						
							|  |  |  |         iflags = GDBM_WRCREAT; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 'n': | 
					
						
							|  |  |  |         iflags = GDBM_NEWDB; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         PyErr_SetString(DbmError, | 
					
						
							| 
									
										
										
										
											2000-12-17 07:14:13 +00:00
										 |  |  |                         "First flag must be one of 'r', 'w', 'c' or 'n'"); | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2000-12-17 07:14:13 +00:00
										 |  |  |     for (flags++; *flags != '\0'; flags++) { | 
					
						
							|  |  |  |         char buf[40]; | 
					
						
							|  |  |  |         switch (*flags) { | 
					
						
							|  |  |  | #ifdef GDBM_FAST
 | 
					
						
							|  |  |  |             case 'f': | 
					
						
							|  |  |  |                 iflags |= GDBM_FAST; | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef GDBM_SYNC
 | 
					
						
							|  |  |  |             case 's': | 
					
						
							|  |  |  |                 iflags |= GDBM_SYNC; | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef GDBM_NOLOCK
 | 
					
						
							|  |  |  |             case 'u': | 
					
						
							|  |  |  |                 iflags |= GDBM_NOLOCK; | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |             default: | 
					
						
							|  |  |  |                 sprintf(buf, "Flag '%c' is not supported.", *flags); | 
					
						
							|  |  |  |                 PyErr_SetString(DbmError, buf); | 
					
						
							|  |  |  |                 return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     return newdbmobject(name, iflags, mode); | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-12-17 07:14:13 +00:00
										 |  |  | static char dbmmodule_open_flags[] = "rwcn" | 
					
						
							|  |  |  | #ifdef GDBM_FAST
 | 
					
						
							|  |  |  |                                      "f" | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef GDBM_SYNC
 | 
					
						
							|  |  |  |                                      "s" | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef GDBM_NOLOCK
 | 
					
						
							|  |  |  |                                      "u" | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |                                      ; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-17 19:55:33 +00:00
										 |  |  | static PyMethodDef dbmmodule_methods[] = { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     { "open", (PyCFunction)dbmopen, METH_VARARGS, dbmopen__doc__}, | 
					
						
							|  |  |  |     { 0, 0 }, | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-12-04 18:50:17 +00:00
										 |  |  | DL_EXPORT(void) | 
					
						
							| 
									
										
										
										
											2000-07-24 14:43:35 +00:00
										 |  |  | initgdbm(void) { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |     PyObject *m, *d; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Dbmtype.ob_type = &PyType_Type; | 
					
						
							|  |  |  |     m = Py_InitModule4("gdbm", dbmmodule_methods, | 
					
						
							|  |  |  |                        gdbmmodule__doc__, (PyObject *)NULL, | 
					
						
							|  |  |  |                        PYTHON_API_VERSION); | 
					
						
							|  |  |  |     d = PyModule_GetDict(m); | 
					
						
							|  |  |  |     DbmError = PyErr_NewException("gdbm.error", NULL, NULL); | 
					
						
							| 
									
										
										
										
											2000-12-17 07:14:13 +00:00
										 |  |  |     if (DbmError != NULL) { | 
					
						
							| 
									
										
										
										
											2000-07-08 05:00:07 +00:00
										 |  |  |         PyDict_SetItemString(d, "error", DbmError); | 
					
						
							| 
									
										
										
										
											2000-12-17 07:14:13 +00:00
										 |  |  |         PyDict_SetItemString(d, "open_flags", | 
					
						
							|  |  |  |                 PyString_FromString(dbmmodule_open_flags)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											1994-08-08 08:06:37 +00:00
										 |  |  | } |