blob: d916c33366ed7570e17d430d8830b5410359a78c [file] [log] [blame]
Guido van Rossum4b4c6641994-08-08 08:06:37 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum4b4c6641994-08-08 08:06:37 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossum4b4c6641994-08-08 08:06:37 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossum4b4c6641994-08-08 08:06:37 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossum4b4c6641994-08-08 08:06:37 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum4b4c6641994-08-08 08:06:37 +000029
30******************************************************************/
31
32/* DBM module using dictionary interface */
Guido van Rossumbfc49e81998-03-03 22:02:24 +000033/* Author: Anthony Baxter, after dbmmodule.c */
34/* Doc strings: Mitch Chapman */
Guido van Rossum4b4c6641994-08-08 08:06:37 +000035
36
Roger E. Masseb15bef81996-12-17 19:55:33 +000037#include "Python.h"
Guido van Rossum4b4c6641994-08-08 08:06:37 +000038
39#include <sys/types.h>
40#include <sys/stat.h>
41#include <fcntl.h>
42#include "gdbm.h"
43
Guido van Rossumbfc49e81998-03-03 22:02:24 +000044static char gdbmmodule__doc__[] = "\
45This module provides an interface to the GNU DBM (GDBM) library.\n\
46\n\
47This module is quite similar to the dbm module, but uses GDBM instead to\n\
48provide some additional functionality. Please note that the file formats\n\
49created by GDBM and dbm are incompatible. \n\
50\n\
51GDBM objects behave like mappings (dictionaries), except that keys and\n\
52values are always strings. Printing a GDBM object doesn't print the\n\
53keys and values, and the items() and values() methods are not\n\
54supported.";
55
Guido van Rossum4b4c6641994-08-08 08:06:37 +000056typedef struct {
Roger E. Masseb15bef81996-12-17 19:55:33 +000057 PyObject_HEAD
Guido van Rossum4b4c6641994-08-08 08:06:37 +000058 int di_size; /* -1 means recompute */
59 GDBM_FILE di_dbm;
60} dbmobject;
61
Roger E. Masseb15bef81996-12-17 19:55:33 +000062staticforward PyTypeObject Dbmtype;
Guido van Rossum4b4c6641994-08-08 08:06:37 +000063
64#define is_dbmobject(v) ((v)->ob_type == &Dbmtype)
Guido van Rossum77eecfa1997-07-17 22:56:01 +000065#define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \
66 { PyErr_SetString(DbmError, "GDBM object has already been closed"); \
67 return NULL; }
68
69
Guido van Rossum4b4c6641994-08-08 08:06:37 +000070
Roger E. Masseb15bef81996-12-17 19:55:33 +000071static PyObject *DbmError;
Guido van Rossum4b4c6641994-08-08 08:06:37 +000072
Guido van Rossumbfc49e81998-03-03 22:02:24 +000073static char gdbm_object__doc__[] = "\
74This object represents a GDBM database.\n\
75GDBM objects behave like mappings (dictionaries), except that keys and\n\
76values are always strings. Printing a GDBM object doesn't print the\n\
77keys and values, and the items() and values() methods are not\n\
78supported.\n\
79\n\
80GDBM objects also support additional operations such as firstkey,\n\
81nextkey, reorganize, and sync.";
82
Roger E. Masseb15bef81996-12-17 19:55:33 +000083static PyObject *
Guido van Rossum4b4c6641994-08-08 08:06:37 +000084newdbmobject(file, flags, mode)
Roger E. Masseb15bef81996-12-17 19:55:33 +000085 char *file;
86int flags;
87int mode;
Guido van Rossum4b4c6641994-08-08 08:06:37 +000088{
89 dbmobject *dp;
90
Roger E. Masseb15bef81996-12-17 19:55:33 +000091 dp = PyObject_NEW(dbmobject, &Dbmtype);
Guido van Rossum4b4c6641994-08-08 08:06:37 +000092 if (dp == NULL)
93 return NULL;
94 dp->di_size = -1;
Guido van Rossumb045afc1995-03-14 15:04:40 +000095 errno = 0;
Guido van Rossum4b4c6641994-08-08 08:06:37 +000096 if ( (dp->di_dbm = gdbm_open(file, 0, flags, mode, NULL)) == 0 ) {
Roger E. Masseb15bef81996-12-17 19:55:33 +000097 if (errno != 0)
98 PyErr_SetFromErrno(DbmError);
99 else
100 PyErr_SetString(DbmError,
101 (char *) gdbm_strerror(gdbm_errno));
102 Py_DECREF(dp);
103 return NULL;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000104 }
Roger E. Masseb15bef81996-12-17 19:55:33 +0000105 return (PyObject *)dp;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000106}
107
108/* Methods */
109
110static void
111dbm_dealloc(dp)
112 register dbmobject *dp;
113{
114 if ( dp->di_dbm )
Roger E. Masseb15bef81996-12-17 19:55:33 +0000115 gdbm_close(dp->di_dbm);
116 PyMem_DEL(dp);
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000117}
118
119static int
120dbm_length(dp)
121 dbmobject *dp;
122{
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000123 if (dp->di_dbm == NULL) {
124 PyErr_SetString(DbmError, "GDBM object has already been closed");
125 return -1;
126 }
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000127 if ( dp->di_size < 0 ) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000128 datum key,okey;
129 int size;
130 okey.dsize=0;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000131
Roger E. Masseb15bef81996-12-17 19:55:33 +0000132 size = 0;
133 for ( key=gdbm_firstkey(dp->di_dbm); key.dptr;
134 key = gdbm_nextkey(dp->di_dbm,okey)) {
135 size++;
136 if(okey.dsize) free(okey.dptr);
137 okey=key;
138 }
139 dp->di_size = size;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000140 }
141 return dp->di_size;
142}
143
Roger E. Masseb15bef81996-12-17 19:55:33 +0000144static PyObject *
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000145dbm_subscript(dp, key)
146 dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000147register PyObject *key;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000148{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000149 PyObject *v;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000150 datum drec, krec;
151
Roger E. Masseb15bef81996-12-17 19:55:33 +0000152 if (!PyArg_Parse(key, "s#", &krec.dptr, &krec.dsize) )
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000153 return NULL;
154
155 drec = gdbm_fetch(dp->di_dbm, krec);
156 if ( drec.dptr == 0 ) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000157 PyErr_SetString(PyExc_KeyError,
158 PyString_AS_STRING((PyStringObject *)key));
159 return NULL;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000160 }
Roger E. Masseb15bef81996-12-17 19:55:33 +0000161 v = PyString_FromStringAndSize(drec.dptr, drec.dsize);
Guido van Rossumb045afc1995-03-14 15:04:40 +0000162 free(drec.dptr);
163 return v;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000164}
165
166static int
167dbm_ass_sub(dp, v, w)
168 dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000169PyObject *v, *w;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000170{
171 datum krec, drec;
172
Roger E. Masseb15bef81996-12-17 19:55:33 +0000173 if ( !PyArg_Parse(v, "s#", &krec.dptr, &krec.dsize) ) {
174 PyErr_SetString(PyExc_TypeError,
175 "gdbm mappings have string indices only");
176 return -1;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000177 }
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000178 if (dp->di_dbm == NULL) {
179 PyErr_SetString(DbmError, "GDBM object has already been closed");
180 return -1;
181 }
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000182 dp->di_size = -1;
183 if (w == NULL) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000184 if ( gdbm_delete(dp->di_dbm, krec) < 0 ) {
185 PyErr_SetString(PyExc_KeyError,
186 PyString_AS_STRING((PyStringObject *)v));
187 return -1;
188 }
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000189 } else {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000190 if ( !PyArg_Parse(w, "s#", &drec.dptr, &drec.dsize) ) {
191 PyErr_SetString(PyExc_TypeError,
192 "gdbm mappings have string elements only");
193 return -1;
194 }
195 errno = 0;
196 if ( gdbm_store(dp->di_dbm, krec, drec, GDBM_REPLACE) < 0 ) {
197 if (errno != 0)
198 PyErr_SetFromErrno(DbmError);
199 else
200 PyErr_SetString(DbmError,
201 (char *) gdbm_strerror(gdbm_errno));
202 return -1;
203 }
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000204 }
205 return 0;
206}
207
Roger E. Masseb15bef81996-12-17 19:55:33 +0000208static PyMappingMethods dbm_as_mapping = {
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000209 (inquiry)dbm_length, /*mp_length*/
210 (binaryfunc)dbm_subscript, /*mp_subscript*/
211 (objobjargproc)dbm_ass_sub, /*mp_ass_subscript*/
212};
213
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000214static char dbm_close__doc__[] = "\
215close() -> None\n\
Guido van Rossumcef113c1998-04-13 18:11:55 +0000216Closes the database.";
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000217
Roger E. Masseb15bef81996-12-17 19:55:33 +0000218static PyObject *
Guido van Rossum807b7be1995-07-07 22:37:11 +0000219dbm_close(dp, args)
220 register dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000221PyObject *args;
Guido van Rossum807b7be1995-07-07 22:37:11 +0000222{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000223 if ( !PyArg_NoArgs(args) )
Guido van Rossum807b7be1995-07-07 22:37:11 +0000224 return NULL;
225 if ( dp->di_dbm )
226 gdbm_close(dp->di_dbm);
227 dp->di_dbm = NULL;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000228 Py_INCREF(Py_None);
229 return Py_None;
Guido van Rossum807b7be1995-07-07 22:37:11 +0000230}
231
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000232static char dbm_keys__doc__[] = "\
233keys() -> list_of_keys\n\
234Get a list of all keys in the database.";
235
Roger E. Masseb15bef81996-12-17 19:55:33 +0000236static PyObject *
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000237dbm_keys(dp, args)
238 register dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000239PyObject *args;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000240{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000241 register PyObject *v, *item;
Guido van Rossum3be71401996-07-21 02:32:44 +0000242 datum key, nextkey;
Guido van Rossum66017aa1995-08-28 02:58:00 +0000243 int err;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000244
245 if (dp == NULL || !is_dbmobject(dp)) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000246 PyErr_BadInternalCall();
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000247 return NULL;
248 }
Guido van Rossum3be71401996-07-21 02:32:44 +0000249
Roger E. Masseb15bef81996-12-17 19:55:33 +0000250 if (!PyArg_NoArgs(args))
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000251 return NULL;
Guido van Rossum3be71401996-07-21 02:32:44 +0000252
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000253 check_dbmobject_open(dp);
254
Roger E. Masseb15bef81996-12-17 19:55:33 +0000255 v = PyList_New(0);
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000256 if (v == NULL)
257 return NULL;
Guido van Rossum3be71401996-07-21 02:32:44 +0000258
259 key = gdbm_firstkey(dp->di_dbm);
260 while (key.dptr) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000261 item = PyString_FromStringAndSize(key.dptr, key.dsize);
262 if (item == NULL) {
263 free(key.dptr);
264 Py_DECREF(v);
265 return NULL;
266 }
267 err = PyList_Append(v, item);
268 Py_DECREF(item);
269 if (err != 0) {
270 free(key.dptr);
271 Py_DECREF(v);
272 return NULL;
273 }
274 nextkey = gdbm_nextkey(dp->di_dbm, key);
Guido van Rossum3be71401996-07-21 02:32:44 +0000275 free(key.dptr);
Roger E. Masseb15bef81996-12-17 19:55:33 +0000276 key = nextkey;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000277 }
Guido van Rossum3be71401996-07-21 02:32:44 +0000278
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000279 return v;
280}
281
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000282static char dbm_has_key__doc__[] = "\
283has_key(key) -> boolean\n\
284Find out whether or not the database contains a given key.";
285
Roger E. Masseb15bef81996-12-17 19:55:33 +0000286static PyObject *
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000287dbm_has_key(dp, args)
288 register dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000289PyObject *args;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000290{
Guido van Rossumb045afc1995-03-14 15:04:40 +0000291 datum key;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000292
Roger E. Masseb15bef81996-12-17 19:55:33 +0000293 if (!PyArg_Parse(args, "s#", &key.dptr, &key.dsize))
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000294 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000295 check_dbmobject_open(dp);
Roger E. Masseb15bef81996-12-17 19:55:33 +0000296 return PyInt_FromLong((long) gdbm_exists(dp->di_dbm, key));
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000297}
298
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000299static char dbm_firstkey__doc__[] = "\
300firstkey() -> key\n\
301It's possible to loop over every key in the database using this method\n\
302and the nextkey() method. The traversal is ordered by GDBM's internal\n\
303hash values, and won't be sorted by the key values. This method\n\
304returns the starting key.";
305
Roger E. Masseb15bef81996-12-17 19:55:33 +0000306static PyObject *
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000307dbm_firstkey(dp, args)
308 register dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000309PyObject *args;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000310{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000311 register PyObject *v;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000312 datum key;
313
Roger E. Masseb15bef81996-12-17 19:55:33 +0000314 if (!PyArg_NoArgs(args))
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000315 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000316 check_dbmobject_open(dp);
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000317 key = gdbm_firstkey(dp->di_dbm);
318 if (key.dptr) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000319 v = PyString_FromStringAndSize(key.dptr, key.dsize);
320 free(key.dptr);
321 return v;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000322 } else {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000323 Py_INCREF(Py_None);
324 return Py_None;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000325 }
326}
327
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000328static char dbm_nextkey__doc__[] = "\
329nextkey(key) -> next_key\n\
330Returns the key that follows key in the traversal.\n\
331The following code prints every key in the database db, without having\n\
332to create a list in memory that contains them all:\n\
333\n\
334 k = db.firstkey()\n\
335 while k != None:\n\
336 print k\n\
337 k = db.nextkey(k)";
338
Roger E. Masseb15bef81996-12-17 19:55:33 +0000339static PyObject *
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000340dbm_nextkey(dp, args)
341 register dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000342PyObject *args;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000343{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000344 register PyObject *v;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000345 datum key, nextkey;
346
Roger E. Masseb15bef81996-12-17 19:55:33 +0000347 if (!PyArg_Parse(args, "s#", &key.dptr, &key.dsize))
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000348 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000349 check_dbmobject_open(dp);
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000350 nextkey = gdbm_nextkey(dp->di_dbm, key);
351 if (nextkey.dptr) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000352 v = PyString_FromStringAndSize(nextkey.dptr, nextkey.dsize);
353 free(nextkey.dptr);
354 return v;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000355 } else {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000356 Py_INCREF(Py_None);
357 return Py_None;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000358 }
359}
360
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000361static char dbm_reorganize__doc__[] = "\
362reorganize() -> None\n\
363If you have carried out a lot of deletions and would like to shrink\n\
364the space used by the GDBM file, this routine will reorganize the\n\
365database. GDBM will not shorten the length of a database file except\n\
366by using this reorganization; otherwise, deleted file space will be\n\
367kept and reused as new (key,value) pairs are added.";
368
Roger E. Masseb15bef81996-12-17 19:55:33 +0000369static PyObject *
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000370dbm_reorganize(dp, args)
371 register dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000372PyObject *args;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000373{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000374 if (!PyArg_NoArgs(args))
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000375 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000376 check_dbmobject_open(dp);
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000377 errno = 0;
378 if (gdbm_reorganize(dp->di_dbm) < 0) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000379 if (errno != 0)
380 PyErr_SetFromErrno(DbmError);
381 else
382 PyErr_SetString(DbmError,
383 (char *) gdbm_strerror(gdbm_errno));
384 return NULL;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000385 }
Roger E. Masseb15bef81996-12-17 19:55:33 +0000386 Py_INCREF(Py_None);
387 return Py_None;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000388}
389
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000390static char dbm_sync__doc__[] = "\
391sync() -> None\n\
392When the database has been opened in fast mode, this method forces\n\
393any unwritten data to be written to the disk.";
394
Roger E. Massee5a9c8f1997-03-25 17:39:56 +0000395static PyObject *
396dbm_sync(dp, args)
397 register dbmobject *dp;
398 PyObject *args;
399{
400 if (!PyArg_NoArgs(args))
401 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000402 check_dbmobject_open(dp);
Roger E. Massee5a9c8f1997-03-25 17:39:56 +0000403 gdbm_sync(dp->di_dbm);
404 Py_INCREF(Py_None);
405 return Py_None;
406}
407
Roger E. Masseb15bef81996-12-17 19:55:33 +0000408static PyMethodDef dbm_methods[] = {
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000409 {"close", (PyCFunction)dbm_close, 0, dbm_close__doc__},
410 {"keys", (PyCFunction)dbm_keys, 0, dbm_keys__doc__},
411 {"has_key", (PyCFunction)dbm_has_key, 0, dbm_has_key__doc__},
412 {"firstkey", (PyCFunction)dbm_firstkey, 0, dbm_firstkey__doc__},
413 {"nextkey", (PyCFunction)dbm_nextkey, 0, dbm_nextkey__doc__},
414 {"reorganize", (PyCFunction)dbm_reorganize, 0, dbm_reorganize__doc__},
415 {"sync", (PyCFunction)dbm_sync, 0, dbm_sync__doc__},
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000416 {NULL, NULL} /* sentinel */
417};
418
Roger E. Masseb15bef81996-12-17 19:55:33 +0000419static PyObject *
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000420dbm_getattr(dp, name)
421 dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000422char *name;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000423{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000424 return Py_FindMethod(dbm_methods, (PyObject *)dp, name);
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000425}
426
Roger E. Masseb15bef81996-12-17 19:55:33 +0000427static PyTypeObject Dbmtype = {
428 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000429 0,
Guido van Rossum807b7be1995-07-07 22:37:11 +0000430 "gdbm",
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000431 sizeof(dbmobject),
432 0,
Roger E. Masseb15bef81996-12-17 19:55:33 +0000433 (destructor)dbm_dealloc, /*tp_dealloc*/
434 0, /*tp_print*/
435 (getattrfunc)dbm_getattr, /*tp_getattr*/
436 0, /*tp_setattr*/
437 0, /*tp_compare*/
438 0, /*tp_repr*/
439 0, /*tp_as_number*/
440 0, /*tp_as_sequence*/
441 &dbm_as_mapping, /*tp_as_mapping*/
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000442 0, /*tp_hash*/
443 0, /*tp_call*/
444 0, /*tp_str*/
445 0, /*tp_getattro*/
446 0, /*tp_setattro*/
447 0, /*tp_as_buffer*/
448 0, /*tp_xxx4*/
449 gdbm_object__doc__, /*tp_doc*/
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000450};
451
452/* ----------------------------------------------------------------- */
453
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000454static char dbmopen__doc__[] = "\
455open(filename, [flag, [mode]]) -> dbm_object\n\
456Open a dbm database and return a dbm object. The filename argument is\n\
457the name of the database file.\n\
458\n\
459The optional flag argument can be 'r' (to open an existing database\n\
460for reading only -- default), 'w' (to open an existing database for\n\
461reading and writing), 'c' (which creates the database if it doesn't\n\
462exist), or 'n' (which always creates a new empty database).\n\
463\n\
464Appending f to the flag opens the database in fast mode; altered\n\
465data will not automatically be written to the disk after every\n\
466change. This results in faster writes to the database, but may\n\
467result in an inconsistent database if the program crashes while the\n\
468database is still open. Use the sync() method to force any\n\
469unwritten data to be written to the disk.\n\
470\n\
471The optional mode argument is the Unix mode of the file, used only\n\
472when the database has to be created. It defaults to octal 0666. ";
473
Roger E. Masseb15bef81996-12-17 19:55:33 +0000474static PyObject *
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000475dbmopen(self, args)
Roger E. Masseb15bef81996-12-17 19:55:33 +0000476 PyObject *self;
477PyObject *args;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000478{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000479 char *name;
480 char *flags = "r ";
481 int iflags;
482 int mode = 0666;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000483
Roger E. Masseb15bef81996-12-17 19:55:33 +0000484 if ( !PyArg_ParseTuple(args, "s|si", &name, &flags, &mode) )
485 return NULL;
Guido van Rossume36e1fe1996-01-26 21:08:01 +0000486 switch (flags[0]) {
487 case 'r':
Roger E. Masseb15bef81996-12-17 19:55:33 +0000488 iflags = GDBM_READER;
489 break;
Guido van Rossume36e1fe1996-01-26 21:08:01 +0000490 case 'w':
Roger E. Masseb15bef81996-12-17 19:55:33 +0000491 iflags = GDBM_WRITER;
492 break;
Guido van Rossume36e1fe1996-01-26 21:08:01 +0000493 case 'c':
Roger E. Masseb15bef81996-12-17 19:55:33 +0000494 iflags = GDBM_WRCREAT;
495 break;
Guido van Rossume36e1fe1996-01-26 21:08:01 +0000496 case 'n':
Roger E. Masseb15bef81996-12-17 19:55:33 +0000497 iflags = GDBM_NEWDB;
498 break;
499 default:
500 PyErr_SetString(DbmError,
501 "Flags should be one of 'r', 'w', 'c' or 'n'");
502 return NULL;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000503 }
Guido van Rossume36e1fe1996-01-26 21:08:01 +0000504 if (flags[1] == 'f')
Roger E. Masseb15bef81996-12-17 19:55:33 +0000505 iflags |= GDBM_FAST;
506 return newdbmobject(name, iflags, mode);
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000507}
508
Roger E. Masseb15bef81996-12-17 19:55:33 +0000509static PyMethodDef dbmmodule_methods[] = {
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000510 { "open", (PyCFunction)dbmopen, 1, dbmopen__doc__},
Roger E. Masseb15bef81996-12-17 19:55:33 +0000511 { 0, 0 },
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000512};
513
514void
515initgdbm() {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000516 PyObject *m, *d;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000517
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000518 m = Py_InitModule4("gdbm", dbmmodule_methods,
519 gdbmmodule__doc__, (PyObject *)NULL,
520 PYTHON_API_VERSION);
Roger E. Masseb15bef81996-12-17 19:55:33 +0000521 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000522 DbmError = PyErr_NewException("gdbm.error", NULL, NULL);
523 if (DbmError != NULL)
524 PyDict_SetItemString(d, "error", DbmError);
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000525}