blob: ca7fa5f0d6ca9fcbb5ccbc649bb29f90d9112f54 [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 Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossum1100dca1995-08-30 23:43:03 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossum1100dca1995-08-30 23:43:03 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossum1100dca1995-08-30 23:43:03 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum1100dca1995-08-30 23:43:03 +000029
30******************************************************************/
31
32/* Berkeley DB interface.
33 Author: Michael McLay
34 Hacked: Guido van Rossum
35 Btree and Recno additions plus sequence methods: David Ely
36
37 XXX To do:
38 - provide interface to the B-tree and record libraries too
39 - provide a way to access the various hash functions
40 - support more open flags
41 */
42
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000043#include "Python.h"
Guido van Rossum4f199ea1998-04-09 20:56:35 +000044#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000045#include "pythread.h"
Guido van Rossum4f199ea1998-04-09 20:56:35 +000046#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +000047
48#include <sys/types.h>
49#include <sys/stat.h>
50#include <fcntl.h>
51#include <db.h>
52/* Please don't include internal header files of the Berkeley db package
53 (it messes up the info required in the Setup file) */
54
55typedef struct {
Roger E. Massed9240d11997-01-16 22:05:33 +000056 PyObject_HEAD
57 DB *di_bsddb;
58 int di_size; /* -1 means recompute */
Guido van Rossum4f199ea1998-04-09 20:56:35 +000059#ifdef WITH_THREAD
60 type_lock di_lock;
61#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +000062} bsddbobject;
63
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000064staticforward PyTypeObject Bsddbtype;
Guido van Rossum1100dca1995-08-30 23:43:03 +000065
66#define is_bsddbobject(v) ((v)->ob_type == &Bsddbtype)
Guido van Rossum77eecfa1997-07-17 22:56:01 +000067#define check_bsddbobject_open(v) if ((v)->di_bsddb == NULL) \
68 { PyErr_SetString(BsddbError, "BSDDB object has already been closed"); \
69 return NULL; }
Guido van Rossum1100dca1995-08-30 23:43:03 +000070
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000071static PyObject *BsddbError;
Guido van Rossum1100dca1995-08-30 23:43:03 +000072
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000073static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +000074newdbhashobject(file, flags, mode,
75 bsize, ffactor, nelem, cachesize, hash, lorder)
Roger E. Massed9240d11997-01-16 22:05:33 +000076 char *file;
77 int flags;
78 int mode;
79 int bsize;
80 int ffactor;
81 int nelem;
82 int cachesize;
83 int hash; /* XXX ignored */
84 int lorder;
Guido van Rossum1100dca1995-08-30 23:43:03 +000085{
Roger E. Massed9240d11997-01-16 22:05:33 +000086 bsddbobject *dp;
87 HASHINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +000088
Roger E. Massed9240d11997-01-16 22:05:33 +000089 if ((dp = PyObject_NEW(bsddbobject, &Bsddbtype)) == NULL)
90 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +000091
Roger E. Massed9240d11997-01-16 22:05:33 +000092 info.bsize = bsize;
93 info.ffactor = ffactor;
94 info.nelem = nelem;
95 info.cachesize = cachesize;
96 info.hash = NULL; /* XXX should derive from hash argument */
97 info.lorder = lorder;
Guido van Rossum1100dca1995-08-30 23:43:03 +000098
Guido van Rossum6beb4791996-09-11 23:22:25 +000099#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +0000100 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +0000101#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000102 Py_BEGIN_ALLOW_THREADS
103 dp->di_bsddb = dbopen(file, flags, mode, DB_HASH, &info);
104 Py_END_ALLOW_THREADS
105 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000106 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000107#ifdef WITH_THREAD
108 dp->di_lock = NULL;
109#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000110 Py_DECREF(dp);
111 return NULL;
112 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000113
Roger E. Massed9240d11997-01-16 22:05:33 +0000114 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000115#ifdef WITH_THREAD
116 dp->di_lock = allocate_lock();
117 if (dp->di_lock == NULL) {
118 PyErr_SetString(BsddbError, "can't allocate lock");
119 Py_DECREF(dp);
120 return NULL;
121 }
122#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000123
Roger E. Massed9240d11997-01-16 22:05:33 +0000124 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000125}
126
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000127static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000128newdbbtobject(file, flags, mode,
Roger E. Massed9240d11997-01-16 22:05:33 +0000129 btflags, cachesize, maxkeypage, minkeypage, psize, lorder)
130 char *file;
131 int flags;
132 int mode;
133 int btflags;
134 int cachesize;
135 int maxkeypage;
136 int minkeypage;
137 int psize;
138 int lorder;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000139{
Roger E. Massed9240d11997-01-16 22:05:33 +0000140 bsddbobject *dp;
141 BTREEINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000142
Roger E. Massed9240d11997-01-16 22:05:33 +0000143 if ((dp = PyObject_NEW(bsddbobject, &Bsddbtype)) == NULL)
144 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000145
Roger E. Massed9240d11997-01-16 22:05:33 +0000146 info.flags = btflags;
147 info.cachesize = cachesize;
148 info.maxkeypage = maxkeypage;
149 info.minkeypage = minkeypage;
150 info.psize = psize;
151 info.lorder = lorder;
152 info.compare = 0; /* Use default comparison functions, for now..*/
153 info.prefix = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000154
Guido van Rossum6beb4791996-09-11 23:22:25 +0000155#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +0000156 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +0000157#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000158 Py_BEGIN_ALLOW_THREADS
159 dp->di_bsddb = dbopen(file, flags, mode, DB_BTREE, &info);
160 Py_END_ALLOW_THREADS
161 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000162 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000163#ifdef WITH_THREAD
164 dp->di_lock = NULL;
165#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000166 Py_DECREF(dp);
167 return NULL;
168 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000169
Roger E. Massed9240d11997-01-16 22:05:33 +0000170 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000171#ifdef WITH_THREAD
172 dp->di_lock = allocate_lock();
173 if (dp->di_lock == NULL) {
174 PyErr_SetString(BsddbError, "can't allocate lock");
175 Py_DECREF(dp);
176 return NULL;
177 }
178#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000179
Roger E. Massed9240d11997-01-16 22:05:33 +0000180 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000181}
182
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000183static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000184newdbrnobject(file, flags, mode,
Roger E. Massed9240d11997-01-16 22:05:33 +0000185 rnflags, cachesize, psize, lorder, reclen, bval, bfname)
186 char *file;
187 int flags;
188 int mode;
189 int rnflags;
190 int cachesize;
191 int psize;
192 int lorder;
193 size_t reclen;
194 u_char bval;
195 char *bfname;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000196{
Roger E. Massed9240d11997-01-16 22:05:33 +0000197 bsddbobject *dp;
198 RECNOINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000199
Roger E. Massed9240d11997-01-16 22:05:33 +0000200 if ((dp = PyObject_NEW(bsddbobject, &Bsddbtype)) == NULL)
201 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000202
Roger E. Massed9240d11997-01-16 22:05:33 +0000203 info.flags = rnflags;
204 info.cachesize = cachesize;
205 info.psize = psize;
206 info.lorder = lorder;
207 info.reclen = reclen;
208 info.bval = bval;
209 info.bfname = bfname;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000210
Guido van Rossum6beb4791996-09-11 23:22:25 +0000211#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +0000212 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +0000213#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000214 Py_BEGIN_ALLOW_THREADS
215 dp->di_bsddb = dbopen(file, flags, mode, DB_RECNO, &info);
216 Py_END_ALLOW_THREADS
217 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000218 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000219#ifdef WITH_THREAD
220 dp->di_lock = NULL;
221#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000222 Py_DECREF(dp);
223 return NULL;
224 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000225
Roger E. Massed9240d11997-01-16 22:05:33 +0000226 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000227#ifdef WITH_THREAD
228 dp->di_lock = allocate_lock();
229 if (dp->di_lock == NULL) {
230 PyErr_SetString(BsddbError, "can't allocate lock");
231 Py_DECREF(dp);
232 return NULL;
233 }
234#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000235
Roger E. Massed9240d11997-01-16 22:05:33 +0000236 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000237}
238
Guido van Rossum1100dca1995-08-30 23:43:03 +0000239static void
240bsddb_dealloc(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000241 bsddbobject *dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000242{
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000243#ifdef WITH_THREAD
244 if (dp->di_lock) {
245 acquire_lock(dp->di_lock, 0);
246 release_lock(dp->di_lock);
247 free_lock(dp->di_lock);
248 dp->di_lock = NULL;
249 }
250#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000251 if (dp->di_bsddb != NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000252 int status;
253 Py_BEGIN_ALLOW_THREADS
254 status = (dp->di_bsddb->close)(dp->di_bsddb);
255 Py_END_ALLOW_THREADS
256 if (status != 0)
Roger E. Massed9240d11997-01-16 22:05:33 +0000257 fprintf(stderr,
258 "Python bsddb: close errno %d in dealloc\n",
259 errno);
260 }
261 PyMem_DEL(dp);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000262}
263
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000264#ifdef WITH_THREAD
265#define BSDDB_BGN_SAVE(_dp) Py_BEGIN_ALLOW_THREADS acquire_lock(_dp->di_lock,1);
266#define BSDDB_END_SAVE(_dp) release_lock(_dp->di_lock); Py_END_ALLOW_THREADS
267#else
268#define BSDDB_BGN_SAVE(_dp) Py_BEGIN_ALLOW_THREADS
269#define BSDDB_END_SAVE(_dp) Py_END_ALLOW_THREADS
270#endif
271
Guido van Rossum1100dca1995-08-30 23:43:03 +0000272static int
273bsddb_length(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000274 bsddbobject *dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000275{
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000276 if (dp->di_bsddb == NULL) {
277 PyErr_SetString(BsddbError, "BSDDB object has already been closed");
278 return -1;
279 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000280 if (dp->di_size < 0) {
281 DBT krec, drec;
282 int status;
283 int size = 0;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000284 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000285 for (status = (dp->di_bsddb->seq)(dp->di_bsddb,
286 &krec, &drec,R_FIRST);
287 status == 0;
288 status = (dp->di_bsddb->seq)(dp->di_bsddb,
289 &krec, &drec, R_NEXT))
290 size++;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000291 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000292 if (status < 0) {
293 PyErr_SetFromErrno(BsddbError);
294 return -1;
295 }
296 dp->di_size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000297 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000298 return dp->di_size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000299}
300
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000301static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000302bsddb_subscript(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000303 bsddbobject *dp;
304 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000305{
Roger E. Massed9240d11997-01-16 22:05:33 +0000306 int status;
307 DBT krec, drec;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000308 char *data,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000309 int size;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000310 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000311
Roger E. Massed9240d11997-01-16 22:05:33 +0000312 if (!PyArg_Parse(key, "s#", &data, &size))
313 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000314 check_bsddbobject_open(dp);
315
Roger E. Massed9240d11997-01-16 22:05:33 +0000316 krec.data = data;
317 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000318
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000319 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000320 status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000321 if (status == 0) {
322 if (drec.size > sizeof(buf)) data = malloc(drec.size);
323 else data = buf;
324 memcpy(data,drec.data,drec.size);
325 }
326 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000327 if (status != 0) {
328 if (status < 0)
329 PyErr_SetFromErrno(BsddbError);
330 else
331 PyErr_SetObject(PyExc_KeyError, key);
332 return NULL;
333 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000334
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000335 result = PyString_FromStringAndSize(data, (int)drec.size);
336 if (data != buf) free(data);
337 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000338}
339
340static int
341bsddb_ass_sub(dp, key, value)
Roger E. Massed9240d11997-01-16 22:05:33 +0000342 bsddbobject *dp;
343 PyObject *key, *value;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000344{
Roger E. Massed9240d11997-01-16 22:05:33 +0000345 int status;
346 DBT krec, drec;
347 char *data;
348 int size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000349
Roger E. Massed9240d11997-01-16 22:05:33 +0000350 if (!PyArg_Parse(key, "s#", &data, &size)) {
351 PyErr_SetString(PyExc_TypeError,
352 "bsddb key type must be string");
353 return -1;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000354 }
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000355 if (dp->di_bsddb == NULL) {
356 PyErr_SetString(BsddbError, "BSDDB object has already been closed");
357 return -1;
358 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000359 krec.data = data;
360 krec.size = size;
361 dp->di_size = -1;
362 if (value == NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000363 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000364 status = (dp->di_bsddb->del)(dp->di_bsddb, &krec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000365 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000366 }
367 else {
368 if (!PyArg_Parse(value, "s#", &data, &size)) {
369 PyErr_SetString(PyExc_TypeError,
370 "bsddb value type must be string");
371 return -1;
372 }
373 drec.data = data;
374 drec.size = size;
375#if 0
376 /* For RECNO, put fails with 'No space left on device'
377 after a few short records are added?? Looks fine
378 to this point... linked with 1.85 on Solaris Intel
379 Roger E. Masse 1/16/97
380 */
381 printf("before put data: '%s', size: %d\n",
382 drec.data, drec.size);
383 printf("before put key= '%s', size= %d\n",
384 krec.data, krec.size);
385#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000386 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000387 status = (dp->di_bsddb->put)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000388 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000389 }
390 if (status != 0) {
391 if (status < 0)
392 PyErr_SetFromErrno(BsddbError);
393 else
394 PyErr_SetObject(PyExc_KeyError, key);
395 return -1;
396 }
397 return 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000398}
399
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000400static PyMappingMethods bsddb_as_mapping = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000401 (inquiry)bsddb_length, /*mp_length*/
402 (binaryfunc)bsddb_subscript, /*mp_subscript*/
403 (objobjargproc)bsddb_ass_sub, /*mp_ass_subscript*/
Guido van Rossum1100dca1995-08-30 23:43:03 +0000404};
405
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000406static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000407bsddb_close(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000408 bsddbobject *dp;
409 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000410{
Roger E. Massed9240d11997-01-16 22:05:33 +0000411 if (!PyArg_NoArgs(args))
412 return NULL;
413 if (dp->di_bsddb != NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000414 int status;
415 BSDDB_BGN_SAVE(dp)
416 status = (dp->di_bsddb->close)(dp->di_bsddb);
417 BSDDB_END_SAVE(dp)
418 if (status != 0) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000419 dp->di_bsddb = NULL;
420 PyErr_SetFromErrno(BsddbError);
421 return NULL;
422 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000423 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000424 dp->di_bsddb = NULL;
425 Py_INCREF(Py_None);
426 return Py_None;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000427}
428
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000429static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000430bsddb_keys(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000431 bsddbobject *dp;
432 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000433{
Roger E. Massed9240d11997-01-16 22:05:33 +0000434 PyObject *list, *item;
435 DBT krec, drec;
Guido van Rossum730806d1998-04-10 22:27:42 +0000436 char *data=NULL,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000437 int status;
438 int err;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000439
Roger E. Massed9240d11997-01-16 22:05:33 +0000440 if (!PyArg_NoArgs(args))
441 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000442 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000443 list = PyList_New(0);
444 if (list == NULL)
445 return NULL;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000446 BSDDB_BGN_SAVE(dp)
447 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_FIRST);
448 if (status == 0) {
449 if (krec.size > sizeof(buf)) data = malloc(krec.size);
450 else data = buf;
451 memcpy(data,krec.data,krec.size);
452 }
453 BSDDB_END_SAVE(dp)
454 while (status == 0) {
455 item = PyString_FromStringAndSize(data, (int)krec.size);
456 if (data != buf) free(data);
Roger E. Massed9240d11997-01-16 22:05:33 +0000457 if (item == NULL) {
458 Py_DECREF(list);
459 return NULL;
460 }
461 err = PyList_Append(list, item);
462 Py_DECREF(item);
463 if (err != 0) {
464 Py_DECREF(list);
465 return NULL;
466 }
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000467 BSDDB_BGN_SAVE(dp)
468 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_NEXT);
469 if (status == 0) {
470 if (krec.size > sizeof(buf)) data = malloc(krec.size);
471 else data = buf;
472 memcpy(data,krec.data,krec.size);
473 }
474 BSDDB_END_SAVE(dp)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000475 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000476 if (status < 0) {
477 PyErr_SetFromErrno(BsddbError);
478 Py_DECREF(list);
479 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000480 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000481 if (dp->di_size < 0)
482 dp->di_size = PyList_Size(list); /* We just did the work */
483 return list;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000484}
485
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000486static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000487bsddb_has_key(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000488 bsddbobject *dp;
489 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000490{
Roger E. Massed9240d11997-01-16 22:05:33 +0000491 DBT krec, drec;
492 int status;
493 char *data;
494 int size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000495
Roger E. Massed9240d11997-01-16 22:05:33 +0000496 if (!PyArg_Parse(args, "s#", &data, &size))
497 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000498 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000499 krec.data = data;
500 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000501
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000502 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000503 status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000504 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000505 if (status < 0) {
506 PyErr_SetFromErrno(BsddbError);
507 return NULL;
508 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000509
Roger E. Massed9240d11997-01-16 22:05:33 +0000510 return PyInt_FromLong(status == 0);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000511}
512
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000513static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000514bsddb_set_location(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000515 bsddbobject *dp;
516 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000517{
Roger E. Massed9240d11997-01-16 22:05:33 +0000518 int status;
519 DBT krec, drec;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000520 char *data,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000521 int size;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000522 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000523
Roger E. Massed9240d11997-01-16 22:05:33 +0000524 if (!PyArg_Parse(key, "s#", &data, &size))
525 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000526 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000527 krec.data = data;
528 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000529
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000530 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000531 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_CURSOR);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000532 if (status == 0) {
533 if (drec.size > sizeof(buf)) data = malloc(drec.size);
534 else data = buf;
535 memcpy(data,drec.data,drec.size);
536 }
537 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000538 if (status != 0) {
539 if (status < 0)
540 PyErr_SetFromErrno(BsddbError);
541 else
542 PyErr_SetObject(PyExc_KeyError, key);
543 return NULL;
544 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000545
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000546 result = Py_BuildValue("s#s#", krec.data, krec.size, data, drec.size);
547 if (data != buf) free(data);
548 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000549}
550
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000551static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000552bsddb_seq(dp, args, sequence_request)
Roger E. Massed9240d11997-01-16 22:05:33 +0000553 bsddbobject *dp;
554 PyObject *args;
555 int sequence_request;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000556{
Roger E. Massed9240d11997-01-16 22:05:33 +0000557 int status;
558 DBT krec, drec;
Guido van Rossum730806d1998-04-10 22:27:42 +0000559 char *kdata=NULL,kbuf[4096];
560 char *ddata=NULL,dbuf[4096];
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000561 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000562
Roger E. Massed9240d11997-01-16 22:05:33 +0000563 if (!PyArg_NoArgs(args))
564 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000565
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000566 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000567 krec.data = 0;
568 krec.size = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000569
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000570 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000571 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec,
572 &drec, sequence_request);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000573 if (status == 0) {
574 if (krec.size > sizeof(kbuf)) kdata = malloc(krec.size);
575 else kdata = kbuf;
576 memcpy(kdata,krec.data,krec.size);
577 if (drec.size > sizeof(dbuf)) ddata = malloc(drec.size);
578 else ddata = dbuf;
579 memcpy(ddata,drec.data,drec.size);
580 }
581 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000582 if (status != 0) {
583 if (status < 0)
584 PyErr_SetFromErrno(BsddbError);
585 else
586 PyErr_SetObject(PyExc_KeyError, args);
587 return NULL;
588 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000589
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000590 result = Py_BuildValue("s#s#", kdata, krec.size, ddata, drec.size);
591 if (kdata != kbuf) free(kdata);
592 if (ddata != dbuf) free(ddata);
593 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000594}
595
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000596static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000597bsddb_next(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000598 bsddbobject *dp;
599 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000600{
Roger E. Massed9240d11997-01-16 22:05:33 +0000601 return bsddb_seq(dp, key, R_NEXT);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000602}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000603static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000604bsddb_previous(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000605 bsddbobject *dp;
606 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000607{
Roger E. Massed9240d11997-01-16 22:05:33 +0000608 return bsddb_seq(dp, key, R_PREV);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000609}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000610static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000611bsddb_first(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000612 bsddbobject *dp;
613 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000614{
Roger E. Massed9240d11997-01-16 22:05:33 +0000615 return bsddb_seq(dp, key, R_FIRST);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000616}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000617static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000618bsddb_last(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000619 bsddbobject *dp;
620 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000621{
Roger E. Massed9240d11997-01-16 22:05:33 +0000622 return bsddb_seq(dp, key, R_LAST);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000623}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000624static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000625bsddb_sync(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000626 bsddbobject *dp;
627 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000628{
Roger E. Massed9240d11997-01-16 22:05:33 +0000629 int status;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000630
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000631 if (!PyArg_NoArgs(args))
632 return NULL;
633 check_bsddbobject_open(dp);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000634 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000635 status = (dp->di_bsddb->sync)(dp->di_bsddb, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000636 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000637 if (status != 0) {
638 PyErr_SetFromErrno(BsddbError);
639 return NULL;
640 }
641 return PyInt_FromLong(status = 0);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000642}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000643static PyMethodDef bsddb_methods[] = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000644 {"close", (PyCFunction)bsddb_close},
645 {"keys", (PyCFunction)bsddb_keys},
646 {"has_key", (PyCFunction)bsddb_has_key},
647 {"set_location", (PyCFunction)bsddb_set_location},
648 {"next", (PyCFunction)bsddb_next},
649 {"previous", (PyCFunction)bsddb_previous},
650 {"first", (PyCFunction)bsddb_first},
651 {"last", (PyCFunction)bsddb_last},
652 {"sync", (PyCFunction)bsddb_sync},
653 {NULL, NULL} /* sentinel */
Guido van Rossum1100dca1995-08-30 23:43:03 +0000654};
655
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000656static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000657bsddb_getattr(dp, name)
Roger E. Massed9240d11997-01-16 22:05:33 +0000658 PyObject *dp;
659 char *name;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000660{
Roger E. Massed9240d11997-01-16 22:05:33 +0000661 return Py_FindMethod(bsddb_methods, dp, name);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000662}
663
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000664static PyTypeObject Bsddbtype = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000665 PyObject_HEAD_INIT(NULL)
666 0,
667 "bsddb",
668 sizeof(bsddbobject),
669 0,
670 (destructor)bsddb_dealloc, /*tp_dealloc*/
671 0, /*tp_print*/
672 (getattrfunc)bsddb_getattr, /*tp_getattr*/
673 0, /*tp_setattr*/
674 0, /*tp_compare*/
675 0, /*tp_repr*/
676 0, /*tp_as_number*/
677 0, /*tp_as_sequence*/
678 &bsddb_as_mapping, /*tp_as_mapping*/
Guido van Rossum1100dca1995-08-30 23:43:03 +0000679};
680
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000681static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000682bsdhashopen(self, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000683 PyObject *self;
684 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000685{
Roger E. Massed9240d11997-01-16 22:05:33 +0000686 char *file;
687 char *flag = NULL;
688 int flags = O_RDONLY;
689 int mode = 0666;
690 int bsize = 0;
691 int ffactor = 0;
692 int nelem = 0;
693 int cachesize = 0;
694 int hash = 0; /* XXX currently ignored */
695 int lorder = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000696
Roger E. Massed9240d11997-01-16 22:05:33 +0000697 if (!PyArg_ParseTuple(args, "s|siiiiiii",
698 &file, &flag, &mode,
699 &bsize, &ffactor, &nelem, &cachesize,
700 &hash, &lorder))
701 return NULL;
702 if (flag != NULL) {
703 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
704 if (flag[0] == 'r')
705 flags = O_RDONLY;
706 else if (flag[0] == 'w')
707 flags = O_RDWR;
708 else if (flag[0] == 'c')
709 flags = O_RDWR|O_CREAT;
710 else if (flag[0] == 'n')
711 flags = O_RDWR|O_CREAT|O_TRUNC;
712 else {
713 PyErr_SetString(BsddbError,
714 "Flag should begin with 'r', 'w', 'c' or 'n'");
715 return NULL;
716 }
717 if (flag[1] == 'l') {
Guido van Rossum1100dca1995-08-30 23:43:03 +0000718#if defined(O_EXLOCK) && defined(O_SHLOCK)
Roger E. Massed9240d11997-01-16 22:05:33 +0000719 if (flag[0] == 'r')
720 flags |= O_SHLOCK;
721 else
722 flags |= O_EXLOCK;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000723#else
Roger E. Massed9240d11997-01-16 22:05:33 +0000724 PyErr_SetString(BsddbError,
725 "locking not supported on this platform");
726 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000727#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000728 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000729 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000730 return newdbhashobject(file, flags, mode,
731 bsize, ffactor, nelem, cachesize, hash, lorder);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000732}
733
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000734static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000735bsdbtopen(self, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000736 PyObject *self;
737 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000738{
Roger E. Massed9240d11997-01-16 22:05:33 +0000739 char *file;
740 char *flag = NULL;
741 int flags = O_RDONLY;
742 int mode = 0666;
743 int cachesize = 0;
744 int maxkeypage = 0;
745 int minkeypage = 0;
746 int btflags = 0;
747 unsigned int psize = 0;
748 int lorder = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000749
Roger E. Massed9240d11997-01-16 22:05:33 +0000750 if (!PyArg_ParseTuple(args, "s|siiiiiii",
751 &file, &flag, &mode,
752 &btflags, &cachesize, &maxkeypage, &minkeypage,
753 &psize, &lorder))
754 return NULL;
755 if (flag != NULL) {
756 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
757 if (flag[0] == 'r')
758 flags = O_RDONLY;
759 else if (flag[0] == 'w')
760 flags = O_RDWR;
761 else if (flag[0] == 'c')
762 flags = O_RDWR|O_CREAT;
763 else if (flag[0] == 'n')
764 flags = O_RDWR|O_CREAT|O_TRUNC;
765 else {
766 PyErr_SetString(BsddbError,
767 "Flag should begin with 'r', 'w', 'c' or 'n'");
768 return NULL;
769 }
770 if (flag[1] == 'l') {
Guido van Rossum1100dca1995-08-30 23:43:03 +0000771#if defined(O_EXLOCK) && defined(O_SHLOCK)
Roger E. Massed9240d11997-01-16 22:05:33 +0000772 if (flag[0] == 'r')
773 flags |= O_SHLOCK;
774 else
775 flags |= O_EXLOCK;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000776#else
Roger E. Massed9240d11997-01-16 22:05:33 +0000777 PyErr_SetString(BsddbError,
778 "locking not supported on this platform");
779 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000780#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000781 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000782 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000783 return newdbbtobject(file, flags, mode,
784 btflags, cachesize, maxkeypage, minkeypage,
785 psize, lorder);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000786}
Guido van Rossumdd96ca71996-05-23 22:57:54 +0000787
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000788static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000789bsdrnopen(self, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000790 PyObject *self;
791 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000792{
Roger E. Massed9240d11997-01-16 22:05:33 +0000793 char *file;
794 char *flag = NULL;
795 int flags = O_RDONLY;
796 int mode = 0666;
797 int cachesize = 0;
798 int rnflags = 0;
799 unsigned int psize = 0;
800 int lorder = 0;
801 size_t reclen = 0;
802 char *bval = "";
803 char *bfname = NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000804
Roger E. Massed9240d11997-01-16 22:05:33 +0000805 if (!PyArg_ParseTuple(args, "s|siiiiiiss",
806 &file, &flag, &mode,
807 &rnflags, &cachesize, &psize, &lorder,
808 &reclen, &bval, &bfname))
809 return NULL;
810
811# if 0
812 printf("file: %s\n", file);
813 printf("flag: %s\n", flag);
814 printf("mode: %d\n", mode);
815 printf("rnflags: 0x%x\n", rnflags);
816 printf("cachesize: %d\n", cachesize);
817 printf("psize: %d\n", psize);
818 printf("lorder: %d\n", 0);
819 printf("reclen: %d\n", reclen);
820 printf("bval: %c\n", bval[0]);
821 printf("bfname %s\n", bfname);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000822#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000823
824 if (flag != NULL) {
825 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
826 if (flag[0] == 'r')
827 flags = O_RDONLY;
828 else if (flag[0] == 'w')
829 flags = O_RDWR;
830 else if (flag[0] == 'c')
831 flags = O_RDWR|O_CREAT;
832 else if (flag[0] == 'n')
833 flags = O_RDWR|O_CREAT|O_TRUNC;
834 else {
835 PyErr_SetString(BsddbError,
836 "Flag should begin with 'r', 'w', 'c' or 'n'");
837 return NULL;
838 }
839 if (flag[1] == 'l') {
840#if defined(O_EXLOCK) && defined(O_SHLOCK)
841 if (flag[0] == 'r')
842 flags |= O_SHLOCK;
843 else
844 flags |= O_EXLOCK;
845#else
846 PyErr_SetString(BsddbError,
847 "locking not supported on this platform");
848 return NULL;
849#endif
850 }
851 else if (flag[1] != '\0') {
852 PyErr_SetString(BsddbError,
853 "Flag char 2 should be 'l' or absent");
854 return NULL;
855 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000856 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000857 return newdbrnobject(file, flags, mode, rnflags, cachesize,
858 psize, lorder, reclen, bval[0], bfname);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000859}
860
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000861static PyMethodDef bsddbmodule_methods[] = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000862 {"hashopen", (PyCFunction)bsdhashopen, 1},
863 {"btopen", (PyCFunction)bsdbtopen, 1},
864 {"rnopen", (PyCFunction)bsdrnopen, 1},
865 {0, 0},
Guido van Rossum1100dca1995-08-30 23:43:03 +0000866};
867
868void
869initbsddb() {
Roger E. Massed9240d11997-01-16 22:05:33 +0000870 PyObject *m, *d;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000871
Roger E. Massed9240d11997-01-16 22:05:33 +0000872 Bsddbtype.ob_type = &PyType_Type;
873 m = Py_InitModule("bsddb", bsddbmodule_methods);
874 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000875 BsddbError = PyErr_NewException("bsddb.error", NULL, NULL);
876 if (BsddbError != NULL)
877 PyDict_SetItemString(d, "error", BsddbError);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000878}