blob: 97a8e8be4341e7195481bf6693e017b61ea5efc8 [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>
54#include <db.h>
55/* Please don't include internal header files of the Berkeley db package
56 (it messes up the info required in the Setup file) */
57
58typedef struct {
Roger E. Massed9240d11997-01-16 22:05:33 +000059 PyObject_HEAD
60 DB *di_bsddb;
61 int di_size; /* -1 means recompute */
Guido van Rossum4f199ea1998-04-09 20:56:35 +000062#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +000063 PyThread_type_lock di_lock;
Guido van Rossum4f199ea1998-04-09 20:56:35 +000064#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +000065} bsddbobject;
66
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000067staticforward PyTypeObject Bsddbtype;
Guido van Rossum1100dca1995-08-30 23:43:03 +000068
69#define is_bsddbobject(v) ((v)->ob_type == &Bsddbtype)
Guido van Rossum77eecfa1997-07-17 22:56:01 +000070#define check_bsddbobject_open(v) if ((v)->di_bsddb == NULL) \
71 { PyErr_SetString(BsddbError, "BSDDB object has already been closed"); \
72 return NULL; }
Guido van Rossum1100dca1995-08-30 23:43:03 +000073
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000074static PyObject *BsddbError;
Guido van Rossum1100dca1995-08-30 23:43:03 +000075
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000076static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +000077newdbhashobject(file, flags, mode,
78 bsize, ffactor, nelem, cachesize, hash, lorder)
Roger E. Massed9240d11997-01-16 22:05:33 +000079 char *file;
80 int flags;
81 int mode;
82 int bsize;
83 int ffactor;
84 int nelem;
85 int cachesize;
86 int hash; /* XXX ignored */
87 int lorder;
Guido van Rossum1100dca1995-08-30 23:43:03 +000088{
Roger E. Massed9240d11997-01-16 22:05:33 +000089 bsddbobject *dp;
90 HASHINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +000091
Guido van Rossumb18618d2000-05-03 23:44:39 +000092 if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
Roger E. Massed9240d11997-01-16 22:05:33 +000093 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +000094
Roger E. Massed9240d11997-01-16 22:05:33 +000095 info.bsize = bsize;
96 info.ffactor = ffactor;
97 info.nelem = nelem;
98 info.cachesize = cachesize;
99 info.hash = NULL; /* XXX should derive from hash argument */
100 info.lorder = lorder;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000101
Guido van Rossum6beb4791996-09-11 23:22:25 +0000102#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +0000103 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +0000104#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000105 Py_BEGIN_ALLOW_THREADS
106 dp->di_bsddb = dbopen(file, flags, mode, DB_HASH, &info);
107 Py_END_ALLOW_THREADS
108 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000109 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000110#ifdef WITH_THREAD
111 dp->di_lock = NULL;
112#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000113 Py_DECREF(dp);
114 return NULL;
115 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000116
Roger E. Massed9240d11997-01-16 22:05:33 +0000117 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000118#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000119 dp->di_lock = PyThread_allocate_lock();
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000120 if (dp->di_lock == NULL) {
121 PyErr_SetString(BsddbError, "can't allocate lock");
122 Py_DECREF(dp);
123 return NULL;
124 }
125#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000126
Roger E. Massed9240d11997-01-16 22:05:33 +0000127 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000128}
129
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000130static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000131newdbbtobject(file, flags, mode,
Roger E. Massed9240d11997-01-16 22:05:33 +0000132 btflags, cachesize, maxkeypage, minkeypage, psize, lorder)
133 char *file;
134 int flags;
135 int mode;
136 int btflags;
137 int cachesize;
138 int maxkeypage;
139 int minkeypage;
140 int psize;
141 int lorder;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000142{
Roger E. Massed9240d11997-01-16 22:05:33 +0000143 bsddbobject *dp;
144 BTREEINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000145
Guido van Rossumb18618d2000-05-03 23:44:39 +0000146 if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
Roger E. Massed9240d11997-01-16 22:05:33 +0000147 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000148
Roger E. Massed9240d11997-01-16 22:05:33 +0000149 info.flags = btflags;
150 info.cachesize = cachesize;
151 info.maxkeypage = maxkeypage;
152 info.minkeypage = minkeypage;
153 info.psize = psize;
154 info.lorder = lorder;
155 info.compare = 0; /* Use default comparison functions, for now..*/
156 info.prefix = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000157
Guido van Rossum6beb4791996-09-11 23:22:25 +0000158#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +0000159 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +0000160#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000161 Py_BEGIN_ALLOW_THREADS
162 dp->di_bsddb = dbopen(file, flags, mode, DB_BTREE, &info);
163 Py_END_ALLOW_THREADS
164 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000165 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000166#ifdef WITH_THREAD
167 dp->di_lock = NULL;
168#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000169 Py_DECREF(dp);
170 return NULL;
171 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000172
Roger E. Massed9240d11997-01-16 22:05:33 +0000173 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000174#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000175 dp->di_lock = PyThread_allocate_lock();
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000176 if (dp->di_lock == NULL) {
177 PyErr_SetString(BsddbError, "can't allocate lock");
178 Py_DECREF(dp);
179 return NULL;
180 }
181#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000182
Roger E. Massed9240d11997-01-16 22:05:33 +0000183 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000184}
185
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000186static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000187newdbrnobject(file, flags, mode,
Roger E. Massed9240d11997-01-16 22:05:33 +0000188 rnflags, cachesize, psize, lorder, reclen, bval, bfname)
189 char *file;
190 int flags;
191 int mode;
192 int rnflags;
193 int cachesize;
194 int psize;
195 int lorder;
196 size_t reclen;
197 u_char bval;
198 char *bfname;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000199{
Roger E. Massed9240d11997-01-16 22:05:33 +0000200 bsddbobject *dp;
201 RECNOINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000202
Guido van Rossumb18618d2000-05-03 23:44:39 +0000203 if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
Roger E. Massed9240d11997-01-16 22:05:33 +0000204 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000205
Roger E. Massed9240d11997-01-16 22:05:33 +0000206 info.flags = rnflags;
207 info.cachesize = cachesize;
208 info.psize = psize;
209 info.lorder = lorder;
210 info.reclen = reclen;
211 info.bval = bval;
212 info.bfname = bfname;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000213
Guido van Rossum6beb4791996-09-11 23:22:25 +0000214#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +0000215 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +0000216#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000217 Py_BEGIN_ALLOW_THREADS
218 dp->di_bsddb = dbopen(file, flags, mode, DB_RECNO, &info);
219 Py_END_ALLOW_THREADS
220 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000221 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000222#ifdef WITH_THREAD
223 dp->di_lock = NULL;
224#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000225 Py_DECREF(dp);
226 return NULL;
227 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000228
Roger E. Massed9240d11997-01-16 22:05:33 +0000229 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000230#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000231 dp->di_lock = PyThread_allocate_lock();
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000232 if (dp->di_lock == NULL) {
233 PyErr_SetString(BsddbError, "can't allocate lock");
234 Py_DECREF(dp);
235 return NULL;
236 }
237#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000238
Roger E. Massed9240d11997-01-16 22:05:33 +0000239 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000240}
241
Guido van Rossum1100dca1995-08-30 23:43:03 +0000242static void
243bsddb_dealloc(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000244 bsddbobject *dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000245{
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000246#ifdef WITH_THREAD
247 if (dp->di_lock) {
Guido van Rossum65d5b571998-12-21 19:32:43 +0000248 PyThread_acquire_lock(dp->di_lock, 0);
249 PyThread_release_lock(dp->di_lock);
250 PyThread_free_lock(dp->di_lock);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000251 dp->di_lock = NULL;
252 }
253#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000254 if (dp->di_bsddb != NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000255 int status;
256 Py_BEGIN_ALLOW_THREADS
257 status = (dp->di_bsddb->close)(dp->di_bsddb);
258 Py_END_ALLOW_THREADS
259 if (status != 0)
Roger E. Massed9240d11997-01-16 22:05:33 +0000260 fprintf(stderr,
261 "Python bsddb: close errno %d in dealloc\n",
262 errno);
263 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000264 PyObject_Del(dp);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000265}
266
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000267#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000268#define BSDDB_BGN_SAVE(_dp) Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(_dp->di_lock,1);
269#define BSDDB_END_SAVE(_dp) PyThread_release_lock(_dp->di_lock); Py_END_ALLOW_THREADS
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000270#else
271#define BSDDB_BGN_SAVE(_dp) Py_BEGIN_ALLOW_THREADS
272#define BSDDB_END_SAVE(_dp) Py_END_ALLOW_THREADS
273#endif
274
Guido van Rossum1100dca1995-08-30 23:43:03 +0000275static int
276bsddb_length(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000277 bsddbobject *dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000278{
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000279 if (dp->di_bsddb == NULL) {
280 PyErr_SetString(BsddbError, "BSDDB object has already been closed");
281 return -1;
282 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000283 if (dp->di_size < 0) {
284 DBT krec, drec;
285 int status;
286 int size = 0;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000287 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000288 for (status = (dp->di_bsddb->seq)(dp->di_bsddb,
289 &krec, &drec,R_FIRST);
290 status == 0;
291 status = (dp->di_bsddb->seq)(dp->di_bsddb,
292 &krec, &drec, R_NEXT))
293 size++;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000294 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000295 if (status < 0) {
296 PyErr_SetFromErrno(BsddbError);
297 return -1;
298 }
299 dp->di_size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000300 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000301 return dp->di_size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000302}
303
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000304static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000305bsddb_subscript(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000306 bsddbobject *dp;
307 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000308{
Roger E. Massed9240d11997-01-16 22:05:33 +0000309 int status;
310 DBT krec, drec;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000311 char *data,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000312 int size;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000313 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000314
Roger E. Massed9240d11997-01-16 22:05:33 +0000315 if (!PyArg_Parse(key, "s#", &data, &size))
316 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000317 check_bsddbobject_open(dp);
318
Roger E. Massed9240d11997-01-16 22:05:33 +0000319 krec.data = data;
320 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000321
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000322 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000323 status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000324 if (status == 0) {
325 if (drec.size > sizeof(buf)) data = malloc(drec.size);
326 else data = buf;
327 memcpy(data,drec.data,drec.size);
328 }
329 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000330 if (status != 0) {
331 if (status < 0)
332 PyErr_SetFromErrno(BsddbError);
333 else
334 PyErr_SetObject(PyExc_KeyError, key);
335 return NULL;
336 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000337
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000338 result = PyString_FromStringAndSize(data, (int)drec.size);
339 if (data != buf) free(data);
340 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000341}
342
343static int
344bsddb_ass_sub(dp, key, value)
Roger E. Massed9240d11997-01-16 22:05:33 +0000345 bsddbobject *dp;
346 PyObject *key, *value;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000347{
Roger E. Massed9240d11997-01-16 22:05:33 +0000348 int status;
349 DBT krec, drec;
350 char *data;
351 int size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000352
Roger E. Massed9240d11997-01-16 22:05:33 +0000353 if (!PyArg_Parse(key, "s#", &data, &size)) {
354 PyErr_SetString(PyExc_TypeError,
355 "bsddb key type must be string");
356 return -1;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000357 }
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000358 if (dp->di_bsddb == NULL) {
359 PyErr_SetString(BsddbError, "BSDDB object has already been closed");
360 return -1;
361 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000362 krec.data = data;
363 krec.size = size;
364 dp->di_size = -1;
365 if (value == NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000366 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000367 status = (dp->di_bsddb->del)(dp->di_bsddb, &krec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000368 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000369 }
370 else {
371 if (!PyArg_Parse(value, "s#", &data, &size)) {
372 PyErr_SetString(PyExc_TypeError,
373 "bsddb value type must be string");
374 return -1;
375 }
376 drec.data = data;
377 drec.size = size;
378#if 0
379 /* For RECNO, put fails with 'No space left on device'
380 after a few short records are added?? Looks fine
381 to this point... linked with 1.85 on Solaris Intel
382 Roger E. Masse 1/16/97
383 */
384 printf("before put data: '%s', size: %d\n",
385 drec.data, drec.size);
386 printf("before put key= '%s', size= %d\n",
387 krec.data, krec.size);
388#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000389 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000390 status = (dp->di_bsddb->put)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000391 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000392 }
393 if (status != 0) {
394 if (status < 0)
395 PyErr_SetFromErrno(BsddbError);
396 else
397 PyErr_SetObject(PyExc_KeyError, key);
398 return -1;
399 }
400 return 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000401}
402
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000403static PyMappingMethods bsddb_as_mapping = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000404 (inquiry)bsddb_length, /*mp_length*/
405 (binaryfunc)bsddb_subscript, /*mp_subscript*/
406 (objobjargproc)bsddb_ass_sub, /*mp_ass_subscript*/
Guido van Rossum1100dca1995-08-30 23:43:03 +0000407};
408
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000409static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000410bsddb_close(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000411 bsddbobject *dp;
412 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000413{
Roger E. Massed9240d11997-01-16 22:05:33 +0000414 if (!PyArg_NoArgs(args))
415 return NULL;
416 if (dp->di_bsddb != NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000417 int status;
418 BSDDB_BGN_SAVE(dp)
419 status = (dp->di_bsddb->close)(dp->di_bsddb);
420 BSDDB_END_SAVE(dp)
421 if (status != 0) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000422 dp->di_bsddb = NULL;
423 PyErr_SetFromErrno(BsddbError);
424 return NULL;
425 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000426 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000427 dp->di_bsddb = NULL;
428 Py_INCREF(Py_None);
429 return Py_None;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000430}
431
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000432static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000433bsddb_keys(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000434 bsddbobject *dp;
435 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000436{
Roger E. Massed9240d11997-01-16 22:05:33 +0000437 PyObject *list, *item;
438 DBT krec, drec;
Guido van Rossum730806d1998-04-10 22:27:42 +0000439 char *data=NULL,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000440 int status;
441 int err;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000442
Roger E. Massed9240d11997-01-16 22:05:33 +0000443 if (!PyArg_NoArgs(args))
444 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000445 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000446 list = PyList_New(0);
447 if (list == NULL)
448 return NULL;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000449 BSDDB_BGN_SAVE(dp)
450 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_FIRST);
451 if (status == 0) {
452 if (krec.size > sizeof(buf)) data = malloc(krec.size);
453 else data = buf;
454 memcpy(data,krec.data,krec.size);
455 }
456 BSDDB_END_SAVE(dp)
457 while (status == 0) {
458 item = PyString_FromStringAndSize(data, (int)krec.size);
459 if (data != buf) free(data);
Roger E. Massed9240d11997-01-16 22:05:33 +0000460 if (item == NULL) {
461 Py_DECREF(list);
462 return NULL;
463 }
464 err = PyList_Append(list, item);
465 Py_DECREF(item);
466 if (err != 0) {
467 Py_DECREF(list);
468 return NULL;
469 }
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000470 BSDDB_BGN_SAVE(dp)
471 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_NEXT);
472 if (status == 0) {
473 if (krec.size > sizeof(buf)) data = malloc(krec.size);
474 else data = buf;
475 memcpy(data,krec.data,krec.size);
476 }
477 BSDDB_END_SAVE(dp)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000478 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000479 if (status < 0) {
480 PyErr_SetFromErrno(BsddbError);
481 Py_DECREF(list);
482 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000483 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000484 if (dp->di_size < 0)
485 dp->di_size = PyList_Size(list); /* We just did the work */
486 return list;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000487}
488
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000489static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000490bsddb_has_key(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000491 bsddbobject *dp;
492 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000493{
Roger E. Massed9240d11997-01-16 22:05:33 +0000494 DBT krec, drec;
495 int status;
496 char *data;
497 int size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000498
Roger E. Massed9240d11997-01-16 22:05:33 +0000499 if (!PyArg_Parse(args, "s#", &data, &size))
500 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000501 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000502 krec.data = data;
503 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000504
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000505 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000506 status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000507 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000508 if (status < 0) {
509 PyErr_SetFromErrno(BsddbError);
510 return NULL;
511 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000512
Roger E. Massed9240d11997-01-16 22:05:33 +0000513 return PyInt_FromLong(status == 0);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000514}
515
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000516static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000517bsddb_set_location(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000518 bsddbobject *dp;
519 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000520{
Roger E. Massed9240d11997-01-16 22:05:33 +0000521 int status;
522 DBT krec, drec;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000523 char *data,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000524 int size;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000525 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000526
Roger E. Massed9240d11997-01-16 22:05:33 +0000527 if (!PyArg_Parse(key, "s#", &data, &size))
528 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000529 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000530 krec.data = data;
531 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000532
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000533 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000534 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_CURSOR);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000535 if (status == 0) {
536 if (drec.size > sizeof(buf)) data = malloc(drec.size);
537 else data = buf;
538 memcpy(data,drec.data,drec.size);
539 }
540 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000541 if (status != 0) {
542 if (status < 0)
543 PyErr_SetFromErrno(BsddbError);
544 else
545 PyErr_SetObject(PyExc_KeyError, key);
546 return NULL;
547 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000548
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000549 result = Py_BuildValue("s#s#", krec.data, krec.size, data, drec.size);
550 if (data != buf) free(data);
551 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000552}
553
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000554static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000555bsddb_seq(dp, args, sequence_request)
Roger E. Massed9240d11997-01-16 22:05:33 +0000556 bsddbobject *dp;
557 PyObject *args;
558 int sequence_request;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000559{
Roger E. Massed9240d11997-01-16 22:05:33 +0000560 int status;
561 DBT krec, drec;
Guido van Rossum730806d1998-04-10 22:27:42 +0000562 char *kdata=NULL,kbuf[4096];
563 char *ddata=NULL,dbuf[4096];
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000564 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000565
Roger E. Massed9240d11997-01-16 22:05:33 +0000566 if (!PyArg_NoArgs(args))
567 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000568
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000569 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000570 krec.data = 0;
571 krec.size = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000572
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000573 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000574 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec,
575 &drec, sequence_request);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000576 if (status == 0) {
577 if (krec.size > sizeof(kbuf)) kdata = malloc(krec.size);
578 else kdata = kbuf;
579 memcpy(kdata,krec.data,krec.size);
580 if (drec.size > sizeof(dbuf)) ddata = malloc(drec.size);
581 else ddata = dbuf;
582 memcpy(ddata,drec.data,drec.size);
583 }
584 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000585 if (status != 0) {
586 if (status < 0)
587 PyErr_SetFromErrno(BsddbError);
588 else
589 PyErr_SetObject(PyExc_KeyError, args);
590 return NULL;
591 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000592
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000593 result = Py_BuildValue("s#s#", kdata, krec.size, ddata, drec.size);
594 if (kdata != kbuf) free(kdata);
595 if (ddata != dbuf) free(ddata);
596 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000597}
598
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000599static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000600bsddb_next(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_NEXT);
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_previous(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_PREV);
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_first(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000615 bsddbobject *dp;
616 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000617{
Roger E. Massed9240d11997-01-16 22:05:33 +0000618 return bsddb_seq(dp, key, R_FIRST);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000619}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000620static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000621bsddb_last(dp, key)
Roger E. Massed9240d11997-01-16 22:05:33 +0000622 bsddbobject *dp;
623 PyObject *key;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000624{
Roger E. Massed9240d11997-01-16 22:05:33 +0000625 return bsddb_seq(dp, key, R_LAST);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000626}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000627static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000628bsddb_sync(dp, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000629 bsddbobject *dp;
630 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000631{
Roger E. Massed9240d11997-01-16 22:05:33 +0000632 int status;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000633
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000634 if (!PyArg_NoArgs(args))
635 return NULL;
636 check_bsddbobject_open(dp);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000637 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000638 status = (dp->di_bsddb->sync)(dp->di_bsddb, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000639 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000640 if (status != 0) {
641 PyErr_SetFromErrno(BsddbError);
642 return NULL;
643 }
644 return PyInt_FromLong(status = 0);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000645}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000646static PyMethodDef bsddb_methods[] = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000647 {"close", (PyCFunction)bsddb_close},
648 {"keys", (PyCFunction)bsddb_keys},
649 {"has_key", (PyCFunction)bsddb_has_key},
650 {"set_location", (PyCFunction)bsddb_set_location},
651 {"next", (PyCFunction)bsddb_next},
652 {"previous", (PyCFunction)bsddb_previous},
653 {"first", (PyCFunction)bsddb_first},
654 {"last", (PyCFunction)bsddb_last},
655 {"sync", (PyCFunction)bsddb_sync},
656 {NULL, NULL} /* sentinel */
Guido van Rossum1100dca1995-08-30 23:43:03 +0000657};
658
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000659static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000660bsddb_getattr(dp, name)
Roger E. Massed9240d11997-01-16 22:05:33 +0000661 PyObject *dp;
662 char *name;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000663{
Roger E. Massed9240d11997-01-16 22:05:33 +0000664 return Py_FindMethod(bsddb_methods, dp, name);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000665}
666
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000667static PyTypeObject Bsddbtype = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000668 PyObject_HEAD_INIT(NULL)
669 0,
670 "bsddb",
671 sizeof(bsddbobject),
672 0,
673 (destructor)bsddb_dealloc, /*tp_dealloc*/
674 0, /*tp_print*/
675 (getattrfunc)bsddb_getattr, /*tp_getattr*/
676 0, /*tp_setattr*/
677 0, /*tp_compare*/
678 0, /*tp_repr*/
679 0, /*tp_as_number*/
680 0, /*tp_as_sequence*/
681 &bsddb_as_mapping, /*tp_as_mapping*/
Guido van Rossum1100dca1995-08-30 23:43:03 +0000682};
683
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000684static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000685bsdhashopen(self, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000686 PyObject *self;
687 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000688{
Roger E. Massed9240d11997-01-16 22:05:33 +0000689 char *file;
690 char *flag = NULL;
691 int flags = O_RDONLY;
692 int mode = 0666;
693 int bsize = 0;
694 int ffactor = 0;
695 int nelem = 0;
696 int cachesize = 0;
697 int hash = 0; /* XXX currently ignored */
698 int lorder = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000699
Guido van Rossum43713e52000-02-29 13:59:29 +0000700 if (!PyArg_ParseTuple(args, "s|siiiiiii:hashopen",
Roger E. Massed9240d11997-01-16 22:05:33 +0000701 &file, &flag, &mode,
702 &bsize, &ffactor, &nelem, &cachesize,
703 &hash, &lorder))
704 return NULL;
705 if (flag != NULL) {
706 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
707 if (flag[0] == 'r')
708 flags = O_RDONLY;
709 else if (flag[0] == 'w')
710 flags = O_RDWR;
711 else if (flag[0] == 'c')
712 flags = O_RDWR|O_CREAT;
713 else if (flag[0] == 'n')
714 flags = O_RDWR|O_CREAT|O_TRUNC;
715 else {
716 PyErr_SetString(BsddbError,
717 "Flag should begin with 'r', 'w', 'c' or 'n'");
718 return NULL;
719 }
720 if (flag[1] == 'l') {
Guido van Rossum1100dca1995-08-30 23:43:03 +0000721#if defined(O_EXLOCK) && defined(O_SHLOCK)
Roger E. Massed9240d11997-01-16 22:05:33 +0000722 if (flag[0] == 'r')
723 flags |= O_SHLOCK;
724 else
725 flags |= O_EXLOCK;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000726#else
Roger E. Massed9240d11997-01-16 22:05:33 +0000727 PyErr_SetString(BsddbError,
728 "locking not supported on this platform");
729 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000730#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000731 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000732 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000733 return newdbhashobject(file, flags, mode,
734 bsize, ffactor, nelem, cachesize, hash, lorder);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000735}
736
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000737static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000738bsdbtopen(self, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000739 PyObject *self;
740 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000741{
Roger E. Massed9240d11997-01-16 22:05:33 +0000742 char *file;
743 char *flag = NULL;
744 int flags = O_RDONLY;
745 int mode = 0666;
746 int cachesize = 0;
747 int maxkeypage = 0;
748 int minkeypage = 0;
749 int btflags = 0;
750 unsigned int psize = 0;
751 int lorder = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000752
Guido van Rossum43713e52000-02-29 13:59:29 +0000753 if (!PyArg_ParseTuple(args, "s|siiiiiii:btopen",
Roger E. Massed9240d11997-01-16 22:05:33 +0000754 &file, &flag, &mode,
755 &btflags, &cachesize, &maxkeypage, &minkeypage,
756 &psize, &lorder))
757 return NULL;
758 if (flag != NULL) {
759 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
760 if (flag[0] == 'r')
761 flags = O_RDONLY;
762 else if (flag[0] == 'w')
763 flags = O_RDWR;
764 else if (flag[0] == 'c')
765 flags = O_RDWR|O_CREAT;
766 else if (flag[0] == 'n')
767 flags = O_RDWR|O_CREAT|O_TRUNC;
768 else {
769 PyErr_SetString(BsddbError,
770 "Flag should begin with 'r', 'w', 'c' or 'n'");
771 return NULL;
772 }
773 if (flag[1] == 'l') {
Guido van Rossum1100dca1995-08-30 23:43:03 +0000774#if defined(O_EXLOCK) && defined(O_SHLOCK)
Roger E. Massed9240d11997-01-16 22:05:33 +0000775 if (flag[0] == 'r')
776 flags |= O_SHLOCK;
777 else
778 flags |= O_EXLOCK;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000779#else
Roger E. Massed9240d11997-01-16 22:05:33 +0000780 PyErr_SetString(BsddbError,
781 "locking not supported on this platform");
782 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000783#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000784 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000785 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000786 return newdbbtobject(file, flags, mode,
787 btflags, cachesize, maxkeypage, minkeypage,
788 psize, lorder);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000789}
Guido van Rossumdd96ca71996-05-23 22:57:54 +0000790
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000791static PyObject *
Guido van Rossum1100dca1995-08-30 23:43:03 +0000792bsdrnopen(self, args)
Roger E. Massed9240d11997-01-16 22:05:33 +0000793 PyObject *self;
794 PyObject *args;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000795{
Roger E. Massed9240d11997-01-16 22:05:33 +0000796 char *file;
797 char *flag = NULL;
798 int flags = O_RDONLY;
799 int mode = 0666;
800 int cachesize = 0;
801 int rnflags = 0;
802 unsigned int psize = 0;
803 int lorder = 0;
804 size_t reclen = 0;
805 char *bval = "";
806 char *bfname = NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000807
Guido van Rossum43713e52000-02-29 13:59:29 +0000808 if (!PyArg_ParseTuple(args, "s|siiiiiiss:rnopen",
Roger E. Massed9240d11997-01-16 22:05:33 +0000809 &file, &flag, &mode,
810 &rnflags, &cachesize, &psize, &lorder,
811 &reclen, &bval, &bfname))
812 return NULL;
813
814# if 0
815 printf("file: %s\n", file);
816 printf("flag: %s\n", flag);
817 printf("mode: %d\n", mode);
818 printf("rnflags: 0x%x\n", rnflags);
819 printf("cachesize: %d\n", cachesize);
820 printf("psize: %d\n", psize);
821 printf("lorder: %d\n", 0);
822 printf("reclen: %d\n", reclen);
823 printf("bval: %c\n", bval[0]);
824 printf("bfname %s\n", bfname);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000825#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000826
827 if (flag != NULL) {
828 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
829 if (flag[0] == 'r')
830 flags = O_RDONLY;
831 else if (flag[0] == 'w')
832 flags = O_RDWR;
833 else if (flag[0] == 'c')
834 flags = O_RDWR|O_CREAT;
835 else if (flag[0] == 'n')
836 flags = O_RDWR|O_CREAT|O_TRUNC;
837 else {
838 PyErr_SetString(BsddbError,
839 "Flag should begin with 'r', 'w', 'c' or 'n'");
840 return NULL;
841 }
842 if (flag[1] == 'l') {
843#if defined(O_EXLOCK) && defined(O_SHLOCK)
844 if (flag[0] == 'r')
845 flags |= O_SHLOCK;
846 else
847 flags |= O_EXLOCK;
848#else
849 PyErr_SetString(BsddbError,
850 "locking not supported on this platform");
851 return NULL;
852#endif
853 }
854 else if (flag[1] != '\0') {
855 PyErr_SetString(BsddbError,
856 "Flag char 2 should be 'l' or absent");
857 return NULL;
858 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000859 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000860 return newdbrnobject(file, flags, mode, rnflags, cachesize,
861 psize, lorder, reclen, bval[0], bfname);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000862}
863
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000864static PyMethodDef bsddbmodule_methods[] = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000865 {"hashopen", (PyCFunction)bsdhashopen, 1},
866 {"btopen", (PyCFunction)bsdbtopen, 1},
867 {"rnopen", (PyCFunction)bsdrnopen, 1},
868 {0, 0},
Guido van Rossum1100dca1995-08-30 23:43:03 +0000869};
870
Guido van Rossum3886bb61998-12-04 18:50:17 +0000871DL_EXPORT(void)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000872initbsddb() {
Roger E. Massed9240d11997-01-16 22:05:33 +0000873 PyObject *m, *d;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000874
Roger E. Massed9240d11997-01-16 22:05:33 +0000875 Bsddbtype.ob_type = &PyType_Type;
876 m = Py_InitModule("bsddb", bsddbmodule_methods);
877 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000878 BsddbError = PyErr_NewException("bsddb.error", NULL, NULL);
879 if (BsddbError != NULL)
880 PyDict_SetItemString(d, "error", BsddbError);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000881}