blob: 7aed1fe1de1b5c5396cccc73534f837bf8e4b618 [file] [log] [blame]
Guido van Rossum1100dca1995-08-30 23:43:03 +00001/* Berkeley DB interface.
2 Author: Michael McLay
3 Hacked: Guido van Rossum
4 Btree and Recno additions plus sequence methods: David Ely
5
6 XXX To do:
7 - provide interface to the B-tree and record libraries too
8 - provide a way to access the various hash functions
9 - support more open flags
Guido van Rossum675e9941999-09-20 13:28:18 +000010
11 The windows port of the Berkeley DB code is hard to find on the web:
12 www.nightmare.com/software.html
13*/
Guido van Rossum1100dca1995-08-30 23:43:03 +000014
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000015#include "Python.h"
Guido van Rossum4f199ea1998-04-09 20:56:35 +000016#ifdef WITH_THREAD
Guido van Rossum49b56061998-10-01 20:42:43 +000017#include "pythread.h"
Guido van Rossum4f199ea1998-04-09 20:56:35 +000018#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +000019
20#include <sys/types.h>
21#include <sys/stat.h>
22#include <fcntl.h>
Fred Drakec9cb8472000-08-31 16:11:07 +000023#ifdef HAVE_DB_185_H
24#include <db_185.h>
25#else
Guido van Rossum1100dca1995-08-30 23:43:03 +000026#include <db.h>
Fred Drakec9cb8472000-08-31 16:11:07 +000027#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +000028/* Please don't include internal header files of the Berkeley db package
29 (it messes up the info required in the Setup file) */
30
31typedef struct {
Roger E. Massed9240d11997-01-16 22:05:33 +000032 PyObject_HEAD
33 DB *di_bsddb;
34 int di_size; /* -1 means recompute */
Guido van Rossum4f199ea1998-04-09 20:56:35 +000035#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +000036 PyThread_type_lock di_lock;
Guido van Rossum4f199ea1998-04-09 20:56:35 +000037#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +000038} bsddbobject;
39
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000040staticforward PyTypeObject Bsddbtype;
Guido van Rossum1100dca1995-08-30 23:43:03 +000041
42#define is_bsddbobject(v) ((v)->ob_type == &Bsddbtype)
Guido van Rossum77eecfa1997-07-17 22:56:01 +000043#define check_bsddbobject_open(v) if ((v)->di_bsddb == NULL) \
Fred Drakec9f7c262001-02-19 21:16:00 +000044 { PyErr_SetString(BsddbError, \
45 "BSDDB object has already been closed"); \
Guido van Rossum77eecfa1997-07-17 22:56:01 +000046 return NULL; }
Guido van Rossum1100dca1995-08-30 23:43:03 +000047
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000048static PyObject *BsddbError;
Guido van Rossum1100dca1995-08-30 23:43:03 +000049
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000050static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +000051newdbhashobject(char *file, int flags, int mode,
Fred Drakec9f7c262001-02-19 21:16:00 +000052 int bsize, int ffactor, int nelem, int cachesize,
53 int hash, int lorder)
Guido van Rossum1100dca1995-08-30 23:43:03 +000054{
Roger E. Massed9240d11997-01-16 22:05:33 +000055 bsddbobject *dp;
56 HASHINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +000057
Guido van Rossumb18618d2000-05-03 23:44:39 +000058 if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
Roger E. Massed9240d11997-01-16 22:05:33 +000059 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +000060
Roger E. Massed9240d11997-01-16 22:05:33 +000061 info.bsize = bsize;
62 info.ffactor = ffactor;
63 info.nelem = nelem;
64 info.cachesize = cachesize;
65 info.hash = NULL; /* XXX should derive from hash argument */
66 info.lorder = lorder;
Guido van Rossum1100dca1995-08-30 23:43:03 +000067
Guido van Rossum6beb4791996-09-11 23:22:25 +000068#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +000069 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +000070#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +000071 Py_BEGIN_ALLOW_THREADS
72 dp->di_bsddb = dbopen(file, flags, mode, DB_HASH, &info);
73 Py_END_ALLOW_THREADS
74 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +000075 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +000076#ifdef WITH_THREAD
77 dp->di_lock = NULL;
78#endif
Roger E. Massed9240d11997-01-16 22:05:33 +000079 Py_DECREF(dp);
80 return NULL;
81 }
Guido van Rossum1100dca1995-08-30 23:43:03 +000082
Roger E. Massed9240d11997-01-16 22:05:33 +000083 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +000084#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +000085 dp->di_lock = PyThread_allocate_lock();
Guido van Rossum4f199ea1998-04-09 20:56:35 +000086 if (dp->di_lock == NULL) {
87 PyErr_SetString(BsddbError, "can't allocate lock");
88 Py_DECREF(dp);
89 return NULL;
90 }
91#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +000092
Roger E. Massed9240d11997-01-16 22:05:33 +000093 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +000094}
95
Guido van Rossumdfe8ad91996-07-24 00:51:20 +000096static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +000097newdbbtobject(char *file, int flags, int mode,
Fred Drakec9f7c262001-02-19 21:16:00 +000098 int btflags, int cachesize, int maxkeypage,
99 int minkeypage, int psize, int lorder)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000100{
Roger E. Massed9240d11997-01-16 22:05:33 +0000101 bsddbobject *dp;
102 BTREEINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000103
Guido van Rossumb18618d2000-05-03 23:44:39 +0000104 if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
Roger E. Massed9240d11997-01-16 22:05:33 +0000105 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000106
Roger E. Massed9240d11997-01-16 22:05:33 +0000107 info.flags = btflags;
108 info.cachesize = cachesize;
109 info.maxkeypage = maxkeypage;
110 info.minkeypage = minkeypage;
111 info.psize = psize;
112 info.lorder = lorder;
113 info.compare = 0; /* Use default comparison functions, for now..*/
114 info.prefix = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000115
Guido van Rossum6beb4791996-09-11 23:22:25 +0000116#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +0000117 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +0000118#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000119 Py_BEGIN_ALLOW_THREADS
120 dp->di_bsddb = dbopen(file, flags, mode, DB_BTREE, &info);
121 Py_END_ALLOW_THREADS
122 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000123 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000124#ifdef WITH_THREAD
125 dp->di_lock = NULL;
126#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000127 Py_DECREF(dp);
128 return NULL;
129 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000130
Roger E. Massed9240d11997-01-16 22:05:33 +0000131 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000132#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000133 dp->di_lock = PyThread_allocate_lock();
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000134 if (dp->di_lock == NULL) {
135 PyErr_SetString(BsddbError, "can't allocate lock");
136 Py_DECREF(dp);
137 return NULL;
138 }
139#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000140
Roger E. Massed9240d11997-01-16 22:05:33 +0000141 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000142}
143
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000144static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000145newdbrnobject(char *file, int flags, int mode,
Fred Drakec9f7c262001-02-19 21:16:00 +0000146 int rnflags, int cachesize, int psize, int lorder,
147 size_t reclen, u_char bval, char *bfname)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000148{
Roger E. Massed9240d11997-01-16 22:05:33 +0000149 bsddbobject *dp;
150 RECNOINFO info;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000151
Guido van Rossumb18618d2000-05-03 23:44:39 +0000152 if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
Roger E. Massed9240d11997-01-16 22:05:33 +0000153 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000154
Roger E. Massed9240d11997-01-16 22:05:33 +0000155 info.flags = rnflags;
156 info.cachesize = cachesize;
157 info.psize = psize;
158 info.lorder = lorder;
159 info.reclen = reclen;
160 info.bval = bval;
161 info.bfname = bfname;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000162
Guido van Rossum6beb4791996-09-11 23:22:25 +0000163#ifdef O_BINARY
Roger E. Massed9240d11997-01-16 22:05:33 +0000164 flags |= O_BINARY;
Guido van Rossum6beb4791996-09-11 23:22:25 +0000165#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000166 Py_BEGIN_ALLOW_THREADS
167 dp->di_bsddb = dbopen(file, flags, mode, DB_RECNO, &info);
168 Py_END_ALLOW_THREADS
169 if (dp->di_bsddb == NULL) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000170 PyErr_SetFromErrno(BsddbError);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000171#ifdef WITH_THREAD
172 dp->di_lock = NULL;
173#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000174 Py_DECREF(dp);
175 return NULL;
176 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000177
Roger E. Massed9240d11997-01-16 22:05:33 +0000178 dp->di_size = -1;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000179#ifdef WITH_THREAD
Guido van Rossum65d5b571998-12-21 19:32:43 +0000180 dp->di_lock = PyThread_allocate_lock();
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000181 if (dp->di_lock == NULL) {
182 PyErr_SetString(BsddbError, "can't allocate lock");
183 Py_DECREF(dp);
184 return NULL;
185 }
186#endif
Guido van Rossum1100dca1995-08-30 23:43:03 +0000187
Roger E. Massed9240d11997-01-16 22:05:33 +0000188 return (PyObject *)dp;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000189}
190
Guido van Rossum1100dca1995-08-30 23:43:03 +0000191static void
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000192bsddb_dealloc(bsddbobject *dp)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000193{
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000194#ifdef WITH_THREAD
195 if (dp->di_lock) {
Guido van Rossum65d5b571998-12-21 19:32:43 +0000196 PyThread_acquire_lock(dp->di_lock, 0);
197 PyThread_release_lock(dp->di_lock);
198 PyThread_free_lock(dp->di_lock);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000199 dp->di_lock = NULL;
200 }
201#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000202 if (dp->di_bsddb != NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000203 int status;
204 Py_BEGIN_ALLOW_THREADS
205 status = (dp->di_bsddb->close)(dp->di_bsddb);
206 Py_END_ALLOW_THREADS
207 if (status != 0)
Roger E. Massed9240d11997-01-16 22:05:33 +0000208 fprintf(stderr,
209 "Python bsddb: close errno %d in dealloc\n",
210 errno);
211 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000212 PyObject_Del(dp);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000213}
214
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000215#ifdef WITH_THREAD
Fred Drakec9f7c262001-02-19 21:16:00 +0000216#define BSDDB_BGN_SAVE(_dp) \
217 Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(_dp->di_lock,1);
218#define BSDDB_END_SAVE(_dp) \
219 PyThread_release_lock(_dp->di_lock); Py_END_ALLOW_THREADS
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000220#else
221#define BSDDB_BGN_SAVE(_dp) Py_BEGIN_ALLOW_THREADS
222#define BSDDB_END_SAVE(_dp) Py_END_ALLOW_THREADS
223#endif
224
Guido van Rossum1100dca1995-08-30 23:43:03 +0000225static int
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000226bsddb_length(bsddbobject *dp)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000227{
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000228 if (dp->di_bsddb == NULL) {
Fred Drakec9f7c262001-02-19 21:16:00 +0000229 PyErr_SetString(BsddbError,
230 "BSDDB object has already been closed");
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000231 return -1;
232 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000233 if (dp->di_size < 0) {
234 DBT krec, drec;
235 int status;
236 int size = 0;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000237 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000238 for (status = (dp->di_bsddb->seq)(dp->di_bsddb,
239 &krec, &drec,R_FIRST);
240 status == 0;
241 status = (dp->di_bsddb->seq)(dp->di_bsddb,
242 &krec, &drec, R_NEXT))
243 size++;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000244 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000245 if (status < 0) {
246 PyErr_SetFromErrno(BsddbError);
247 return -1;
248 }
249 dp->di_size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000250 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000251 return dp->di_size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000252}
253
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000254static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000255bsddb_subscript(bsddbobject *dp, PyObject *key)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000256{
Roger E. Massed9240d11997-01-16 22:05:33 +0000257 int status;
258 DBT krec, drec;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000259 char *data,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000260 int size;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000261 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000262
Roger E. Massed9240d11997-01-16 22:05:33 +0000263 if (!PyArg_Parse(key, "s#", &data, &size))
264 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000265 check_bsddbobject_open(dp);
266
Roger E. Massed9240d11997-01-16 22:05:33 +0000267 krec.data = data;
268 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000269
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000270 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000271 status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000272 if (status == 0) {
273 if (drec.size > sizeof(buf)) data = malloc(drec.size);
274 else data = buf;
Andrew M. Kuchling2e095302000-12-15 00:59:32 +0000275 if (data!=NULL) memcpy(data,drec.data,drec.size);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000276 }
277 BSDDB_END_SAVE(dp)
Andrew M. Kuchling2e095302000-12-15 00:59:32 +0000278 if (data==NULL) return PyErr_NoMemory();
Roger E. Massed9240d11997-01-16 22:05:33 +0000279 if (status != 0) {
280 if (status < 0)
281 PyErr_SetFromErrno(BsddbError);
282 else
283 PyErr_SetObject(PyExc_KeyError, key);
284 return NULL;
285 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000286
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000287 result = PyString_FromStringAndSize(data, (int)drec.size);
288 if (data != buf) free(data);
289 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000290}
291
292static int
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000293bsddb_ass_sub(bsddbobject *dp, PyObject *key, PyObject *value)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000294{
Roger E. Massed9240d11997-01-16 22:05:33 +0000295 int status;
296 DBT krec, drec;
297 char *data;
298 int size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000299
Roger E. Massed9240d11997-01-16 22:05:33 +0000300 if (!PyArg_Parse(key, "s#", &data, &size)) {
301 PyErr_SetString(PyExc_TypeError,
302 "bsddb key type must be string");
303 return -1;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000304 }
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000305 if (dp->di_bsddb == NULL) {
Fred Drakec9f7c262001-02-19 21:16:00 +0000306 PyErr_SetString(BsddbError,
307 "BSDDB object has already been closed");
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000308 return -1;
309 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000310 krec.data = data;
311 krec.size = size;
312 dp->di_size = -1;
313 if (value == NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000314 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000315 status = (dp->di_bsddb->del)(dp->di_bsddb, &krec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000316 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000317 }
318 else {
319 if (!PyArg_Parse(value, "s#", &data, &size)) {
320 PyErr_SetString(PyExc_TypeError,
321 "bsddb value type must be string");
322 return -1;
323 }
324 drec.data = data;
325 drec.size = size;
326#if 0
327 /* For RECNO, put fails with 'No space left on device'
328 after a few short records are added?? Looks fine
329 to this point... linked with 1.85 on Solaris Intel
330 Roger E. Masse 1/16/97
331 */
332 printf("before put data: '%s', size: %d\n",
333 drec.data, drec.size);
334 printf("before put key= '%s', size= %d\n",
335 krec.data, krec.size);
336#endif
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000337 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000338 status = (dp->di_bsddb->put)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000339 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000340 }
341 if (status != 0) {
342 if (status < 0)
343 PyErr_SetFromErrno(BsddbError);
344 else
345 PyErr_SetObject(PyExc_KeyError, key);
346 return -1;
347 }
348 return 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000349}
350
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000351static PyMappingMethods bsddb_as_mapping = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000352 (inquiry)bsddb_length, /*mp_length*/
353 (binaryfunc)bsddb_subscript, /*mp_subscript*/
354 (objobjargproc)bsddb_ass_sub, /*mp_ass_subscript*/
Guido van Rossum1100dca1995-08-30 23:43:03 +0000355};
356
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000357static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000358bsddb_close(bsddbobject *dp, PyObject *args)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000359{
Roger E. Massed9240d11997-01-16 22:05:33 +0000360 if (!PyArg_NoArgs(args))
361 return NULL;
362 if (dp->di_bsddb != NULL) {
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000363 int status;
364 BSDDB_BGN_SAVE(dp)
365 status = (dp->di_bsddb->close)(dp->di_bsddb);
366 BSDDB_END_SAVE(dp)
367 if (status != 0) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000368 dp->di_bsddb = NULL;
369 PyErr_SetFromErrno(BsddbError);
370 return NULL;
371 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000372 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000373 dp->di_bsddb = NULL;
374 Py_INCREF(Py_None);
375 return Py_None;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000376}
377
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000378static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000379bsddb_keys(bsddbobject *dp, PyObject *args)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000380{
Roger E. Massed9240d11997-01-16 22:05:33 +0000381 PyObject *list, *item;
382 DBT krec, drec;
Guido van Rossum730806d1998-04-10 22:27:42 +0000383 char *data=NULL,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000384 int status;
385 int err;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000386
Roger E. Massed9240d11997-01-16 22:05:33 +0000387 if (!PyArg_NoArgs(args))
388 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000389 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000390 list = PyList_New(0);
391 if (list == NULL)
392 return NULL;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000393 BSDDB_BGN_SAVE(dp)
394 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_FIRST);
395 if (status == 0) {
396 if (krec.size > sizeof(buf)) data = malloc(krec.size);
397 else data = buf;
Andrew M. Kuchling2e095302000-12-15 00:59:32 +0000398 if (data!=NULL) memcpy(data,krec.data,krec.size);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000399 }
400 BSDDB_END_SAVE(dp)
Andrew M. Kuchling2e095302000-12-15 00:59:32 +0000401 if (data==NULL) return PyErr_NoMemory();
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000402 while (status == 0) {
403 item = PyString_FromStringAndSize(data, (int)krec.size);
404 if (data != buf) free(data);
Roger E. Massed9240d11997-01-16 22:05:33 +0000405 if (item == NULL) {
406 Py_DECREF(list);
407 return NULL;
408 }
409 err = PyList_Append(list, item);
410 Py_DECREF(item);
411 if (err != 0) {
412 Py_DECREF(list);
413 return NULL;
414 }
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000415 BSDDB_BGN_SAVE(dp)
Fred Drakec9f7c262001-02-19 21:16:00 +0000416 status = (dp->di_bsddb->seq)
417 (dp->di_bsddb, &krec, &drec, R_NEXT);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000418 if (status == 0) {
Fred Drakec9f7c262001-02-19 21:16:00 +0000419 if (krec.size > sizeof(buf))
420 data = malloc(krec.size);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000421 else data = buf;
Fred Drakec9f7c262001-02-19 21:16:00 +0000422 if (data != NULL)
423 memcpy(data,krec.data,krec.size);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000424 }
425 BSDDB_END_SAVE(dp)
Fred Drakec9f7c262001-02-19 21:16:00 +0000426 if (data == NULL) return PyErr_NoMemory();
Guido van Rossum1100dca1995-08-30 23:43:03 +0000427 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000428 if (status < 0) {
429 PyErr_SetFromErrno(BsddbError);
430 Py_DECREF(list);
431 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000432 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000433 if (dp->di_size < 0)
434 dp->di_size = PyList_Size(list); /* We just did the work */
435 return list;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000436}
437
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000438static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000439bsddb_has_key(bsddbobject *dp, PyObject *args)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000440{
Roger E. Massed9240d11997-01-16 22:05:33 +0000441 DBT krec, drec;
442 int status;
443 char *data;
444 int size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000445
Roger E. Massed9240d11997-01-16 22:05:33 +0000446 if (!PyArg_Parse(args, "s#", &data, &size))
447 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000448 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000449 krec.data = data;
450 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000451
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000452 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000453 status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000454 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000455 if (status < 0) {
456 PyErr_SetFromErrno(BsddbError);
457 return NULL;
458 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000459
Roger E. Massed9240d11997-01-16 22:05:33 +0000460 return PyInt_FromLong(status == 0);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000461}
462
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000463static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000464bsddb_set_location(bsddbobject *dp, PyObject *key)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000465{
Roger E. Massed9240d11997-01-16 22:05:33 +0000466 int status;
467 DBT krec, drec;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000468 char *data,buf[4096];
Roger E. Massed9240d11997-01-16 22:05:33 +0000469 int size;
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000470 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000471
Roger E. Massed9240d11997-01-16 22:05:33 +0000472 if (!PyArg_Parse(key, "s#", &data, &size))
473 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000474 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000475 krec.data = data;
476 krec.size = size;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000477
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000478 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000479 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_CURSOR);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000480 if (status == 0) {
481 if (drec.size > sizeof(buf)) data = malloc(drec.size);
482 else data = buf;
Andrew M. Kuchling2e095302000-12-15 00:59:32 +0000483 if (data!=NULL) memcpy(data,drec.data,drec.size);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000484 }
485 BSDDB_END_SAVE(dp)
Andrew M. Kuchling2e095302000-12-15 00:59:32 +0000486 if (data==NULL) return PyErr_NoMemory();
Roger E. Massed9240d11997-01-16 22:05:33 +0000487 if (status != 0) {
488 if (status < 0)
489 PyErr_SetFromErrno(BsddbError);
490 else
491 PyErr_SetObject(PyExc_KeyError, key);
492 return NULL;
493 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000494
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000495 result = Py_BuildValue("s#s#", krec.data, krec.size, data, drec.size);
496 if (data != buf) free(data);
497 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000498}
499
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000500static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000501bsddb_seq(bsddbobject *dp, PyObject *args, int sequence_request)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000502{
Roger E. Massed9240d11997-01-16 22:05:33 +0000503 int status;
504 DBT krec, drec;
Guido van Rossum730806d1998-04-10 22:27:42 +0000505 char *kdata=NULL,kbuf[4096];
506 char *ddata=NULL,dbuf[4096];
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000507 PyObject *result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000508
Roger E. Massed9240d11997-01-16 22:05:33 +0000509 if (!PyArg_NoArgs(args))
510 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000511
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000512 check_bsddbobject_open(dp);
Roger E. Massed9240d11997-01-16 22:05:33 +0000513 krec.data = 0;
514 krec.size = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000515
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000516 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000517 status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec,
518 &drec, sequence_request);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000519 if (status == 0) {
520 if (krec.size > sizeof(kbuf)) kdata = malloc(krec.size);
521 else kdata = kbuf;
Andrew M. Kuchling2e095302000-12-15 00:59:32 +0000522 if (kdata!=NULL) memcpy(kdata,krec.data,krec.size);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000523 if (drec.size > sizeof(dbuf)) ddata = malloc(drec.size);
524 else ddata = dbuf;
Andrew M. Kuchling2e095302000-12-15 00:59:32 +0000525 if (ddata!=NULL) memcpy(ddata,drec.data,drec.size);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000526 }
527 BSDDB_END_SAVE(dp)
Andrew M. Kuchling2e095302000-12-15 00:59:32 +0000528 if (status == 0) {
529 if ((kdata==NULL) || (ddata==NULL))
530 return PyErr_NoMemory();
531 }
532 else {
533 /* (status != 0) */
Roger E. Massed9240d11997-01-16 22:05:33 +0000534 if (status < 0)
535 PyErr_SetFromErrno(BsddbError);
536 else
537 PyErr_SetObject(PyExc_KeyError, args);
538 return NULL;
539 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000540
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000541 result = Py_BuildValue("s#s#", kdata, krec.size, ddata, drec.size);
542 if (kdata != kbuf) free(kdata);
543 if (ddata != dbuf) free(ddata);
544 return result;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000545}
546
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000547static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000548bsddb_next(bsddbobject *dp, PyObject *key)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000549{
Roger E. Massed9240d11997-01-16 22:05:33 +0000550 return bsddb_seq(dp, key, R_NEXT);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000551}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000552static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000553bsddb_previous(bsddbobject *dp, PyObject *key)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000554{
Roger E. Massed9240d11997-01-16 22:05:33 +0000555 return bsddb_seq(dp, key, R_PREV);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000556}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000557static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000558bsddb_first(bsddbobject *dp, PyObject *key)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000559{
Roger E. Massed9240d11997-01-16 22:05:33 +0000560 return bsddb_seq(dp, key, R_FIRST);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000561}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000562static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000563bsddb_last(bsddbobject *dp, PyObject *key)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000564{
Roger E. Massed9240d11997-01-16 22:05:33 +0000565 return bsddb_seq(dp, key, R_LAST);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000566}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000567static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000568bsddb_sync(bsddbobject *dp, PyObject *args)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000569{
Roger E. Massed9240d11997-01-16 22:05:33 +0000570 int status;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000571
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000572 if (!PyArg_NoArgs(args))
573 return NULL;
574 check_bsddbobject_open(dp);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000575 BSDDB_BGN_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000576 status = (dp->di_bsddb->sync)(dp->di_bsddb, 0);
Guido van Rossum4f199ea1998-04-09 20:56:35 +0000577 BSDDB_END_SAVE(dp)
Roger E. Massed9240d11997-01-16 22:05:33 +0000578 if (status != 0) {
579 PyErr_SetFromErrno(BsddbError);
580 return NULL;
581 }
582 return PyInt_FromLong(status = 0);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000583}
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000584static PyMethodDef bsddb_methods[] = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000585 {"close", (PyCFunction)bsddb_close},
586 {"keys", (PyCFunction)bsddb_keys},
587 {"has_key", (PyCFunction)bsddb_has_key},
588 {"set_location", (PyCFunction)bsddb_set_location},
589 {"next", (PyCFunction)bsddb_next},
590 {"previous", (PyCFunction)bsddb_previous},
591 {"first", (PyCFunction)bsddb_first},
592 {"last", (PyCFunction)bsddb_last},
593 {"sync", (PyCFunction)bsddb_sync},
594 {NULL, NULL} /* sentinel */
Guido van Rossum1100dca1995-08-30 23:43:03 +0000595};
596
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000597static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000598bsddb_getattr(PyObject *dp, char *name)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000599{
Roger E. Massed9240d11997-01-16 22:05:33 +0000600 return Py_FindMethod(bsddb_methods, dp, name);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000601}
602
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000603static PyTypeObject Bsddbtype = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000604 PyObject_HEAD_INIT(NULL)
605 0,
606 "bsddb",
607 sizeof(bsddbobject),
608 0,
609 (destructor)bsddb_dealloc, /*tp_dealloc*/
610 0, /*tp_print*/
611 (getattrfunc)bsddb_getattr, /*tp_getattr*/
612 0, /*tp_setattr*/
613 0, /*tp_compare*/
614 0, /*tp_repr*/
615 0, /*tp_as_number*/
616 0, /*tp_as_sequence*/
617 &bsddb_as_mapping, /*tp_as_mapping*/
Guido van Rossum1100dca1995-08-30 23:43:03 +0000618};
619
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000620static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000621bsdhashopen(PyObject *self, PyObject *args)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000622{
Roger E. Massed9240d11997-01-16 22:05:33 +0000623 char *file;
624 char *flag = NULL;
625 int flags = O_RDONLY;
626 int mode = 0666;
627 int bsize = 0;
628 int ffactor = 0;
629 int nelem = 0;
630 int cachesize = 0;
631 int hash = 0; /* XXX currently ignored */
632 int lorder = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000633
Guido van Rossum43713e52000-02-29 13:59:29 +0000634 if (!PyArg_ParseTuple(args, "s|siiiiiii:hashopen",
Roger E. Massed9240d11997-01-16 22:05:33 +0000635 &file, &flag, &mode,
636 &bsize, &ffactor, &nelem, &cachesize,
637 &hash, &lorder))
638 return NULL;
639 if (flag != NULL) {
640 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
641 if (flag[0] == 'r')
642 flags = O_RDONLY;
643 else if (flag[0] == 'w')
644 flags = O_RDWR;
645 else if (flag[0] == 'c')
646 flags = O_RDWR|O_CREAT;
647 else if (flag[0] == 'n')
648 flags = O_RDWR|O_CREAT|O_TRUNC;
649 else {
650 PyErr_SetString(BsddbError,
651 "Flag should begin with 'r', 'w', 'c' or 'n'");
652 return NULL;
653 }
654 if (flag[1] == 'l') {
Guido van Rossum1100dca1995-08-30 23:43:03 +0000655#if defined(O_EXLOCK) && defined(O_SHLOCK)
Roger E. Massed9240d11997-01-16 22:05:33 +0000656 if (flag[0] == 'r')
657 flags |= O_SHLOCK;
658 else
659 flags |= O_EXLOCK;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000660#else
Roger E. Massed9240d11997-01-16 22:05:33 +0000661 PyErr_SetString(BsddbError,
662 "locking not supported on this platform");
663 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000664#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000665 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000666 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000667 return newdbhashobject(file, flags, mode,
668 bsize, ffactor, nelem, cachesize, hash, lorder);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000669}
670
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000671static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000672bsdbtopen(PyObject *self, PyObject *args)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000673{
Roger E. Massed9240d11997-01-16 22:05:33 +0000674 char *file;
675 char *flag = NULL;
676 int flags = O_RDONLY;
677 int mode = 0666;
678 int cachesize = 0;
679 int maxkeypage = 0;
680 int minkeypage = 0;
681 int btflags = 0;
682 unsigned int psize = 0;
683 int lorder = 0;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000684
Guido van Rossum43713e52000-02-29 13:59:29 +0000685 if (!PyArg_ParseTuple(args, "s|siiiiiii:btopen",
Roger E. Massed9240d11997-01-16 22:05:33 +0000686 &file, &flag, &mode,
687 &btflags, &cachesize, &maxkeypage, &minkeypage,
688 &psize, &lorder))
689 return NULL;
690 if (flag != NULL) {
691 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
692 if (flag[0] == 'r')
693 flags = O_RDONLY;
694 else if (flag[0] == 'w')
695 flags = O_RDWR;
696 else if (flag[0] == 'c')
697 flags = O_RDWR|O_CREAT;
698 else if (flag[0] == 'n')
699 flags = O_RDWR|O_CREAT|O_TRUNC;
700 else {
701 PyErr_SetString(BsddbError,
702 "Flag should begin with 'r', 'w', 'c' or 'n'");
703 return NULL;
704 }
705 if (flag[1] == 'l') {
Guido van Rossum1100dca1995-08-30 23:43:03 +0000706#if defined(O_EXLOCK) && defined(O_SHLOCK)
Roger E. Massed9240d11997-01-16 22:05:33 +0000707 if (flag[0] == 'r')
708 flags |= O_SHLOCK;
709 else
710 flags |= O_EXLOCK;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000711#else
Roger E. Massed9240d11997-01-16 22:05:33 +0000712 PyErr_SetString(BsddbError,
713 "locking not supported on this platform");
714 return NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000715#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000716 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000717 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000718 return newdbbtobject(file, flags, mode,
719 btflags, cachesize, maxkeypage, minkeypage,
720 psize, lorder);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000721}
Guido van Rossumdd96ca71996-05-23 22:57:54 +0000722
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000723static PyObject *
Peter Schneider-Kampcb27c352000-07-10 17:06:38 +0000724bsdrnopen(PyObject *self, PyObject *args)
Guido van Rossum1100dca1995-08-30 23:43:03 +0000725{
Roger E. Massed9240d11997-01-16 22:05:33 +0000726 char *file;
727 char *flag = NULL;
728 int flags = O_RDONLY;
729 int mode = 0666;
730 int cachesize = 0;
731 int rnflags = 0;
732 unsigned int psize = 0;
733 int lorder = 0;
734 size_t reclen = 0;
735 char *bval = "";
736 char *bfname = NULL;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000737
Guido van Rossum43713e52000-02-29 13:59:29 +0000738 if (!PyArg_ParseTuple(args, "s|siiiiiiss:rnopen",
Roger E. Massed9240d11997-01-16 22:05:33 +0000739 &file, &flag, &mode,
740 &rnflags, &cachesize, &psize, &lorder,
741 &reclen, &bval, &bfname))
742 return NULL;
743
744# if 0
745 printf("file: %s\n", file);
746 printf("flag: %s\n", flag);
747 printf("mode: %d\n", mode);
748 printf("rnflags: 0x%x\n", rnflags);
749 printf("cachesize: %d\n", cachesize);
750 printf("psize: %d\n", psize);
751 printf("lorder: %d\n", 0);
752 printf("reclen: %d\n", reclen);
753 printf("bval: %c\n", bval[0]);
754 printf("bfname %s\n", bfname);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000755#endif
Roger E. Massed9240d11997-01-16 22:05:33 +0000756
757 if (flag != NULL) {
758 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
759 if (flag[0] == 'r')
760 flags = O_RDONLY;
761 else if (flag[0] == 'w')
762 flags = O_RDWR;
763 else if (flag[0] == 'c')
764 flags = O_RDWR|O_CREAT;
765 else if (flag[0] == 'n')
766 flags = O_RDWR|O_CREAT|O_TRUNC;
767 else {
768 PyErr_SetString(BsddbError,
769 "Flag should begin with 'r', 'w', 'c' or 'n'");
770 return NULL;
771 }
772 if (flag[1] == 'l') {
773#if defined(O_EXLOCK) && defined(O_SHLOCK)
774 if (flag[0] == 'r')
775 flags |= O_SHLOCK;
776 else
777 flags |= O_EXLOCK;
778#else
779 PyErr_SetString(BsddbError,
780 "locking not supported on this platform");
781 return NULL;
782#endif
783 }
784 else if (flag[1] != '\0') {
785 PyErr_SetString(BsddbError,
786 "Flag char 2 should be 'l' or absent");
787 return NULL;
788 }
Guido van Rossum1100dca1995-08-30 23:43:03 +0000789 }
Roger E. Massed9240d11997-01-16 22:05:33 +0000790 return newdbrnobject(file, flags, mode, rnflags, cachesize,
791 psize, lorder, reclen, bval[0], bfname);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000792}
793
Guido van Rossumdfe8ad91996-07-24 00:51:20 +0000794static PyMethodDef bsddbmodule_methods[] = {
Roger E. Massed9240d11997-01-16 22:05:33 +0000795 {"hashopen", (PyCFunction)bsdhashopen, 1},
796 {"btopen", (PyCFunction)bsdbtopen, 1},
797 {"rnopen", (PyCFunction)bsdrnopen, 1},
798 {0, 0},
Guido van Rossum1100dca1995-08-30 23:43:03 +0000799};
800
Guido van Rossum3886bb61998-12-04 18:50:17 +0000801DL_EXPORT(void)
Thomas Wouters58d05102000-07-24 14:43:35 +0000802initbsddb(void) {
Roger E. Massed9240d11997-01-16 22:05:33 +0000803 PyObject *m, *d;
Guido van Rossum1100dca1995-08-30 23:43:03 +0000804
Roger E. Massed9240d11997-01-16 22:05:33 +0000805 Bsddbtype.ob_type = &PyType_Type;
806 m = Py_InitModule("bsddb", bsddbmodule_methods);
807 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000808 BsddbError = PyErr_NewException("bsddb.error", NULL, NULL);
809 if (BsddbError != NULL)
810 PyDict_SetItemString(d, "error", BsddbError);
Guido van Rossum1100dca1995-08-30 23:43:03 +0000811}