blob: 0df7df24cf0e4ca9084e839d6efb7349b40090f9 [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 Rossumb6e2a991998-10-03 05:13:27 +000044#ifdef WIN32
45#include "gdbmerrno.h"
46extern const char * gdbm_strerror(gdbm_error);
47#endif
48
Guido van Rossumbfc49e81998-03-03 22:02:24 +000049static char gdbmmodule__doc__[] = "\
50This module provides an interface to the GNU DBM (GDBM) library.\n\
51\n\
52This module is quite similar to the dbm module, but uses GDBM instead to\n\
53provide some additional functionality. Please note that the file formats\n\
54created by GDBM and dbm are incompatible. \n\
55\n\
56GDBM objects behave like mappings (dictionaries), except that keys and\n\
57values are always strings. Printing a GDBM object doesn't print the\n\
58keys and values, and the items() and values() methods are not\n\
59supported.";
60
Guido van Rossum4b4c6641994-08-08 08:06:37 +000061typedef struct {
Roger E. Masseb15bef81996-12-17 19:55:33 +000062 PyObject_HEAD
Guido van Rossum4b4c6641994-08-08 08:06:37 +000063 int di_size; /* -1 means recompute */
64 GDBM_FILE di_dbm;
65} dbmobject;
66
Roger E. Masseb15bef81996-12-17 19:55:33 +000067staticforward PyTypeObject Dbmtype;
Guido van Rossum4b4c6641994-08-08 08:06:37 +000068
69#define is_dbmobject(v) ((v)->ob_type == &Dbmtype)
Guido van Rossum77eecfa1997-07-17 22:56:01 +000070#define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \
71 { PyErr_SetString(DbmError, "GDBM object has already been closed"); \
72 return NULL; }
73
74
Guido van Rossum4b4c6641994-08-08 08:06:37 +000075
Roger E. Masseb15bef81996-12-17 19:55:33 +000076static PyObject *DbmError;
Guido van Rossum4b4c6641994-08-08 08:06:37 +000077
Guido van Rossumbfc49e81998-03-03 22:02:24 +000078static char gdbm_object__doc__[] = "\
79This object represents a GDBM database.\n\
80GDBM objects behave like mappings (dictionaries), except that keys and\n\
81values are always strings. Printing a GDBM object doesn't print the\n\
82keys and values, and the items() and values() methods are not\n\
83supported.\n\
84\n\
85GDBM objects also support additional operations such as firstkey,\n\
86nextkey, reorganize, and sync.";
87
Roger E. Masseb15bef81996-12-17 19:55:33 +000088static PyObject *
Guido van Rossum4b4c6641994-08-08 08:06:37 +000089newdbmobject(file, flags, mode)
Roger E. Masseb15bef81996-12-17 19:55:33 +000090 char *file;
91int flags;
92int mode;
Guido van Rossum4b4c6641994-08-08 08:06:37 +000093{
94 dbmobject *dp;
95
Roger E. Masseb15bef81996-12-17 19:55:33 +000096 dp = PyObject_NEW(dbmobject, &Dbmtype);
Guido van Rossum4b4c6641994-08-08 08:06:37 +000097 if (dp == NULL)
98 return NULL;
99 dp->di_size = -1;
Guido van Rossumb045afc1995-03-14 15:04:40 +0000100 errno = 0;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000101 if ( (dp->di_dbm = gdbm_open(file, 0, flags, mode, NULL)) == 0 ) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000102 if (errno != 0)
103 PyErr_SetFromErrno(DbmError);
104 else
Guido van Rossum573788e1998-10-03 05:15:07 +0000105 PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno));
Roger E. Masseb15bef81996-12-17 19:55:33 +0000106 Py_DECREF(dp);
107 return NULL;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000108 }
Roger E. Masseb15bef81996-12-17 19:55:33 +0000109 return (PyObject *)dp;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000110}
111
112/* Methods */
113
114static void
115dbm_dealloc(dp)
116 register dbmobject *dp;
117{
118 if ( dp->di_dbm )
Roger E. Masseb15bef81996-12-17 19:55:33 +0000119 gdbm_close(dp->di_dbm);
120 PyMem_DEL(dp);
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000121}
122
123static int
124dbm_length(dp)
125 dbmobject *dp;
126{
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000127 if (dp->di_dbm == NULL) {
128 PyErr_SetString(DbmError, "GDBM object has already been closed");
129 return -1;
130 }
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000131 if ( dp->di_size < 0 ) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000132 datum key,okey;
133 int size;
134 okey.dsize=0;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000135
Roger E. Masseb15bef81996-12-17 19:55:33 +0000136 size = 0;
137 for ( key=gdbm_firstkey(dp->di_dbm); key.dptr;
138 key = gdbm_nextkey(dp->di_dbm,okey)) {
139 size++;
140 if(okey.dsize) free(okey.dptr);
141 okey=key;
142 }
143 dp->di_size = size;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000144 }
145 return dp->di_size;
146}
147
Roger E. Masseb15bef81996-12-17 19:55:33 +0000148static PyObject *
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000149dbm_subscript(dp, key)
150 dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000151register PyObject *key;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000152{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000153 PyObject *v;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000154 datum drec, krec;
155
Roger E. Masseb15bef81996-12-17 19:55:33 +0000156 if (!PyArg_Parse(key, "s#", &krec.dptr, &krec.dsize) )
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000157 return NULL;
158
159 drec = gdbm_fetch(dp->di_dbm, krec);
160 if ( drec.dptr == 0 ) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000161 PyErr_SetString(PyExc_KeyError,
162 PyString_AS_STRING((PyStringObject *)key));
163 return NULL;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000164 }
Roger E. Masseb15bef81996-12-17 19:55:33 +0000165 v = PyString_FromStringAndSize(drec.dptr, drec.dsize);
Guido van Rossumb045afc1995-03-14 15:04:40 +0000166 free(drec.dptr);
167 return v;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000168}
169
170static int
171dbm_ass_sub(dp, v, w)
172 dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000173PyObject *v, *w;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000174{
175 datum krec, drec;
176
Roger E. Masseb15bef81996-12-17 19:55:33 +0000177 if ( !PyArg_Parse(v, "s#", &krec.dptr, &krec.dsize) ) {
178 PyErr_SetString(PyExc_TypeError,
179 "gdbm mappings have string indices only");
180 return -1;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000181 }
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000182 if (dp->di_dbm == NULL) {
183 PyErr_SetString(DbmError, "GDBM object has already been closed");
184 return -1;
185 }
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000186 dp->di_size = -1;
187 if (w == NULL) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000188 if ( gdbm_delete(dp->di_dbm, krec) < 0 ) {
189 PyErr_SetString(PyExc_KeyError,
190 PyString_AS_STRING((PyStringObject *)v));
191 return -1;
192 }
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000193 } else {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000194 if ( !PyArg_Parse(w, "s#", &drec.dptr, &drec.dsize) ) {
195 PyErr_SetString(PyExc_TypeError,
196 "gdbm mappings have string elements only");
197 return -1;
198 }
199 errno = 0;
200 if ( gdbm_store(dp->di_dbm, krec, drec, GDBM_REPLACE) < 0 ) {
201 if (errno != 0)
202 PyErr_SetFromErrno(DbmError);
203 else
204 PyErr_SetString(DbmError,
Guido van Rossum573788e1998-10-03 05:15:07 +0000205 gdbm_strerror(gdbm_errno));
Roger E. Masseb15bef81996-12-17 19:55:33 +0000206 return -1;
207 }
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000208 }
209 return 0;
210}
211
Roger E. Masseb15bef81996-12-17 19:55:33 +0000212static PyMappingMethods dbm_as_mapping = {
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000213 (inquiry)dbm_length, /*mp_length*/
214 (binaryfunc)dbm_subscript, /*mp_subscript*/
215 (objobjargproc)dbm_ass_sub, /*mp_ass_subscript*/
216};
217
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000218static char dbm_close__doc__[] = "\
219close() -> None\n\
Guido van Rossumcef113c1998-04-13 18:11:55 +0000220Closes the database.";
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000221
Roger E. Masseb15bef81996-12-17 19:55:33 +0000222static PyObject *
Guido van Rossum807b7be1995-07-07 22:37:11 +0000223dbm_close(dp, args)
224 register dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000225PyObject *args;
Guido van Rossum807b7be1995-07-07 22:37:11 +0000226{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000227 if ( !PyArg_NoArgs(args) )
Guido van Rossum807b7be1995-07-07 22:37:11 +0000228 return NULL;
229 if ( dp->di_dbm )
230 gdbm_close(dp->di_dbm);
231 dp->di_dbm = NULL;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000232 Py_INCREF(Py_None);
233 return Py_None;
Guido van Rossum807b7be1995-07-07 22:37:11 +0000234}
235
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000236static char dbm_keys__doc__[] = "\
237keys() -> list_of_keys\n\
238Get a list of all keys in the database.";
239
Roger E. Masseb15bef81996-12-17 19:55:33 +0000240static PyObject *
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000241dbm_keys(dp, args)
242 register dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000243PyObject *args;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000244{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000245 register PyObject *v, *item;
Guido van Rossum3be71401996-07-21 02:32:44 +0000246 datum key, nextkey;
Guido van Rossum66017aa1995-08-28 02:58:00 +0000247 int err;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000248
249 if (dp == NULL || !is_dbmobject(dp)) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000250 PyErr_BadInternalCall();
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000251 return NULL;
252 }
Guido van Rossum3be71401996-07-21 02:32:44 +0000253
Roger E. Masseb15bef81996-12-17 19:55:33 +0000254 if (!PyArg_NoArgs(args))
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000255 return NULL;
Guido van Rossum3be71401996-07-21 02:32:44 +0000256
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000257 check_dbmobject_open(dp);
258
Roger E. Masseb15bef81996-12-17 19:55:33 +0000259 v = PyList_New(0);
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000260 if (v == NULL)
261 return NULL;
Guido van Rossum3be71401996-07-21 02:32:44 +0000262
263 key = gdbm_firstkey(dp->di_dbm);
264 while (key.dptr) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000265 item = PyString_FromStringAndSize(key.dptr, key.dsize);
266 if (item == NULL) {
267 free(key.dptr);
268 Py_DECREF(v);
269 return NULL;
270 }
271 err = PyList_Append(v, item);
272 Py_DECREF(item);
273 if (err != 0) {
274 free(key.dptr);
275 Py_DECREF(v);
276 return NULL;
277 }
278 nextkey = gdbm_nextkey(dp->di_dbm, key);
Guido van Rossum3be71401996-07-21 02:32:44 +0000279 free(key.dptr);
Roger E. Masseb15bef81996-12-17 19:55:33 +0000280 key = nextkey;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000281 }
Guido van Rossum3be71401996-07-21 02:32:44 +0000282
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000283 return v;
284}
285
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000286static char dbm_has_key__doc__[] = "\
287has_key(key) -> boolean\n\
288Find out whether or not the database contains a given key.";
289
Roger E. Masseb15bef81996-12-17 19:55:33 +0000290static PyObject *
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000291dbm_has_key(dp, args)
292 register dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000293PyObject *args;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000294{
Guido van Rossumb045afc1995-03-14 15:04:40 +0000295 datum key;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000296
Roger E. Masseb15bef81996-12-17 19:55:33 +0000297 if (!PyArg_Parse(args, "s#", &key.dptr, &key.dsize))
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000298 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000299 check_dbmobject_open(dp);
Roger E. Masseb15bef81996-12-17 19:55:33 +0000300 return PyInt_FromLong((long) gdbm_exists(dp->di_dbm, key));
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000301}
302
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000303static char dbm_firstkey__doc__[] = "\
304firstkey() -> key\n\
305It's possible to loop over every key in the database using this method\n\
306and the nextkey() method. The traversal is ordered by GDBM's internal\n\
307hash values, and won't be sorted by the key values. This method\n\
308returns the starting key.";
309
Roger E. Masseb15bef81996-12-17 19:55:33 +0000310static PyObject *
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000311dbm_firstkey(dp, args)
312 register dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000313PyObject *args;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000314{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000315 register PyObject *v;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000316 datum key;
317
Roger E. Masseb15bef81996-12-17 19:55:33 +0000318 if (!PyArg_NoArgs(args))
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000319 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000320 check_dbmobject_open(dp);
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000321 key = gdbm_firstkey(dp->di_dbm);
322 if (key.dptr) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000323 v = PyString_FromStringAndSize(key.dptr, key.dsize);
324 free(key.dptr);
325 return v;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000326 } else {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000327 Py_INCREF(Py_None);
328 return Py_None;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000329 }
330}
331
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000332static char dbm_nextkey__doc__[] = "\
333nextkey(key) -> next_key\n\
334Returns the key that follows key in the traversal.\n\
335The following code prints every key in the database db, without having\n\
336to create a list in memory that contains them all:\n\
337\n\
338 k = db.firstkey()\n\
339 while k != None:\n\
340 print k\n\
341 k = db.nextkey(k)";
342
Roger E. Masseb15bef81996-12-17 19:55:33 +0000343static PyObject *
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000344dbm_nextkey(dp, args)
345 register dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000346PyObject *args;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000347{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000348 register PyObject *v;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000349 datum key, nextkey;
350
Roger E. Masseb15bef81996-12-17 19:55:33 +0000351 if (!PyArg_Parse(args, "s#", &key.dptr, &key.dsize))
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000352 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000353 check_dbmobject_open(dp);
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000354 nextkey = gdbm_nextkey(dp->di_dbm, key);
355 if (nextkey.dptr) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000356 v = PyString_FromStringAndSize(nextkey.dptr, nextkey.dsize);
357 free(nextkey.dptr);
358 return v;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000359 } else {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000360 Py_INCREF(Py_None);
361 return Py_None;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000362 }
363}
364
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000365static char dbm_reorganize__doc__[] = "\
366reorganize() -> None\n\
367If you have carried out a lot of deletions and would like to shrink\n\
368the space used by the GDBM file, this routine will reorganize the\n\
369database. GDBM will not shorten the length of a database file except\n\
370by using this reorganization; otherwise, deleted file space will be\n\
371kept and reused as new (key,value) pairs are added.";
372
Roger E. Masseb15bef81996-12-17 19:55:33 +0000373static PyObject *
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000374dbm_reorganize(dp, args)
375 register dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000376PyObject *args;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000377{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000378 if (!PyArg_NoArgs(args))
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000379 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000380 check_dbmobject_open(dp);
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000381 errno = 0;
382 if (gdbm_reorganize(dp->di_dbm) < 0) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000383 if (errno != 0)
384 PyErr_SetFromErrno(DbmError);
385 else
Guido van Rossum573788e1998-10-03 05:15:07 +0000386 PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno));
Roger E. Masseb15bef81996-12-17 19:55:33 +0000387 return NULL;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000388 }
Roger E. Masseb15bef81996-12-17 19:55:33 +0000389 Py_INCREF(Py_None);
390 return Py_None;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000391}
392
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000393static char dbm_sync__doc__[] = "\
394sync() -> None\n\
395When the database has been opened in fast mode, this method forces\n\
396any unwritten data to be written to the disk.";
397
Roger E. Massee5a9c8f1997-03-25 17:39:56 +0000398static PyObject *
399dbm_sync(dp, args)
400 register dbmobject *dp;
401 PyObject *args;
402{
403 if (!PyArg_NoArgs(args))
404 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000405 check_dbmobject_open(dp);
Roger E. Massee5a9c8f1997-03-25 17:39:56 +0000406 gdbm_sync(dp->di_dbm);
407 Py_INCREF(Py_None);
408 return Py_None;
409}
410
Roger E. Masseb15bef81996-12-17 19:55:33 +0000411static PyMethodDef dbm_methods[] = {
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000412 {"close", (PyCFunction)dbm_close, 0, dbm_close__doc__},
413 {"keys", (PyCFunction)dbm_keys, 0, dbm_keys__doc__},
414 {"has_key", (PyCFunction)dbm_has_key, 0, dbm_has_key__doc__},
415 {"firstkey", (PyCFunction)dbm_firstkey, 0, dbm_firstkey__doc__},
416 {"nextkey", (PyCFunction)dbm_nextkey, 0, dbm_nextkey__doc__},
417 {"reorganize", (PyCFunction)dbm_reorganize, 0, dbm_reorganize__doc__},
418 {"sync", (PyCFunction)dbm_sync, 0, dbm_sync__doc__},
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000419 {NULL, NULL} /* sentinel */
420};
421
Roger E. Masseb15bef81996-12-17 19:55:33 +0000422static PyObject *
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000423dbm_getattr(dp, name)
424 dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000425char *name;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000426{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000427 return Py_FindMethod(dbm_methods, (PyObject *)dp, name);
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000428}
429
Roger E. Masseb15bef81996-12-17 19:55:33 +0000430static PyTypeObject Dbmtype = {
Guido van Rossumb6e2a991998-10-03 05:13:27 +0000431 PyObject_HEAD_INIT(0)
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000432 0,
Guido van Rossum807b7be1995-07-07 22:37:11 +0000433 "gdbm",
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000434 sizeof(dbmobject),
435 0,
Roger E. Masseb15bef81996-12-17 19:55:33 +0000436 (destructor)dbm_dealloc, /*tp_dealloc*/
437 0, /*tp_print*/
438 (getattrfunc)dbm_getattr, /*tp_getattr*/
439 0, /*tp_setattr*/
440 0, /*tp_compare*/
441 0, /*tp_repr*/
442 0, /*tp_as_number*/
443 0, /*tp_as_sequence*/
444 &dbm_as_mapping, /*tp_as_mapping*/
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000445 0, /*tp_hash*/
446 0, /*tp_call*/
447 0, /*tp_str*/
448 0, /*tp_getattro*/
449 0, /*tp_setattro*/
450 0, /*tp_as_buffer*/
451 0, /*tp_xxx4*/
452 gdbm_object__doc__, /*tp_doc*/
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000453};
454
455/* ----------------------------------------------------------------- */
456
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000457static char dbmopen__doc__[] = "\
458open(filename, [flag, [mode]]) -> dbm_object\n\
459Open a dbm database and return a dbm object. The filename argument is\n\
460the name of the database file.\n\
461\n\
462The optional flag argument can be 'r' (to open an existing database\n\
463for reading only -- default), 'w' (to open an existing database for\n\
464reading and writing), 'c' (which creates the database if it doesn't\n\
465exist), or 'n' (which always creates a new empty database).\n\
466\n\
467Appending f to the flag opens the database in fast mode; altered\n\
468data will not automatically be written to the disk after every\n\
469change. This results in faster writes to the database, but may\n\
470result in an inconsistent database if the program crashes while the\n\
471database is still open. Use the sync() method to force any\n\
472unwritten data to be written to the disk.\n\
473\n\
474The optional mode argument is the Unix mode of the file, used only\n\
475when the database has to be created. It defaults to octal 0666. ";
476
Roger E. Masseb15bef81996-12-17 19:55:33 +0000477static PyObject *
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000478dbmopen(self, args)
Roger E. Masseb15bef81996-12-17 19:55:33 +0000479 PyObject *self;
480PyObject *args;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000481{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000482 char *name;
483 char *flags = "r ";
484 int iflags;
485 int mode = 0666;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000486
Roger E. Masseb15bef81996-12-17 19:55:33 +0000487 if ( !PyArg_ParseTuple(args, "s|si", &name, &flags, &mode) )
488 return NULL;
Guido van Rossume36e1fe1996-01-26 21:08:01 +0000489 switch (flags[0]) {
490 case 'r':
Roger E. Masseb15bef81996-12-17 19:55:33 +0000491 iflags = GDBM_READER;
492 break;
Guido van Rossume36e1fe1996-01-26 21:08:01 +0000493 case 'w':
Roger E. Masseb15bef81996-12-17 19:55:33 +0000494 iflags = GDBM_WRITER;
495 break;
Guido van Rossume36e1fe1996-01-26 21:08:01 +0000496 case 'c':
Roger E. Masseb15bef81996-12-17 19:55:33 +0000497 iflags = GDBM_WRCREAT;
498 break;
Guido van Rossume36e1fe1996-01-26 21:08:01 +0000499 case 'n':
Roger E. Masseb15bef81996-12-17 19:55:33 +0000500 iflags = GDBM_NEWDB;
501 break;
502 default:
503 PyErr_SetString(DbmError,
504 "Flags should be one of 'r', 'w', 'c' or 'n'");
505 return NULL;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000506 }
Guido van Rossume36e1fe1996-01-26 21:08:01 +0000507 if (flags[1] == 'f')
Roger E. Masseb15bef81996-12-17 19:55:33 +0000508 iflags |= GDBM_FAST;
509 return newdbmobject(name, iflags, mode);
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000510}
511
Roger E. Masseb15bef81996-12-17 19:55:33 +0000512static PyMethodDef dbmmodule_methods[] = {
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000513 { "open", (PyCFunction)dbmopen, 1, dbmopen__doc__},
Roger E. Masseb15bef81996-12-17 19:55:33 +0000514 { 0, 0 },
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000515};
516
Guido van Rossum3886bb61998-12-04 18:50:17 +0000517DL_EXPORT(void)
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000518initgdbm() {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000519 PyObject *m, *d;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000520
Guido van Rossumb6e2a991998-10-03 05:13:27 +0000521 Dbmtype.ob_type = &PyType_Type;
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000522 m = Py_InitModule4("gdbm", dbmmodule_methods,
523 gdbmmodule__doc__, (PyObject *)NULL,
524 PYTHON_API_VERSION);
Roger E. Masseb15bef81996-12-17 19:55:33 +0000525 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000526 DbmError = PyErr_NewException("gdbm.error", NULL, NULL);
527 if (DbmError != NULL)
528 PyDict_SetItemString(d, "error", DbmError);
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000529}