blob: 31855f5e72e175f6e3b8c09241d95db6dc9587e0 [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;
Fred Drakeda8d2162000-02-07 17:19:41 +0000158
159 if (dp->di_dbm == NULL) {
160 PyErr_SetString(DbmError,
161 "GDBM object has already been closed");
162 return NULL;
163 }
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000164 drec = gdbm_fetch(dp->di_dbm, krec);
165 if ( drec.dptr == 0 ) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000166 PyErr_SetString(PyExc_KeyError,
167 PyString_AS_STRING((PyStringObject *)key));
168 return NULL;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000169 }
Roger E. Masseb15bef81996-12-17 19:55:33 +0000170 v = PyString_FromStringAndSize(drec.dptr, drec.dsize);
Guido van Rossumb045afc1995-03-14 15:04:40 +0000171 free(drec.dptr);
172 return v;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000173}
174
175static int
176dbm_ass_sub(dp, v, w)
177 dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000178PyObject *v, *w;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000179{
180 datum krec, drec;
181
Roger E. Masseb15bef81996-12-17 19:55:33 +0000182 if ( !PyArg_Parse(v, "s#", &krec.dptr, &krec.dsize) ) {
183 PyErr_SetString(PyExc_TypeError,
184 "gdbm mappings have string indices only");
185 return -1;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000186 }
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000187 if (dp->di_dbm == NULL) {
Fred Drakeda8d2162000-02-07 17:19:41 +0000188 PyErr_SetString(DbmError,
189 "GDBM object has already been closed");
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000190 return -1;
191 }
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000192 dp->di_size = -1;
193 if (w == NULL) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000194 if ( gdbm_delete(dp->di_dbm, krec) < 0 ) {
195 PyErr_SetString(PyExc_KeyError,
196 PyString_AS_STRING((PyStringObject *)v));
197 return -1;
198 }
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000199 } else {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000200 if ( !PyArg_Parse(w, "s#", &drec.dptr, &drec.dsize) ) {
201 PyErr_SetString(PyExc_TypeError,
202 "gdbm mappings have string elements only");
203 return -1;
204 }
205 errno = 0;
206 if ( gdbm_store(dp->di_dbm, krec, drec, GDBM_REPLACE) < 0 ) {
207 if (errno != 0)
208 PyErr_SetFromErrno(DbmError);
209 else
210 PyErr_SetString(DbmError,
Guido van Rossum573788e1998-10-03 05:15:07 +0000211 gdbm_strerror(gdbm_errno));
Roger E. Masseb15bef81996-12-17 19:55:33 +0000212 return -1;
213 }
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000214 }
215 return 0;
216}
217
Roger E. Masseb15bef81996-12-17 19:55:33 +0000218static PyMappingMethods dbm_as_mapping = {
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000219 (inquiry)dbm_length, /*mp_length*/
220 (binaryfunc)dbm_subscript, /*mp_subscript*/
221 (objobjargproc)dbm_ass_sub, /*mp_ass_subscript*/
222};
223
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000224static char dbm_close__doc__[] = "\
225close() -> None\n\
Guido van Rossumcef113c1998-04-13 18:11:55 +0000226Closes the database.";
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000227
Roger E. Masseb15bef81996-12-17 19:55:33 +0000228static PyObject *
Guido van Rossum807b7be1995-07-07 22:37:11 +0000229dbm_close(dp, args)
230 register dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000231PyObject *args;
Guido van Rossum807b7be1995-07-07 22:37:11 +0000232{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000233 if ( !PyArg_NoArgs(args) )
Guido van Rossum807b7be1995-07-07 22:37:11 +0000234 return NULL;
235 if ( dp->di_dbm )
236 gdbm_close(dp->di_dbm);
237 dp->di_dbm = NULL;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000238 Py_INCREF(Py_None);
239 return Py_None;
Guido van Rossum807b7be1995-07-07 22:37:11 +0000240}
241
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000242static char dbm_keys__doc__[] = "\
243keys() -> list_of_keys\n\
244Get a list of all keys in the database.";
245
Roger E. Masseb15bef81996-12-17 19:55:33 +0000246static PyObject *
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000247dbm_keys(dp, args)
248 register dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000249PyObject *args;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000250{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000251 register PyObject *v, *item;
Guido van Rossum3be71401996-07-21 02:32:44 +0000252 datum key, nextkey;
Guido van Rossum66017aa1995-08-28 02:58:00 +0000253 int err;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000254
255 if (dp == NULL || !is_dbmobject(dp)) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000256 PyErr_BadInternalCall();
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000257 return NULL;
258 }
Guido van Rossum3be71401996-07-21 02:32:44 +0000259
Roger E. Masseb15bef81996-12-17 19:55:33 +0000260 if (!PyArg_NoArgs(args))
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000261 return NULL;
Guido van Rossum3be71401996-07-21 02:32:44 +0000262
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000263 check_dbmobject_open(dp);
264
Roger E. Masseb15bef81996-12-17 19:55:33 +0000265 v = PyList_New(0);
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000266 if (v == NULL)
267 return NULL;
Guido van Rossum3be71401996-07-21 02:32:44 +0000268
269 key = gdbm_firstkey(dp->di_dbm);
270 while (key.dptr) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000271 item = PyString_FromStringAndSize(key.dptr, key.dsize);
272 if (item == NULL) {
273 free(key.dptr);
274 Py_DECREF(v);
275 return NULL;
276 }
277 err = PyList_Append(v, item);
278 Py_DECREF(item);
279 if (err != 0) {
280 free(key.dptr);
281 Py_DECREF(v);
282 return NULL;
283 }
284 nextkey = gdbm_nextkey(dp->di_dbm, key);
Guido van Rossum3be71401996-07-21 02:32:44 +0000285 free(key.dptr);
Roger E. Masseb15bef81996-12-17 19:55:33 +0000286 key = nextkey;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000287 }
Guido van Rossum3be71401996-07-21 02:32:44 +0000288
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000289 return v;
290}
291
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000292static char dbm_has_key__doc__[] = "\
293has_key(key) -> boolean\n\
294Find out whether or not the database contains a given key.";
295
Roger E. Masseb15bef81996-12-17 19:55:33 +0000296static PyObject *
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000297dbm_has_key(dp, args)
298 register dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000299PyObject *args;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000300{
Guido van Rossumb045afc1995-03-14 15:04:40 +0000301 datum key;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000302
Roger E. Masseb15bef81996-12-17 19:55:33 +0000303 if (!PyArg_Parse(args, "s#", &key.dptr, &key.dsize))
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000304 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000305 check_dbmobject_open(dp);
Roger E. Masseb15bef81996-12-17 19:55:33 +0000306 return PyInt_FromLong((long) gdbm_exists(dp->di_dbm, key));
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000307}
308
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000309static char dbm_firstkey__doc__[] = "\
310firstkey() -> key\n\
311It's possible to loop over every key in the database using this method\n\
312and the nextkey() method. The traversal is ordered by GDBM's internal\n\
313hash values, and won't be sorted by the key values. This method\n\
314returns the starting key.";
315
Roger E. Masseb15bef81996-12-17 19:55:33 +0000316static PyObject *
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000317dbm_firstkey(dp, args)
318 register dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000319PyObject *args;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000320{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000321 register PyObject *v;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000322 datum key;
323
Roger E. Masseb15bef81996-12-17 19:55:33 +0000324 if (!PyArg_NoArgs(args))
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000325 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000326 check_dbmobject_open(dp);
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000327 key = gdbm_firstkey(dp->di_dbm);
328 if (key.dptr) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000329 v = PyString_FromStringAndSize(key.dptr, key.dsize);
330 free(key.dptr);
331 return v;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000332 } else {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000333 Py_INCREF(Py_None);
334 return Py_None;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000335 }
336}
337
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000338static char dbm_nextkey__doc__[] = "\
339nextkey(key) -> next_key\n\
340Returns the key that follows key in the traversal.\n\
341The following code prints every key in the database db, without having\n\
342to create a list in memory that contains them all:\n\
343\n\
344 k = db.firstkey()\n\
345 while k != None:\n\
346 print k\n\
347 k = db.nextkey(k)";
348
Roger E. Masseb15bef81996-12-17 19:55:33 +0000349static PyObject *
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000350dbm_nextkey(dp, args)
351 register dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000352PyObject *args;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000353{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000354 register PyObject *v;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000355 datum key, nextkey;
356
Roger E. Masseb15bef81996-12-17 19:55:33 +0000357 if (!PyArg_Parse(args, "s#", &key.dptr, &key.dsize))
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000358 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000359 check_dbmobject_open(dp);
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000360 nextkey = gdbm_nextkey(dp->di_dbm, key);
361 if (nextkey.dptr) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000362 v = PyString_FromStringAndSize(nextkey.dptr, nextkey.dsize);
363 free(nextkey.dptr);
364 return v;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000365 } else {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000366 Py_INCREF(Py_None);
367 return Py_None;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000368 }
369}
370
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000371static char dbm_reorganize__doc__[] = "\
372reorganize() -> None\n\
373If you have carried out a lot of deletions and would like to shrink\n\
374the space used by the GDBM file, this routine will reorganize the\n\
375database. GDBM will not shorten the length of a database file except\n\
376by using this reorganization; otherwise, deleted file space will be\n\
377kept and reused as new (key,value) pairs are added.";
378
Roger E. Masseb15bef81996-12-17 19:55:33 +0000379static PyObject *
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000380dbm_reorganize(dp, args)
381 register dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000382PyObject *args;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000383{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000384 if (!PyArg_NoArgs(args))
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000385 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000386 check_dbmobject_open(dp);
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000387 errno = 0;
388 if (gdbm_reorganize(dp->di_dbm) < 0) {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000389 if (errno != 0)
390 PyErr_SetFromErrno(DbmError);
391 else
Guido van Rossum573788e1998-10-03 05:15:07 +0000392 PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno));
Roger E. Masseb15bef81996-12-17 19:55:33 +0000393 return NULL;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000394 }
Roger E. Masseb15bef81996-12-17 19:55:33 +0000395 Py_INCREF(Py_None);
396 return Py_None;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000397}
398
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000399static char dbm_sync__doc__[] = "\
400sync() -> None\n\
401When the database has been opened in fast mode, this method forces\n\
402any unwritten data to be written to the disk.";
403
Roger E. Massee5a9c8f1997-03-25 17:39:56 +0000404static PyObject *
405dbm_sync(dp, args)
406 register dbmobject *dp;
407 PyObject *args;
408{
409 if (!PyArg_NoArgs(args))
410 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000411 check_dbmobject_open(dp);
Roger E. Massee5a9c8f1997-03-25 17:39:56 +0000412 gdbm_sync(dp->di_dbm);
413 Py_INCREF(Py_None);
414 return Py_None;
415}
416
Roger E. Masseb15bef81996-12-17 19:55:33 +0000417static PyMethodDef dbm_methods[] = {
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000418 {"close", (PyCFunction)dbm_close, 0, dbm_close__doc__},
419 {"keys", (PyCFunction)dbm_keys, 0, dbm_keys__doc__},
420 {"has_key", (PyCFunction)dbm_has_key, 0, dbm_has_key__doc__},
421 {"firstkey", (PyCFunction)dbm_firstkey, 0, dbm_firstkey__doc__},
422 {"nextkey", (PyCFunction)dbm_nextkey, 0, dbm_nextkey__doc__},
423 {"reorganize", (PyCFunction)dbm_reorganize, 0, dbm_reorganize__doc__},
424 {"sync", (PyCFunction)dbm_sync, 0, dbm_sync__doc__},
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000425 {NULL, NULL} /* sentinel */
426};
427
Roger E. Masseb15bef81996-12-17 19:55:33 +0000428static PyObject *
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000429dbm_getattr(dp, name)
430 dbmobject *dp;
Roger E. Masseb15bef81996-12-17 19:55:33 +0000431char *name;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000432{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000433 return Py_FindMethod(dbm_methods, (PyObject *)dp, name);
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000434}
435
Roger E. Masseb15bef81996-12-17 19:55:33 +0000436static PyTypeObject Dbmtype = {
Guido van Rossumb6e2a991998-10-03 05:13:27 +0000437 PyObject_HEAD_INIT(0)
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000438 0,
Guido van Rossum807b7be1995-07-07 22:37:11 +0000439 "gdbm",
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000440 sizeof(dbmobject),
441 0,
Roger E. Masseb15bef81996-12-17 19:55:33 +0000442 (destructor)dbm_dealloc, /*tp_dealloc*/
443 0, /*tp_print*/
444 (getattrfunc)dbm_getattr, /*tp_getattr*/
445 0, /*tp_setattr*/
446 0, /*tp_compare*/
447 0, /*tp_repr*/
448 0, /*tp_as_number*/
449 0, /*tp_as_sequence*/
450 &dbm_as_mapping, /*tp_as_mapping*/
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000451 0, /*tp_hash*/
452 0, /*tp_call*/
453 0, /*tp_str*/
454 0, /*tp_getattro*/
455 0, /*tp_setattro*/
456 0, /*tp_as_buffer*/
457 0, /*tp_xxx4*/
458 gdbm_object__doc__, /*tp_doc*/
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000459};
460
461/* ----------------------------------------------------------------- */
462
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000463static char dbmopen__doc__[] = "\
464open(filename, [flag, [mode]]) -> dbm_object\n\
465Open a dbm database and return a dbm object. The filename argument is\n\
466the name of the database file.\n\
467\n\
468The optional flag argument can be 'r' (to open an existing database\n\
469for reading only -- default), 'w' (to open an existing database for\n\
470reading and writing), 'c' (which creates the database if it doesn't\n\
471exist), or 'n' (which always creates a new empty database).\n\
472\n\
473Appending f to the flag opens the database in fast mode; altered\n\
474data will not automatically be written to the disk after every\n\
475change. This results in faster writes to the database, but may\n\
476result in an inconsistent database if the program crashes while the\n\
477database is still open. Use the sync() method to force any\n\
478unwritten data to be written to the disk.\n\
479\n\
480The optional mode argument is the Unix mode of the file, used only\n\
481when the database has to be created. It defaults to octal 0666. ";
482
Roger E. Masseb15bef81996-12-17 19:55:33 +0000483static PyObject *
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000484dbmopen(self, args)
Roger E. Masseb15bef81996-12-17 19:55:33 +0000485 PyObject *self;
486PyObject *args;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000487{
Roger E. Masseb15bef81996-12-17 19:55:33 +0000488 char *name;
489 char *flags = "r ";
490 int iflags;
491 int mode = 0666;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000492
Roger E. Masseb15bef81996-12-17 19:55:33 +0000493 if ( !PyArg_ParseTuple(args, "s|si", &name, &flags, &mode) )
494 return NULL;
Guido van Rossume36e1fe1996-01-26 21:08:01 +0000495 switch (flags[0]) {
496 case 'r':
Roger E. Masseb15bef81996-12-17 19:55:33 +0000497 iflags = GDBM_READER;
498 break;
Guido van Rossume36e1fe1996-01-26 21:08:01 +0000499 case 'w':
Roger E. Masseb15bef81996-12-17 19:55:33 +0000500 iflags = GDBM_WRITER;
501 break;
Guido van Rossume36e1fe1996-01-26 21:08:01 +0000502 case 'c':
Roger E. Masseb15bef81996-12-17 19:55:33 +0000503 iflags = GDBM_WRCREAT;
504 break;
Guido van Rossume36e1fe1996-01-26 21:08:01 +0000505 case 'n':
Roger E. Masseb15bef81996-12-17 19:55:33 +0000506 iflags = GDBM_NEWDB;
507 break;
508 default:
509 PyErr_SetString(DbmError,
510 "Flags should be one of 'r', 'w', 'c' or 'n'");
511 return NULL;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000512 }
Guido van Rossume36e1fe1996-01-26 21:08:01 +0000513 if (flags[1] == 'f')
Roger E. Masseb15bef81996-12-17 19:55:33 +0000514 iflags |= GDBM_FAST;
515 return newdbmobject(name, iflags, mode);
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000516}
517
Roger E. Masseb15bef81996-12-17 19:55:33 +0000518static PyMethodDef dbmmodule_methods[] = {
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000519 { "open", (PyCFunction)dbmopen, 1, dbmopen__doc__},
Roger E. Masseb15bef81996-12-17 19:55:33 +0000520 { 0, 0 },
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000521};
522
Guido van Rossum3886bb61998-12-04 18:50:17 +0000523DL_EXPORT(void)
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000524initgdbm() {
Roger E. Masseb15bef81996-12-17 19:55:33 +0000525 PyObject *m, *d;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000526
Guido van Rossumb6e2a991998-10-03 05:13:27 +0000527 Dbmtype.ob_type = &PyType_Type;
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000528 m = Py_InitModule4("gdbm", dbmmodule_methods,
529 gdbmmodule__doc__, (PyObject *)NULL,
530 PYTHON_API_VERSION);
Roger E. Masseb15bef81996-12-17 19:55:33 +0000531 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000532 DbmError = PyErr_NewException("gdbm.error", NULL, NULL);
533 if (DbmError != NULL)
534 PyDict_SetItemString(d, "error", DbmError);
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000535}