blob: 36e7ca82187d423881c192fd438317d95d3c0120 [file] [log] [blame]
Guido van Rossum1100dca1995-08-30 23:43:03 +00001/***********************************************************
2Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5 All Rights Reserved
6
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007Copyright (c) 2000, BeOpen.com.
8Copyright (c) 1995-2000, Corporation for National Research Initiatives.
9Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
10All rights reserved.
Guido van Rossum1100dca1995-08-30 23:43:03 +000011
Guido van Rossumfd71b9e2000-06-30 23:50:40 +000012See the file "Misc/COPYRIGHT" for information on usage and
13redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum1100dca1995-08-30 23:43:03 +000014
15******************************************************************/
16
17/* Berkeley DB interface.
18 Author: Michael McLay
19 Hacked: Guido van Rossum
20 Btree and Recno additions plus sequence methods: David Ely
21
22 XXX To do:
23 - provide interface to the B-tree and record libraries too
24 - provide a way to access the various hash functions
25 - support more open flags
Guido van Rossum675e9941999-09-20 13:28:18 +000026
27 The windows port of the Berkeley DB code is hard to find on the web:
28 www.nightmare.com/software.html
29*/
Guido van Rossum1100dca1995-08-30 23:43:03 +000030
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000031#include "Python.h"
Guido van Rossum4f199ea1998-04-09 20:56:35 +000032#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000033#include "pythread.h"
Guido van Rossum4f199ea1998-04-09 20:56:35 +000034#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +000035
36#include <sys/types.h>
37#include <sys/stat.h>
38#include <fcntl.h>
Fred Drake947121f2000-06-30 04:17:11 +000039/* If using Berkeley DB 2.0 or newer, change this include to <db_185.h>: */
Guido van Rossum1100dca1995-08-30 23:43:03 +000040#include <db.h>
41/* Please don't include internal header files of the Berkeley db package
42 (it messes up the info required in the Setup file) */
43
44typedef struct {
Roger E. Massed9240d11997-01-16 22:05:33 +000045 PyObject_HEAD
46 DB *di_bsddb;
47 int di_size; /* -1 means recompute */
Guido van Rossum4f199ea1998-04-09 20:56:35 +000048#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +000049 PyThread_type_lock di_lock;
Guido van Rossum4f199ea1998-04-09 20:56:35 +000050#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +000051} bsddbobject;
52
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000053staticforward PyTypeObject Bsddbtype;
Guido van Rossum1100dca1995-08-30 23:43:03 +000054
55#define is_bsddbobject(v) ((v)->ob_type == &Bsddbtype)
Guido van Rossum77eecfa1997-07-17 22:56:01 +000056#define check_bsddbobject_open(v) if ((v)->di_bsddb == NULL) \
57 { PyErr_SetString(BsddbError, "BSDDB object has already been closed"); \
58 return NULL; }
Guido van Rossum1100dca1995-08-30 23:43:03 +000059
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000060static PyObject *BsddbError;
Guido van Rossum1100dca1995-08-30 23:43:03 +000061
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000062static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +000063newdbhashobject(file, flags, mode,
64 bsize, ffactor, nelem, cachesize, hash, lorder)
Roger E. Massed9240d11997-01-16 22:05:33 +000065 char *file;
66 int flags;
67 int mode;
68 int bsize;
69 int ffactor;
70 int nelem;
71 int cachesize;
72 int hash; /* XXX ignored */
73 int lorder;
Guido van Rossum1100dca1995-08-30 23:43:03 +000074{
Roger E. Massed9240d11997-01-16 22:05:33 +000075 bsddbobject *dp;
76 HASHINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +000077
Guido van Rossumb18618d2000-05-03 23:44:39 +000078 if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
Roger E. Massed9240d11997-01-16 22:05:33 +000079 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +000080
Roger E. Massed9240d11997-01-16 22:05:33 +000081 info.bsize = bsize;
82 info.ffactor = ffactor;
83 info.nelem = nelem;
84 info.cachesize = cachesize;
85 info.hash = NULL; /* XXX should derive from hash argument */
86 info.lorder = lorder;
Guido van Rossum1100dca1995-08-30 23:43:03 +000087
Guido van Rossum6beb4791996-09-11 23:22:25 +000088#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +000089 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +000090#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +000091 Py_BEGIN_ALLOW_THREADS
92 dp->di_bsddb = dbopen(file, flags, mode, DB_HASH, &info);
93 Py_END_ALLOW_THREADS
94 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +000095 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +000096#ifdef WITH_THREAD
97 dp->di_lock = NULL;
98#endif
Roger E. Massed9240d11997-01-16 22:05:33 +000099 Py_DECREF(dp);
100 return NULL;
101 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000102
Roger E. Massed9240d11997-01-16 22:05:33 +0000103 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000104#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000105 dp->di_lock = PyThread_allocate_lock();
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000106 if (dp->di_lock == NULL) {
107 PyErr_SetString(BsddbError, "can't allocate lock");
108 Py_DECREF(dp);
109 return NULL;
110 }
111#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000112
Roger E. Massed9240d11997-01-16 22:05:33 +0000113 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000114}
115
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000116static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000117newdbbtobject(file, flags, mode,
Roger E. Massed9240d11997-01-16 22:05:33 +0000118 btflags, cachesize, maxkeypage, minkeypage, psize, lorder)
119 char *file;
120 int flags;
121 int mode;
122 int btflags;
123 int cachesize;
124 int maxkeypage;
125 int minkeypage;
126 int psize;
127 int lorder;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000128{
Roger E. Massed9240d11997-01-16 22:05:33 +0000129 bsddbobject *dp;
130 BTREEINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000131
Guido van Rossumb18618d2000-05-03 23:44:39 +0000132 if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
Roger E. Massed9240d11997-01-16 22:05:33 +0000133 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000134
Roger E. Massed9240d11997-01-16 22:05:33 +0000135 info.flags = btflags;
136 info.cachesize = cachesize;
137 info.maxkeypage = maxkeypage;
138 info.minkeypage = minkeypage;
139 info.psize = psize;
140 info.lorder = lorder;
141 info.compare = 0; /* Use default comparison functions, for now..*/
142 info.prefix = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000143
Guido van Rossum6beb4791996-09-11 23:22:25 +0000144#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +0000145 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +0000146#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000147 Py_BEGIN_ALLOW_THREADS
148 dp->di_bsddb = dbopen(file, flags, mode, DB_BTREE, &info);
149 Py_END_ALLOW_THREADS
150 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000151 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000152#ifdef WITH_THREAD
153 dp->di_lock = NULL;
154#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000155 Py_DECREF(dp);
156 return NULL;
157 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000158
Roger E. Massed9240d11997-01-16 22:05:33 +0000159 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000160#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000161 dp->di_lock = PyThread_allocate_lock();
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000162 if (dp->di_lock == NULL) {
163 PyErr_SetString(BsddbError, "can't allocate lock");
164 Py_DECREF(dp);
165 return NULL;
166 }
167#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000168
Roger E. Massed9240d11997-01-16 22:05:33 +0000169 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000170}
171
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000172static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000173newdbrnobject(file, flags, mode,
Roger E. Massed9240d11997-01-16 22:05:33 +0000174 rnflags, cachesize, psize, lorder, reclen, bval, bfname)
175 char *file;
176 int flags;
177 int mode;
178 int rnflags;
179 int cachesize;
180 int psize;
181 int lorder;
182 size_t reclen;
183 u_char bval;
184 char *bfname;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000185{
Roger E. Massed9240d11997-01-16 22:05:33 +0000186 bsddbobject *dp;
187 RECNOINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000188
Guido van Rossumb18618d2000-05-03 23:44:39 +0000189 if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
Roger E. Massed9240d11997-01-16 22:05:33 +0000190 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000191
Roger E. Massed9240d11997-01-16 22:05:33 +0000192 info.flags = rnflags;
193 info.cachesize = cachesize;
194 info.psize = psize;
195 info.lorder = lorder;
196 info.reclen = reclen;
197 info.bval = bval;
198 info.bfname = bfname;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000199
Guido van Rossum6beb4791996-09-11 23:22:25 +0000200#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +0000201 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +0000202#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000203 Py_BEGIN_ALLOW_THREADS
204 dp->di_bsddb = dbopen(file, flags, mode, DB_RECNO, &info);
205 Py_END_ALLOW_THREADS
206 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000207 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000208#ifdef WITH_THREAD
209 dp->di_lock = NULL;
210#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000211 Py_DECREF(dp);
212 return NULL;
213 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000214
Roger E. Massed9240d11997-01-16 22:05:33 +0000215 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000216#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000217 dp->di_lock = PyThread_allocate_lock();
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000218 if (dp->di_lock == NULL) {
219 PyErr_SetString(BsddbError, "can't allocate lock");
220 Py_DECREF(dp);
221 return NULL;
222 }
223#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000224
Roger E. Massed9240d11997-01-16 22:05:33 +0000225 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000226}
227
Guido van Rossum1100dca1995-08-30 23:43:03 +0000228static void
229bsddb_dealloc(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000230 bsddbobject *dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000231{
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000232#ifdef WITH_THREAD
233 if (dp->di_lock) {
Guido van Rossum65d5b571998-12-21 19:32:43 +0000234 PyThread_acquire_lock(dp->di_lock, 0);
235 PyThread_release_lock(dp->di_lock);
236 PyThread_free_lock(dp->di_lock);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000237 dp->di_lock = NULL;
238 }
239#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000240 if (dp->di_bsddb != NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000241 int status;
242 Py_BEGIN_ALLOW_THREADS
243 status = (dp->di_bsddb->close)(dp->di_bsddb);
244 Py_END_ALLOW_THREADS
245 if (status != 0)
Roger E. Massed9240d11997-01-16 22:05:33 +0000246 fprintf(stderr,
247 "Python bsddb: close errno %d in dealloc\n",
248 errno);
249 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000250 PyObject_Del(dp);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000251}
252
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000253#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000254#define BSDDB_BGN_SAVE(_dp) Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(_dp->di_lock,1);
255#define BSDDB_END_SAVE(_dp) PyThread_release_lock(_dp->di_lock); Py_END_ALLOW_THREADS
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000256#else
257#define BSDDB_BGN_SAVE(_dp) Py_BEGIN_ALLOW_THREADS
258#define BSDDB_END_SAVE(_dp) Py_END_ALLOW_THREADS
259#endif
260
Guido van Rossum1100dca1995-08-30 23:43:03 +0000261static int
262bsddb_length(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000263 bsddbobject *dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000264{
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000265 if (dp->di_bsddb == NULL) {
266 PyErr_SetString(BsddbError, "BSDDB object has already been closed");
267 return -1;
268 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000269 if (dp->di_size < 0) {
270 DBT krec, drec;
271 int status;
272 int size = 0;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000273 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000274 for (status = (dp->di_bsddb->seq)(dp->di_bsddb,
275 &krec, &drec,R_FIRST);
276 status == 0;
277 status = (dp->di_bsddb->seq)(dp->di_bsddb,
278 &krec, &drec, R_NEXT))
279 size++;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000280 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000281 if (status < 0) {
282 PyErr_SetFromErrno(BsddbError);
283 return -1;
284 }
285 dp->di_size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000286 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000287 return dp->di_size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000288}
289
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000290static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000291bsddb_subscript(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000292 bsddbobject *dp;
293 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000294{
Roger E. Massed9240d11997-01-16 22:05:33 +0000295 int status;
296 DBT krec, drec;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000297 char *data,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000298 int size;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000299 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000300
Roger E. Massed9240d11997-01-16 22:05:33 +0000301 if (!PyArg_Parse(key, "s#", &data, &size))
302 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000303 check_bsddbobject_open(dp);
304
Roger E. Massed9240d11997-01-16 22:05:33 +0000305 krec.data = data;
306 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000307
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000308 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000309 status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000310 if (status == 0) {
311 if (drec.size > sizeof(buf)) data = malloc(drec.size);
312 else data = buf;
313 memcpy(data,drec.data,drec.size);
314 }
315 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000316 if (status != 0) {
317 if (status < 0)
318 PyErr_SetFromErrno(BsddbError);
319 else
320 PyErr_SetObject(PyExc_KeyError, key);
321 return NULL;
322 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000323
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000324 result = PyString_FromStringAndSize(data, (int)drec.size);
325 if (data != buf) free(data);
326 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000327}
328
329static int
330bsddb_ass_sub(dp, key, value)
Roger E. Massed9240d11997-01-16 22:05:33 +0000331 bsddbobject *dp;
332 PyObject *key, *value;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000333{
Roger E. Massed9240d11997-01-16 22:05:33 +0000334 int status;
335 DBT krec, drec;
336 char *data;
337 int size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000338
Roger E. Massed9240d11997-01-16 22:05:33 +0000339 if (!PyArg_Parse(key, "s#", &data, &size)) {
340 PyErr_SetString(PyExc_TypeError,
341 "bsddb key type must be string");
342 return -1;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000343 }
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000344 if (dp->di_bsddb == NULL) {
345 PyErr_SetString(BsddbError, "BSDDB object has already been closed");
346 return -1;
347 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000348 krec.data = data;
349 krec.size = size;
350 dp->di_size = -1;
351 if (value == NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000352 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000353 status = (dp->di_bsddb->del)(dp->di_bsddb, &krec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000354 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000355 }
356 else {
357 if (!PyArg_Parse(value, "s#", &data, &size)) {
358 PyErr_SetString(PyExc_TypeError,
359 "bsddb value type must be string");
360 return -1;
361 }
362 drec.data = data;
363 drec.size = size;
364#if 0
365 /* For RECNO, put fails with 'No space left on device'
366 after a few short records are added?? Looks fine
367 to this point... linked with 1.85 on Solaris Intel
368 Roger E. Masse 1/16/97
369 */
370 printf("before put data: '%s', size: %d\n",
371 drec.data, drec.size);
372 printf("before put key= '%s', size= %d\n",
373 krec.data, krec.size);
374#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000375 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000376 status = (dp->di_bsddb->put)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000377 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000378 }
379 if (status != 0) {
380 if (status < 0)
381 PyErr_SetFromErrno(BsddbError);
382 else
383 PyErr_SetObject(PyExc_KeyError, key);
384 return -1;
385 }
386 return 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000387}
388
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000389static PyMappingMethods bsddb_as_mapping = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000390 (inquiry)bsddb_length, /*mp_length*/
391 (binaryfunc)bsddb_subscript, /*mp_subscript*/
392 (objobjargproc)bsddb_ass_sub, /*mp_ass_subscript*/
Guido van Rossum1100dca1995-08-30 23:43:03 +0000393};
394
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000395static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000396bsddb_close(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000397 bsddbobject *dp;
398 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000399{
Roger E. Massed9240d11997-01-16 22:05:33 +0000400 if (!PyArg_NoArgs(args))
401 return NULL;
402 if (dp->di_bsddb != NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000403 int status;
404 BSDDB_BGN_SAVE(dp)
405 status = (dp->di_bsddb->close)(dp->di_bsddb);
406 BSDDB_END_SAVE(dp)
407 if (status != 0) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000408 dp->di_bsddb = NULL;
409 PyErr_SetFromErrno(BsddbError);
410 return NULL;
411 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000412 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000413 dp->di_bsddb = NULL;
414 Py_INCREF(Py_None);
415 return Py_None;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000416}
417
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000418static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000419bsddb_keys(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000420 bsddbobject *dp;
421 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000422{
Roger E. Massed9240d11997-01-16 22:05:33 +0000423 PyObject *list, *item;
424 DBT krec, drec;
Guido van Rossum730806d1998-04-10 22:27:42 +0000425 char *data=NULL,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000426 int status;
427 int err;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000428
Roger E. Massed9240d11997-01-16 22:05:33 +0000429 if (!PyArg_NoArgs(args))
430 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000431 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000432 list = PyList_New(0);
433 if (list == NULL)
434 return NULL;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000435 BSDDB_BGN_SAVE(dp)
436 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_FIRST);
437 if (status == 0) {
438 if (krec.size > sizeof(buf)) data = malloc(krec.size);
439 else data = buf;
440 memcpy(data,krec.data,krec.size);
441 }
442 BSDDB_END_SAVE(dp)
443 while (status == 0) {
444 item = PyString_FromStringAndSize(data, (int)krec.size);
445 if (data != buf) free(data);
Roger E. Massed9240d11997-01-16 22:05:33 +0000446 if (item == NULL) {
447 Py_DECREF(list);
448 return NULL;
449 }
450 err = PyList_Append(list, item);
451 Py_DECREF(item);
452 if (err != 0) {
453 Py_DECREF(list);
454 return NULL;
455 }
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000456 BSDDB_BGN_SAVE(dp)
457 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_NEXT);
458 if (status == 0) {
459 if (krec.size > sizeof(buf)) data = malloc(krec.size);
460 else data = buf;
461 memcpy(data,krec.data,krec.size);
462 }
463 BSDDB_END_SAVE(dp)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000464 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000465 if (status < 0) {
466 PyErr_SetFromErrno(BsddbError);
467 Py_DECREF(list);
468 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000469 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000470 if (dp->di_size < 0)
471 dp->di_size = PyList_Size(list); /* We just did the work */
472 return list;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000473}
474
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000475static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000476bsddb_has_key(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000477 bsddbobject *dp;
478 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000479{
Roger E. Massed9240d11997-01-16 22:05:33 +0000480 DBT krec, drec;
481 int status;
482 char *data;
483 int size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000484
Roger E. Massed9240d11997-01-16 22:05:33 +0000485 if (!PyArg_Parse(args, "s#", &data, &size))
486 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000487 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000488 krec.data = data;
489 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000490
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000491 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000492 status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000493 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000494 if (status < 0) {
495 PyErr_SetFromErrno(BsddbError);
496 return NULL;
497 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000498
Roger E. Massed9240d11997-01-16 22:05:33 +0000499 return PyInt_FromLong(status == 0);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000500}
501
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000502static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000503bsddb_set_location(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000504 bsddbobject *dp;
505 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000506{
Roger E. Massed9240d11997-01-16 22:05:33 +0000507 int status;
508 DBT krec, drec;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000509 char *data,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000510 int size;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000511 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000512
Roger E. Massed9240d11997-01-16 22:05:33 +0000513 if (!PyArg_Parse(key, "s#", &data, &size))
514 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000515 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000516 krec.data = data;
517 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000518
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000519 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000520 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_CURSOR);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000521 if (status == 0) {
522 if (drec.size > sizeof(buf)) data = malloc(drec.size);
523 else data = buf;
524 memcpy(data,drec.data,drec.size);
525 }
526 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000527 if (status != 0) {
528 if (status < 0)
529 PyErr_SetFromErrno(BsddbError);
530 else
531 PyErr_SetObject(PyExc_KeyError, key);
532 return NULL;
533 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000534
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000535 result = Py_BuildValue("s#s#", krec.data, krec.size, data, drec.size);
536 if (data != buf) free(data);
537 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000538}
539
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000540static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000541bsddb_seq(dp, args, sequence_request)
Roger E. Massed9240d11997-01-16 22:05:33 +0000542 bsddbobject *dp;
543 PyObject *args;
544 int sequence_request;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000545{
Roger E. Massed9240d11997-01-16 22:05:33 +0000546 int status;
547 DBT krec, drec;
Guido van Rossum730806d1998-04-10 22:27:42 +0000548 char *kdata=NULL,kbuf[4096];
549 char *ddata=NULL,dbuf[4096];
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000550 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000551
Roger E. Massed9240d11997-01-16 22:05:33 +0000552 if (!PyArg_NoArgs(args))
553 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000554
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000555 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000556 krec.data = 0;
557 krec.size = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000558
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000559 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000560 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec,
561 &drec, sequence_request);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000562 if (status == 0) {
563 if (krec.size > sizeof(kbuf)) kdata = malloc(krec.size);
564 else kdata = kbuf;
565 memcpy(kdata,krec.data,krec.size);
566 if (drec.size > sizeof(dbuf)) ddata = malloc(drec.size);
567 else ddata = dbuf;
568 memcpy(ddata,drec.data,drec.size);
569 }
570 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000571 if (status != 0) {
572 if (status < 0)
573 PyErr_SetFromErrno(BsddbError);
574 else
575 PyErr_SetObject(PyExc_KeyError, args);
576 return NULL;
577 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000578
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000579 result = Py_BuildValue("s#s#", kdata, krec.size, ddata, drec.size);
580 if (kdata != kbuf) free(kdata);
581 if (ddata != dbuf) free(ddata);
582 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000583}
584
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000585static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000586bsddb_next(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000587 bsddbobject *dp;
588 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000589{
Roger E. Massed9240d11997-01-16 22:05:33 +0000590 return bsddb_seq(dp, key, R_NEXT);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000591}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000592static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000593bsddb_previous(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000594 bsddbobject *dp;
595 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000596{
Roger E. Massed9240d11997-01-16 22:05:33 +0000597 return bsddb_seq(dp, key, R_PREV);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000598}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000599static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000600bsddb_first(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000601 bsddbobject *dp;
602 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000603{
Roger E. Massed9240d11997-01-16 22:05:33 +0000604 return bsddb_seq(dp, key, R_FIRST);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000605}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000606static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000607bsddb_last(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000608 bsddbobject *dp;
609 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000610{
Roger E. Massed9240d11997-01-16 22:05:33 +0000611 return bsddb_seq(dp, key, R_LAST);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000612}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000613static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000614bsddb_sync(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000615 bsddbobject *dp;
616 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000617{
Roger E. Massed9240d11997-01-16 22:05:33 +0000618 int status;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000619
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000620 if (!PyArg_NoArgs(args))
621 return NULL;
622 check_bsddbobject_open(dp);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000623 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000624 status = (dp->di_bsddb->sync)(dp->di_bsddb, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000625 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000626 if (status != 0) {
627 PyErr_SetFromErrno(BsddbError);
628 return NULL;
629 }
630 return PyInt_FromLong(status = 0);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000631}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000632static PyMethodDef bsddb_methods[] = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000633 {"close", (PyCFunction)bsddb_close},
634 {"keys", (PyCFunction)bsddb_keys},
635 {"has_key", (PyCFunction)bsddb_has_key},
636 {"set_location", (PyCFunction)bsddb_set_location},
637 {"next", (PyCFunction)bsddb_next},
638 {"previous", (PyCFunction)bsddb_previous},
639 {"first", (PyCFunction)bsddb_first},
640 {"last", (PyCFunction)bsddb_last},
641 {"sync", (PyCFunction)bsddb_sync},
642 {NULL, NULL} /* sentinel */
Guido van Rossum1100dca1995-08-30 23:43:03 +0000643};
644
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000645static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000646bsddb_getattr(dp, name)
Roger E. Massed9240d11997-01-16 22:05:33 +0000647 PyObject *dp;
648 char *name;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000649{
Roger E. Massed9240d11997-01-16 22:05:33 +0000650 return Py_FindMethod(bsddb_methods, dp, name);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000651}
652
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000653static PyTypeObject Bsddbtype = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000654 PyObject_HEAD_INIT(NULL)
655 0,
656 "bsddb",
657 sizeof(bsddbobject),
658 0,
659 (destructor)bsddb_dealloc, /*tp_dealloc*/
660 0, /*tp_print*/
661 (getattrfunc)bsddb_getattr, /*tp_getattr*/
662 0, /*tp_setattr*/
663 0, /*tp_compare*/
664 0, /*tp_repr*/
665 0, /*tp_as_number*/
666 0, /*tp_as_sequence*/
667 &bsddb_as_mapping, /*tp_as_mapping*/
Guido van Rossum1100dca1995-08-30 23:43:03 +0000668};
669
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000670static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000671bsdhashopen(self, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000672 PyObject *self;
673 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000674{
Roger E. Massed9240d11997-01-16 22:05:33 +0000675 char *file;
676 char *flag = NULL;
677 int flags = O_RDONLY;
678 int mode = 0666;
679 int bsize = 0;
680 int ffactor = 0;
681 int nelem = 0;
682 int cachesize = 0;
683 int hash = 0; /* XXX currently ignored */
684 int lorder = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000685
Guido van Rossum43713e52000-02-29 13:59:29 +0000686 if (!PyArg_ParseTuple(args, "s|siiiiiii:hashopen",
Roger E. Massed9240d11997-01-16 22:05:33 +0000687 &file, &flag, &mode,
688 &bsize, &ffactor, &nelem, &cachesize,
689 &hash, &lorder))
690 return NULL;
691 if (flag != NULL) {
692 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
693 if (flag[0] == 'r')
694 flags = O_RDONLY;
695 else if (flag[0] == 'w')
696 flags = O_RDWR;
697 else if (flag[0] == 'c')
698 flags = O_RDWR|O_CREAT;
699 else if (flag[0] == 'n')
700 flags = O_RDWR|O_CREAT|O_TRUNC;
701 else {
702 PyErr_SetString(BsddbError,
703 "Flag should begin with 'r', 'w', 'c' or 'n'");
704 return NULL;
705 }
706 if (flag[1] == 'l') {
Guido van Rossum1100dca1995-08-30 23:43:03 +0000707#if defined(O_EXLOCK) && defined(O_SHLOCK)
Roger E. Massed9240d11997-01-16 22:05:33 +0000708 if (flag[0] == 'r')
709 flags |= O_SHLOCK;
710 else
711 flags |= O_EXLOCK;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000712#else
Roger E. Massed9240d11997-01-16 22:05:33 +0000713 PyErr_SetString(BsddbError,
714 "locking not supported on this platform");
715 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000716#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000717 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000718 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000719 return newdbhashobject(file, flags, mode,
720 bsize, ffactor, nelem, cachesize, hash, lorder);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000721}
722
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000723static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000724bsdbtopen(self, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000725 PyObject *self;
726 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000727{
Roger E. Massed9240d11997-01-16 22:05:33 +0000728 char *file;
729 char *flag = NULL;
730 int flags = O_RDONLY;
731 int mode = 0666;
732 int cachesize = 0;
733 int maxkeypage = 0;
734 int minkeypage = 0;
735 int btflags = 0;
736 unsigned int psize = 0;
737 int lorder = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000738
Guido van Rossum43713e52000-02-29 13:59:29 +0000739 if (!PyArg_ParseTuple(args, "s|siiiiiii:btopen",
Roger E. Massed9240d11997-01-16 22:05:33 +0000740 &file, &flag, &mode,
741 &btflags, &cachesize, &maxkeypage, &minkeypage,
742 &psize, &lorder))
743 return NULL;
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') {
Guido van Rossum1100dca1995-08-30 23:43:03 +0000760#if defined(O_EXLOCK) && defined(O_SHLOCK)
Roger E. Massed9240d11997-01-16 22:05:33 +0000761 if (flag[0] == 'r')
762 flags |= O_SHLOCK;
763 else
764 flags |= O_EXLOCK;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000765#else
Roger E. Massed9240d11997-01-16 22:05:33 +0000766 PyErr_SetString(BsddbError,
767 "locking not supported on this platform");
768 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000769#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000770 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000771 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000772 return newdbbtobject(file, flags, mode,
773 btflags, cachesize, maxkeypage, minkeypage,
774 psize, lorder);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000775}
Guido van Rossumdd96ca71996-05-23 22:57:54 +0000776
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000777static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000778bsdrnopen(self, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000779 PyObject *self;
780 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000781{
Roger E. Massed9240d11997-01-16 22:05:33 +0000782 char *file;
783 char *flag = NULL;
784 int flags = O_RDONLY;
785 int mode = 0666;
786 int cachesize = 0;
787 int rnflags = 0;
788 unsigned int psize = 0;
789 int lorder = 0;
790 size_t reclen = 0;
791 char *bval = "";
792 char *bfname = NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000793
Guido van Rossum43713e52000-02-29 13:59:29 +0000794 if (!PyArg_ParseTuple(args, "s|siiiiiiss:rnopen",
Roger E. Massed9240d11997-01-16 22:05:33 +0000795 &file, &flag, &mode,
796 &rnflags, &cachesize, &psize, &lorder,
797 &reclen, &bval, &bfname))
798 return NULL;
799
800# if 0
801 printf("file: %s\n", file);
802 printf("flag: %s\n", flag);
803 printf("mode: %d\n", mode);
804 printf("rnflags: 0x%x\n", rnflags);
805 printf("cachesize: %d\n", cachesize);
806 printf("psize: %d\n", psize);
807 printf("lorder: %d\n", 0);
808 printf("reclen: %d\n", reclen);
809 printf("bval: %c\n", bval[0]);
810 printf("bfname %s\n", bfname);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000811#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000812
813 if (flag != NULL) {
814 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
815 if (flag[0] == 'r')
816 flags = O_RDONLY;
817 else if (flag[0] == 'w')
818 flags = O_RDWR;
819 else if (flag[0] == 'c')
820 flags = O_RDWR|O_CREAT;
821 else if (flag[0] == 'n')
822 flags = O_RDWR|O_CREAT|O_TRUNC;
823 else {
824 PyErr_SetString(BsddbError,
825 "Flag should begin with 'r', 'w', 'c' or 'n'");
826 return NULL;
827 }
828 if (flag[1] == 'l') {
829#if defined(O_EXLOCK) && defined(O_SHLOCK)
830 if (flag[0] == 'r')
831 flags |= O_SHLOCK;
832 else
833 flags |= O_EXLOCK;
834#else
835 PyErr_SetString(BsddbError,
836 "locking not supported on this platform");
837 return NULL;
838#endif
839 }
840 else if (flag[1] != '\0') {
841 PyErr_SetString(BsddbError,
842 "Flag char 2 should be 'l' or absent");
843 return NULL;
844 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000845 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000846 return newdbrnobject(file, flags, mode, rnflags, cachesize,
847 psize, lorder, reclen, bval[0], bfname);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000848}
849
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000850static PyMethodDef bsddbmodule_methods[] = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000851 {"hashopen", (PyCFunction)bsdhashopen, 1},
852 {"btopen", (PyCFunction)bsdbtopen, 1},
853 {"rnopen", (PyCFunction)bsdrnopen, 1},
854 {0, 0},
Guido van Rossum1100dca1995-08-30 23:43:03 +0000855};
856
Guido van Rossum3886bb61998-12-04 18:50:17 +0000857DL_EXPORT(void)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000858initbsddb() {
Roger E. Massed9240d11997-01-16 22:05:33 +0000859 PyObject *m, *d;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000860
Roger E. Massed9240d11997-01-16 22:05:33 +0000861 Bsddbtype.ob_type = &PyType_Type;
862 m = Py_InitModule("bsddb", bsddbmodule_methods);
863 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000864 BsddbError = PyErr_NewException("bsddb.error", NULL, NULL);
865 if (BsddbError != NULL)
866 PyDict_SetItemString(d, "error", BsddbError);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000867}