blob: 23c2894ce10dc653c3142826661bf643ca9e11e4 [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 *
Guido van Rossum1100dca1995-08-30 23:43:03 +000057newdbhashobject(file, flags, mode,
58 bsize, ffactor, nelem, cachesize, hash, lorder)
Roger E. Massed9240d11997-01-16 22:05:33 +000059 char *file;
60 int flags;
61 int mode;
62 int bsize;
63 int ffactor;
64 int nelem;
65 int cachesize;
66 int hash; /* XXX ignored */
67 int lorder;
Guido van Rossum1100dca1995-08-30 23:43:03 +000068{
Roger E. Massed9240d11997-01-16 22:05:33 +000069 bsddbobject *dp;
70 HASHINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +000071
Guido van Rossumb18618d2000-05-03 23:44:39 +000072 if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
Roger E. Massed9240d11997-01-16 22:05:33 +000073 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +000074
Roger E. Massed9240d11997-01-16 22:05:33 +000075 info.bsize = bsize;
76 info.ffactor = ffactor;
77 info.nelem = nelem;
78 info.cachesize = cachesize;
79 info.hash = NULL; /* XXX should derive from hash argument */
80 info.lorder = lorder;
Guido van Rossum1100dca1995-08-30 23:43:03 +000081
Guido van Rossum6beb4791996-09-11 23:22:25 +000082#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +000083 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +000084#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +000085 Py_BEGIN_ALLOW_THREADS
86 dp->di_bsddb = dbopen(file, flags, mode, DB_HASH, &info);
87 Py_END_ALLOW_THREADS
88 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +000089 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +000090#ifdef WITH_THREAD
91 dp->di_lock = NULL;
92#endif
Roger E. Massed9240d11997-01-16 22:05:33 +000093 Py_DECREF(dp);
94 return NULL;
95 }
Guido van Rossum1100dca1995-08-30 23:43:03 +000096
Roger E. Massed9240d11997-01-16 22:05:33 +000097 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +000098#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +000099 dp->di_lock = PyThread_allocate_lock();
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000100 if (dp->di_lock == NULL) {
101 PyErr_SetString(BsddbError, "can't allocate lock");
102 Py_DECREF(dp);
103 return NULL;
104 }
105#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000106
Roger E. Massed9240d11997-01-16 22:05:33 +0000107 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000108}
109
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000110static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000111newdbbtobject(file, flags, mode,
Roger E. Massed9240d11997-01-16 22:05:33 +0000112 btflags, cachesize, maxkeypage, minkeypage, psize, lorder)
113 char *file;
114 int flags;
115 int mode;
116 int btflags;
117 int cachesize;
118 int maxkeypage;
119 int minkeypage;
120 int psize;
121 int lorder;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000122{
Roger E. Massed9240d11997-01-16 22:05:33 +0000123 bsddbobject *dp;
124 BTREEINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000125
Guido van Rossumb18618d2000-05-03 23:44:39 +0000126 if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
Roger E. Massed9240d11997-01-16 22:05:33 +0000127 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000128
Roger E. Massed9240d11997-01-16 22:05:33 +0000129 info.flags = btflags;
130 info.cachesize = cachesize;
131 info.maxkeypage = maxkeypage;
132 info.minkeypage = minkeypage;
133 info.psize = psize;
134 info.lorder = lorder;
135 info.compare = 0; /* Use default comparison functions, for now..*/
136 info.prefix = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000137
Guido van Rossum6beb4791996-09-11 23:22:25 +0000138#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +0000139 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +0000140#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000141 Py_BEGIN_ALLOW_THREADS
142 dp->di_bsddb = dbopen(file, flags, mode, DB_BTREE, &info);
143 Py_END_ALLOW_THREADS
144 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000145 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000146#ifdef WITH_THREAD
147 dp->di_lock = NULL;
148#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000149 Py_DECREF(dp);
150 return NULL;
151 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000152
Roger E. Massed9240d11997-01-16 22:05:33 +0000153 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000154#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000155 dp->di_lock = PyThread_allocate_lock();
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000156 if (dp->di_lock == NULL) {
157 PyErr_SetString(BsddbError, "can't allocate lock");
158 Py_DECREF(dp);
159 return NULL;
160 }
161#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000162
Roger E. Massed9240d11997-01-16 22:05:33 +0000163 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000164}
165
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000166static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000167newdbrnobject(file, flags, mode,
Roger E. Massed9240d11997-01-16 22:05:33 +0000168 rnflags, cachesize, psize, lorder, reclen, bval, bfname)
169 char *file;
170 int flags;
171 int mode;
172 int rnflags;
173 int cachesize;
174 int psize;
175 int lorder;
176 size_t reclen;
177 u_char bval;
178 char *bfname;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000179{
Roger E. Massed9240d11997-01-16 22:05:33 +0000180 bsddbobject *dp;
181 RECNOINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000182
Guido van Rossumb18618d2000-05-03 23:44:39 +0000183 if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
Roger E. Massed9240d11997-01-16 22:05:33 +0000184 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000185
Roger E. Massed9240d11997-01-16 22:05:33 +0000186 info.flags = rnflags;
187 info.cachesize = cachesize;
188 info.psize = psize;
189 info.lorder = lorder;
190 info.reclen = reclen;
191 info.bval = bval;
192 info.bfname = bfname;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000193
Guido van Rossum6beb4791996-09-11 23:22:25 +0000194#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +0000195 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +0000196#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000197 Py_BEGIN_ALLOW_THREADS
198 dp->di_bsddb = dbopen(file, flags, mode, DB_RECNO, &info);
199 Py_END_ALLOW_THREADS
200 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000201 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000202#ifdef WITH_THREAD
203 dp->di_lock = NULL;
204#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000205 Py_DECREF(dp);
206 return NULL;
207 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000208
Roger E. Massed9240d11997-01-16 22:05:33 +0000209 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000210#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000211 dp->di_lock = PyThread_allocate_lock();
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000212 if (dp->di_lock == NULL) {
213 PyErr_SetString(BsddbError, "can't allocate lock");
214 Py_DECREF(dp);
215 return NULL;
216 }
217#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000218
Roger E. Massed9240d11997-01-16 22:05:33 +0000219 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000220}
221
Guido van Rossum1100dca1995-08-30 23:43:03 +0000222static void
223bsddb_dealloc(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000224 bsddbobject *dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000225{
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000226#ifdef WITH_THREAD
227 if (dp->di_lock) {
Guido van Rossum65d5b571998-12-21 19:32:43 +0000228 PyThread_acquire_lock(dp->di_lock, 0);
229 PyThread_release_lock(dp->di_lock);
230 PyThread_free_lock(dp->di_lock);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000231 dp->di_lock = NULL;
232 }
233#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000234 if (dp->di_bsddb != NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000235 int status;
236 Py_BEGIN_ALLOW_THREADS
237 status = (dp->di_bsddb->close)(dp->di_bsddb);
238 Py_END_ALLOW_THREADS
239 if (status != 0)
Roger E. Massed9240d11997-01-16 22:05:33 +0000240 fprintf(stderr,
241 "Python bsddb: close errno %d in dealloc\n",
242 errno);
243 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000244 PyObject_Del(dp);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000245}
246
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000247#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000248#define BSDDB_BGN_SAVE(_dp) Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(_dp->di_lock,1);
249#define BSDDB_END_SAVE(_dp) PyThread_release_lock(_dp->di_lock); Py_END_ALLOW_THREADS
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000250#else
251#define BSDDB_BGN_SAVE(_dp) Py_BEGIN_ALLOW_THREADS
252#define BSDDB_END_SAVE(_dp) Py_END_ALLOW_THREADS
253#endif
254
Guido van Rossum1100dca1995-08-30 23:43:03 +0000255static int
256bsddb_length(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000257 bsddbobject *dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000258{
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000259 if (dp->di_bsddb == NULL) {
260 PyErr_SetString(BsddbError, "BSDDB object has already been closed");
261 return -1;
262 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000263 if (dp->di_size < 0) {
264 DBT krec, drec;
265 int status;
266 int size = 0;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000267 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000268 for (status = (dp->di_bsddb->seq)(dp->di_bsddb,
269 &krec, &drec,R_FIRST);
270 status == 0;
271 status = (dp->di_bsddb->seq)(dp->di_bsddb,
272 &krec, &drec, R_NEXT))
273 size++;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000274 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000275 if (status < 0) {
276 PyErr_SetFromErrno(BsddbError);
277 return -1;
278 }
279 dp->di_size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000280 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000281 return dp->di_size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000282}
283
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000284static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000285bsddb_subscript(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000286 bsddbobject *dp;
287 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000288{
Roger E. Massed9240d11997-01-16 22:05:33 +0000289 int status;
290 DBT krec, drec;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000291 char *data,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000292 int size;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000293 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000294
Roger E. Massed9240d11997-01-16 22:05:33 +0000295 if (!PyArg_Parse(key, "s#", &data, &size))
296 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000297 check_bsddbobject_open(dp);
298
Roger E. Massed9240d11997-01-16 22:05:33 +0000299 krec.data = data;
300 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000301
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000302 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000303 status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000304 if (status == 0) {
305 if (drec.size > sizeof(buf)) data = malloc(drec.size);
306 else data = buf;
307 memcpy(data,drec.data,drec.size);
308 }
309 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000310 if (status != 0) {
311 if (status < 0)
312 PyErr_SetFromErrno(BsddbError);
313 else
314 PyErr_SetObject(PyExc_KeyError, key);
315 return NULL;
316 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000317
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000318 result = PyString_FromStringAndSize(data, (int)drec.size);
319 if (data != buf) free(data);
320 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000321}
322
323static int
324bsddb_ass_sub(dp, key, value)
Roger E. Massed9240d11997-01-16 22:05:33 +0000325 bsddbobject *dp;
326 PyObject *key, *value;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000327{
Roger E. Massed9240d11997-01-16 22:05:33 +0000328 int status;
329 DBT krec, drec;
330 char *data;
331 int size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000332
Roger E. Massed9240d11997-01-16 22:05:33 +0000333 if (!PyArg_Parse(key, "s#", &data, &size)) {
334 PyErr_SetString(PyExc_TypeError,
335 "bsddb key type must be string");
336 return -1;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000337 }
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000338 if (dp->di_bsddb == NULL) {
339 PyErr_SetString(BsddbError, "BSDDB object has already been closed");
340 return -1;
341 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000342 krec.data = data;
343 krec.size = size;
344 dp->di_size = -1;
345 if (value == NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000346 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000347 status = (dp->di_bsddb->del)(dp->di_bsddb, &krec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000348 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000349 }
350 else {
351 if (!PyArg_Parse(value, "s#", &data, &size)) {
352 PyErr_SetString(PyExc_TypeError,
353 "bsddb value type must be string");
354 return -1;
355 }
356 drec.data = data;
357 drec.size = size;
358#if 0
359 /* For RECNO, put fails with 'No space left on device'
360 after a few short records are added?? Looks fine
361 to this point... linked with 1.85 on Solaris Intel
362 Roger E. Masse 1/16/97
363 */
364 printf("before put data: '%s', size: %d\n",
365 drec.data, drec.size);
366 printf("before put key= '%s', size= %d\n",
367 krec.data, krec.size);
368#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000369 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000370 status = (dp->di_bsddb->put)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000371 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000372 }
373 if (status != 0) {
374 if (status < 0)
375 PyErr_SetFromErrno(BsddbError);
376 else
377 PyErr_SetObject(PyExc_KeyError, key);
378 return -1;
379 }
380 return 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000381}
382
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000383static PyMappingMethods bsddb_as_mapping = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000384 (inquiry)bsddb_length, /*mp_length*/
385 (binaryfunc)bsddb_subscript, /*mp_subscript*/
386 (objobjargproc)bsddb_ass_sub, /*mp_ass_subscript*/
Guido van Rossum1100dca1995-08-30 23:43:03 +0000387};
388
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000389static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000390bsddb_close(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000391 bsddbobject *dp;
392 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000393{
Roger E. Massed9240d11997-01-16 22:05:33 +0000394 if (!PyArg_NoArgs(args))
395 return NULL;
396 if (dp->di_bsddb != NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000397 int status;
398 BSDDB_BGN_SAVE(dp)
399 status = (dp->di_bsddb->close)(dp->di_bsddb);
400 BSDDB_END_SAVE(dp)
401 if (status != 0) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000402 dp->di_bsddb = NULL;
403 PyErr_SetFromErrno(BsddbError);
404 return NULL;
405 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000406 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000407 dp->di_bsddb = NULL;
408 Py_INCREF(Py_None);
409 return Py_None;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000410}
411
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000412static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000413bsddb_keys(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000414 bsddbobject *dp;
415 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000416{
Roger E. Massed9240d11997-01-16 22:05:33 +0000417 PyObject *list, *item;
418 DBT krec, drec;
Guido van Rossum730806d1998-04-10 22:27:42 +0000419 char *data=NULL,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000420 int status;
421 int err;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000422
Roger E. Massed9240d11997-01-16 22:05:33 +0000423 if (!PyArg_NoArgs(args))
424 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000425 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000426 list = PyList_New(0);
427 if (list == NULL)
428 return NULL;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000429 BSDDB_BGN_SAVE(dp)
430 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_FIRST);
431 if (status == 0) {
432 if (krec.size > sizeof(buf)) data = malloc(krec.size);
433 else data = buf;
434 memcpy(data,krec.data,krec.size);
435 }
436 BSDDB_END_SAVE(dp)
437 while (status == 0) {
438 item = PyString_FromStringAndSize(data, (int)krec.size);
439 if (data != buf) free(data);
Roger E. Massed9240d11997-01-16 22:05:33 +0000440 if (item == NULL) {
441 Py_DECREF(list);
442 return NULL;
443 }
444 err = PyList_Append(list, item);
445 Py_DECREF(item);
446 if (err != 0) {
447 Py_DECREF(list);
448 return NULL;
449 }
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000450 BSDDB_BGN_SAVE(dp)
451 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_NEXT);
452 if (status == 0) {
453 if (krec.size > sizeof(buf)) data = malloc(krec.size);
454 else data = buf;
455 memcpy(data,krec.data,krec.size);
456 }
457 BSDDB_END_SAVE(dp)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000458 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000459 if (status < 0) {
460 PyErr_SetFromErrno(BsddbError);
461 Py_DECREF(list);
462 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000463 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000464 if (dp->di_size < 0)
465 dp->di_size = PyList_Size(list); /* We just did the work */
466 return list;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000467}
468
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000469static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000470bsddb_has_key(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000471 bsddbobject *dp;
472 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000473{
Roger E. Massed9240d11997-01-16 22:05:33 +0000474 DBT krec, drec;
475 int status;
476 char *data;
477 int size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000478
Roger E. Massed9240d11997-01-16 22:05:33 +0000479 if (!PyArg_Parse(args, "s#", &data, &size))
480 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000481 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000482 krec.data = data;
483 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000484
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000485 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000486 status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000487 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000488 if (status < 0) {
489 PyErr_SetFromErrno(BsddbError);
490 return NULL;
491 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000492
Roger E. Massed9240d11997-01-16 22:05:33 +0000493 return PyInt_FromLong(status == 0);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000494}
495
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000496static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000497bsddb_set_location(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000498 bsddbobject *dp;
499 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000500{
Roger E. Massed9240d11997-01-16 22:05:33 +0000501 int status;
502 DBT krec, drec;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000503 char *data,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000504 int size;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000505 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000506
Roger E. Massed9240d11997-01-16 22:05:33 +0000507 if (!PyArg_Parse(key, "s#", &data, &size))
508 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000509 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000510 krec.data = data;
511 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000512
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000513 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000514 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_CURSOR);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000515 if (status == 0) {
516 if (drec.size > sizeof(buf)) data = malloc(drec.size);
517 else data = buf;
518 memcpy(data,drec.data,drec.size);
519 }
520 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000521 if (status != 0) {
522 if (status < 0)
523 PyErr_SetFromErrno(BsddbError);
524 else
525 PyErr_SetObject(PyExc_KeyError, key);
526 return NULL;
527 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000528
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000529 result = Py_BuildValue("s#s#", krec.data, krec.size, data, drec.size);
530 if (data != buf) free(data);
531 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000532}
533
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000534static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000535bsddb_seq(dp, args, sequence_request)
Roger E. Massed9240d11997-01-16 22:05:33 +0000536 bsddbobject *dp;
537 PyObject *args;
538 int sequence_request;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000539{
Roger E. Massed9240d11997-01-16 22:05:33 +0000540 int status;
541 DBT krec, drec;
Guido van Rossum730806d1998-04-10 22:27:42 +0000542 char *kdata=NULL,kbuf[4096];
543 char *ddata=NULL,dbuf[4096];
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000544 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000545
Roger E. Massed9240d11997-01-16 22:05:33 +0000546 if (!PyArg_NoArgs(args))
547 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000548
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000549 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000550 krec.data = 0;
551 krec.size = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000552
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000553 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000554 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec,
555 &drec, sequence_request);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000556 if (status == 0) {
557 if (krec.size > sizeof(kbuf)) kdata = malloc(krec.size);
558 else kdata = kbuf;
559 memcpy(kdata,krec.data,krec.size);
560 if (drec.size > sizeof(dbuf)) ddata = malloc(drec.size);
561 else ddata = dbuf;
562 memcpy(ddata,drec.data,drec.size);
563 }
564 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000565 if (status != 0) {
566 if (status < 0)
567 PyErr_SetFromErrno(BsddbError);
568 else
569 PyErr_SetObject(PyExc_KeyError, args);
570 return NULL;
571 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000572
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000573 result = Py_BuildValue("s#s#", kdata, krec.size, ddata, drec.size);
574 if (kdata != kbuf) free(kdata);
575 if (ddata != dbuf) free(ddata);
576 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000577}
578
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000579static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000580bsddb_next(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000581 bsddbobject *dp;
582 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000583{
Roger E. Massed9240d11997-01-16 22:05:33 +0000584 return bsddb_seq(dp, key, R_NEXT);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000585}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000586static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000587bsddb_previous(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000588 bsddbobject *dp;
589 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000590{
Roger E. Massed9240d11997-01-16 22:05:33 +0000591 return bsddb_seq(dp, key, R_PREV);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000592}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000593static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000594bsddb_first(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000595 bsddbobject *dp;
596 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000597{
Roger E. Massed9240d11997-01-16 22:05:33 +0000598 return bsddb_seq(dp, key, R_FIRST);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000599}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000600static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000601bsddb_last(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000602 bsddbobject *dp;
603 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000604{
Roger E. Massed9240d11997-01-16 22:05:33 +0000605 return bsddb_seq(dp, key, R_LAST);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000606}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000607static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000608bsddb_sync(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000609 bsddbobject *dp;
610 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000611{
Roger E. Massed9240d11997-01-16 22:05:33 +0000612 int status;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000613
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000614 if (!PyArg_NoArgs(args))
615 return NULL;
616 check_bsddbobject_open(dp);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000617 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000618 status = (dp->di_bsddb->sync)(dp->di_bsddb, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000619 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000620 if (status != 0) {
621 PyErr_SetFromErrno(BsddbError);
622 return NULL;
623 }
624 return PyInt_FromLong(status = 0);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000625}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000626static PyMethodDef bsddb_methods[] = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000627 {"close", (PyCFunction)bsddb_close},
628 {"keys", (PyCFunction)bsddb_keys},
629 {"has_key", (PyCFunction)bsddb_has_key},
630 {"set_location", (PyCFunction)bsddb_set_location},
631 {"next", (PyCFunction)bsddb_next},
632 {"previous", (PyCFunction)bsddb_previous},
633 {"first", (PyCFunction)bsddb_first},
634 {"last", (PyCFunction)bsddb_last},
635 {"sync", (PyCFunction)bsddb_sync},
636 {NULL, NULL} /* sentinel */
Guido van Rossum1100dca1995-08-30 23:43:03 +0000637};
638
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000639static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000640bsddb_getattr(dp, name)
Roger E. Massed9240d11997-01-16 22:05:33 +0000641 PyObject *dp;
642 char *name;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000643{
Roger E. Massed9240d11997-01-16 22:05:33 +0000644 return Py_FindMethod(bsddb_methods, dp, name);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000645}
646
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000647static PyTypeObject Bsddbtype = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000648 PyObject_HEAD_INIT(NULL)
649 0,
650 "bsddb",
651 sizeof(bsddbobject),
652 0,
653 (destructor)bsddb_dealloc, /*tp_dealloc*/
654 0, /*tp_print*/
655 (getattrfunc)bsddb_getattr, /*tp_getattr*/
656 0, /*tp_setattr*/
657 0, /*tp_compare*/
658 0, /*tp_repr*/
659 0, /*tp_as_number*/
660 0, /*tp_as_sequence*/
661 &bsddb_as_mapping, /*tp_as_mapping*/
Guido van Rossum1100dca1995-08-30 23:43:03 +0000662};
663
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000664static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000665bsdhashopen(self, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000666 PyObject *self;
667 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000668{
Roger E. Massed9240d11997-01-16 22:05:33 +0000669 char *file;
670 char *flag = NULL;
671 int flags = O_RDONLY;
672 int mode = 0666;
673 int bsize = 0;
674 int ffactor = 0;
675 int nelem = 0;
676 int cachesize = 0;
677 int hash = 0; /* XXX currently ignored */
678 int lorder = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000679
Guido van Rossum43713e52000-02-29 13:59:29 +0000680 if (!PyArg_ParseTuple(args, "s|siiiiiii:hashopen",
Roger E. Massed9240d11997-01-16 22:05:33 +0000681 &file, &flag, &mode,
682 &bsize, &ffactor, &nelem, &cachesize,
683 &hash, &lorder))
684 return NULL;
685 if (flag != NULL) {
686 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
687 if (flag[0] == 'r')
688 flags = O_RDONLY;
689 else if (flag[0] == 'w')
690 flags = O_RDWR;
691 else if (flag[0] == 'c')
692 flags = O_RDWR|O_CREAT;
693 else if (flag[0] == 'n')
694 flags = O_RDWR|O_CREAT|O_TRUNC;
695 else {
696 PyErr_SetString(BsddbError,
697 "Flag should begin with 'r', 'w', 'c' or 'n'");
698 return NULL;
699 }
700 if (flag[1] == 'l') {
Guido van Rossum1100dca1995-08-30 23:43:03 +0000701#if defined(O_EXLOCK) && defined(O_SHLOCK)
Roger E. Massed9240d11997-01-16 22:05:33 +0000702 if (flag[0] == 'r')
703 flags |= O_SHLOCK;
704 else
705 flags |= O_EXLOCK;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000706#else
Roger E. Massed9240d11997-01-16 22:05:33 +0000707 PyErr_SetString(BsddbError,
708 "locking not supported on this platform");
709 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000710#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000711 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000712 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000713 return newdbhashobject(file, flags, mode,
714 bsize, ffactor, nelem, cachesize, hash, lorder);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000715}
716
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000717static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000718bsdbtopen(self, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000719 PyObject *self;
720 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000721{
Roger E. Massed9240d11997-01-16 22:05:33 +0000722 char *file;
723 char *flag = NULL;
724 int flags = O_RDONLY;
725 int mode = 0666;
726 int cachesize = 0;
727 int maxkeypage = 0;
728 int minkeypage = 0;
729 int btflags = 0;
730 unsigned int psize = 0;
731 int lorder = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000732
Guido van Rossum43713e52000-02-29 13:59:29 +0000733 if (!PyArg_ParseTuple(args, "s|siiiiiii:btopen",
Roger E. Massed9240d11997-01-16 22:05:33 +0000734 &file, &flag, &mode,
735 &btflags, &cachesize, &maxkeypage, &minkeypage,
736 &psize, &lorder))
737 return NULL;
738 if (flag != NULL) {
739 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
740 if (flag[0] == 'r')
741 flags = O_RDONLY;
742 else if (flag[0] == 'w')
743 flags = O_RDWR;
744 else if (flag[0] == 'c')
745 flags = O_RDWR|O_CREAT;
746 else if (flag[0] == 'n')
747 flags = O_RDWR|O_CREAT|O_TRUNC;
748 else {
749 PyErr_SetString(BsddbError,
750 "Flag should begin with 'r', 'w', 'c' or 'n'");
751 return NULL;
752 }
753 if (flag[1] == 'l') {
Guido van Rossum1100dca1995-08-30 23:43:03 +0000754#if defined(O_EXLOCK) && defined(O_SHLOCK)
Roger E. Massed9240d11997-01-16 22:05:33 +0000755 if (flag[0] == 'r')
756 flags |= O_SHLOCK;
757 else
758 flags |= O_EXLOCK;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000759#else
Roger E. Massed9240d11997-01-16 22:05:33 +0000760 PyErr_SetString(BsddbError,
761 "locking not supported on this platform");
762 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000763#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000764 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000765 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000766 return newdbbtobject(file, flags, mode,
767 btflags, cachesize, maxkeypage, minkeypage,
768 psize, lorder);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000769}
Guido van Rossumdd96ca71996-05-23 22:57:54 +0000770
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000771static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000772bsdrnopen(self, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000773 PyObject *self;
774 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000775{
Roger E. Massed9240d11997-01-16 22:05:33 +0000776 char *file;
777 char *flag = NULL;
778 int flags = O_RDONLY;
779 int mode = 0666;
780 int cachesize = 0;
781 int rnflags = 0;
782 unsigned int psize = 0;
783 int lorder = 0;
784 size_t reclen = 0;
785 char *bval = "";
786 char *bfname = NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000787
Guido van Rossum43713e52000-02-29 13:59:29 +0000788 if (!PyArg_ParseTuple(args, "s|siiiiiiss:rnopen",
Roger E. Massed9240d11997-01-16 22:05:33 +0000789 &file, &flag, &mode,
790 &rnflags, &cachesize, &psize, &lorder,
791 &reclen, &bval, &bfname))
792 return NULL;
793
794# if 0
795 printf("file: %s\n", file);
796 printf("flag: %s\n", flag);
797 printf("mode: %d\n", mode);
798 printf("rnflags: 0x%x\n", rnflags);
799 printf("cachesize: %d\n", cachesize);
800 printf("psize: %d\n", psize);
801 printf("lorder: %d\n", 0);
802 printf("reclen: %d\n", reclen);
803 printf("bval: %c\n", bval[0]);
804 printf("bfname %s\n", bfname);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000805#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000806
807 if (flag != NULL) {
808 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
809 if (flag[0] == 'r')
810 flags = O_RDONLY;
811 else if (flag[0] == 'w')
812 flags = O_RDWR;
813 else if (flag[0] == 'c')
814 flags = O_RDWR|O_CREAT;
815 else if (flag[0] == 'n')
816 flags = O_RDWR|O_CREAT|O_TRUNC;
817 else {
818 PyErr_SetString(BsddbError,
819 "Flag should begin with 'r', 'w', 'c' or 'n'");
820 return NULL;
821 }
822 if (flag[1] == 'l') {
823#if defined(O_EXLOCK) && defined(O_SHLOCK)
824 if (flag[0] == 'r')
825 flags |= O_SHLOCK;
826 else
827 flags |= O_EXLOCK;
828#else
829 PyErr_SetString(BsddbError,
830 "locking not supported on this platform");
831 return NULL;
832#endif
833 }
834 else if (flag[1] != '\0') {
835 PyErr_SetString(BsddbError,
836 "Flag char 2 should be 'l' or absent");
837 return NULL;
838 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000839 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000840 return newdbrnobject(file, flags, mode, rnflags, cachesize,
841 psize, lorder, reclen, bval[0], bfname);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000842}
843
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000844static PyMethodDef bsddbmodule_methods[] = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000845 {"hashopen", (PyCFunction)bsdhashopen, 1},
846 {"btopen", (PyCFunction)bsdbtopen, 1},
847 {"rnopen", (PyCFunction)bsdrnopen, 1},
848 {0, 0},
Guido van Rossum1100dca1995-08-30 23:43:03 +0000849};
850
Guido van Rossum3886bb61998-12-04 18:50:17 +0000851DL_EXPORT(void)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000852initbsddb() {
Roger E. Massed9240d11997-01-16 22:05:33 +0000853 PyObject *m, *d;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000854
Roger E. Massed9240d11997-01-16 22:05:33 +0000855 Bsddbtype.ob_type = &PyType_Type;
856 m = Py_InitModule("bsddb", bsddbmodule_methods);
857 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000858 BsddbError = PyErr_NewException("bsddb.error", NULL, NULL);
859 if (BsddbError != NULL)
860 PyDict_SetItemString(d, "error", BsddbError);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000861}