1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* DBM module using dictionary interface */
37 #include <sys/types.h>
44 int di_size
; /* -1 means recompute */
48 staticforward PyTypeObject Dbmtype
;
50 #define is_dbmobject(v) ((v)->ob_type == &Dbmtype)
51 #define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \
52 { PyErr_SetString(DbmError, "DBM object has already been closed"); \
55 static PyObject
*DbmError
;
58 newdbmobject(file
, flags
, mode
)
65 dp
= PyObject_NEW(dbmobject
, &Dbmtype
);
69 if ( (dp
->di_dbm
= dbm_open(file
, flags
, mode
)) == 0 ) {
70 PyErr_SetFromErrno(DbmError
);
74 return (PyObject
*)dp
;
81 register dbmobject
*dp
;
84 dbm_close(dp
->di_dbm
);
92 if (dp
->di_dbm
== NULL
) {
93 PyErr_SetString(DbmError
, "DBM object has already been closed");
96 if ( dp
->di_size
< 0 ) {
101 for ( key
=dbm_firstkey(dp
->di_dbm
); key
.dptr
;
102 key
= dbm_nextkey(dp
->di_dbm
))
110 dbm_subscript(dp
, key
)
112 register PyObject
*key
;
116 if (!PyArg_Parse(key
, "s#", &krec
.dptr
, &krec
.dsize
) )
119 check_dbmobject_open(dp
);
120 drec
= dbm_fetch(dp
->di_dbm
, krec
);
121 if ( drec
.dptr
== 0 ) {
122 PyErr_SetString(PyExc_KeyError
,
123 PyString_AS_STRING((PyStringObject
*)key
));
126 if ( dbm_error(dp
->di_dbm
) ) {
127 dbm_clearerr(dp
->di_dbm
);
128 PyErr_SetString(DbmError
, "");
131 return PyString_FromStringAndSize(drec
.dptr
, drec
.dsize
);
135 dbm_ass_sub(dp
, v
, w
)
141 if ( !PyArg_Parse(v
, "s#", &krec
.dptr
, &krec
.dsize
) ) {
142 PyErr_SetString(PyExc_TypeError
,
143 "dbm mappings have string indices only");
146 if (dp
->di_dbm
== NULL
) {
147 PyErr_SetString(DbmError
, "DBM object has already been closed");
152 if ( dbm_delete(dp
->di_dbm
, krec
) < 0 ) {
153 dbm_clearerr(dp
->di_dbm
);
154 PyErr_SetString(PyExc_KeyError
,
155 PyString_AS_STRING((PyStringObject
*)v
));
159 if ( !PyArg_Parse(w
, "s#", &drec
.dptr
, &drec
.dsize
) ) {
160 PyErr_SetString(PyExc_TypeError
,
161 "dbm mappings have string elements only");
164 if ( dbm_store(dp
->di_dbm
, krec
, drec
, DBM_REPLACE
) < 0 ) {
165 dbm_clearerr(dp
->di_dbm
);
166 PyErr_SetString(DbmError
,
167 "Cannot add item to database");
171 if ( dbm_error(dp
->di_dbm
) ) {
172 dbm_clearerr(dp
->di_dbm
);
173 PyErr_SetString(DbmError
, "");
179 static PyMappingMethods dbm_as_mapping
= {
180 (inquiry
)dbm_length
, /*mp_length*/
181 (binaryfunc
)dbm_subscript
, /*mp_subscript*/
182 (objobjargproc
)dbm_ass_sub
, /*mp_ass_subscript*/
187 register dbmobject
*dp
;
190 if ( !PyArg_NoArgs(args
) )
193 dbm_close(dp
->di_dbm
);
201 register dbmobject
*dp
;
204 register PyObject
*v
, *item
;
208 if (!PyArg_NoArgs(args
))
210 check_dbmobject_open(dp
);
214 for (key
= dbm_firstkey(dp
->di_dbm
); key
.dptr
;
215 key
= dbm_nextkey(dp
->di_dbm
)) {
216 item
= PyString_FromStringAndSize(key
.dptr
, key
.dsize
);
221 err
= PyList_Append(v
, item
);
232 dbm_has_key(dp
, args
)
233 register dbmobject
*dp
;
238 if (!PyArg_Parse(args
, "s#", &key
.dptr
, &key
.dsize
))
240 check_dbmobject_open(dp
);
241 val
= dbm_fetch(dp
->di_dbm
, key
);
242 return PyInt_FromLong(val
.dptr
!= NULL
);
245 static PyMethodDef dbm_methods
[] = {
246 {"close", (PyCFunction
)dbm__close
},
247 {"keys", (PyCFunction
)dbm_keys
},
248 {"has_key", (PyCFunction
)dbm_has_key
},
249 {NULL
, NULL
} /* sentinel */
253 dbm_getattr(dp
, name
)
257 return Py_FindMethod(dbm_methods
, (PyObject
*)dp
, name
);
260 static PyTypeObject Dbmtype
= {
261 PyObject_HEAD_INIT(&PyType_Type
)
266 (destructor
)dbm_dealloc
, /*tp_dealloc*/
268 (getattrfunc
)dbm_getattr
, /*tp_getattr*/
273 0, /*tp_as_sequence*/
274 &dbm_as_mapping
, /*tp_as_mapping*/
277 /* ----------------------------------------------------------------- */
289 if ( !PyArg_ParseTuple(args
, "s|si", &name
, &flags
, &mode
) )
291 if ( strcmp(flags
, "r") == 0 )
293 else if ( strcmp(flags
, "w") == 0 )
295 else if ( strcmp(flags
, "rw") == 0 ) /* B/W compat */
296 iflags
= O_RDWR
|O_CREAT
;
297 else if ( strcmp(flags
, "c") == 0 )
298 iflags
= O_RDWR
|O_CREAT
;
299 else if ( strcmp(flags
, "n") == 0 )
300 iflags
= O_RDWR
|O_CREAT
|O_TRUNC
;
302 PyErr_SetString(DbmError
,
303 "Flags should be one of 'r', 'w', 'c' or 'n'");
306 return newdbmobject(name
, iflags
, mode
);
309 static PyMethodDef dbmmodule_methods
[] = {
310 { "open", (PyCFunction
)dbmopen
, 1 },
318 m
= Py_InitModule("dbm", dbmmodule_methods
);
319 d
= PyModule_GetDict(m
);
320 DbmError
= PyErr_NewException("dbm.error", NULL
, NULL
);
321 if (DbmError
!= NULL
)
322 PyDict_SetItemString(d
, "error", DbmError
);