blob: a956ada61a9b4f30ef695da37d564d2d599beac7 [file] [log] [blame]
Guido van Rossum1100dca1995-08-30 23:43:03 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossum1100dca1995-08-30 23:43:03 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum1100dca1995-08-30 23:43:03 +00009******************************************************************/
10
11/* Berkeley DB interface.
12 Author: Michael McLay
13 Hacked: Guido van Rossum
14 Btree and Recno additions plus sequence methods: David Ely
15
16 XXX To do:
17 - provide interface to the B-tree and record libraries too
18 - provide a way to access the various hash functions
19 - support more open flags
Guido van Rossum675e9941999-09-20 13:28:18 +000020
21 The windows port of the Berkeley DB code is hard to find on the web:
22 www.nightmare.com/software.html
23*/
Guido van Rossum1100dca1995-08-30 23:43:03 +000024
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000025#include "Python.h"
Guido van Rossum4f199ea1998-04-09 20:56:35 +000026#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000027#include "pythread.h"
Guido van Rossum4f199ea1998-04-09 20:56:35 +000028#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +000029
30#include <sys/types.h>
31#include <sys/stat.h>
32#include <fcntl.h>
Fred Drake947121f2000-06-30 04:17:11 +000033/* If using Berkeley DB 2.0 or newer, change this include to <db_185.h>: */
Guido van Rossum1100dca1995-08-30 23:43:03 +000034#include <db.h>
35/* Please don't include internal header files of the Berkeley db package
36 (it messes up the info required in the Setup file) */
37
38typedef struct {
Roger E. Massed9240d11997-01-16 22:05:33 +000039 PyObject_HEAD
40 DB *di_bsddb;
41 int di_size; /* -1 means recompute */
Guido van Rossum4f199ea1998-04-09 20:56:35 +000042#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +000043 PyThread_type_lock di_lock;
Guido van Rossum4f199ea1998-04-09 20:56:35 +000044#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +000045} bsddbobject;
46
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000047staticforward PyTypeObject Bsddbtype;
Guido van Rossum1100dca1995-08-30 23:43:03 +000048
49#define is_bsddbobject(v) ((v)->ob_type == &Bsddbtype)
Guido van Rossum77eecfa1997-07-17 22:56:01 +000050#define check_bsddbobject_open(v) if ((v)->di_bsddb == NULL) \
51 { PyErr_SetString(BsddbError, "BSDDB object has already been closed"); \
52 return NULL; }
Guido van Rossum1100dca1995-08-30 23:43:03 +000053
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000054static PyObject *BsddbError;
Guido van Rossum1100dca1995-08-30 23:43:03 +000055
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000056static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +000057newdbhashobject(char *file, int flags, int mode,
58 int bsize, int ffactor, int nelem, int cachesize, int hash, int lorder)
Guido van Rossum1100dca1995-08-30 23:43:03 +000059{
Roger E. Massed9240d11997-01-16 22:05:33 +000060 bsddbobject *dp;
61 HASHINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +000062
Guido van Rossumb18618d2000-05-03 23:44:39 +000063 if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
Roger E. Massed9240d11997-01-16 22:05:33 +000064 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +000065
Roger E. Massed9240d11997-01-16 22:05:33 +000066 info.bsize = bsize;
67 info.ffactor = ffactor;
68 info.nelem = nelem;
69 info.cachesize = cachesize;
70 info.hash = NULL; /* XXX should derive from hash argument */
71 info.lorder = lorder;
Guido van Rossum1100dca1995-08-30 23:43:03 +000072
Guido van Rossum6beb4791996-09-11 23:22:25 +000073#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +000074 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +000075#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +000076 Py_BEGIN_ALLOW_THREADS
77 dp->di_bsddb = dbopen(file, flags, mode, DB_HASH, &info);
78 Py_END_ALLOW_THREADS
79 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +000080 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +000081#ifdef WITH_THREAD
82 dp->di_lock = NULL;
83#endif
Roger E. Massed9240d11997-01-16 22:05:33 +000084 Py_DECREF(dp);
85 return NULL;
86 }
Guido van Rossum1100dca1995-08-30 23:43:03 +000087
Roger E. Massed9240d11997-01-16 22:05:33 +000088 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +000089#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +000090 dp->di_lock = PyThread_allocate_lock();
Guido van Rossum4f199ea1998-04-09 20:56:35 +000091 if (dp->di_lock == NULL) {
92 PyErr_SetString(BsddbError, "can't allocate lock");
93 Py_DECREF(dp);
94 return NULL;
95 }
96#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +000097
Roger E. Massed9240d11997-01-16 22:05:33 +000098 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +000099}
100
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000101static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000102newdbbtobject(char *file, int flags, int mode,
103 int btflags, int cachesize, int maxkeypage, int minkeypage, int psize, int lorder)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000104{
Roger E. Massed9240d11997-01-16 22:05:33 +0000105 bsddbobject *dp;
106 BTREEINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000107
Guido van Rossumb18618d2000-05-03 23:44:39 +0000108 if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
Roger E. Massed9240d11997-01-16 22:05:33 +0000109 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000110
Roger E. Massed9240d11997-01-16 22:05:33 +0000111 info.flags = btflags;
112 info.cachesize = cachesize;
113 info.maxkeypage = maxkeypage;
114 info.minkeypage = minkeypage;
115 info.psize = psize;
116 info.lorder = lorder;
117 info.compare = 0; /* Use default comparison functions, for now..*/
118 info.prefix = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000119
Guido van Rossum6beb4791996-09-11 23:22:25 +0000120#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +0000121 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +0000122#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000123 Py_BEGIN_ALLOW_THREADS
124 dp->di_bsddb = dbopen(file, flags, mode, DB_BTREE, &info);
125 Py_END_ALLOW_THREADS
126 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000127 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000128#ifdef WITH_THREAD
129 dp->di_lock = NULL;
130#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000131 Py_DECREF(dp);
132 return NULL;
133 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000134
Roger E. Massed9240d11997-01-16 22:05:33 +0000135 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000136#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000137 dp->di_lock = PyThread_allocate_lock();
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000138 if (dp->di_lock == NULL) {
139 PyErr_SetString(BsddbError, "can't allocate lock");
140 Py_DECREF(dp);
141 return NULL;
142 }
143#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000144
Roger E. Massed9240d11997-01-16 22:05:33 +0000145 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000146}
147
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000148static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000149newdbrnobject(char *file, int flags, int mode,
150 int rnflags, int cachesize, int psize, int lorder, size_t reclen, u_char bval, char *bfname)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000151{
Roger E. Massed9240d11997-01-16 22:05:33 +0000152 bsddbobject *dp;
153 RECNOINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000154
Guido van Rossumb18618d2000-05-03 23:44:39 +0000155 if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
Roger E. Massed9240d11997-01-16 22:05:33 +0000156 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000157
Roger E. Massed9240d11997-01-16 22:05:33 +0000158 info.flags = rnflags;
159 info.cachesize = cachesize;
160 info.psize = psize;
161 info.lorder = lorder;
162 info.reclen = reclen;
163 info.bval = bval;
164 info.bfname = bfname;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000165
Guido van Rossum6beb4791996-09-11 23:22:25 +0000166#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +0000167 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +0000168#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000169 Py_BEGIN_ALLOW_THREADS
170 dp->di_bsddb = dbopen(file, flags, mode, DB_RECNO, &info);
171 Py_END_ALLOW_THREADS
172 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000173 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000174#ifdef WITH_THREAD
175 dp->di_lock = NULL;
176#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000177 Py_DECREF(dp);
178 return NULL;
179 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000180
Roger E. Massed9240d11997-01-16 22:05:33 +0000181 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000182#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000183 dp->di_lock = PyThread_allocate_lock();
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000184 if (dp->di_lock == NULL) {
185 PyErr_SetString(BsddbError, "can't allocate lock");
186 Py_DECREF(dp);
187 return NULL;
188 }
189#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000190
Roger E. Massed9240d11997-01-16 22:05:33 +0000191 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000192}
193
Guido van Rossum1100dca1995-08-30 23:43:03 +0000194static void
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000195bsddb_dealloc(bsddbobject *dp)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000196{
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000197#ifdef WITH_THREAD
198 if (dp->di_lock) {
Guido van Rossum65d5b571998-12-21 19:32:43 +0000199 PyThread_acquire_lock(dp->di_lock, 0);
200 PyThread_release_lock(dp->di_lock);
201 PyThread_free_lock(dp->di_lock);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000202 dp->di_lock = NULL;
203 }
204#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000205 if (dp->di_bsddb != NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000206 int status;
207 Py_BEGIN_ALLOW_THREADS
208 status = (dp->di_bsddb->close)(dp->di_bsddb);
209 Py_END_ALLOW_THREADS
210 if (status != 0)
Roger E. Massed9240d11997-01-16 22:05:33 +0000211 fprintf(stderr,
212 "Python bsddb: close errno %d in dealloc\n",
213 errno);
214 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000215 PyObject_Del(dp);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000216}
217
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000218#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000219#define BSDDB_BGN_SAVE(_dp) Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(_dp->di_lock,1);
220#define BSDDB_END_SAVE(_dp) PyThread_release_lock(_dp->di_lock); Py_END_ALLOW_THREADS
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000221#else
222#define BSDDB_BGN_SAVE(_dp) Py_BEGIN_ALLOW_THREADS
223#define BSDDB_END_SAVE(_dp) Py_END_ALLOW_THREADS
224#endif
225
Guido van Rossum1100dca1995-08-30 23:43:03 +0000226static int
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000227bsddb_length(bsddbobject *dp)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000228{
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000229 if (dp->di_bsddb == NULL) {
230 PyErr_SetString(BsddbError, "BSDDB object has already been closed");
231 return -1;
232 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000233 if (dp->di_size < 0) {
234 DBT krec, drec;
235 int status;
236 int size = 0;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000237 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000238 for (status = (dp->di_bsddb->seq)(dp->di_bsddb,
239 &krec, &drec,R_FIRST);
240 status == 0;
241 status = (dp->di_bsddb->seq)(dp->di_bsddb,
242 &krec, &drec, R_NEXT))
243 size++;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000244 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000245 if (status < 0) {
246 PyErr_SetFromErrno(BsddbError);
247 return -1;
248 }
249 dp->di_size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000250 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000251 return dp->di_size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000252}
253
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000254static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000255bsddb_subscript(bsddbobject *dp, PyObject *key)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000256{
Roger E. Massed9240d11997-01-16 22:05:33 +0000257 int status;
258 DBT krec, drec;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000259 char *data,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000260 int size;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000261 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000262
Roger E. Massed9240d11997-01-16 22:05:33 +0000263 if (!PyArg_Parse(key, "s#", &data, &size))
264 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000265 check_bsddbobject_open(dp);
266
Roger E. Massed9240d11997-01-16 22:05:33 +0000267 krec.data = data;
268 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000269
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000270 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000271 status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000272 if (status == 0) {
273 if (drec.size > sizeof(buf)) data = malloc(drec.size);
274 else data = buf;
275 memcpy(data,drec.data,drec.size);
276 }
277 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000278 if (status != 0) {
279 if (status < 0)
280 PyErr_SetFromErrno(BsddbError);
281 else
282 PyErr_SetObject(PyExc_KeyError, key);
283 return NULL;
284 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000285
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000286 result = PyString_FromStringAndSize(data, (int)drec.size);
287 if (data != buf) free(data);
288 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000289}
290
291static int
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000292bsddb_ass_sub(bsddbobject *dp, PyObject *key, PyObject *value)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000293{
Roger E. Massed9240d11997-01-16 22:05:33 +0000294 int status;
295 DBT krec, drec;
296 char *data;
297 int size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000298
Roger E. Massed9240d11997-01-16 22:05:33 +0000299 if (!PyArg_Parse(key, "s#", &data, &size)) {
300 PyErr_SetString(PyExc_TypeError,
301 "bsddb key type must be string");
302 return -1;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000303 }
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000304 if (dp->di_bsddb == NULL) {
305 PyErr_SetString(BsddbError, "BSDDB object has already been closed");
306 return -1;
307 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000308 krec.data = data;
309 krec.size = size;
310 dp->di_size = -1;
311 if (value == NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000312 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000313 status = (dp->di_bsddb->del)(dp->di_bsddb, &krec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000314 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000315 }
316 else {
317 if (!PyArg_Parse(value, "s#", &data, &size)) {
318 PyErr_SetString(PyExc_TypeError,
319 "bsddb value type must be string");
320 return -1;
321 }
322 drec.data = data;
323 drec.size = size;
324#if 0
325 /* For RECNO, put fails with 'No space left on device'
326 after a few short records are added?? Looks fine
327 to this point... linked with 1.85 on Solaris Intel
328 Roger E. Masse 1/16/97
329 */
330 printf("before put data: '%s', size: %d\n",
331 drec.data, drec.size);
332 printf("before put key= '%s', size= %d\n",
333 krec.data, krec.size);
334#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000335 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000336 status = (dp->di_bsddb->put)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000337 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000338 }
339 if (status != 0) {
340 if (status < 0)
341 PyErr_SetFromErrno(BsddbError);
342 else
343 PyErr_SetObject(PyExc_KeyError, key);
344 return -1;
345 }
346 return 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000347}
348
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000349static PyMappingMethods bsddb_as_mapping = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000350 (inquiry)bsddb_length, /*mp_length*/
351 (binaryfunc)bsddb_subscript, /*mp_subscript*/
352 (objobjargproc)bsddb_ass_sub, /*mp_ass_subscript*/
Guido van Rossum1100dca1995-08-30 23:43:03 +0000353};
354
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000355static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000356bsddb_close(bsddbobject *dp, PyObject *args)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000357{
Roger E. Massed9240d11997-01-16 22:05:33 +0000358 if (!PyArg_NoArgs(args))
359 return NULL;
360 if (dp->di_bsddb != NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000361 int status;
362 BSDDB_BGN_SAVE(dp)
363 status = (dp->di_bsddb->close)(dp->di_bsddb);
364 BSDDB_END_SAVE(dp)
365 if (status != 0) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000366 dp->di_bsddb = NULL;
367 PyErr_SetFromErrno(BsddbError);
368 return NULL;
369 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000370 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000371 dp->di_bsddb = NULL;
372 Py_INCREF(Py_None);
373 return Py_None;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000374}
375
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000376static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000377bsddb_keys(bsddbobject *dp, PyObject *args)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000378{
Roger E. Massed9240d11997-01-16 22:05:33 +0000379 PyObject *list, *item;
380 DBT krec, drec;
Guido van Rossum730806d1998-04-10 22:27:42 +0000381 char *data=NULL,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000382 int status;
383 int err;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000384
Roger E. Massed9240d11997-01-16 22:05:33 +0000385 if (!PyArg_NoArgs(args))
386 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000387 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000388 list = PyList_New(0);
389 if (list == NULL)
390 return NULL;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000391 BSDDB_BGN_SAVE(dp)
392 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_FIRST);
393 if (status == 0) {
394 if (krec.size > sizeof(buf)) data = malloc(krec.size);
395 else data = buf;
396 memcpy(data,krec.data,krec.size);
397 }
398 BSDDB_END_SAVE(dp)
399 while (status == 0) {
400 item = PyString_FromStringAndSize(data, (int)krec.size);
401 if (data != buf) free(data);
Roger E. Massed9240d11997-01-16 22:05:33 +0000402 if (item == NULL) {
403 Py_DECREF(list);
404 return NULL;
405 }
406 err = PyList_Append(list, item);
407 Py_DECREF(item);
408 if (err != 0) {
409 Py_DECREF(list);
410 return NULL;
411 }
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000412 BSDDB_BGN_SAVE(dp)
413 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_NEXT);
414 if (status == 0) {
415 if (krec.size > sizeof(buf)) data = malloc(krec.size);
416 else data = buf;
417 memcpy(data,krec.data,krec.size);
418 }
419 BSDDB_END_SAVE(dp)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000420 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000421 if (status < 0) {
422 PyErr_SetFromErrno(BsddbError);
423 Py_DECREF(list);
424 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000425 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000426 if (dp->di_size < 0)
427 dp->di_size = PyList_Size(list); /* We just did the work */
428 return list;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000429}
430
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000431static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000432bsddb_has_key(bsddbobject *dp, PyObject *args)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000433{
Roger E. Massed9240d11997-01-16 22:05:33 +0000434 DBT krec, drec;
435 int status;
436 char *data;
437 int size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000438
Roger E. Massed9240d11997-01-16 22:05:33 +0000439 if (!PyArg_Parse(args, "s#", &data, &size))
440 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000441 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000442 krec.data = data;
443 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000444
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000445 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000446 status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000447 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000448 if (status < 0) {
449 PyErr_SetFromErrno(BsddbError);
450 return NULL;
451 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000452
Roger E. Massed9240d11997-01-16 22:05:33 +0000453 return PyInt_FromLong(status == 0);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000454}
455
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000456static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000457bsddb_set_location(bsddbobject *dp, PyObject *key)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000458{
Roger E. Massed9240d11997-01-16 22:05:33 +0000459 int status;
460 DBT krec, drec;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000461 char *data,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000462 int size;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000463 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000464
Roger E. Massed9240d11997-01-16 22:05:33 +0000465 if (!PyArg_Parse(key, "s#", &data, &size))
466 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000467 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000468 krec.data = data;
469 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000470
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000471 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000472 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_CURSOR);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000473 if (status == 0) {
474 if (drec.size > sizeof(buf)) data = malloc(drec.size);
475 else data = buf;
476 memcpy(data,drec.data,drec.size);
477 }
478 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000479 if (status != 0) {
480 if (status < 0)
481 PyErr_SetFromErrno(BsddbError);
482 else
483 PyErr_SetObject(PyExc_KeyError, key);
484 return NULL;
485 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000486
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000487 result = Py_BuildValue("s#s#", krec.data, krec.size, data, drec.size);
488 if (data != buf) free(data);
489 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000490}
491
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000492static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000493bsddb_seq(bsddbobject *dp, PyObject *args, int sequence_request)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000494{
Roger E. Massed9240d11997-01-16 22:05:33 +0000495 int status;
496 DBT krec, drec;
Guido van Rossum730806d1998-04-10 22:27:42 +0000497 char *kdata=NULL,kbuf[4096];
498 char *ddata=NULL,dbuf[4096];
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000499 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000500
Roger E. Massed9240d11997-01-16 22:05:33 +0000501 if (!PyArg_NoArgs(args))
502 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000503
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000504 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000505 krec.data = 0;
506 krec.size = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000507
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000508 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000509 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec,
510 &drec, sequence_request);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000511 if (status == 0) {
512 if (krec.size > sizeof(kbuf)) kdata = malloc(krec.size);
513 else kdata = kbuf;
514 memcpy(kdata,krec.data,krec.size);
515 if (drec.size > sizeof(dbuf)) ddata = malloc(drec.size);
516 else ddata = dbuf;
517 memcpy(ddata,drec.data,drec.size);
518 }
519 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000520 if (status != 0) {
521 if (status < 0)
522 PyErr_SetFromErrno(BsddbError);
523 else
524 PyErr_SetObject(PyExc_KeyError, args);
525 return NULL;
526 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000527
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000528 result = Py_BuildValue("s#s#", kdata, krec.size, ddata, drec.size);
529 if (kdata != kbuf) free(kdata);
530 if (ddata != dbuf) free(ddata);
531 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000532}
533
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000534static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000535bsddb_next(bsddbobject *dp, PyObject *key)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000536{
Roger E. Massed9240d11997-01-16 22:05:33 +0000537 return bsddb_seq(dp, key, R_NEXT);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000538}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000539static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000540bsddb_previous(bsddbobject *dp, PyObject *key)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000541{
Roger E. Massed9240d11997-01-16 22:05:33 +0000542 return bsddb_seq(dp, key, R_PREV);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000543}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000544static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000545bsddb_first(bsddbobject *dp, PyObject *key)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000546{
Roger E. Massed9240d11997-01-16 22:05:33 +0000547 return bsddb_seq(dp, key, R_FIRST);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000548}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000549static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000550bsddb_last(bsddbobject *dp, PyObject *key)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000551{
Roger E. Massed9240d11997-01-16 22:05:33 +0000552 return bsddb_seq(dp, key, R_LAST);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000553}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000554static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000555bsddb_sync(bsddbobject *dp, PyObject *args)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000556{
Roger E. Massed9240d11997-01-16 22:05:33 +0000557 int status;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000558
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000559 if (!PyArg_NoArgs(args))
560 return NULL;
561 check_bsddbobject_open(dp);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000562 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000563 status = (dp->di_bsddb->sync)(dp->di_bsddb, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000564 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000565 if (status != 0) {
566 PyErr_SetFromErrno(BsddbError);
567 return NULL;
568 }
569 return PyInt_FromLong(status = 0);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000570}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000571static PyMethodDef bsddb_methods[] = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000572 {"close", (PyCFunction)bsddb_close},
573 {"keys", (PyCFunction)bsddb_keys},
574 {"has_key", (PyCFunction)bsddb_has_key},
575 {"set_location", (PyCFunction)bsddb_set_location},
576 {"next", (PyCFunction)bsddb_next},
577 {"previous", (PyCFunction)bsddb_previous},
578 {"first", (PyCFunction)bsddb_first},
579 {"last", (PyCFunction)bsddb_last},
580 {"sync", (PyCFunction)bsddb_sync},
581 {NULL, NULL} /* sentinel */
Guido van Rossum1100dca1995-08-30 23:43:03 +0000582};
583
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000584static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000585bsddb_getattr(PyObject *dp, char *name)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000586{
Roger E. Massed9240d11997-01-16 22:05:33 +0000587 return Py_FindMethod(bsddb_methods, dp, name);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000588}
589
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000590static PyTypeObject Bsddbtype = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000591 PyObject_HEAD_INIT(NULL)
592 0,
593 "bsddb",
594 sizeof(bsddbobject),
595 0,
596 (destructor)bsddb_dealloc, /*tp_dealloc*/
597 0, /*tp_print*/
598 (getattrfunc)bsddb_getattr, /*tp_getattr*/
599 0, /*tp_setattr*/
600 0, /*tp_compare*/
601 0, /*tp_repr*/
602 0, /*tp_as_number*/
603 0, /*tp_as_sequence*/
604 &bsddb_as_mapping, /*tp_as_mapping*/
Guido van Rossum1100dca1995-08-30 23:43:03 +0000605};
606
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000607static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000608bsdhashopen(PyObject *self, PyObject *args)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000609{
Roger E. Massed9240d11997-01-16 22:05:33 +0000610 char *file;
611 char *flag = NULL;
612 int flags = O_RDONLY;
613 int mode = 0666;
614 int bsize = 0;
615 int ffactor = 0;
616 int nelem = 0;
617 int cachesize = 0;
618 int hash = 0; /* XXX currently ignored */
619 int lorder = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000620
Guido van Rossum43713e52000-02-29 13:59:29 +0000621 if (!PyArg_ParseTuple(args, "s|siiiiiii:hashopen",
Roger E. Massed9240d11997-01-16 22:05:33 +0000622 &file, &flag, &mode,
623 &bsize, &ffactor, &nelem, &cachesize,
624 &hash, &lorder))
625 return NULL;
626 if (flag != NULL) {
627 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
628 if (flag[0] == 'r')
629 flags = O_RDONLY;
630 else if (flag[0] == 'w')
631 flags = O_RDWR;
632 else if (flag[0] == 'c')
633 flags = O_RDWR|O_CREAT;
634 else if (flag[0] == 'n')
635 flags = O_RDWR|O_CREAT|O_TRUNC;
636 else {
637 PyErr_SetString(BsddbError,
638 "Flag should begin with 'r', 'w', 'c' or 'n'");
639 return NULL;
640 }
641 if (flag[1] == 'l') {
Guido van Rossum1100dca1995-08-30 23:43:03 +0000642#if defined(O_EXLOCK) && defined(O_SHLOCK)
Roger E. Massed9240d11997-01-16 22:05:33 +0000643 if (flag[0] == 'r')
644 flags |= O_SHLOCK;
645 else
646 flags |= O_EXLOCK;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000647#else
Roger E. Massed9240d11997-01-16 22:05:33 +0000648 PyErr_SetString(BsddbError,
649 "locking not supported on this platform");
650 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000651#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000652 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000653 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000654 return newdbhashobject(file, flags, mode,
655 bsize, ffactor, nelem, cachesize, hash, lorder);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000656}
657
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000658static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000659bsdbtopen(PyObject *self, PyObject *args)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000660{
Roger E. Massed9240d11997-01-16 22:05:33 +0000661 char *file;
662 char *flag = NULL;
663 int flags = O_RDONLY;
664 int mode = 0666;
665 int cachesize = 0;
666 int maxkeypage = 0;
667 int minkeypage = 0;
668 int btflags = 0;
669 unsigned int psize = 0;
670 int lorder = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000671
Guido van Rossum43713e52000-02-29 13:59:29 +0000672 if (!PyArg_ParseTuple(args, "s|siiiiiii:btopen",
Roger E. Massed9240d11997-01-16 22:05:33 +0000673 &file, &flag, &mode,
674 &btflags, &cachesize, &maxkeypage, &minkeypage,
675 &psize, &lorder))
676 return NULL;
677 if (flag != NULL) {
678 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
679 if (flag[0] == 'r')
680 flags = O_RDONLY;
681 else if (flag[0] == 'w')
682 flags = O_RDWR;
683 else if (flag[0] == 'c')
684 flags = O_RDWR|O_CREAT;
685 else if (flag[0] == 'n')
686 flags = O_RDWR|O_CREAT|O_TRUNC;
687 else {
688 PyErr_SetString(BsddbError,
689 "Flag should begin with 'r', 'w', 'c' or 'n'");
690 return NULL;
691 }
692 if (flag[1] == 'l') {
Guido van Rossum1100dca1995-08-30 23:43:03 +0000693#if defined(O_EXLOCK) && defined(O_SHLOCK)
Roger E. Massed9240d11997-01-16 22:05:33 +0000694 if (flag[0] == 'r')
695 flags |= O_SHLOCK;
696 else
697 flags |= O_EXLOCK;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000698#else
Roger E. Massed9240d11997-01-16 22:05:33 +0000699 PyErr_SetString(BsddbError,
700 "locking not supported on this platform");
701 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000702#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000703 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000704 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000705 return newdbbtobject(file, flags, mode,
706 btflags, cachesize, maxkeypage, minkeypage,
707 psize, lorder);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000708}
Guido van Rossumdd96ca71996-05-23 22:57:54 +0000709
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000710static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000711bsdrnopen(PyObject *self, PyObject *args)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000712{
Roger E. Massed9240d11997-01-16 22:05:33 +0000713 char *file;
714 char *flag = NULL;
715 int flags = O_RDONLY;
716 int mode = 0666;
717 int cachesize = 0;
718 int rnflags = 0;
719 unsigned int psize = 0;
720 int lorder = 0;
721 size_t reclen = 0;
722 char *bval = "";
723 char *bfname = NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000724
Guido van Rossum43713e52000-02-29 13:59:29 +0000725 if (!PyArg_ParseTuple(args, "s|siiiiiiss:rnopen",
Roger E. Massed9240d11997-01-16 22:05:33 +0000726 &file, &flag, &mode,
727 &rnflags, &cachesize, &psize, &lorder,
728 &reclen, &bval, &bfname))
729 return NULL;
730
731# if 0
732 printf("file: %s\n", file);
733 printf("flag: %s\n", flag);
734 printf("mode: %d\n", mode);
735 printf("rnflags: 0x%x\n", rnflags);
736 printf("cachesize: %d\n", cachesize);
737 printf("psize: %d\n", psize);
738 printf("lorder: %d\n", 0);
739 printf("reclen: %d\n", reclen);
740 printf("bval: %c\n", bval[0]);
741 printf("bfname %s\n", bfname);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000742#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000743
744 if (flag != NULL) {
745 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
746 if (flag[0] == 'r')
747 flags = O_RDONLY;
748 else if (flag[0] == 'w')
749 flags = O_RDWR;
750 else if (flag[0] == 'c')
751 flags = O_RDWR|O_CREAT;
752 else if (flag[0] == 'n')
753 flags = O_RDWR|O_CREAT|O_TRUNC;
754 else {
755 PyErr_SetString(BsddbError,
756 "Flag should begin with 'r', 'w', 'c' or 'n'");
757 return NULL;
758 }
759 if (flag[1] == 'l') {
760#if defined(O_EXLOCK) && defined(O_SHLOCK)
761 if (flag[0] == 'r')
762 flags |= O_SHLOCK;
763 else
764 flags |= O_EXLOCK;
765#else
766 PyErr_SetString(BsddbError,
767 "locking not supported on this platform");
768 return NULL;
769#endif
770 }
771 else if (flag[1] != '\0') {
772 PyErr_SetString(BsddbError,
773 "Flag char 2 should be 'l' or absent");
774 return NULL;
775 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000776 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000777 return newdbrnobject(file, flags, mode, rnflags, cachesize,
778 psize, lorder, reclen, bval[0], bfname);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000779}
780
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000781static PyMethodDef bsddbmodule_methods[] = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000782 {"hashopen", (PyCFunction)bsdhashopen, 1},
783 {"btopen", (PyCFunction)bsdbtopen, 1},
784 {"rnopen", (PyCFunction)bsdrnopen, 1},
785 {0, 0},
Guido van Rossum1100dca1995-08-30 23:43:03 +0000786};
787
Guido van Rossum3886bb61998-12-04 18:50:17 +0000788DL_EXPORT(void)
Thomas Wouters58d05102000-07-24 14:43:35 +0000789initbsddb(void) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000790 PyObject *m, *d;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000791
Roger E. Massed9240d11997-01-16 22:05:33 +0000792 Bsddbtype.ob_type = &PyType_Type;
793 m = Py_InitModule("bsddb", bsddbmodule_methods);
794 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000795 BsddbError = PyErr_NewException("bsddb.error", NULL, NULL);
796 if (BsddbError != NULL)
797 PyDict_SetItemString(d, "error", BsddbError);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000798}