blob: 925e9281611dd5d04d5acd531880bc3b2c5cc405 [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
Guido van Rossum675e9941999-09-20 13:28:18 +000041
42 The windows port of the Berkeley DB code is hard to find on the web:
43 www.nightmare.com/software.html
44*/
Guido van Rossum1100dca1995-08-30 23:43:03 +000045
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000046#include "Python.h"
Guido van Rossum4f199ea1998-04-09 20:56:35 +000047#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000048#include "pythread.h"
Guido van Rossum4f199ea1998-04-09 20:56:35 +000049#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +000050
51#include <sys/types.h>
52#include <sys/stat.h>
53#include <fcntl.h>
Fred Drake947121f2000-06-30 04:17:11 +000054/* If using Berkeley DB 2.0 or newer, change this include to <db_185.h>: */
Guido van Rossum1100dca1995-08-30 23:43:03 +000055#include <db.h>
56/* Please don't include internal header files of the Berkeley db package
57 (it messes up the info required in the Setup file) */
58
59typedef struct {
Roger E. Massed9240d11997-01-16 22:05:33 +000060 PyObject_HEAD
61 DB *di_bsddb;
62 int di_size; /* -1 means recompute */
Guido van Rossum4f199ea1998-04-09 20:56:35 +000063#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +000064 PyThread_type_lock di_lock;
Guido van Rossum4f199ea1998-04-09 20:56:35 +000065#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +000066} bsddbobject;
67
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000068staticforward PyTypeObject Bsddbtype;
Guido van Rossum1100dca1995-08-30 23:43:03 +000069
70#define is_bsddbobject(v) ((v)->ob_type == &Bsddbtype)
Guido van Rossum77eecfa1997-07-17 22:56:01 +000071#define check_bsddbobject_open(v) if ((v)->di_bsddb == NULL) \
72 { PyErr_SetString(BsddbError, "BSDDB object has already been closed"); \
73 return NULL; }
Guido van Rossum1100dca1995-08-30 23:43:03 +000074
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000075static PyObject *BsddbError;
Guido van Rossum1100dca1995-08-30 23:43:03 +000076
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000077static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +000078newdbhashobject(file, flags, mode,
79 bsize, ffactor, nelem, cachesize, hash, lorder)
Roger E. Massed9240d11997-01-16 22:05:33 +000080 char *file;
81 int flags;
82 int mode;
83 int bsize;
84 int ffactor;
85 int nelem;
86 int cachesize;
87 int hash; /* XXX ignored */
88 int lorder;
Guido van Rossum1100dca1995-08-30 23:43:03 +000089{
Roger E. Massed9240d11997-01-16 22:05:33 +000090 bsddbobject *dp;
91 HASHINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +000092
Guido van Rossumb18618d2000-05-03 23:44:39 +000093 if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
Roger E. Massed9240d11997-01-16 22:05:33 +000094 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +000095
Roger E. Massed9240d11997-01-16 22:05:33 +000096 info.bsize = bsize;
97 info.ffactor = ffactor;
98 info.nelem = nelem;
99 info.cachesize = cachesize;
100 info.hash = NULL; /* XXX should derive from hash argument */
101 info.lorder = lorder;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000102
Guido van Rossum6beb4791996-09-11 23:22:25 +0000103#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +0000104 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +0000105#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000106 Py_BEGIN_ALLOW_THREADS
107 dp->di_bsddb = dbopen(file, flags, mode, DB_HASH, &info);
108 Py_END_ALLOW_THREADS
109 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000110 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000111#ifdef WITH_THREAD
112 dp->di_lock = NULL;
113#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000114 Py_DECREF(dp);
115 return NULL;
116 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000117
Roger E. Massed9240d11997-01-16 22:05:33 +0000118 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000119#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000120 dp->di_lock = PyThread_allocate_lock();
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000121 if (dp->di_lock == NULL) {
122 PyErr_SetString(BsddbError, "can't allocate lock");
123 Py_DECREF(dp);
124 return NULL;
125 }
126#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000127
Roger E. Massed9240d11997-01-16 22:05:33 +0000128 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000129}
130
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000131static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000132newdbbtobject(file, flags, mode,
Roger E. Massed9240d11997-01-16 22:05:33 +0000133 btflags, cachesize, maxkeypage, minkeypage, psize, lorder)
134 char *file;
135 int flags;
136 int mode;
137 int btflags;
138 int cachesize;
139 int maxkeypage;
140 int minkeypage;
141 int psize;
142 int lorder;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000143{
Roger E. Massed9240d11997-01-16 22:05:33 +0000144 bsddbobject *dp;
145 BTREEINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000146
Guido van Rossumb18618d2000-05-03 23:44:39 +0000147 if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
Roger E. Massed9240d11997-01-16 22:05:33 +0000148 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000149
Roger E. Massed9240d11997-01-16 22:05:33 +0000150 info.flags = btflags;
151 info.cachesize = cachesize;
152 info.maxkeypage = maxkeypage;
153 info.minkeypage = minkeypage;
154 info.psize = psize;
155 info.lorder = lorder;
156 info.compare = 0; /* Use default comparison functions, for now..*/
157 info.prefix = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000158
Guido van Rossum6beb4791996-09-11 23:22:25 +0000159#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +0000160 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +0000161#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000162 Py_BEGIN_ALLOW_THREADS
163 dp->di_bsddb = dbopen(file, flags, mode, DB_BTREE, &info);
164 Py_END_ALLOW_THREADS
165 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000166 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000167#ifdef WITH_THREAD
168 dp->di_lock = NULL;
169#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000170 Py_DECREF(dp);
171 return NULL;
172 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000173
Roger E. Massed9240d11997-01-16 22:05:33 +0000174 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000175#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000176 dp->di_lock = PyThread_allocate_lock();
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000177 if (dp->di_lock == NULL) {
178 PyErr_SetString(BsddbError, "can't allocate lock");
179 Py_DECREF(dp);
180 return NULL;
181 }
182#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000183
Roger E. Massed9240d11997-01-16 22:05:33 +0000184 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000185}
186
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000187static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000188newdbrnobject(file, flags, mode,
Roger E. Massed9240d11997-01-16 22:05:33 +0000189 rnflags, cachesize, psize, lorder, reclen, bval, bfname)
190 char *file;
191 int flags;
192 int mode;
193 int rnflags;
194 int cachesize;
195 int psize;
196 int lorder;
197 size_t reclen;
198 u_char bval;
199 char *bfname;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000200{
Roger E. Massed9240d11997-01-16 22:05:33 +0000201 bsddbobject *dp;
202 RECNOINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000203
Guido van Rossumb18618d2000-05-03 23:44:39 +0000204 if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
Roger E. Massed9240d11997-01-16 22:05:33 +0000205 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000206
Roger E. Massed9240d11997-01-16 22:05:33 +0000207 info.flags = rnflags;
208 info.cachesize = cachesize;
209 info.psize = psize;
210 info.lorder = lorder;
211 info.reclen = reclen;
212 info.bval = bval;
213 info.bfname = bfname;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000214
Guido van Rossum6beb4791996-09-11 23:22:25 +0000215#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +0000216 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +0000217#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000218 Py_BEGIN_ALLOW_THREADS
219 dp->di_bsddb = dbopen(file, flags, mode, DB_RECNO, &info);
220 Py_END_ALLOW_THREADS
221 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000222 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000223#ifdef WITH_THREAD
224 dp->di_lock = NULL;
225#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000226 Py_DECREF(dp);
227 return NULL;
228 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000229
Roger E. Massed9240d11997-01-16 22:05:33 +0000230 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000231#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000232 dp->di_lock = PyThread_allocate_lock();
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000233 if (dp->di_lock == NULL) {
234 PyErr_SetString(BsddbError, "can't allocate lock");
235 Py_DECREF(dp);
236 return NULL;
237 }
238#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000239
Roger E. Massed9240d11997-01-16 22:05:33 +0000240 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000241}
242
Guido van Rossum1100dca1995-08-30 23:43:03 +0000243static void
244bsddb_dealloc(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000245 bsddbobject *dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000246{
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000247#ifdef WITH_THREAD
248 if (dp->di_lock) {
Guido van Rossum65d5b571998-12-21 19:32:43 +0000249 PyThread_acquire_lock(dp->di_lock, 0);
250 PyThread_release_lock(dp->di_lock);
251 PyThread_free_lock(dp->di_lock);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000252 dp->di_lock = NULL;
253 }
254#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000255 if (dp->di_bsddb != NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000256 int status;
257 Py_BEGIN_ALLOW_THREADS
258 status = (dp->di_bsddb->close)(dp->di_bsddb);
259 Py_END_ALLOW_THREADS
260 if (status != 0)
Roger E. Massed9240d11997-01-16 22:05:33 +0000261 fprintf(stderr,
262 "Python bsddb: close errno %d in dealloc\n",
263 errno);
264 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000265 PyObject_Del(dp);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000266}
267
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000268#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000269#define BSDDB_BGN_SAVE(_dp) Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(_dp->di_lock,1);
270#define BSDDB_END_SAVE(_dp) PyThread_release_lock(_dp->di_lock); Py_END_ALLOW_THREADS
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000271#else
272#define BSDDB_BGN_SAVE(_dp) Py_BEGIN_ALLOW_THREADS
273#define BSDDB_END_SAVE(_dp) Py_END_ALLOW_THREADS
274#endif
275
Guido van Rossum1100dca1995-08-30 23:43:03 +0000276static int
277bsddb_length(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000278 bsddbobject *dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000279{
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000280 if (dp->di_bsddb == NULL) {
281 PyErr_SetString(BsddbError, "BSDDB object has already been closed");
282 return -1;
283 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000284 if (dp->di_size < 0) {
285 DBT krec, drec;
286 int status;
287 int size = 0;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000288 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000289 for (status = (dp->di_bsddb->seq)(dp->di_bsddb,
290 &krec, &drec,R_FIRST);
291 status == 0;
292 status = (dp->di_bsddb->seq)(dp->di_bsddb,
293 &krec, &drec, R_NEXT))
294 size++;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000295 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000296 if (status < 0) {
297 PyErr_SetFromErrno(BsddbError);
298 return -1;
299 }
300 dp->di_size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000301 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000302 return dp->di_size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000303}
304
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000305static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000306bsddb_subscript(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000307 bsddbobject *dp;
308 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000309{
Roger E. Massed9240d11997-01-16 22:05:33 +0000310 int status;
311 DBT krec, drec;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000312 char *data,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000313 int size;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000314 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000315
Roger E. Massed9240d11997-01-16 22:05:33 +0000316 if (!PyArg_Parse(key, "s#", &data, &size))
317 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000318 check_bsddbobject_open(dp);
319
Roger E. Massed9240d11997-01-16 22:05:33 +0000320 krec.data = data;
321 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000322
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000323 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000324 status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000325 if (status == 0) {
326 if (drec.size > sizeof(buf)) data = malloc(drec.size);
327 else data = buf;
328 memcpy(data,drec.data,drec.size);
329 }
330 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000331 if (status != 0) {
332 if (status < 0)
333 PyErr_SetFromErrno(BsddbError);
334 else
335 PyErr_SetObject(PyExc_KeyError, key);
336 return NULL;
337 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000338
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000339 result = PyString_FromStringAndSize(data, (int)drec.size);
340 if (data != buf) free(data);
341 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000342}
343
344static int
345bsddb_ass_sub(dp, key, value)
Roger E. Massed9240d11997-01-16 22:05:33 +0000346 bsddbobject *dp;
347 PyObject *key, *value;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000348{
Roger E. Massed9240d11997-01-16 22:05:33 +0000349 int status;
350 DBT krec, drec;
351 char *data;
352 int size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000353
Roger E. Massed9240d11997-01-16 22:05:33 +0000354 if (!PyArg_Parse(key, "s#", &data, &size)) {
355 PyErr_SetString(PyExc_TypeError,
356 "bsddb key type must be string");
357 return -1;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000358 }
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000359 if (dp->di_bsddb == NULL) {
360 PyErr_SetString(BsddbError, "BSDDB object has already been closed");
361 return -1;
362 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000363 krec.data = data;
364 krec.size = size;
365 dp->di_size = -1;
366 if (value == NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000367 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000368 status = (dp->di_bsddb->del)(dp->di_bsddb, &krec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000369 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000370 }
371 else {
372 if (!PyArg_Parse(value, "s#", &data, &size)) {
373 PyErr_SetString(PyExc_TypeError,
374 "bsddb value type must be string");
375 return -1;
376 }
377 drec.data = data;
378 drec.size = size;
379#if 0
380 /* For RECNO, put fails with 'No space left on device'
381 after a few short records are added?? Looks fine
382 to this point... linked with 1.85 on Solaris Intel
383 Roger E. Masse 1/16/97
384 */
385 printf("before put data: '%s', size: %d\n",
386 drec.data, drec.size);
387 printf("before put key= '%s', size= %d\n",
388 krec.data, krec.size);
389#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000390 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000391 status = (dp->di_bsddb->put)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000392 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000393 }
394 if (status != 0) {
395 if (status < 0)
396 PyErr_SetFromErrno(BsddbError);
397 else
398 PyErr_SetObject(PyExc_KeyError, key);
399 return -1;
400 }
401 return 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000402}
403
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000404static PyMappingMethods bsddb_as_mapping = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000405 (inquiry)bsddb_length, /*mp_length*/
406 (binaryfunc)bsddb_subscript, /*mp_subscript*/
407 (objobjargproc)bsddb_ass_sub, /*mp_ass_subscript*/
Guido van Rossum1100dca1995-08-30 23:43:03 +0000408};
409
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000410static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000411bsddb_close(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000412 bsddbobject *dp;
413 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000414{
Roger E. Massed9240d11997-01-16 22:05:33 +0000415 if (!PyArg_NoArgs(args))
416 return NULL;
417 if (dp->di_bsddb != NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000418 int status;
419 BSDDB_BGN_SAVE(dp)
420 status = (dp->di_bsddb->close)(dp->di_bsddb);
421 BSDDB_END_SAVE(dp)
422 if (status != 0) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000423 dp->di_bsddb = NULL;
424 PyErr_SetFromErrno(BsddbError);
425 return NULL;
426 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000427 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000428 dp->di_bsddb = NULL;
429 Py_INCREF(Py_None);
430 return Py_None;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000431}
432
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000433static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000434bsddb_keys(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000435 bsddbobject *dp;
436 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000437{
Roger E. Massed9240d11997-01-16 22:05:33 +0000438 PyObject *list, *item;
439 DBT krec, drec;
Guido van Rossum730806d1998-04-10 22:27:42 +0000440 char *data=NULL,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000441 int status;
442 int err;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000443
Roger E. Massed9240d11997-01-16 22:05:33 +0000444 if (!PyArg_NoArgs(args))
445 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000446 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000447 list = PyList_New(0);
448 if (list == NULL)
449 return NULL;
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_FIRST);
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)
458 while (status == 0) {
459 item = PyString_FromStringAndSize(data, (int)krec.size);
460 if (data != buf) free(data);
Roger E. Massed9240d11997-01-16 22:05:33 +0000461 if (item == NULL) {
462 Py_DECREF(list);
463 return NULL;
464 }
465 err = PyList_Append(list, item);
466 Py_DECREF(item);
467 if (err != 0) {
468 Py_DECREF(list);
469 return NULL;
470 }
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000471 BSDDB_BGN_SAVE(dp)
472 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_NEXT);
473 if (status == 0) {
474 if (krec.size > sizeof(buf)) data = malloc(krec.size);
475 else data = buf;
476 memcpy(data,krec.data,krec.size);
477 }
478 BSDDB_END_SAVE(dp)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000479 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000480 if (status < 0) {
481 PyErr_SetFromErrno(BsddbError);
482 Py_DECREF(list);
483 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000484 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000485 if (dp->di_size < 0)
486 dp->di_size = PyList_Size(list); /* We just did the work */
487 return list;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000488}
489
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000490static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000491bsddb_has_key(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000492 bsddbobject *dp;
493 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000494{
Roger E. Massed9240d11997-01-16 22:05:33 +0000495 DBT krec, drec;
496 int status;
497 char *data;
498 int size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000499
Roger E. Massed9240d11997-01-16 22:05:33 +0000500 if (!PyArg_Parse(args, "s#", &data, &size))
501 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000502 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000503 krec.data = data;
504 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000505
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000506 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000507 status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000508 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000509 if (status < 0) {
510 PyErr_SetFromErrno(BsddbError);
511 return NULL;
512 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000513
Roger E. Massed9240d11997-01-16 22:05:33 +0000514 return PyInt_FromLong(status == 0);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000515}
516
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000517static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000518bsddb_set_location(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000519 bsddbobject *dp;
520 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000521{
Roger E. Massed9240d11997-01-16 22:05:33 +0000522 int status;
523 DBT krec, drec;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000524 char *data,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000525 int size;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000526 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000527
Roger E. Massed9240d11997-01-16 22:05:33 +0000528 if (!PyArg_Parse(key, "s#", &data, &size))
529 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000530 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000531 krec.data = data;
532 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000533
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000534 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000535 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_CURSOR);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000536 if (status == 0) {
537 if (drec.size > sizeof(buf)) data = malloc(drec.size);
538 else data = buf;
539 memcpy(data,drec.data,drec.size);
540 }
541 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000542 if (status != 0) {
543 if (status < 0)
544 PyErr_SetFromErrno(BsddbError);
545 else
546 PyErr_SetObject(PyExc_KeyError, key);
547 return NULL;
548 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000549
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000550 result = Py_BuildValue("s#s#", krec.data, krec.size, data, drec.size);
551 if (data != buf) free(data);
552 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000553}
554
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000555static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000556bsddb_seq(dp, args, sequence_request)
Roger E. Massed9240d11997-01-16 22:05:33 +0000557 bsddbobject *dp;
558 PyObject *args;
559 int sequence_request;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000560{
Roger E. Massed9240d11997-01-16 22:05:33 +0000561 int status;
562 DBT krec, drec;
Guido van Rossum730806d1998-04-10 22:27:42 +0000563 char *kdata=NULL,kbuf[4096];
564 char *ddata=NULL,dbuf[4096];
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000565 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000566
Roger E. Massed9240d11997-01-16 22:05:33 +0000567 if (!PyArg_NoArgs(args))
568 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000569
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000570 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000571 krec.data = 0;
572 krec.size = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000573
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000574 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000575 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec,
576 &drec, sequence_request);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000577 if (status == 0) {
578 if (krec.size > sizeof(kbuf)) kdata = malloc(krec.size);
579 else kdata = kbuf;
580 memcpy(kdata,krec.data,krec.size);
581 if (drec.size > sizeof(dbuf)) ddata = malloc(drec.size);
582 else ddata = dbuf;
583 memcpy(ddata,drec.data,drec.size);
584 }
585 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000586 if (status != 0) {
587 if (status < 0)
588 PyErr_SetFromErrno(BsddbError);
589 else
590 PyErr_SetObject(PyExc_KeyError, args);
591 return NULL;
592 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000593
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000594 result = Py_BuildValue("s#s#", kdata, krec.size, ddata, drec.size);
595 if (kdata != kbuf) free(kdata);
596 if (ddata != dbuf) free(ddata);
597 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000598}
599
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000600static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000601bsddb_next(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_NEXT);
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_previous(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000609 bsddbobject *dp;
610 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000611{
Roger E. Massed9240d11997-01-16 22:05:33 +0000612 return bsddb_seq(dp, key, R_PREV);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000613}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000614static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000615bsddb_first(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000616 bsddbobject *dp;
617 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000618{
Roger E. Massed9240d11997-01-16 22:05:33 +0000619 return bsddb_seq(dp, key, R_FIRST);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000620}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000621static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000622bsddb_last(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000623 bsddbobject *dp;
624 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000625{
Roger E. Massed9240d11997-01-16 22:05:33 +0000626 return bsddb_seq(dp, key, R_LAST);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000627}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000628static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000629bsddb_sync(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000630 bsddbobject *dp;
631 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000632{
Roger E. Massed9240d11997-01-16 22:05:33 +0000633 int status;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000634
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000635 if (!PyArg_NoArgs(args))
636 return NULL;
637 check_bsddbobject_open(dp);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000638 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000639 status = (dp->di_bsddb->sync)(dp->di_bsddb, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000640 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000641 if (status != 0) {
642 PyErr_SetFromErrno(BsddbError);
643 return NULL;
644 }
645 return PyInt_FromLong(status = 0);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000646}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000647static PyMethodDef bsddb_methods[] = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000648 {"close", (PyCFunction)bsddb_close},
649 {"keys", (PyCFunction)bsddb_keys},
650 {"has_key", (PyCFunction)bsddb_has_key},
651 {"set_location", (PyCFunction)bsddb_set_location},
652 {"next", (PyCFunction)bsddb_next},
653 {"previous", (PyCFunction)bsddb_previous},
654 {"first", (PyCFunction)bsddb_first},
655 {"last", (PyCFunction)bsddb_last},
656 {"sync", (PyCFunction)bsddb_sync},
657 {NULL, NULL} /* sentinel */
Guido van Rossum1100dca1995-08-30 23:43:03 +0000658};
659
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000660static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000661bsddb_getattr(dp, name)
Roger E. Massed9240d11997-01-16 22:05:33 +0000662 PyObject *dp;
663 char *name;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000664{
Roger E. Massed9240d11997-01-16 22:05:33 +0000665 return Py_FindMethod(bsddb_methods, dp, name);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000666}
667
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000668static PyTypeObject Bsddbtype = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000669 PyObject_HEAD_INIT(NULL)
670 0,
671 "bsddb",
672 sizeof(bsddbobject),
673 0,
674 (destructor)bsddb_dealloc, /*tp_dealloc*/
675 0, /*tp_print*/
676 (getattrfunc)bsddb_getattr, /*tp_getattr*/
677 0, /*tp_setattr*/
678 0, /*tp_compare*/
679 0, /*tp_repr*/
680 0, /*tp_as_number*/
681 0, /*tp_as_sequence*/
682 &bsddb_as_mapping, /*tp_as_mapping*/
Guido van Rossum1100dca1995-08-30 23:43:03 +0000683};
684
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000685static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000686bsdhashopen(self, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000687 PyObject *self;
688 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000689{
Roger E. Massed9240d11997-01-16 22:05:33 +0000690 char *file;
691 char *flag = NULL;
692 int flags = O_RDONLY;
693 int mode = 0666;
694 int bsize = 0;
695 int ffactor = 0;
696 int nelem = 0;
697 int cachesize = 0;
698 int hash = 0; /* XXX currently ignored */
699 int lorder = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000700
Guido van Rossum43713e52000-02-29 13:59:29 +0000701 if (!PyArg_ParseTuple(args, "s|siiiiiii:hashopen",
Roger E. Massed9240d11997-01-16 22:05:33 +0000702 &file, &flag, &mode,
703 &bsize, &ffactor, &nelem, &cachesize,
704 &hash, &lorder))
705 return NULL;
706 if (flag != NULL) {
707 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
708 if (flag[0] == 'r')
709 flags = O_RDONLY;
710 else if (flag[0] == 'w')
711 flags = O_RDWR;
712 else if (flag[0] == 'c')
713 flags = O_RDWR|O_CREAT;
714 else if (flag[0] == 'n')
715 flags = O_RDWR|O_CREAT|O_TRUNC;
716 else {
717 PyErr_SetString(BsddbError,
718 "Flag should begin with 'r', 'w', 'c' or 'n'");
719 return NULL;
720 }
721 if (flag[1] == 'l') {
Guido van Rossum1100dca1995-08-30 23:43:03 +0000722#if defined(O_EXLOCK) && defined(O_SHLOCK)
Roger E. Massed9240d11997-01-16 22:05:33 +0000723 if (flag[0] == 'r')
724 flags |= O_SHLOCK;
725 else
726 flags |= O_EXLOCK;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000727#else
Roger E. Massed9240d11997-01-16 22:05:33 +0000728 PyErr_SetString(BsddbError,
729 "locking not supported on this platform");
730 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000731#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000732 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000733 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000734 return newdbhashobject(file, flags, mode,
735 bsize, ffactor, nelem, cachesize, hash, lorder);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000736}
737
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000738static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000739bsdbtopen(self, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000740 PyObject *self;
741 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000742{
Roger E. Massed9240d11997-01-16 22:05:33 +0000743 char *file;
744 char *flag = NULL;
745 int flags = O_RDONLY;
746 int mode = 0666;
747 int cachesize = 0;
748 int maxkeypage = 0;
749 int minkeypage = 0;
750 int btflags = 0;
751 unsigned int psize = 0;
752 int lorder = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000753
Guido van Rossum43713e52000-02-29 13:59:29 +0000754 if (!PyArg_ParseTuple(args, "s|siiiiiii:btopen",
Roger E. Massed9240d11997-01-16 22:05:33 +0000755 &file, &flag, &mode,
756 &btflags, &cachesize, &maxkeypage, &minkeypage,
757 &psize, &lorder))
758 return NULL;
759 if (flag != NULL) {
760 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
761 if (flag[0] == 'r')
762 flags = O_RDONLY;
763 else if (flag[0] == 'w')
764 flags = O_RDWR;
765 else if (flag[0] == 'c')
766 flags = O_RDWR|O_CREAT;
767 else if (flag[0] == 'n')
768 flags = O_RDWR|O_CREAT|O_TRUNC;
769 else {
770 PyErr_SetString(BsddbError,
771 "Flag should begin with 'r', 'w', 'c' or 'n'");
772 return NULL;
773 }
774 if (flag[1] == 'l') {
Guido van Rossum1100dca1995-08-30 23:43:03 +0000775#if defined(O_EXLOCK) && defined(O_SHLOCK)
Roger E. Massed9240d11997-01-16 22:05:33 +0000776 if (flag[0] == 'r')
777 flags |= O_SHLOCK;
778 else
779 flags |= O_EXLOCK;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000780#else
Roger E. Massed9240d11997-01-16 22:05:33 +0000781 PyErr_SetString(BsddbError,
782 "locking not supported on this platform");
783 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000784#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000785 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000786 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000787 return newdbbtobject(file, flags, mode,
788 btflags, cachesize, maxkeypage, minkeypage,
789 psize, lorder);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000790}
Guido van Rossumdd96ca71996-05-23 22:57:54 +0000791
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000792static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000793bsdrnopen(self, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000794 PyObject *self;
795 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000796{
Roger E. Massed9240d11997-01-16 22:05:33 +0000797 char *file;
798 char *flag = NULL;
799 int flags = O_RDONLY;
800 int mode = 0666;
801 int cachesize = 0;
802 int rnflags = 0;
803 unsigned int psize = 0;
804 int lorder = 0;
805 size_t reclen = 0;
806 char *bval = "";
807 char *bfname = NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000808
Guido van Rossum43713e52000-02-29 13:59:29 +0000809 if (!PyArg_ParseTuple(args, "s|siiiiiiss:rnopen",
Roger E. Massed9240d11997-01-16 22:05:33 +0000810 &file, &flag, &mode,
811 &rnflags, &cachesize, &psize, &lorder,
812 &reclen, &bval, &bfname))
813 return NULL;
814
815# if 0
816 printf("file: %s\n", file);
817 printf("flag: %s\n", flag);
818 printf("mode: %d\n", mode);
819 printf("rnflags: 0x%x\n", rnflags);
820 printf("cachesize: %d\n", cachesize);
821 printf("psize: %d\n", psize);
822 printf("lorder: %d\n", 0);
823 printf("reclen: %d\n", reclen);
824 printf("bval: %c\n", bval[0]);
825 printf("bfname %s\n", bfname);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000826#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000827
828 if (flag != NULL) {
829 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
830 if (flag[0] == 'r')
831 flags = O_RDONLY;
832 else if (flag[0] == 'w')
833 flags = O_RDWR;
834 else if (flag[0] == 'c')
835 flags = O_RDWR|O_CREAT;
836 else if (flag[0] == 'n')
837 flags = O_RDWR|O_CREAT|O_TRUNC;
838 else {
839 PyErr_SetString(BsddbError,
840 "Flag should begin with 'r', 'w', 'c' or 'n'");
841 return NULL;
842 }
843 if (flag[1] == 'l') {
844#if defined(O_EXLOCK) && defined(O_SHLOCK)
845 if (flag[0] == 'r')
846 flags |= O_SHLOCK;
847 else
848 flags |= O_EXLOCK;
849#else
850 PyErr_SetString(BsddbError,
851 "locking not supported on this platform");
852 return NULL;
853#endif
854 }
855 else if (flag[1] != '\0') {
856 PyErr_SetString(BsddbError,
857 "Flag char 2 should be 'l' or absent");
858 return NULL;
859 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000860 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000861 return newdbrnobject(file, flags, mode, rnflags, cachesize,
862 psize, lorder, reclen, bval[0], bfname);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000863}
864
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000865static PyMethodDef bsddbmodule_methods[] = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000866 {"hashopen", (PyCFunction)bsdhashopen, 1},
867 {"btopen", (PyCFunction)bsdbtopen, 1},
868 {"rnopen", (PyCFunction)bsdrnopen, 1},
869 {0, 0},
Guido van Rossum1100dca1995-08-30 23:43:03 +0000870};
871
Guido van Rossum3886bb61998-12-04 18:50:17 +0000872DL_EXPORT(void)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000873initbsddb() {
Roger E. Massed9240d11997-01-16 22:05:33 +0000874 PyObject *m, *d;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000875
Roger E. Massed9240d11997-01-16 22:05:33 +0000876 Bsddbtype.ob_type = &PyType_Type;
877 m = Py_InitModule("bsddb", bsddbmodule_methods);
878 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000879 BsddbError = PyErr_NewException("bsddb.error", NULL, NULL);
880 if (BsddbError != NULL)
881 PyDict_SetItemString(d, "error", BsddbError);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000882}