1 /*----------------------------------------------------------------------
2 Copyright (c) 1999-2001, Digital Creations, Fredericksburg, VA, USA
3 and Andrew Kuchling. All rights reserved.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
9 o Redistributions of source code must retain the above copyright
10 notice, this list of conditions, and the disclaimer that follows.
12 o Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions, and the following disclaimer in
14 the documentation and/or other materials provided with the
17 o Neither the name of Digital Creations nor the names of its
18 contributors may be used to endorse or promote products derived
19 from this software without specific prior written permission.
21 THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
22 IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
25 CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
33 ------------------------------------------------------------------------*/
37 * Handwritten code to wrap version 3.x of the Berkeley DB library,
38 * written to replace a SWIG-generated file. It has since been updated
39 * to compile with BerkeleyDB versions 3.2 through 4.2.
41 * This module was started by Andrew Kuchling to remove the dependency
42 * on SWIG in a package by Gregory P. Smith who based his work on a
43 * similar package by Robin Dunn <robin@alldunn.com> which wrapped
46 * Development of this module then returned full circle back to Robin Dunn
47 * who worked on behalf of Digital Creations to complete the wrapping of
48 * the DB 3.x API and to build a solid unit test suite. Robin has
49 * since gone onto other projects (wxPython).
51 * Gregory P. Smith <greg@krypto.org> is once again the maintainer.
53 * Use the pybsddb-users@lists.sf.net mailing list for all questions.
54 * Things can change faster than the header of this file is updated. This
55 * file is shared with the PyBSDDB project at SourceForge:
57 * http://pybsddb.sf.net
59 * This file should remain backward compatible with Python 2.1, but see PEP
60 * 291 for the most current backward compatibility requirements:
62 * http://www.python.org/peps/pep-0291.html
64 * This module contains 6 types:
67 * DBCursor (Database Cursor)
68 * DBEnv (database environment)
69 * DBTxn (An explicit database transaction)
70 * DBLock (A lock handle)
71 * DBSequence (Sequence)
75 /* --------------------------------------------------------------------- */
78 * Portions of this module, associated unit tests and build scripts are the
79 * result of a contract with The Written Word (http://thewrittenword.com/)
80 * Many thanks go out to them for causing me to raise the bar on quality and
81 * functionality, resulting in a better bsddb3 package for all of us to use.
86 /* --------------------------------------------------------------------- */
88 #include <stddef.h> /* for offsetof() */
91 #define COMPILING_BSDDB_C
93 #undef COMPILING_BSDDB_C
95 static char *rcs_id
= "$Id$";
97 /* --------------------------------------------------------------------- */
98 /* Various macro definitions */
100 #if (PY_VERSION_HEX < 0x02050000)
101 typedef int Py_ssize_t
;
106 /* These are for when calling Python --> C */
107 #define MYDB_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS;
108 #define MYDB_END_ALLOW_THREADS Py_END_ALLOW_THREADS;
110 /* For 2.3, use the PyGILState_ calls */
111 #if (PY_VERSION_HEX >= 0x02030000)
112 #define MYDB_USE_GILSTATE
115 /* and these are for calling C --> Python */
116 #if defined(MYDB_USE_GILSTATE)
117 #define MYDB_BEGIN_BLOCK_THREADS \
118 PyGILState_STATE __savestate = PyGILState_Ensure();
119 #define MYDB_END_BLOCK_THREADS \
120 PyGILState_Release(__savestate);
121 #else /* MYDB_USE_GILSTATE */
122 /* Pre GILState API - do it the long old way */
123 static PyInterpreterState
* _db_interpreterState
= NULL
;
124 #define MYDB_BEGIN_BLOCK_THREADS { \
125 PyThreadState* prevState; \
126 PyThreadState* newState; \
127 PyEval_AcquireLock(); \
128 newState = PyThreadState_New(_db_interpreterState); \
129 prevState = PyThreadState_Swap(newState);
131 #define MYDB_END_BLOCK_THREADS \
132 newState = PyThreadState_Swap(prevState); \
133 PyThreadState_Clear(newState); \
134 PyEval_ReleaseLock(); \
135 PyThreadState_Delete(newState); \
137 #endif /* MYDB_USE_GILSTATE */
140 /* Compiled without threads - avoid all this cruft */
141 #define MYDB_BEGIN_ALLOW_THREADS
142 #define MYDB_END_ALLOW_THREADS
143 #define MYDB_BEGIN_BLOCK_THREADS
144 #define MYDB_END_BLOCK_THREADS
148 /* Should DB_INCOMPLETE be turned into a warning or an exception? */
149 #define INCOMPLETE_IS_WARNING 1
151 /* --------------------------------------------------------------------- */
154 static PyObject
* DBError
; /* Base class, all others derive from this */
155 static PyObject
* DBCursorClosedError
; /* raised when trying to use a closed cursor object */
156 static PyObject
* DBKeyEmptyError
; /* DB_KEYEMPTY: also derives from KeyError */
157 static PyObject
* DBKeyExistError
; /* DB_KEYEXIST */
158 static PyObject
* DBLockDeadlockError
; /* DB_LOCK_DEADLOCK */
159 static PyObject
* DBLockNotGrantedError
; /* DB_LOCK_NOTGRANTED */
160 static PyObject
* DBNotFoundError
; /* DB_NOTFOUND: also derives from KeyError */
161 static PyObject
* DBOldVersionError
; /* DB_OLD_VERSION */
162 static PyObject
* DBRunRecoveryError
; /* DB_RUNRECOVERY */
163 static PyObject
* DBVerifyBadError
; /* DB_VERIFY_BAD */
164 static PyObject
* DBNoServerError
; /* DB_NOSERVER */
165 static PyObject
* DBNoServerHomeError
; /* DB_NOSERVER_HOME */
166 static PyObject
* DBNoServerIDError
; /* DB_NOSERVER_ID */
168 static PyObject
* DBPageNotFoundError
; /* DB_PAGE_NOTFOUND */
169 static PyObject
* DBSecondaryBadError
; /* DB_SECONDARY_BAD */
172 #if !INCOMPLETE_IS_WARNING
173 static PyObject
* DBIncompleteError
; /* DB_INCOMPLETE */
176 static PyObject
* DBInvalidArgError
; /* EINVAL */
177 static PyObject
* DBAccessError
; /* EACCES */
178 static PyObject
* DBNoSpaceError
; /* ENOSPC */
179 static PyObject
* DBNoMemoryError
; /* DB_BUFFER_SMALL (ENOMEM when < 4.3) */
180 static PyObject
* DBAgainError
; /* EAGAIN */
181 static PyObject
* DBBusyError
; /* EBUSY */
182 static PyObject
* DBFileExistsError
; /* EEXIST */
183 static PyObject
* DBNoSuchFileError
; /* ENOENT */
184 static PyObject
* DBPermissionsError
; /* EPERM */
187 #define DB_BUFFER_SMALL ENOMEM
191 /* --------------------------------------------------------------------- */
192 /* Structure definitions */
194 #if PYTHON_API_VERSION < 1010
195 #error "Python 2.1 or later required"
199 /* Defaults for moduleFlags in DBEnvObject and DBObject. */
200 #define DEFAULT_GET_RETURNS_NONE 1
201 #define DEFAULT_CURSOR_SET_RETURNS_NONE 1 /* 0 in pybsddb < 4.2, python < 2.4 */
204 staticforward PyTypeObject DB_Type
, DBCursor_Type
, DBEnv_Type
, DBTxn_Type
, DBLock_Type
;
207 /* for compatibility with Python 2.5 and earlier */
208 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
211 #define DBObject_Check(v) (Py_TYPE(v) == &DB_Type)
212 #define DBCursorObject_Check(v) (Py_TYPE(v) == &DBCursor_Type)
213 #define DBEnvObject_Check(v) (Py_TYPE(v) == &DBEnv_Type)
214 #define DBTxnObject_Check(v) (Py_TYPE(v) == &DBTxn_Type)
215 #define DBLockObject_Check(v) (Py_TYPE(v) == &DBLock_Type)
217 #define DBSequenceObject_Check(v) (Py_TYPE(v) == &DBSequence_Type)
221 /* --------------------------------------------------------------------- */
222 /* Utility macros and functions */
224 #define RETURN_IF_ERR() \
225 if (makeDBError(err)) { \
229 #define RETURN_NONE() Py_INCREF(Py_None); return Py_None;
231 #define _CHECK_OBJECT_NOT_CLOSED(nonNull, pyErrObj, name) \
232 if ((nonNull) == NULL) { \
233 PyObject *errTuple = NULL; \
234 errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
235 PyErr_SetObject((pyErrObj), errTuple); \
236 Py_DECREF(errTuple); \
240 #define CHECK_DB_NOT_CLOSED(dbobj) \
241 _CHECK_OBJECT_NOT_CLOSED(dbobj->db, DBError, DB)
243 #define CHECK_ENV_NOT_CLOSED(env) \
244 _CHECK_OBJECT_NOT_CLOSED(env->db_env, DBError, DBEnv)
246 #define CHECK_CURSOR_NOT_CLOSED(curs) \
247 _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)
250 #define CHECK_SEQUENCE_NOT_CLOSED(curs) \
251 _CHECK_OBJECT_NOT_CLOSED(curs->sequence, DBError, DBSequence)
254 #define CHECK_DBFLAG(mydb, flag) (((mydb)->flags & (flag)) || \
255 (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))
257 #define CLEAR_DBT(dbt) (memset(&(dbt), 0, sizeof(dbt)))
259 #define FREE_DBT(dbt) if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
260 dbt.data != NULL) { free(dbt.data); dbt.data = NULL; }
263 static int makeDBError(int err
);
266 /* Return the access method type of the DBObject */
267 static int _DB_get_type(DBObject
* self
)
272 err
= self
->db
->get_type(self
->db
, &type
);
273 if (makeDBError(err
)) {
278 return self
->db
->get_type(self
->db
);
283 /* Create a DBT structure (containing key and data values) from Python
284 strings. Returns 1 on success, 0 on an error. */
285 static int make_dbt(PyObject
* obj
, DBT
* dbt
)
288 if (obj
== Py_None
) {
289 /* no need to do anything, the structure has already been zeroed */
291 else if (!PyArg_Parse(obj
, "s#", &dbt
->data
, &dbt
->size
)) {
292 PyErr_SetString(PyExc_TypeError
,
293 "Data values must be of type string or None.");
300 /* Recno and Queue DBs can have integer keys. This function figures out
301 what's been given, verifies that it's allowed, and then makes the DBT.
303 Caller MUST call FREE_DBT(key) when done. */
305 make_key_dbt(DBObject
* self
, PyObject
* keyobj
, DBT
* key
, int* pflags
)
311 if (keyobj
== Py_None
) {
312 type
= _DB_get_type(self
);
315 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
318 "None keys not allowed for Recno and Queue DB's");
321 /* no need to do anything, the structure has already been zeroed */
324 else if (PyString_Check(keyobj
)) {
325 /* verify access method type */
326 type
= _DB_get_type(self
);
329 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
332 "String keys not allowed for Recno and Queue DB's");
337 * NOTE(gps): I don't like doing a data copy here, it seems
338 * wasteful. But without a clean way to tell FREE_DBT if it
339 * should free key->data or not we have to. Other places in
340 * the code check for DB_THREAD and forceably set DBT_MALLOC
341 * when we otherwise would leave flags 0 to indicate that.
343 key
->data
= malloc(PyString_GET_SIZE(keyobj
));
344 if (key
->data
== NULL
) {
345 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
348 memcpy(key
->data
, PyString_AS_STRING(keyobj
),
349 PyString_GET_SIZE(keyobj
));
350 key
->flags
= DB_DBT_REALLOC
;
351 key
->size
= PyString_GET_SIZE(keyobj
);
354 else if (PyInt_Check(keyobj
)) {
355 /* verify access method type */
356 type
= _DB_get_type(self
);
359 if (type
== DB_BTREE
&& pflags
!= NULL
) {
360 /* if BTREE then an Integer key is allowed with the
361 * DB_SET_RECNO flag */
362 *pflags
|= DB_SET_RECNO
;
364 else if (type
!= DB_RECNO
&& type
!= DB_QUEUE
) {
367 "Integer keys only allowed for Recno and Queue DB's");
371 /* Make a key out of the requested recno, use allocated space so DB
372 * will be able to realloc room for the real key if needed. */
373 recno
= PyInt_AS_LONG(keyobj
);
374 key
->data
= malloc(sizeof(db_recno_t
));
375 if (key
->data
== NULL
) {
376 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
379 key
->ulen
= key
->size
= sizeof(db_recno_t
);
380 memcpy(key
->data
, &recno
, sizeof(db_recno_t
));
381 key
->flags
= DB_DBT_REALLOC
;
384 PyErr_Format(PyExc_TypeError
,
385 "String or Integer object expected for key, %s found",
386 Py_TYPE(keyobj
)->tp_name
);
394 /* Add partial record access to an existing DBT data struct.
395 If dlen and doff are set, then the DB_DBT_PARTIAL flag will be set
396 and the data storage/retrieval will be done using dlen and doff. */
397 static int add_partial_dbt(DBT
* d
, int dlen
, int doff
) {
398 /* if neither were set we do nothing (-1 is the default value) */
399 if ((dlen
== -1) && (doff
== -1)) {
403 if ((dlen
< 0) || (doff
< 0)) {
404 PyErr_SetString(PyExc_TypeError
, "dlen and doff must both be >= 0");
408 d
->flags
= d
->flags
| DB_DBT_PARTIAL
;
409 d
->dlen
= (unsigned int) dlen
;
410 d
->doff
= (unsigned int) doff
;
414 /* a safe strcpy() without the zeroing behaviour and semantics of strncpy. */
415 /* TODO: make this use the native libc strlcpy() when available (BSD) */
416 unsigned int our_strlcpy(char* dest
, const char* src
, unsigned int n
)
418 unsigned int srclen
, copylen
;
420 srclen
= strlen(src
);
423 copylen
= (srclen
> n
-1) ? n
-1 : srclen
;
424 /* populate dest[0] thru dest[copylen-1] */
425 memcpy(dest
, src
, copylen
);
426 /* guarantee null termination */
432 /* Callback used to save away more information about errors from the DB
434 static char _db_errmsg
[1024];
436 static void _db_errorCallback(const char* prefix
, char* msg
)
438 static void _db_errorCallback(const DB_ENV
*db_env
,
439 const char* prefix
, const char* msg
)
442 our_strlcpy(_db_errmsg
, msg
, sizeof(_db_errmsg
));
446 /* make a nice exception object to raise for errors. */
447 static int makeDBError(int err
)
449 char errTxt
[2048]; /* really big, just in case... */
450 PyObject
*errObj
= NULL
;
451 PyObject
*errTuple
= NULL
;
452 int exceptionRaised
= 0;
453 unsigned int bytes_left
;
456 case 0: /* successful, no error */ break;
460 #if INCOMPLETE_IS_WARNING
461 bytes_left
= our_strlcpy(errTxt
, db_strerror(err
), sizeof(errTxt
));
462 /* Ensure that bytes_left never goes negative */
463 if (_db_errmsg
[0] && bytes_left
< (sizeof(errTxt
) - 4)) {
464 bytes_left
= sizeof(errTxt
) - bytes_left
- 4 - 1;
465 assert(bytes_left
>= 0);
466 strcat(errTxt
, " -- ");
467 strncat(errTxt
, _db_errmsg
, bytes_left
);
470 exceptionRaised
= PyErr_Warn(PyExc_RuntimeWarning
, errTxt
);
472 #else /* do an exception instead */
473 errObj
= DBIncompleteError
;
476 #endif /* DBVER < 41 */
478 case DB_KEYEMPTY
: errObj
= DBKeyEmptyError
; break;
479 case DB_KEYEXIST
: errObj
= DBKeyExistError
; break;
480 case DB_LOCK_DEADLOCK
: errObj
= DBLockDeadlockError
; break;
481 case DB_LOCK_NOTGRANTED
: errObj
= DBLockNotGrantedError
; break;
482 case DB_NOTFOUND
: errObj
= DBNotFoundError
; break;
483 case DB_OLD_VERSION
: errObj
= DBOldVersionError
; break;
484 case DB_RUNRECOVERY
: errObj
= DBRunRecoveryError
; break;
485 case DB_VERIFY_BAD
: errObj
= DBVerifyBadError
; break;
486 case DB_NOSERVER
: errObj
= DBNoServerError
; break;
487 case DB_NOSERVER_HOME
: errObj
= DBNoServerHomeError
; break;
488 case DB_NOSERVER_ID
: errObj
= DBNoServerIDError
; break;
490 case DB_PAGE_NOTFOUND
: errObj
= DBPageNotFoundError
; break;
491 case DB_SECONDARY_BAD
: errObj
= DBSecondaryBadError
; break;
493 case DB_BUFFER_SMALL
: errObj
= DBNoMemoryError
; break;
496 /* ENOMEM and DB_BUFFER_SMALL were one and the same until 4.3 */
497 case ENOMEM
: errObj
= PyExc_MemoryError
; break;
499 case EINVAL
: errObj
= DBInvalidArgError
; break;
500 case EACCES
: errObj
= DBAccessError
; break;
501 case ENOSPC
: errObj
= DBNoSpaceError
; break;
502 case EAGAIN
: errObj
= DBAgainError
; break;
503 case EBUSY
: errObj
= DBBusyError
; break;
504 case EEXIST
: errObj
= DBFileExistsError
; break;
505 case ENOENT
: errObj
= DBNoSuchFileError
; break;
506 case EPERM
: errObj
= DBPermissionsError
; break;
508 default: errObj
= DBError
; break;
511 if (errObj
!= NULL
) {
512 bytes_left
= our_strlcpy(errTxt
, db_strerror(err
), sizeof(errTxt
));
513 /* Ensure that bytes_left never goes negative */
514 if (_db_errmsg
[0] && bytes_left
< (sizeof(errTxt
) - 4)) {
515 bytes_left
= sizeof(errTxt
) - bytes_left
- 4 - 1;
516 assert(bytes_left
>= 0);
517 strcat(errTxt
, " -- ");
518 strncat(errTxt
, _db_errmsg
, bytes_left
);
522 errTuple
= Py_BuildValue("(is)", err
, errTxt
);
523 PyErr_SetObject(errObj
, errTuple
);
527 return ((errObj
!= NULL
) || exceptionRaised
);
532 /* set a type exception */
533 static void makeTypeError(char* expected
, PyObject
* found
)
535 PyErr_Format(PyExc_TypeError
, "Expected %s argument, %s found.",
536 expected
, Py_TYPE(found
)->tp_name
);
540 /* verify that an obj is either None or a DBTxn, and set the txn pointer */
541 static int checkTxnObj(PyObject
* txnobj
, DB_TXN
** txn
)
543 if (txnobj
== Py_None
|| txnobj
== NULL
) {
547 if (DBTxnObject_Check(txnobj
)) {
548 *txn
= ((DBTxnObject
*)txnobj
)->txn
;
552 makeTypeError("DBTxn", txnobj
);
557 /* Delete a key from a database
558 Returns 0 on success, -1 on an error. */
559 static int _DB_delete(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, int flags
)
563 MYDB_BEGIN_ALLOW_THREADS
;
564 err
= self
->db
->del(self
->db
, txn
, key
, 0);
565 MYDB_END_ALLOW_THREADS
;
566 if (makeDBError(err
)) {
574 /* Store a key into a database
575 Returns 0 on success, -1 on an error. */
576 static int _DB_put(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, DBT
*data
, int flags
)
580 MYDB_BEGIN_ALLOW_THREADS
;
581 err
= self
->db
->put(self
->db
, txn
, key
, data
, flags
);
582 MYDB_END_ALLOW_THREADS
;
583 if (makeDBError(err
)) {
590 /* Get a key/data pair from a cursor */
591 static PyObject
* _DBCursor_get(DBCursorObject
* self
, int extra_flags
,
592 PyObject
*args
, PyObject
*kwargs
, char *format
)
595 PyObject
* retval
= NULL
;
600 static char* kwnames
[] = { "flags", "dlen", "doff", NULL
};
602 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, format
, kwnames
,
603 &flags
, &dlen
, &doff
))
606 CHECK_CURSOR_NOT_CLOSED(self
);
608 flags
|= extra_flags
;
611 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
612 /* Tell BerkeleyDB to malloc the return value (thread safe) */
613 data
.flags
= DB_DBT_MALLOC
;
614 key
.flags
= DB_DBT_MALLOC
;
616 if (!add_partial_dbt(&data
, dlen
, doff
))
619 MYDB_BEGIN_ALLOW_THREADS
;
620 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
621 MYDB_END_ALLOW_THREADS
;
623 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
624 && self
->mydb
->moduleFlags
.getReturnsNone
) {
628 else if (makeDBError(err
)) {
631 else { /* otherwise, success! */
633 /* if Recno or Queue, return the key as an Int */
634 switch (_DB_get_type(self
->mydb
)) {
641 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
642 data
.data
, data
.size
);
647 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
648 data
.data
, data
.size
);
660 /* add an integer to a dictionary using the given name as a key */
661 static void _addIntToDict(PyObject
* dict
, char *name
, int value
)
663 PyObject
* v
= PyInt_FromLong((long) value
);
664 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
670 /* The same, when the value is a time_t */
671 static void _addTimeTToDict(PyObject
* dict
, char *name
, time_t value
)
674 /* if the value fits in regular int, use that. */
675 #ifdef HAVE_LONG_LONG
676 if (sizeof(time_t) > sizeof(long))
677 v
= PyLong_FromLongLong((PY_LONG_LONG
) value
);
680 v
= PyInt_FromLong((long) value
);
681 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
688 /* add an db_seq_t to a dictionary using the given name as a key */
689 static void _addDb_seq_tToDict(PyObject
* dict
, char *name
, db_seq_t value
)
691 PyObject
* v
= PyLong_FromLongLong(value
);
692 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
701 /* --------------------------------------------------------------------- */
702 /* Allocators and deallocators */
705 newDBObject(DBEnvObject
* arg
, int flags
)
708 DB_ENV
* db_env
= NULL
;
711 self
= PyObject_New(DBObject
, &DB_Type
);
718 self
->myenvobj
= NULL
;
720 self
->associateCallback
= NULL
;
721 self
->btCompareCallback
= NULL
;
722 self
->primaryDBType
= 0;
724 self
->in_weakreflist
= NULL
;
726 /* keep a reference to our python DBEnv object */
729 self
->myenvobj
= arg
;
730 db_env
= arg
->db_env
;
734 self
->moduleFlags
= self
->myenvobj
->moduleFlags
;
736 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
737 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
739 MYDB_BEGIN_ALLOW_THREADS
;
740 err
= db_create(&self
->db
, db_env
, flags
);
741 if (self
->db
!= NULL
) {
742 self
->db
->set_errcall(self
->db
, _db_errorCallback
);
744 self
->db
->app_private
= (void*)self
;
747 MYDB_END_ALLOW_THREADS
;
748 /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
749 * list so that a DBEnv can refuse to close without aborting any open
750 * DBTxns and closing any open DBs first. */
751 if (makeDBError(err
)) {
752 if (self
->myenvobj
) {
753 Py_DECREF(self
->myenvobj
);
754 self
->myenvobj
= NULL
;
764 DB_dealloc(DBObject
* self
)
766 if (self
->db
!= NULL
) {
767 /* avoid closing a DB when its DBEnv has been closed out from under
769 if (!self
->myenvobj
||
770 (self
->myenvobj
&& self
->myenvobj
->db_env
))
772 MYDB_BEGIN_ALLOW_THREADS
;
773 self
->db
->close(self
->db
, 0);
774 MYDB_END_ALLOW_THREADS
;
776 PyErr_Warn(PyExc_RuntimeWarning
,
777 "DB could not be closed in destructor: DBEnv already closed");
781 if (self
->in_weakreflist
!= NULL
) {
782 PyObject_ClearWeakRefs((PyObject
*) self
);
784 if (self
->myenvobj
) {
785 Py_DECREF(self
->myenvobj
);
786 self
->myenvobj
= NULL
;
789 if (self
->associateCallback
!= NULL
) {
790 Py_DECREF(self
->associateCallback
);
791 self
->associateCallback
= NULL
;
793 if (self
->btCompareCallback
!= NULL
) {
794 Py_DECREF(self
->btCompareCallback
);
795 self
->btCompareCallback
= NULL
;
802 static DBCursorObject
*
803 newDBCursorObject(DBC
* dbc
, DBObject
* db
)
805 DBCursorObject
* self
= PyObject_New(DBCursorObject
, &DBCursor_Type
);
811 self
->in_weakreflist
= NULL
;
812 Py_INCREF(self
->mydb
);
818 DBCursor_dealloc(DBCursorObject
* self
)
822 if (self
->in_weakreflist
!= NULL
) {
823 PyObject_ClearWeakRefs((PyObject
*) self
);
826 if (self
->dbc
!= NULL
) {
827 MYDB_BEGIN_ALLOW_THREADS
;
828 /* If the underlying database has been closed, we don't
829 need to do anything. If the environment has been closed
830 we need to leak, as BerkeleyDB will crash trying to access
831 the environment. There was an exception when the
832 user closed the environment even though there still was
834 if (self
->mydb
->db
&& self
->mydb
->myenvobj
&&
835 !self
->mydb
->myenvobj
->closed
)
836 err
= self
->dbc
->c_close(self
->dbc
);
838 MYDB_END_ALLOW_THREADS
;
840 Py_XDECREF( self
->mydb
);
846 newDBEnvObject(int flags
)
849 DBEnvObject
* self
= PyObject_New(DBEnvObject
, &DBEnv_Type
);
855 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
856 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
857 self
->in_weakreflist
= NULL
;
859 MYDB_BEGIN_ALLOW_THREADS
;
860 err
= db_env_create(&self
->db_env
, flags
);
861 MYDB_END_ALLOW_THREADS
;
862 if (makeDBError(err
)) {
867 self
->db_env
->set_errcall(self
->db_env
, _db_errorCallback
);
874 DBEnv_dealloc(DBEnvObject
* self
)
876 if (self
->in_weakreflist
!= NULL
) {
877 PyObject_ClearWeakRefs((PyObject
*) self
);
880 if (self
->db_env
&& !self
->closed
) {
881 MYDB_BEGIN_ALLOW_THREADS
;
882 self
->db_env
->close(self
->db_env
, 0);
883 MYDB_END_ALLOW_THREADS
;
890 newDBTxnObject(DBEnvObject
* myenv
, DB_TXN
*parent
, int flags
)
893 DBTxnObject
* self
= PyObject_New(DBTxnObject
, &DBTxn_Type
);
897 self
->env
= (PyObject
*)myenv
;
898 self
->in_weakreflist
= NULL
;
900 MYDB_BEGIN_ALLOW_THREADS
;
902 err
= myenv
->db_env
->txn_begin(myenv
->db_env
, parent
, &(self
->txn
), flags
);
904 err
= txn_begin(myenv
->db_env
, parent
, &(self
->txn
), flags
);
906 MYDB_END_ALLOW_THREADS
;
907 if (makeDBError(err
)) {
908 Py_DECREF(self
->env
);
917 DBTxn_dealloc(DBTxnObject
* self
)
919 if (self
->in_weakreflist
!= NULL
) {
920 PyObject_ClearWeakRefs((PyObject
*) self
);
924 /* it hasn't been finalized, abort it! */
925 MYDB_BEGIN_ALLOW_THREADS
;
927 self
->txn
->abort(self
->txn
);
929 txn_abort(self
->txn
);
931 MYDB_END_ALLOW_THREADS
;
932 PyErr_Warn(PyExc_RuntimeWarning
,
933 "DBTxn aborted in destructor. No prior commit() or abort().");
936 Py_DECREF(self
->env
);
942 newDBLockObject(DBEnvObject
* myenv
, u_int32_t locker
, DBT
* obj
,
943 db_lockmode_t lock_mode
, int flags
)
946 DBLockObject
* self
= PyObject_New(DBLockObject
, &DBLock_Type
);
949 self
->in_weakreflist
= NULL
;
951 MYDB_BEGIN_ALLOW_THREADS
;
953 err
= myenv
->db_env
->lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
,
956 err
= lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
, &self
->lock
);
958 MYDB_END_ALLOW_THREADS
;
959 if (makeDBError(err
)) {
969 DBLock_dealloc(DBLockObject
* self
)
971 if (self
->in_weakreflist
!= NULL
) {
972 PyObject_ClearWeakRefs((PyObject
*) self
);
974 /* TODO: is this lock held? should we release it? */
981 static DBSequenceObject
*
982 newDBSequenceObject(DBObject
* mydb
, int flags
)
985 DBSequenceObject
* self
= PyObject_New(DBSequenceObject
, &DBSequence_Type
);
990 self
->in_weakreflist
= NULL
;
993 MYDB_BEGIN_ALLOW_THREADS
;
994 err
= db_sequence_create(&self
->sequence
, self
->mydb
->db
, flags
);
995 MYDB_END_ALLOW_THREADS
;
996 if (makeDBError(err
)) {
997 Py_DECREF(self
->mydb
);
1007 DBSequence_dealloc(DBSequenceObject
* self
)
1009 if (self
->in_weakreflist
!= NULL
) {
1010 PyObject_ClearWeakRefs((PyObject
*) self
);
1013 Py_DECREF(self
->mydb
);
1018 /* --------------------------------------------------------------------- */
1022 DB_append(DBObject
* self
, PyObject
* args
)
1024 PyObject
* txnobj
= NULL
;
1030 if (!PyArg_UnpackTuple(args
, "append", 1, 2, &dataobj
, &txnobj
))
1033 CHECK_DB_NOT_CLOSED(self
);
1035 /* make a dummy key out of a recno */
1039 key
.size
= sizeof(recno
);
1040 key
.ulen
= key
.size
;
1041 key
.flags
= DB_DBT_USERMEM
;
1043 if (!make_dbt(dataobj
, &data
)) return NULL
;
1044 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1046 if (-1 == _DB_put(self
, txn
, &key
, &data
, DB_APPEND
))
1049 return PyInt_FromLong(recno
);
1056 _db_associateCallback(DB
* db
, const DBT
* priKey
, const DBT
* priData
,
1059 int retval
= DB_DONOTINDEX
;
1060 DBObject
* secondaryDB
= (DBObject
*)db
->app_private
;
1061 PyObject
* callback
= secondaryDB
->associateCallback
;
1062 int type
= secondaryDB
->primaryDBType
;
1064 PyObject
* result
= NULL
;
1067 if (callback
!= NULL
) {
1068 MYDB_BEGIN_BLOCK_THREADS
;
1070 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
1071 args
= Py_BuildValue("(ls#)", *((db_recno_t
*)priKey
->data
),
1072 priData
->data
, priData
->size
);
1074 args
= Py_BuildValue("(s#s#)", priKey
->data
, priKey
->size
,
1075 priData
->data
, priData
->size
);
1077 result
= PyEval_CallObject(callback
, args
);
1079 if (args
== NULL
|| result
== NULL
) {
1082 else if (result
== Py_None
) {
1083 retval
= DB_DONOTINDEX
;
1085 else if (PyInt_Check(result
)) {
1086 retval
= PyInt_AsLong(result
);
1088 else if (PyString_Check(result
)) {
1093 PyString_AsStringAndSize(result
, &data
, &size
);
1094 secKey
->flags
= DB_DBT_APPMALLOC
; /* DB will free */
1095 secKey
->data
= malloc(size
); /* TODO, check this */
1097 memcpy(secKey
->data
, data
, size
);
1098 secKey
->size
= size
;
1102 PyErr_SetString(PyExc_MemoryError
,
1103 "malloc failed in _db_associateCallback");
1110 "DB associate callback should return DB_DONOTINDEX or string.");
1117 MYDB_END_BLOCK_THREADS
;
1124 DB_associate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1127 DBObject
* secondaryDB
;
1130 PyObject
*txnobj
= NULL
;
1132 static char* kwnames
[] = {"secondaryDB", "callback", "flags", "txn",
1135 static char* kwnames
[] = {"secondaryDB", "callback", "flags", NULL
};
1139 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iO:associate", kwnames
,
1140 &secondaryDB
, &callback
, &flags
,
1143 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|i:associate", kwnames
,
1144 &secondaryDB
, &callback
, &flags
)) {
1150 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1153 CHECK_DB_NOT_CLOSED(self
);
1154 if (!DBObject_Check(secondaryDB
)) {
1155 makeTypeError("DB", (PyObject
*)secondaryDB
);
1158 CHECK_DB_NOT_CLOSED(secondaryDB
);
1159 if (callback
== Py_None
) {
1162 else if (!PyCallable_Check(callback
)) {
1163 makeTypeError("Callable", callback
);
1167 /* Save a reference to the callback in the secondary DB. */
1168 Py_XDECREF(secondaryDB
->associateCallback
);
1169 Py_XINCREF(callback
);
1170 secondaryDB
->associateCallback
= callback
;
1171 secondaryDB
->primaryDBType
= _DB_get_type(self
);
1173 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1174 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1175 * The global interepreter lock is not initialized until the first
1176 * thread is created using thread.start_new_thread() or fork() is
1177 * called. that would cause the ALLOW_THREADS here to segfault due
1178 * to a null pointer reference if no threads or child processes
1179 * have been created. This works around that and is a no-op if
1180 * threads have already been initialized.
1181 * (see pybsddb-users mailing list post on 2002-08-07)
1184 PyEval_InitThreads();
1186 MYDB_BEGIN_ALLOW_THREADS
;
1188 err
= self
->db
->associate(self
->db
,
1191 _db_associateCallback
,
1194 err
= self
->db
->associate(self
->db
,
1196 _db_associateCallback
,
1199 MYDB_END_ALLOW_THREADS
;
1202 Py_XDECREF(secondaryDB
->associateCallback
);
1203 secondaryDB
->associateCallback
= NULL
;
1204 secondaryDB
->primaryDBType
= 0;
1216 DB_close(DBObject
* self
, PyObject
* args
)
1219 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
1221 if (self
->db
!= NULL
) {
1223 CHECK_ENV_NOT_CLOSED(self
->myenvobj
);
1224 err
= self
->db
->close(self
->db
, flags
);
1233 _DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1235 int err
, flags
=0, type
;
1236 PyObject
* txnobj
= NULL
;
1237 PyObject
* retval
= NULL
;
1240 static char* kwnames
[] = { "txn", "flags", NULL
};
1242 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:consume", kwnames
,
1246 CHECK_DB_NOT_CLOSED(self
);
1247 type
= _DB_get_type(self
);
1250 if (type
!= DB_QUEUE
) {
1251 PyErr_SetString(PyExc_TypeError
,
1252 "Consume methods only allowed for Queue DB's");
1255 if (!checkTxnObj(txnobj
, &txn
))
1260 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1261 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1262 data
.flags
= DB_DBT_MALLOC
;
1263 key
.flags
= DB_DBT_MALLOC
;
1266 MYDB_BEGIN_ALLOW_THREADS
;
1267 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
|consume_flag
);
1268 MYDB_END_ALLOW_THREADS
;
1270 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1271 && self
->moduleFlags
.getReturnsNone
) {
1277 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
1288 DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1290 return _DB_consume(self
, args
, kwargs
, DB_CONSUME
);
1294 DB_consume_wait(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
,
1297 return _DB_consume(self
, args
, kwargs
, DB_CONSUME_WAIT
);
1302 DB_cursor(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1306 PyObject
* txnobj
= NULL
;
1308 static char* kwnames
[] = { "txn", "flags", NULL
};
1310 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
1313 CHECK_DB_NOT_CLOSED(self
);
1314 if (!checkTxnObj(txnobj
, &txn
))
1317 MYDB_BEGIN_ALLOW_THREADS
;
1318 err
= self
->db
->cursor(self
->db
, txn
, &dbc
, flags
);
1319 MYDB_END_ALLOW_THREADS
;
1321 return (PyObject
*) newDBCursorObject(dbc
, self
);
1326 DB_delete(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1328 PyObject
* txnobj
= NULL
;
1333 static char* kwnames
[] = { "key", "txn", "flags", NULL
};
1335 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:delete", kwnames
,
1336 &keyobj
, &txnobj
, &flags
))
1338 CHECK_DB_NOT_CLOSED(self
);
1339 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1341 if (!checkTxnObj(txnobj
, &txn
)) {
1346 if (-1 == _DB_delete(self
, txn
, &key
, 0)) {
1357 DB_fd(DBObject
* self
, PyObject
* args
)
1361 if (!PyArg_ParseTuple(args
,":fd"))
1363 CHECK_DB_NOT_CLOSED(self
);
1365 MYDB_BEGIN_ALLOW_THREADS
;
1366 err
= self
->db
->fd(self
->db
, &the_fd
);
1367 MYDB_END_ALLOW_THREADS
;
1369 return PyInt_FromLong(the_fd
);
1374 DB_get(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1377 PyObject
* txnobj
= NULL
;
1379 PyObject
* dfltobj
= NULL
;
1380 PyObject
* retval
= NULL
;
1385 static char* kwnames
[] = {"key", "default", "txn", "flags", "dlen",
1388 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:get", kwnames
,
1389 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1393 CHECK_DB_NOT_CLOSED(self
);
1394 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1396 if (!checkTxnObj(txnobj
, &txn
)) {
1402 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1403 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1404 data
.flags
= DB_DBT_MALLOC
;
1406 if (!add_partial_dbt(&data
, dlen
, doff
)) {
1411 MYDB_BEGIN_ALLOW_THREADS
;
1412 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1413 MYDB_END_ALLOW_THREADS
;
1415 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && (dfltobj
!= NULL
)) {
1420 else if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1421 && self
->moduleFlags
.getReturnsNone
) {
1427 if (flags
& DB_SET_RECNO
) /* return both key and data */
1428 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
1430 else /* return just the data */
1431 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
1442 DB_pget(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1445 PyObject
* txnobj
= NULL
;
1447 PyObject
* dfltobj
= NULL
;
1448 PyObject
* retval
= NULL
;
1451 DBT key
, pkey
, data
;
1453 static char* kwnames
[] = {"key", "default", "txn", "flags", "dlen",
1456 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:pget", kwnames
,
1457 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1461 CHECK_DB_NOT_CLOSED(self
);
1462 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1464 if (!checkTxnObj(txnobj
, &txn
)) {
1470 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1471 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1472 data
.flags
= DB_DBT_MALLOC
;
1474 if (!add_partial_dbt(&data
, dlen
, doff
)) {
1480 pkey
.flags
= DB_DBT_MALLOC
;
1482 MYDB_BEGIN_ALLOW_THREADS
;
1483 err
= self
->db
->pget(self
->db
, txn
, &key
, &pkey
, &data
, flags
);
1484 MYDB_END_ALLOW_THREADS
;
1486 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && (dfltobj
!= NULL
)) {
1491 else if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1492 && self
->moduleFlags
.getReturnsNone
) {
1500 dataObj
= PyString_FromStringAndSize(data
.data
, data
.size
);
1502 if (self
->primaryDBType
== DB_RECNO
||
1503 self
->primaryDBType
== DB_QUEUE
)
1504 pkeyObj
= PyInt_FromLong(*(int *)pkey
.data
);
1506 pkeyObj
= PyString_FromStringAndSize(pkey
.data
, pkey
.size
);
1508 if (flags
& DB_SET_RECNO
) /* return key , pkey and data */
1511 int type
= _DB_get_type(self
);
1512 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
1513 keyObj
= PyInt_FromLong(*(int *)key
.data
);
1515 keyObj
= PyString_FromStringAndSize(key
.data
, key
.size
);
1516 #if (PY_VERSION_HEX >= 0x02040000)
1517 retval
= PyTuple_Pack(3, keyObj
, pkeyObj
, dataObj
);
1519 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
1523 else /* return just the pkey and data */
1525 #if (PY_VERSION_HEX >= 0x02040000)
1526 retval
= PyTuple_Pack(2, pkeyObj
, dataObj
);
1528 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
1544 /* Return size of entry */
1546 DB_get_size(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1549 PyObject
* txnobj
= NULL
;
1551 PyObject
* retval
= NULL
;
1554 static char* kwnames
[] = { "key", "txn", NULL
};
1556 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O:get_size", kwnames
,
1559 CHECK_DB_NOT_CLOSED(self
);
1560 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1562 if (!checkTxnObj(txnobj
, &txn
)) {
1568 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
1569 thus getting the record size. */
1570 data
.flags
= DB_DBT_USERMEM
;
1572 MYDB_BEGIN_ALLOW_THREADS
;
1573 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1574 MYDB_END_ALLOW_THREADS
;
1575 if (err
== DB_BUFFER_SMALL
) {
1576 retval
= PyInt_FromLong((long)data
.size
);
1588 DB_get_both(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1591 PyObject
* txnobj
= NULL
;
1594 PyObject
* retval
= NULL
;
1598 static char* kwnames
[] = { "key", "data", "txn", "flags", NULL
};
1601 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oi:get_both", kwnames
,
1602 &keyobj
, &dataobj
, &txnobj
, &flags
))
1605 CHECK_DB_NOT_CLOSED(self
);
1606 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1608 if ( !make_dbt(dataobj
, &data
) ||
1609 !checkTxnObj(txnobj
, &txn
) )
1615 flags
|= DB_GET_BOTH
;
1616 orig_data
= data
.data
;
1618 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1619 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1620 /* XXX(nnorwitz): At least 4.4.20 and 4.5.20 require this flag. */
1621 data
.flags
= DB_DBT_MALLOC
;
1624 MYDB_BEGIN_ALLOW_THREADS
;
1625 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1626 MYDB_END_ALLOW_THREADS
;
1628 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1629 && self
->moduleFlags
.getReturnsNone
) {
1635 /* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */
1636 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
1638 /* Even though the flags require DB_DBT_MALLOC, data is not always
1639 allocated. 4.4: allocated, 4.5: *not* allocated. :-( */
1640 if (data
.data
!= orig_data
)
1651 DB_get_byteswapped(DBObject
* self
, PyObject
* args
)
1658 if (!PyArg_ParseTuple(args
,":get_byteswapped"))
1660 CHECK_DB_NOT_CLOSED(self
);
1663 MYDB_BEGIN_ALLOW_THREADS
;
1664 err
= self
->db
->get_byteswapped(self
->db
, &retval
);
1665 MYDB_END_ALLOW_THREADS
;
1668 MYDB_BEGIN_ALLOW_THREADS
;
1669 retval
= self
->db
->get_byteswapped(self
->db
);
1670 MYDB_END_ALLOW_THREADS
;
1672 return PyInt_FromLong(retval
);
1677 DB_get_type(DBObject
* self
, PyObject
* args
)
1681 if (!PyArg_ParseTuple(args
,":get_type"))
1683 CHECK_DB_NOT_CLOSED(self
);
1685 type
= _DB_get_type(self
);
1688 return PyInt_FromLong(type
);
1693 DB_join(DBObject
* self
, PyObject
* args
)
1697 PyObject
* cursorsObj
;
1701 if (!PyArg_ParseTuple(args
,"O|i:join", &cursorsObj
, &flags
))
1704 CHECK_DB_NOT_CLOSED(self
);
1706 if (!PySequence_Check(cursorsObj
)) {
1707 PyErr_SetString(PyExc_TypeError
,
1708 "Sequence of DBCursor objects expected");
1712 length
= PyObject_Length(cursorsObj
);
1713 cursors
= malloc((length
+1) * sizeof(DBC
*));
1719 cursors
[length
] = NULL
;
1720 for (x
=0; x
<length
; x
++) {
1721 PyObject
* item
= PySequence_GetItem(cursorsObj
, x
);
1726 if (!DBCursorObject_Check(item
)) {
1727 PyErr_SetString(PyExc_TypeError
,
1728 "Sequence of DBCursor objects expected");
1732 cursors
[x
] = ((DBCursorObject
*)item
)->dbc
;
1736 MYDB_BEGIN_ALLOW_THREADS
;
1737 err
= self
->db
->join(self
->db
, cursors
, &dbc
, flags
);
1738 MYDB_END_ALLOW_THREADS
;
1742 /* FIXME: this is a buggy interface. The returned cursor
1743 contains internal references to the passed in cursors
1744 but does not hold python references to them or prevent
1745 them from being closed prematurely. This can cause
1746 python to crash when things are done in the wrong order. */
1747 return (PyObject
*) newDBCursorObject(dbc
, self
);
1752 DB_key_range(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1755 PyObject
* txnobj
= NULL
;
1760 static char* kwnames
[] = { "key", "txn", "flags", NULL
};
1762 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:key_range", kwnames
,
1763 &keyobj
, &txnobj
, &flags
))
1765 CHECK_DB_NOT_CLOSED(self
);
1766 if (!make_dbt(keyobj
, &key
))
1767 /* BTree only, don't need to allow for an int key */
1769 if (!checkTxnObj(txnobj
, &txn
))
1772 MYDB_BEGIN_ALLOW_THREADS
;
1773 err
= self
->db
->key_range(self
->db
, txn
, &key
, &range
, flags
);
1774 MYDB_END_ALLOW_THREADS
;
1777 return Py_BuildValue("ddd", range
.less
, range
.equal
, range
.greater
);
1782 DB_open(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1784 int err
, type
= DB_UNKNOWN
, flags
=0, mode
=0660;
1785 char* filename
= NULL
;
1786 char* dbname
= NULL
;
1788 PyObject
*txnobj
= NULL
;
1791 static char* kwnames
[] = {
1792 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL
};
1793 /* without dbname */
1794 static char* kwnames_basic
[] = {
1795 "filename", "dbtype", "flags", "mode", "txn", NULL
};
1798 static char* kwnames
[] = {
1799 "filename", "dbname", "dbtype", "flags", "mode", NULL
};
1800 /* without dbname */
1801 static char* kwnames_basic
[] = {
1802 "filename", "dbtype", "flags", "mode", NULL
};
1806 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziiiO:open", kwnames
,
1807 &filename
, &dbname
, &type
, &flags
, &mode
,
1810 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziii:open", kwnames
,
1811 &filename
, &dbname
, &type
, &flags
,
1816 type
= DB_UNKNOWN
; flags
= 0; mode
= 0660;
1817 filename
= NULL
; dbname
= NULL
;
1819 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iiiO:open",
1821 &filename
, &type
, &flags
, &mode
,
1825 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iii:open",
1827 &filename
, &type
, &flags
, &mode
))
1833 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1836 if (NULL
== self
->db
) {
1837 PyObject
*t
= Py_BuildValue("(is)", 0,
1838 "Cannot call open() twice for DB object");
1839 PyErr_SetObject(DBError
, t
);
1844 MYDB_BEGIN_ALLOW_THREADS
;
1846 err
= self
->db
->open(self
->db
, txn
, filename
, dbname
, type
, flags
, mode
);
1848 err
= self
->db
->open(self
->db
, filename
, dbname
, type
, flags
, mode
);
1850 MYDB_END_ALLOW_THREADS
;
1851 if (makeDBError(err
)) {
1852 self
->db
->close(self
->db
, 0);
1858 self
->db
->get_flags(self
->db
, &self
->setflags
);
1861 self
->flags
= flags
;
1867 DB_put(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1870 PyObject
* txnobj
= NULL
;
1873 PyObject
* keyobj
, *dataobj
, *retval
;
1876 static char* kwnames
[] = { "key", "data", "txn", "flags", "dlen",
1879 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oiii:put", kwnames
,
1880 &keyobj
, &dataobj
, &txnobj
, &flags
, &dlen
, &doff
))
1883 CHECK_DB_NOT_CLOSED(self
);
1884 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1886 if ( !make_dbt(dataobj
, &data
) ||
1887 !add_partial_dbt(&data
, dlen
, doff
) ||
1888 !checkTxnObj(txnobj
, &txn
) )
1894 if (-1 == _DB_put(self
, txn
, &key
, &data
, flags
)) {
1899 if (flags
& DB_APPEND
)
1900 retval
= PyInt_FromLong(*((db_recno_t
*)key
.data
));
1912 DB_remove(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1915 char* database
= NULL
;
1917 static char* kwnames
[] = { "filename", "dbname", "flags", NULL
};
1919 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zi:remove", kwnames
,
1920 &filename
, &database
, &flags
))
1922 CHECK_DB_NOT_CLOSED(self
);
1924 err
= self
->db
->remove(self
->db
, filename
, database
, flags
);
1933 DB_rename(DBObject
* self
, PyObject
* args
)
1940 if (!PyArg_ParseTuple(args
, "sss|i:rename", &filename
, &database
, &newname
,
1943 CHECK_DB_NOT_CLOSED(self
);
1945 MYDB_BEGIN_ALLOW_THREADS
;
1946 err
= self
->db
->rename(self
->db
, filename
, database
, newname
, flags
);
1947 MYDB_END_ALLOW_THREADS
;
1954 DB_set_bt_minkey(DBObject
* self
, PyObject
* args
)
1958 if (!PyArg_ParseTuple(args
,"i:set_bt_minkey", &minkey
))
1960 CHECK_DB_NOT_CLOSED(self
);
1962 MYDB_BEGIN_ALLOW_THREADS
;
1963 err
= self
->db
->set_bt_minkey(self
->db
, minkey
);
1964 MYDB_END_ALLOW_THREADS
;
1971 _default_cmp(const DBT
*leftKey
,
1972 const DBT
*rightKey
)
1975 int lsize
= leftKey
->size
, rsize
= rightKey
->size
;
1977 res
= memcmp(leftKey
->data
, rightKey
->data
,
1978 lsize
< rsize
? lsize
: rsize
);
1981 if (lsize
< rsize
) {
1984 else if (lsize
> rsize
) {
1992 _db_compareCallback(DB
* db
,
1994 const DBT
*rightKey
)
1998 PyObject
*result
= NULL
;
1999 DBObject
*self
= (DBObject
*)db
->app_private
;
2001 if (self
== NULL
|| self
->btCompareCallback
== NULL
) {
2002 MYDB_BEGIN_BLOCK_THREADS
;
2003 PyErr_SetString(PyExc_TypeError
,
2005 ? "DB_bt_compare db is NULL."
2006 : "DB_bt_compare callback is NULL."));
2007 /* we're in a callback within the DB code, we can't raise */
2009 res
= _default_cmp(leftKey
, rightKey
);
2010 MYDB_END_BLOCK_THREADS
;
2012 MYDB_BEGIN_BLOCK_THREADS
;
2014 args
= Py_BuildValue("s#s#", leftKey
->data
, leftKey
->size
,
2015 rightKey
->data
, rightKey
->size
);
2017 /* XXX(twouters) I highly doubt this INCREF is correct */
2019 result
= PyEval_CallObject(self
->btCompareCallback
, args
);
2021 if (args
== NULL
|| result
== NULL
) {
2022 /* we're in a callback within the DB code, we can't raise */
2024 res
= _default_cmp(leftKey
, rightKey
);
2025 } else if (PyInt_Check(result
)) {
2026 res
= PyInt_AsLong(result
);
2028 PyErr_SetString(PyExc_TypeError
,
2029 "DB_bt_compare callback MUST return an int.");
2030 /* we're in a callback within the DB code, we can't raise */
2032 res
= _default_cmp(leftKey
, rightKey
);
2038 MYDB_END_BLOCK_THREADS
;
2044 DB_set_bt_compare(DBObject
* self
, PyObject
* args
)
2047 PyObject
*comparator
;
2048 PyObject
*tuple
, *result
;
2050 if (!PyArg_ParseTuple(args
, "O:set_bt_compare", &comparator
))
2053 CHECK_DB_NOT_CLOSED(self
);
2055 if (!PyCallable_Check(comparator
)) {
2056 makeTypeError("Callable", comparator
);
2061 * Perform a test call of the comparator function with two empty
2062 * string objects here. verify that it returns an int (0).
2065 tuple
= Py_BuildValue("(ss)", "", "");
2066 result
= PyEval_CallObject(comparator
, tuple
);
2070 if (!PyInt_Check(result
)) {
2071 PyErr_SetString(PyExc_TypeError
,
2072 "callback MUST return an int");
2074 } else if (PyInt_AsLong(result
) != 0) {
2075 PyErr_SetString(PyExc_TypeError
,
2076 "callback failed to return 0 on two empty strings");
2081 /* We don't accept multiple set_bt_compare operations, in order to
2082 * simplify the code. This would have no real use, as one cannot
2083 * change the function once the db is opened anyway */
2084 if (self
->btCompareCallback
!= NULL
) {
2085 PyErr_SetString(PyExc_RuntimeError
, "set_bt_compare() cannot be called more than once");
2089 Py_INCREF(comparator
);
2090 self
->btCompareCallback
= comparator
;
2092 /* This is to workaround a problem with un-initialized threads (see
2093 comment in DB_associate) */
2095 PyEval_InitThreads();
2098 err
= self
->db
->set_bt_compare(self
->db
, _db_compareCallback
);
2101 /* restore the old state in case of error */
2102 Py_DECREF(comparator
);
2103 self
->btCompareCallback
= NULL
;
2109 #endif /* DBVER >= 33 */
2113 DB_set_cachesize(DBObject
* self
, PyObject
* args
)
2116 int gbytes
= 0, bytes
= 0, ncache
= 0;
2118 if (!PyArg_ParseTuple(args
,"ii|i:set_cachesize",
2119 &gbytes
,&bytes
,&ncache
))
2121 CHECK_DB_NOT_CLOSED(self
);
2123 MYDB_BEGIN_ALLOW_THREADS
;
2124 err
= self
->db
->set_cachesize(self
->db
, gbytes
, bytes
, ncache
);
2125 MYDB_END_ALLOW_THREADS
;
2132 DB_set_flags(DBObject
* self
, PyObject
* args
)
2136 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
2138 CHECK_DB_NOT_CLOSED(self
);
2140 MYDB_BEGIN_ALLOW_THREADS
;
2141 err
= self
->db
->set_flags(self
->db
, flags
);
2142 MYDB_END_ALLOW_THREADS
;
2145 self
->setflags
|= flags
;
2151 DB_set_h_ffactor(DBObject
* self
, PyObject
* args
)
2155 if (!PyArg_ParseTuple(args
,"i:set_h_ffactor", &ffactor
))
2157 CHECK_DB_NOT_CLOSED(self
);
2159 MYDB_BEGIN_ALLOW_THREADS
;
2160 err
= self
->db
->set_h_ffactor(self
->db
, ffactor
);
2161 MYDB_END_ALLOW_THREADS
;
2168 DB_set_h_nelem(DBObject
* self
, PyObject
* args
)
2172 if (!PyArg_ParseTuple(args
,"i:set_h_nelem", &nelem
))
2174 CHECK_DB_NOT_CLOSED(self
);
2176 MYDB_BEGIN_ALLOW_THREADS
;
2177 err
= self
->db
->set_h_nelem(self
->db
, nelem
);
2178 MYDB_END_ALLOW_THREADS
;
2185 DB_set_lorder(DBObject
* self
, PyObject
* args
)
2189 if (!PyArg_ParseTuple(args
,"i:set_lorder", &lorder
))
2191 CHECK_DB_NOT_CLOSED(self
);
2193 MYDB_BEGIN_ALLOW_THREADS
;
2194 err
= self
->db
->set_lorder(self
->db
, lorder
);
2195 MYDB_END_ALLOW_THREADS
;
2202 DB_set_pagesize(DBObject
* self
, PyObject
* args
)
2206 if (!PyArg_ParseTuple(args
,"i:set_pagesize", &pagesize
))
2208 CHECK_DB_NOT_CLOSED(self
);
2210 MYDB_BEGIN_ALLOW_THREADS
;
2211 err
= self
->db
->set_pagesize(self
->db
, pagesize
);
2212 MYDB_END_ALLOW_THREADS
;
2219 DB_set_re_delim(DBObject
* self
, PyObject
* args
)
2224 if (!PyArg_ParseTuple(args
,"b:set_re_delim", &delim
)) {
2226 if (!PyArg_ParseTuple(args
,"c:set_re_delim", &delim
))
2230 CHECK_DB_NOT_CLOSED(self
);
2232 MYDB_BEGIN_ALLOW_THREADS
;
2233 err
= self
->db
->set_re_delim(self
->db
, delim
);
2234 MYDB_END_ALLOW_THREADS
;
2240 DB_set_re_len(DBObject
* self
, PyObject
* args
)
2244 if (!PyArg_ParseTuple(args
,"i:set_re_len", &len
))
2246 CHECK_DB_NOT_CLOSED(self
);
2248 MYDB_BEGIN_ALLOW_THREADS
;
2249 err
= self
->db
->set_re_len(self
->db
, len
);
2250 MYDB_END_ALLOW_THREADS
;
2257 DB_set_re_pad(DBObject
* self
, PyObject
* args
)
2262 if (!PyArg_ParseTuple(args
,"b:set_re_pad", &pad
)) {
2264 if (!PyArg_ParseTuple(args
,"c:set_re_pad", &pad
))
2267 CHECK_DB_NOT_CLOSED(self
);
2269 MYDB_BEGIN_ALLOW_THREADS
;
2270 err
= self
->db
->set_re_pad(self
->db
, pad
);
2271 MYDB_END_ALLOW_THREADS
;
2278 DB_set_re_source(DBObject
* self
, PyObject
* args
)
2283 if (!PyArg_ParseTuple(args
,"s:set_re_source", &re_source
))
2285 CHECK_DB_NOT_CLOSED(self
);
2287 MYDB_BEGIN_ALLOW_THREADS
;
2288 err
= self
->db
->set_re_source(self
->db
, re_source
);
2289 MYDB_END_ALLOW_THREADS
;
2296 DB_set_q_extentsize(DBObject
* self
, PyObject
* args
)
2301 if (!PyArg_ParseTuple(args
,"i:set_q_extentsize", &extentsize
))
2303 CHECK_DB_NOT_CLOSED(self
);
2305 MYDB_BEGIN_ALLOW_THREADS
;
2306 err
= self
->db
->set_q_extentsize(self
->db
, extentsize
);
2307 MYDB_END_ALLOW_THREADS
;
2313 DB_stat(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2315 int err
, flags
= 0, type
;
2319 PyObject
* txnobj
= NULL
;
2321 static char* kwnames
[] = { "flags", "txn", NULL
};
2323 static char* kwnames
[] = { "flags", NULL
};
2327 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iO:stat", kwnames
,
2330 if (!checkTxnObj(txnobj
, &txn
))
2333 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat", kwnames
, &flags
))
2336 CHECK_DB_NOT_CLOSED(self
);
2338 MYDB_BEGIN_ALLOW_THREADS
;
2340 err
= self
->db
->stat(self
->db
, txn
, &sp
, flags
);
2342 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2344 err
= self
->db
->stat(self
->db
, &sp
, NULL
, flags
);
2346 MYDB_END_ALLOW_THREADS
;
2351 /* Turn the stat structure into a dictionary */
2352 type
= _DB_get_type(self
);
2353 if ((type
== -1) || ((d
= PyDict_New()) == NULL
)) {
2358 #define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
2359 #define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
2360 #define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
2364 MAKE_HASH_ENTRY(magic
);
2365 MAKE_HASH_ENTRY(version
);
2366 MAKE_HASH_ENTRY(nkeys
);
2367 MAKE_HASH_ENTRY(ndata
);
2368 MAKE_HASH_ENTRY(pagesize
);
2370 MAKE_HASH_ENTRY(nelem
);
2372 MAKE_HASH_ENTRY(ffactor
);
2373 MAKE_HASH_ENTRY(buckets
);
2374 MAKE_HASH_ENTRY(free
);
2375 MAKE_HASH_ENTRY(bfree
);
2376 MAKE_HASH_ENTRY(bigpages
);
2377 MAKE_HASH_ENTRY(big_bfree
);
2378 MAKE_HASH_ENTRY(overflows
);
2379 MAKE_HASH_ENTRY(ovfl_free
);
2380 MAKE_HASH_ENTRY(dup
);
2381 MAKE_HASH_ENTRY(dup_free
);
2386 MAKE_BT_ENTRY(magic
);
2387 MAKE_BT_ENTRY(version
);
2388 MAKE_BT_ENTRY(nkeys
);
2389 MAKE_BT_ENTRY(ndata
);
2390 MAKE_BT_ENTRY(pagesize
);
2391 MAKE_BT_ENTRY(minkey
);
2392 MAKE_BT_ENTRY(re_len
);
2393 MAKE_BT_ENTRY(re_pad
);
2394 MAKE_BT_ENTRY(levels
);
2395 MAKE_BT_ENTRY(int_pg
);
2396 MAKE_BT_ENTRY(leaf_pg
);
2397 MAKE_BT_ENTRY(dup_pg
);
2398 MAKE_BT_ENTRY(over_pg
);
2399 MAKE_BT_ENTRY(free
);
2400 MAKE_BT_ENTRY(int_pgfree
);
2401 MAKE_BT_ENTRY(leaf_pgfree
);
2402 MAKE_BT_ENTRY(dup_pgfree
);
2403 MAKE_BT_ENTRY(over_pgfree
);
2407 MAKE_QUEUE_ENTRY(magic
);
2408 MAKE_QUEUE_ENTRY(version
);
2409 MAKE_QUEUE_ENTRY(nkeys
);
2410 MAKE_QUEUE_ENTRY(ndata
);
2411 MAKE_QUEUE_ENTRY(pagesize
);
2412 MAKE_QUEUE_ENTRY(pages
);
2413 MAKE_QUEUE_ENTRY(re_len
);
2414 MAKE_QUEUE_ENTRY(re_pad
);
2415 MAKE_QUEUE_ENTRY(pgfree
);
2417 MAKE_QUEUE_ENTRY(start
);
2419 MAKE_QUEUE_ENTRY(first_recno
);
2420 MAKE_QUEUE_ENTRY(cur_recno
);
2424 PyErr_SetString(PyExc_TypeError
, "Unknown DB type, unable to stat");
2429 #undef MAKE_HASH_ENTRY
2430 #undef MAKE_BT_ENTRY
2431 #undef MAKE_QUEUE_ENTRY
2438 DB_sync(DBObject
* self
, PyObject
* args
)
2443 if (!PyArg_ParseTuple(args
,"|i:sync", &flags
))
2445 CHECK_DB_NOT_CLOSED(self
);
2447 MYDB_BEGIN_ALLOW_THREADS
;
2448 err
= self
->db
->sync(self
->db
, flags
);
2449 MYDB_END_ALLOW_THREADS
;
2457 DB_truncate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2461 PyObject
* txnobj
= NULL
;
2463 static char* kwnames
[] = { "txn", "flags", NULL
};
2465 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
2468 CHECK_DB_NOT_CLOSED(self
);
2469 if (!checkTxnObj(txnobj
, &txn
))
2472 MYDB_BEGIN_ALLOW_THREADS
;
2473 err
= self
->db
->truncate(self
->db
, txn
, &count
, flags
);
2474 MYDB_END_ALLOW_THREADS
;
2476 return PyInt_FromLong(count
);
2482 DB_upgrade(DBObject
* self
, PyObject
* args
)
2487 if (!PyArg_ParseTuple(args
,"s|i:upgrade", &filename
, &flags
))
2489 CHECK_DB_NOT_CLOSED(self
);
2491 MYDB_BEGIN_ALLOW_THREADS
;
2492 err
= self
->db
->upgrade(self
->db
, filename
, flags
);
2493 MYDB_END_ALLOW_THREADS
;
2500 DB_verify(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2505 char* outFileName
=NULL
;
2507 static char* kwnames
[] = { "filename", "dbname", "outfile", "flags",
2510 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zzi:verify", kwnames
,
2511 &fileName
, &dbName
, &outFileName
, &flags
))
2514 CHECK_DB_NOT_CLOSED(self
);
2516 outFile
= fopen(outFileName
, "w");
2517 /* XXX(nnorwitz): it should probably be an exception if outFile
2520 MYDB_BEGIN_ALLOW_THREADS
;
2521 err
= self
->db
->verify(self
->db
, fileName
, dbName
, outFile
, flags
);
2522 MYDB_END_ALLOW_THREADS
;
2526 /* DB.verify acts as a DB handle destructor (like close); this was
2527 * documented in BerkeleyDB 4.2 but had the undocumented effect
2528 * of not being safe in prior versions while still requiring an explicit
2529 * DB.close call afterwards. Lets call close for the user to emulate
2530 * the safe 4.2 behaviour. */
2532 self
->db
->close(self
->db
, 0);
2542 DB_set_get_returns_none(DBObject
* self
, PyObject
* args
)
2547 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
2549 CHECK_DB_NOT_CLOSED(self
);
2551 if (self
->moduleFlags
.getReturnsNone
)
2553 if (self
->moduleFlags
.cursorSetReturnsNone
)
2555 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
2556 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
2557 return PyInt_FromLong(oldValue
);
2562 DB_set_encrypt(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2566 char *passwd
= NULL
;
2567 static char* kwnames
[] = { "passwd", "flags", NULL
};
2569 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
2574 MYDB_BEGIN_ALLOW_THREADS
;
2575 err
= self
->db
->set_encrypt(self
->db
, passwd
, flags
);
2576 MYDB_END_ALLOW_THREADS
;
2581 #endif /* DBVER >= 41 */
2584 /*-------------------------------------------------------------- */
2585 /* Mapping and Dictionary-like access routines */
2587 Py_ssize_t
DB_length(PyObject
* _self
)
2590 Py_ssize_t size
= 0;
2593 DBObject
* self
= (DBObject
*)_self
;
2595 if (self
->db
== NULL
) {
2596 PyObject
*t
= Py_BuildValue("(is)", 0, "DB object has been closed");
2597 PyErr_SetObject(DBError
, t
);
2602 if (self
->haveStat
) { /* Has the stat function been called recently? If
2603 so, we can use the cached value. */
2604 flags
= DB_FAST_STAT
;
2607 MYDB_BEGIN_ALLOW_THREADS
;
2608 redo_stat_for_length
:
2610 err
= self
->db
->stat(self
->db
, /*txnid*/ NULL
, &sp
, flags
);
2612 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2614 err
= self
->db
->stat(self
->db
, &sp
, NULL
, flags
);
2617 /* All the stat structures have matching fields upto the ndata field,
2618 so we can use any of them for the type cast */
2619 size
= ((DB_BTREE_STAT
*)sp
)->bt_ndata
;
2621 /* A size of 0 could mean that BerkeleyDB no longer had the stat values cached.
2622 * redo a full stat to make sure.
2623 * Fixes SF python bug 1493322, pybsddb bug 1184012
2625 if (size
== 0 && (flags
& DB_FAST_STAT
)) {
2629 goto redo_stat_for_length
;
2632 MYDB_END_ALLOW_THREADS
;
2644 PyObject
* DB_subscript(DBObject
* self
, PyObject
* keyobj
)
2651 CHECK_DB_NOT_CLOSED(self
);
2652 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2656 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2657 /* Tell BerkeleyDB to malloc the return value (thread safe) */
2658 data
.flags
= DB_DBT_MALLOC
;
2660 MYDB_BEGIN_ALLOW_THREADS
;
2661 err
= self
->db
->get(self
->db
, NULL
, &key
, &data
, 0);
2662 MYDB_END_ALLOW_THREADS
;
2663 if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
2664 PyErr_SetObject(PyExc_KeyError
, keyobj
);
2667 else if (makeDBError(err
)) {
2671 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
2681 DB_ass_sub(DBObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
)
2687 if (self
->db
== NULL
) {
2688 PyObject
*t
= Py_BuildValue("(is)", 0, "DB object has been closed");
2689 PyErr_SetObject(DBError
, t
);
2694 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2697 if (dataobj
!= NULL
) {
2698 if (!make_dbt(dataobj
, &data
))
2701 if (self
->setflags
& (DB_DUP
|DB_DUPSORT
))
2702 /* dictionaries shouldn't have duplicate keys */
2703 flags
= DB_NOOVERWRITE
;
2704 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2706 if ((retval
== -1) && (self
->setflags
& (DB_DUP
|DB_DUPSORT
))) {
2707 /* try deleting any old record that matches and then PUT it
2709 _DB_delete(self
, NULL
, &key
, 0);
2711 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2716 /* dataobj == NULL, so delete the key */
2717 retval
= _DB_delete(self
, NULL
, &key
, 0);
2725 DB_has_key(DBObject
* self
, PyObject
* args
)
2730 PyObject
* txnobj
= NULL
;
2733 if (!PyArg_ParseTuple(args
,"O|O:has_key", &keyobj
, &txnobj
))
2735 CHECK_DB_NOT_CLOSED(self
);
2736 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2738 if (!checkTxnObj(txnobj
, &txn
)) {
2743 /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
2744 it has a record but can't allocate a buffer for the data. This saves
2745 having to deal with data we won't be using.
2748 data
.flags
= DB_DBT_USERMEM
;
2750 MYDB_BEGIN_ALLOW_THREADS
;
2751 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, 0);
2752 MYDB_END_ALLOW_THREADS
;
2755 if (err
== DB_BUFFER_SMALL
|| err
== 0) {
2756 return PyInt_FromLong(1);
2757 } else if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
2758 return PyInt_FromLong(0);
2766 #define _KEYS_LIST 1
2767 #define _VALUES_LIST 2
2768 #define _ITEMS_LIST 3
2771 _DB_make_list(DBObject
* self
, DB_TXN
* txn
, int type
)
2778 PyObject
* item
= NULL
;
2780 CHECK_DB_NOT_CLOSED(self
);
2784 dbtype
= _DB_get_type(self
);
2788 list
= PyList_New(0);
2793 MYDB_BEGIN_ALLOW_THREADS
;
2794 err
= self
->db
->cursor(self
->db
, txn
, &cursor
, 0);
2795 MYDB_END_ALLOW_THREADS
;
2796 if (makeDBError(err
)) {
2801 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2802 key
.flags
= DB_DBT_REALLOC
;
2803 data
.flags
= DB_DBT_REALLOC
;
2806 while (1) { /* use the cursor to traverse the DB, collecting items */
2807 MYDB_BEGIN_ALLOW_THREADS
;
2808 err
= cursor
->c_get(cursor
, &key
, &data
, DB_NEXT
);
2809 MYDB_END_ALLOW_THREADS
;
2812 /* for any error, break out of the loop */
2822 item
= PyString_FromStringAndSize((char*)key
.data
, key
.size
);
2826 item
= PyInt_FromLong(*((db_recno_t
*)key
.data
));
2832 item
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
2840 item
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
2845 item
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
2846 data
.data
, data
.size
);
2851 PyErr_Format(PyExc_ValueError
, "Unknown key type 0x%x", type
);
2860 PyList_Append(list
, item
);
2864 /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
2865 if (err
!= DB_NOTFOUND
&& err
!= DB_KEYEMPTY
&& makeDBError(err
)) {
2873 MYDB_BEGIN_ALLOW_THREADS
;
2874 cursor
->c_close(cursor
);
2875 MYDB_END_ALLOW_THREADS
;
2881 DB_keys(DBObject
* self
, PyObject
* args
)
2883 PyObject
* txnobj
= NULL
;
2886 if (!PyArg_UnpackTuple(args
, "keys", 0, 1, &txnobj
))
2888 if (!checkTxnObj(txnobj
, &txn
))
2890 return _DB_make_list(self
, txn
, _KEYS_LIST
);
2895 DB_items(DBObject
* self
, PyObject
* args
)
2897 PyObject
* txnobj
= NULL
;
2900 if (!PyArg_UnpackTuple(args
, "items", 0, 1, &txnobj
))
2902 if (!checkTxnObj(txnobj
, &txn
))
2904 return _DB_make_list(self
, txn
, _ITEMS_LIST
);
2909 DB_values(DBObject
* self
, PyObject
* args
)
2911 PyObject
* txnobj
= NULL
;
2914 if (!PyArg_UnpackTuple(args
, "values", 0, 1, &txnobj
))
2916 if (!checkTxnObj(txnobj
, &txn
))
2918 return _DB_make_list(self
, txn
, _VALUES_LIST
);
2921 /* --------------------------------------------------------------------- */
2922 /* DBCursor methods */
2926 DBC_close(DBCursorObject
* self
, PyObject
* args
)
2930 if (!PyArg_ParseTuple(args
, ":close"))
2933 if (self
->dbc
!= NULL
) {
2934 MYDB_BEGIN_ALLOW_THREADS
;
2935 err
= self
->dbc
->c_close(self
->dbc
);
2937 MYDB_END_ALLOW_THREADS
;
2945 DBC_count(DBCursorObject
* self
, PyObject
* args
)
2951 if (!PyArg_ParseTuple(args
, "|i:count", &flags
))
2954 CHECK_CURSOR_NOT_CLOSED(self
);
2956 MYDB_BEGIN_ALLOW_THREADS
;
2957 err
= self
->dbc
->c_count(self
->dbc
, &count
, flags
);
2958 MYDB_END_ALLOW_THREADS
;
2961 return PyInt_FromLong(count
);
2966 DBC_current(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2968 return _DBCursor_get(self
,DB_CURRENT
,args
,kwargs
,"|iii:current");
2973 DBC_delete(DBCursorObject
* self
, PyObject
* args
)
2977 if (!PyArg_ParseTuple(args
, "|i:delete", &flags
))
2980 CHECK_CURSOR_NOT_CLOSED(self
);
2982 MYDB_BEGIN_ALLOW_THREADS
;
2983 err
= self
->dbc
->c_del(self
->dbc
, flags
);
2984 MYDB_END_ALLOW_THREADS
;
2987 self
->mydb
->haveStat
= 0;
2993 DBC_dup(DBCursorObject
* self
, PyObject
* args
)
2998 if (!PyArg_ParseTuple(args
, "|i:dup", &flags
))
3001 CHECK_CURSOR_NOT_CLOSED(self
);
3003 MYDB_BEGIN_ALLOW_THREADS
;
3004 err
= self
->dbc
->c_dup(self
->dbc
, &dbc
, flags
);
3005 MYDB_END_ALLOW_THREADS
;
3008 return (PyObject
*) newDBCursorObject(dbc
, self
->mydb
);
3012 DBC_first(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3014 return _DBCursor_get(self
,DB_FIRST
,args
,kwargs
,"|iii:first");
3019 DBC_get(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3022 PyObject
* keyobj
= NULL
;
3023 PyObject
* dataobj
= NULL
;
3024 PyObject
* retval
= NULL
;
3028 static char* kwnames
[] = { "key","data", "flags", "dlen", "doff",
3033 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:get", &kwnames
[2],
3034 &flags
, &dlen
, &doff
))
3037 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:get",
3039 &keyobj
, &flags
, &dlen
, &doff
))
3042 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:get",
3043 kwnames
, &keyobj
, &dataobj
,
3044 &flags
, &dlen
, &doff
))
3051 CHECK_CURSOR_NOT_CLOSED(self
);
3053 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3055 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
3056 (!add_partial_dbt(&data
, dlen
, doff
)) )
3062 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3063 data
.flags
= DB_DBT_MALLOC
;
3064 if (!(key
.flags
& DB_DBT_REALLOC
)) {
3065 key
.flags
|= DB_DBT_MALLOC
;
3069 MYDB_BEGIN_ALLOW_THREADS
;
3070 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
3071 MYDB_END_ALLOW_THREADS
;
3073 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3074 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3078 else if (makeDBError(err
)) {
3082 switch (_DB_get_type(self
->mydb
)) {
3089 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3090 data
.data
, data
.size
);
3094 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3095 data
.data
, data
.size
);
3106 DBC_pget(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3109 PyObject
* keyobj
= NULL
;
3110 PyObject
* dataobj
= NULL
;
3111 PyObject
* retval
= NULL
;
3114 DBT key
, pkey
, data
;
3115 static char* kwnames_keyOnly
[] = { "key", "flags", "dlen", "doff", NULL
};
3116 static char* kwnames
[] = { "key", "data", "flags", "dlen", "doff", NULL
};
3120 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:pget", &kwnames
[2],
3121 &flags
, &dlen
, &doff
))
3124 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:pget",
3126 &keyobj
, &flags
, &dlen
, &doff
))
3129 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:pget",
3130 kwnames
, &keyobj
, &dataobj
,
3131 &flags
, &dlen
, &doff
))
3138 CHECK_CURSOR_NOT_CLOSED(self
);
3140 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3142 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
3143 (!add_partial_dbt(&data
, dlen
, doff
)) ) {
3148 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3149 data
.flags
= DB_DBT_MALLOC
;
3150 if (!(key
.flags
& DB_DBT_REALLOC
)) {
3151 key
.flags
|= DB_DBT_MALLOC
;
3156 pkey
.flags
= DB_DBT_MALLOC
;
3158 MYDB_BEGIN_ALLOW_THREADS
;
3159 err
= self
->dbc
->c_pget(self
->dbc
, &key
, &pkey
, &data
, flags
);
3160 MYDB_END_ALLOW_THREADS
;
3162 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3163 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3167 else if (makeDBError(err
)) {
3173 dataObj
= PyString_FromStringAndSize(data
.data
, data
.size
);
3175 if (self
->mydb
->primaryDBType
== DB_RECNO
||
3176 self
->mydb
->primaryDBType
== DB_QUEUE
)
3177 pkeyObj
= PyInt_FromLong(*(int *)pkey
.data
);
3179 pkeyObj
= PyString_FromStringAndSize(pkey
.data
, pkey
.size
);
3181 if (key
.data
&& key
.size
) /* return key, pkey and data */
3184 int type
= _DB_get_type(self
->mydb
);
3185 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
3186 keyObj
= PyInt_FromLong(*(int *)key
.data
);
3188 keyObj
= PyString_FromStringAndSize(key
.data
, key
.size
);
3189 #if (PY_VERSION_HEX >= 0x02040000)
3190 retval
= PyTuple_Pack(3, keyObj
, pkeyObj
, dataObj
);
3192 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
3197 else /* return just the pkey and data */
3199 #if (PY_VERSION_HEX >= 0x02040000)
3200 retval
= PyTuple_Pack(2, pkeyObj
, dataObj
);
3202 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
3210 /* the only time REALLOC should be set is if we used an integer
3211 * key that make_key_dbt malloc'd for us. always free these. */
3212 if (key
.flags
& DB_DBT_REALLOC
) {
3221 DBC_get_recno(DBCursorObject
* self
, PyObject
* args
)
3228 if (!PyArg_ParseTuple(args
, ":get_recno"))
3231 CHECK_CURSOR_NOT_CLOSED(self
);
3235 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3236 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3237 data
.flags
= DB_DBT_MALLOC
;
3238 key
.flags
= DB_DBT_MALLOC
;
3241 MYDB_BEGIN_ALLOW_THREADS
;
3242 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, DB_GET_RECNO
);
3243 MYDB_END_ALLOW_THREADS
;
3246 recno
= *((db_recno_t
*)data
.data
);
3249 return PyInt_FromLong(recno
);
3254 DBC_last(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3256 return _DBCursor_get(self
,DB_LAST
,args
,kwargs
,"|iii:last");
3261 DBC_next(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3263 return _DBCursor_get(self
,DB_NEXT
,args
,kwargs
,"|iii:next");
3268 DBC_prev(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3270 return _DBCursor_get(self
,DB_PREV
,args
,kwargs
,"|iii:prev");
3275 DBC_put(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3278 PyObject
* keyobj
, *dataobj
;
3280 static char* kwnames
[] = { "key", "data", "flags", "dlen", "doff",
3285 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iii:put", kwnames
,
3286 &keyobj
, &dataobj
, &flags
, &dlen
, &doff
))
3289 CHECK_CURSOR_NOT_CLOSED(self
);
3291 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3293 if (!make_dbt(dataobj
, &data
) ||
3294 !add_partial_dbt(&data
, dlen
, doff
) )
3300 MYDB_BEGIN_ALLOW_THREADS
;
3301 err
= self
->dbc
->c_put(self
->dbc
, &key
, &data
, flags
);
3302 MYDB_END_ALLOW_THREADS
;
3305 self
->mydb
->haveStat
= 0;
3311 DBC_set(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3315 PyObject
* retval
, *keyobj
;
3316 static char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
3320 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set", kwnames
,
3321 &keyobj
, &flags
, &dlen
, &doff
))
3324 CHECK_CURSOR_NOT_CLOSED(self
);
3326 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3330 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3331 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3332 data
.flags
= DB_DBT_MALLOC
;
3334 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3339 MYDB_BEGIN_ALLOW_THREADS
;
3340 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET
);
3341 MYDB_END_ALLOW_THREADS
;
3342 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3343 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3347 else if (makeDBError(err
)) {
3351 switch (_DB_get_type(self
->mydb
)) {
3358 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3359 data
.data
, data
.size
);
3363 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3364 data
.data
, data
.size
);
3370 /* the only time REALLOC should be set is if we used an integer
3371 * key that make_key_dbt malloc'd for us. always free these. */
3372 if (key
.flags
& DB_DBT_REALLOC
) {
3381 DBC_set_range(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3385 PyObject
* retval
, *keyobj
;
3386 static char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
3390 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set_range", kwnames
,
3391 &keyobj
, &flags
, &dlen
, &doff
))
3394 CHECK_CURSOR_NOT_CLOSED(self
);
3396 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3400 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3404 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3405 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3406 data
.flags
|= DB_DBT_MALLOC
;
3407 /* only BTREE databases will return anything in the key */
3408 if (!(key
.flags
& DB_DBT_REALLOC
) && _DB_get_type(self
->mydb
) == DB_BTREE
) {
3409 key
.flags
|= DB_DBT_MALLOC
;
3412 MYDB_BEGIN_ALLOW_THREADS
;
3413 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RANGE
);
3414 MYDB_END_ALLOW_THREADS
;
3415 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3416 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3420 else if (makeDBError(err
)) {
3424 switch (_DB_get_type(self
->mydb
)) {
3431 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3432 data
.data
, data
.size
);
3436 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3437 data
.data
, data
.size
);
3443 /* the only time REALLOC should be set is if we used an integer
3444 * key that make_key_dbt malloc'd for us. always free these. */
3445 if (key
.flags
& DB_DBT_REALLOC
) {
3453 _DBC_get_set_both(DBCursorObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
,
3454 int flags
, unsigned int returnsNone
)
3460 /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
3461 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3463 if (!make_dbt(dataobj
, &data
)) {
3468 MYDB_BEGIN_ALLOW_THREADS
;
3469 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_GET_BOTH
);
3470 MYDB_END_ALLOW_THREADS
;
3471 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && returnsNone
) {
3475 else if (makeDBError(err
)) {
3479 switch (_DB_get_type(self
->mydb
)) {
3486 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3487 data
.data
, data
.size
);
3491 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3492 data
.data
, data
.size
);
3502 DBC_get_both(DBCursorObject
* self
, PyObject
* args
)
3505 PyObject
*keyobj
, *dataobj
;
3507 if (!PyArg_ParseTuple(args
, "OO|i:get_both", &keyobj
, &dataobj
, &flags
))
3510 /* if the cursor is closed, self->mydb may be invalid */
3511 CHECK_CURSOR_NOT_CLOSED(self
);
3513 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3514 self
->mydb
->moduleFlags
.getReturnsNone
);
3517 /* Return size of entry */
3519 DBC_get_current_size(DBCursorObject
* self
, PyObject
* args
)
3521 int err
, flags
=DB_CURRENT
;
3522 PyObject
* retval
= NULL
;
3525 if (!PyArg_ParseTuple(args
, ":get_current_size"))
3527 CHECK_CURSOR_NOT_CLOSED(self
);
3531 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
3532 getting the record size. */
3533 data
.flags
= DB_DBT_USERMEM
;
3535 MYDB_BEGIN_ALLOW_THREADS
;
3536 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
3537 MYDB_END_ALLOW_THREADS
;
3538 if (err
== DB_BUFFER_SMALL
|| !err
) {
3539 /* DB_BUFFER_SMALL means positive size, !err means zero length value */
3540 retval
= PyInt_FromLong((long)data
.size
);
3551 DBC_set_both(DBCursorObject
* self
, PyObject
* args
)
3554 PyObject
*keyobj
, *dataobj
;
3556 if (!PyArg_ParseTuple(args
, "OO|i:set_both", &keyobj
, &dataobj
, &flags
))
3559 /* if the cursor is closed, self->mydb may be invalid */
3560 CHECK_CURSOR_NOT_CLOSED(self
);
3562 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3563 self
->mydb
->moduleFlags
.cursorSetReturnsNone
);
3568 DBC_set_recno(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3570 int err
, irecno
, flags
=0;
3576 static char* kwnames
[] = { "recno","flags", "dlen", "doff", NULL
};
3578 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|iii:set_recno", kwnames
,
3579 &irecno
, &flags
, &dlen
, &doff
))
3582 CHECK_CURSOR_NOT_CLOSED(self
);
3585 recno
= (db_recno_t
) irecno
;
3586 /* use allocated space so DB will be able to realloc room for the real
3588 key
.data
= malloc(sizeof(db_recno_t
));
3589 if (key
.data
== NULL
) {
3590 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
3593 key
.size
= sizeof(db_recno_t
);
3594 key
.ulen
= key
.size
;
3595 memcpy(key
.data
, &recno
, sizeof(db_recno_t
));
3596 key
.flags
= DB_DBT_REALLOC
;
3599 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3600 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3601 data
.flags
= DB_DBT_MALLOC
;
3603 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3608 MYDB_BEGIN_ALLOW_THREADS
;
3609 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RECNO
);
3610 MYDB_END_ALLOW_THREADS
;
3611 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3612 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3616 else if (makeDBError(err
)) {
3619 else { /* Can only be used for BTrees, so no need to return int key */
3620 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3621 data
.data
, data
.size
);
3631 DBC_consume(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3633 return _DBCursor_get(self
,DB_CONSUME
,args
,kwargs
,"|iii:consume");
3638 DBC_next_dup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3640 return _DBCursor_get(self
,DB_NEXT_DUP
,args
,kwargs
,"|iii:next_dup");
3645 DBC_next_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3647 return _DBCursor_get(self
,DB_NEXT_NODUP
,args
,kwargs
,"|iii:next_nodup");
3652 DBC_prev_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3654 return _DBCursor_get(self
,DB_PREV_NODUP
,args
,kwargs
,"|iii:prev_nodup");
3659 DBC_join_item(DBCursorObject
* self
, PyObject
* args
)
3665 if (!PyArg_ParseTuple(args
, "|i:join_item", &flags
))
3668 CHECK_CURSOR_NOT_CLOSED(self
);
3672 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3673 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3674 key
.flags
= DB_DBT_MALLOC
;
3677 MYDB_BEGIN_ALLOW_THREADS
;
3678 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
| DB_JOIN_ITEM
);
3679 MYDB_END_ALLOW_THREADS
;
3680 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3681 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3685 else if (makeDBError(err
)) {
3689 retval
= Py_BuildValue("s#", key
.data
, key
.size
);
3698 /* --------------------------------------------------------------------- */
3703 DBEnv_close(DBEnvObject
* self
, PyObject
* args
)
3707 if (!PyArg_ParseTuple(args
, "|i:close", &flags
))
3709 if (!self
->closed
) { /* Don't close more than once */
3710 MYDB_BEGIN_ALLOW_THREADS
;
3711 err
= self
->db_env
->close(self
->db_env
, flags
);
3712 MYDB_END_ALLOW_THREADS
;
3713 /* after calling DBEnv->close, regardless of error, this DBEnv
3714 * may not be accessed again (BerkeleyDB docs). */
3716 self
->db_env
= NULL
;
3724 DBEnv_open(DBEnvObject
* self
, PyObject
* args
)
3726 int err
, flags
=0, mode
=0660;
3729 if (!PyArg_ParseTuple(args
, "z|ii:open", &db_home
, &flags
, &mode
))
3732 CHECK_ENV_NOT_CLOSED(self
);
3734 MYDB_BEGIN_ALLOW_THREADS
;
3735 err
= self
->db_env
->open(self
->db_env
, db_home
, flags
, mode
);
3736 MYDB_END_ALLOW_THREADS
;
3739 self
->flags
= flags
;
3745 DBEnv_remove(DBEnvObject
* self
, PyObject
* args
)
3750 if (!PyArg_ParseTuple(args
, "s|i:remove", &db_home
, &flags
))
3752 CHECK_ENV_NOT_CLOSED(self
);
3753 MYDB_BEGIN_ALLOW_THREADS
;
3754 err
= self
->db_env
->remove(self
->db_env
, db_home
, flags
);
3755 MYDB_END_ALLOW_THREADS
;
3762 DBEnv_dbremove(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3767 char *database
= NULL
;
3768 PyObject
*txnobj
= NULL
;
3770 static char* kwnames
[] = { "file", "database", "txn", "flags",
3773 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zOi:dbremove", kwnames
,
3774 &file
, &database
, &txnobj
, &flags
)) {
3777 if (!checkTxnObj(txnobj
, &txn
)) {
3780 CHECK_ENV_NOT_CLOSED(self
);
3781 MYDB_BEGIN_ALLOW_THREADS
;
3782 err
= self
->db_env
->dbremove(self
->db_env
, txn
, file
, database
, flags
);
3783 MYDB_END_ALLOW_THREADS
;
3789 DBEnv_dbrename(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3794 char *database
= NULL
;
3795 char *newname
= NULL
;
3796 PyObject
*txnobj
= NULL
;
3798 static char* kwnames
[] = { "file", "database", "newname", "txn",
3801 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "szs|Oi:dbrename", kwnames
,
3802 &file
, &database
, &newname
, &txnobj
, &flags
)) {
3805 if (!checkTxnObj(txnobj
, &txn
)) {
3808 CHECK_ENV_NOT_CLOSED(self
);
3809 MYDB_BEGIN_ALLOW_THREADS
;
3810 err
= self
->db_env
->dbrename(self
->db_env
, txn
, file
, database
, newname
,
3812 MYDB_END_ALLOW_THREADS
;
3818 DBEnv_set_encrypt(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3822 char *passwd
= NULL
;
3823 static char* kwnames
[] = { "passwd", "flags", NULL
};
3825 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
3830 MYDB_BEGIN_ALLOW_THREADS
;
3831 err
= self
->db_env
->set_encrypt(self
->db_env
, passwd
, flags
);
3832 MYDB_END_ALLOW_THREADS
;
3837 #endif /* DBVER >= 41 */
3841 DBEnv_set_timeout(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3845 u_int32_t timeout
= 0;
3846 static char* kwnames
[] = { "timeout", "flags", NULL
};
3848 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ii:set_timeout", kwnames
,
3849 &timeout
, &flags
)) {
3853 MYDB_BEGIN_ALLOW_THREADS
;
3854 err
= self
->db_env
->set_timeout(self
->db_env
, (db_timeout_t
)timeout
, flags
);
3855 MYDB_END_ALLOW_THREADS
;
3860 #endif /* DBVER >= 40 */
3863 DBEnv_set_shm_key(DBEnvObject
* self
, PyObject
* args
)
3868 if (!PyArg_ParseTuple(args
, "l:set_shm_key", &shm_key
))
3870 CHECK_ENV_NOT_CLOSED(self
);
3872 err
= self
->db_env
->set_shm_key(self
->db_env
, shm_key
);
3878 DBEnv_set_cachesize(DBEnvObject
* self
, PyObject
* args
)
3880 int err
, gbytes
=0, bytes
=0, ncache
=0;
3882 if (!PyArg_ParseTuple(args
, "ii|i:set_cachesize",
3883 &gbytes
, &bytes
, &ncache
))
3885 CHECK_ENV_NOT_CLOSED(self
);
3887 MYDB_BEGIN_ALLOW_THREADS
;
3888 err
= self
->db_env
->set_cachesize(self
->db_env
, gbytes
, bytes
, ncache
);
3889 MYDB_END_ALLOW_THREADS
;
3896 DBEnv_set_flags(DBEnvObject
* self
, PyObject
* args
)
3898 int err
, flags
=0, onoff
=0;
3900 if (!PyArg_ParseTuple(args
, "ii:set_flags",
3903 CHECK_ENV_NOT_CLOSED(self
);
3905 MYDB_BEGIN_ALLOW_THREADS
;
3906 err
= self
->db_env
->set_flags(self
->db_env
, flags
, onoff
);
3907 MYDB_END_ALLOW_THREADS
;
3914 DBEnv_set_data_dir(DBEnvObject
* self
, PyObject
* args
)
3919 if (!PyArg_ParseTuple(args
, "s:set_data_dir", &dir
))
3921 CHECK_ENV_NOT_CLOSED(self
);
3923 MYDB_BEGIN_ALLOW_THREADS
;
3924 err
= self
->db_env
->set_data_dir(self
->db_env
, dir
);
3925 MYDB_END_ALLOW_THREADS
;
3932 DBEnv_set_lg_bsize(DBEnvObject
* self
, PyObject
* args
)
3936 if (!PyArg_ParseTuple(args
, "i:set_lg_bsize", &lg_bsize
))
3938 CHECK_ENV_NOT_CLOSED(self
);
3940 MYDB_BEGIN_ALLOW_THREADS
;
3941 err
= self
->db_env
->set_lg_bsize(self
->db_env
, lg_bsize
);
3942 MYDB_END_ALLOW_THREADS
;
3949 DBEnv_set_lg_dir(DBEnvObject
* self
, PyObject
* args
)
3954 if (!PyArg_ParseTuple(args
, "s:set_lg_dir", &dir
))
3956 CHECK_ENV_NOT_CLOSED(self
);
3958 MYDB_BEGIN_ALLOW_THREADS
;
3959 err
= self
->db_env
->set_lg_dir(self
->db_env
, dir
);
3960 MYDB_END_ALLOW_THREADS
;
3966 DBEnv_set_lg_max(DBEnvObject
* self
, PyObject
* args
)
3970 if (!PyArg_ParseTuple(args
, "i:set_lg_max", &lg_max
))
3972 CHECK_ENV_NOT_CLOSED(self
);
3974 MYDB_BEGIN_ALLOW_THREADS
;
3975 err
= self
->db_env
->set_lg_max(self
->db_env
, lg_max
);
3976 MYDB_END_ALLOW_THREADS
;
3984 DBEnv_set_lg_regionmax(DBEnvObject
* self
, PyObject
* args
)
3988 if (!PyArg_ParseTuple(args
, "i:set_lg_regionmax", &lg_max
))
3990 CHECK_ENV_NOT_CLOSED(self
);
3992 MYDB_BEGIN_ALLOW_THREADS
;
3993 err
= self
->db_env
->set_lg_regionmax(self
->db_env
, lg_max
);
3994 MYDB_END_ALLOW_THREADS
;
4002 DBEnv_set_lk_detect(DBEnvObject
* self
, PyObject
* args
)
4006 if (!PyArg_ParseTuple(args
, "i:set_lk_detect", &lk_detect
))
4008 CHECK_ENV_NOT_CLOSED(self
);
4010 MYDB_BEGIN_ALLOW_THREADS
;
4011 err
= self
->db_env
->set_lk_detect(self
->db_env
, lk_detect
);
4012 MYDB_END_ALLOW_THREADS
;
4020 DBEnv_set_lk_max(DBEnvObject
* self
, PyObject
* args
)
4024 if (!PyArg_ParseTuple(args
, "i:set_lk_max", &max
))
4026 CHECK_ENV_NOT_CLOSED(self
);
4028 MYDB_BEGIN_ALLOW_THREADS
;
4029 err
= self
->db_env
->set_lk_max(self
->db_env
, max
);
4030 MYDB_END_ALLOW_THREADS
;
4039 DBEnv_set_lk_max_locks(DBEnvObject
* self
, PyObject
* args
)
4043 if (!PyArg_ParseTuple(args
, "i:set_lk_max_locks", &max
))
4045 CHECK_ENV_NOT_CLOSED(self
);
4047 MYDB_BEGIN_ALLOW_THREADS
;
4048 err
= self
->db_env
->set_lk_max_locks(self
->db_env
, max
);
4049 MYDB_END_ALLOW_THREADS
;
4056 DBEnv_set_lk_max_lockers(DBEnvObject
* self
, PyObject
* args
)
4060 if (!PyArg_ParseTuple(args
, "i:set_lk_max_lockers", &max
))
4062 CHECK_ENV_NOT_CLOSED(self
);
4064 MYDB_BEGIN_ALLOW_THREADS
;
4065 err
= self
->db_env
->set_lk_max_lockers(self
->db_env
, max
);
4066 MYDB_END_ALLOW_THREADS
;
4073 DBEnv_set_lk_max_objects(DBEnvObject
* self
, PyObject
* args
)
4077 if (!PyArg_ParseTuple(args
, "i:set_lk_max_objects", &max
))
4079 CHECK_ENV_NOT_CLOSED(self
);
4081 MYDB_BEGIN_ALLOW_THREADS
;
4082 err
= self
->db_env
->set_lk_max_objects(self
->db_env
, max
);
4083 MYDB_END_ALLOW_THREADS
;
4090 DBEnv_set_mp_mmapsize(DBEnvObject
* self
, PyObject
* args
)
4092 int err
, mp_mmapsize
;
4094 if (!PyArg_ParseTuple(args
, "i:set_mp_mmapsize", &mp_mmapsize
))
4096 CHECK_ENV_NOT_CLOSED(self
);
4098 MYDB_BEGIN_ALLOW_THREADS
;
4099 err
= self
->db_env
->set_mp_mmapsize(self
->db_env
, mp_mmapsize
);
4100 MYDB_END_ALLOW_THREADS
;
4107 DBEnv_set_tmp_dir(DBEnvObject
* self
, PyObject
* args
)
4112 if (!PyArg_ParseTuple(args
, "s:set_tmp_dir", &dir
))
4114 CHECK_ENV_NOT_CLOSED(self
);
4116 MYDB_BEGIN_ALLOW_THREADS
;
4117 err
= self
->db_env
->set_tmp_dir(self
->db_env
, dir
);
4118 MYDB_END_ALLOW_THREADS
;
4125 DBEnv_txn_begin(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4128 PyObject
* txnobj
= NULL
;
4130 static char* kwnames
[] = { "parent", "flags", NULL
};
4132 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:txn_begin", kwnames
,
4136 if (!checkTxnObj(txnobj
, &txn
))
4138 CHECK_ENV_NOT_CLOSED(self
);
4140 return (PyObject
*)newDBTxnObject(self
, txn
, flags
);
4145 DBEnv_txn_checkpoint(DBEnvObject
* self
, PyObject
* args
)
4147 int err
, kbyte
=0, min
=0, flags
=0;
4149 if (!PyArg_ParseTuple(args
, "|iii:txn_checkpoint", &kbyte
, &min
, &flags
))
4151 CHECK_ENV_NOT_CLOSED(self
);
4153 MYDB_BEGIN_ALLOW_THREADS
;
4155 err
= self
->db_env
->txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
4157 err
= txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
4159 MYDB_END_ALLOW_THREADS
;
4166 DBEnv_set_tx_max(DBEnvObject
* self
, PyObject
* args
)
4170 if (!PyArg_ParseTuple(args
, "i:set_tx_max", &max
))
4172 CHECK_ENV_NOT_CLOSED(self
);
4174 err
= self
->db_env
->set_tx_max(self
->db_env
, max
);
4181 DBEnv_set_tx_timestamp(DBEnvObject
* self
, PyObject
* args
)
4187 if (!PyArg_ParseTuple(args
, "l:set_tx_timestamp", &stamp
))
4189 CHECK_ENV_NOT_CLOSED(self
);
4190 timestamp
= (time_t)stamp
;
4191 err
= self
->db_env
->set_tx_timestamp(self
->db_env
, ×tamp
);
4198 DBEnv_lock_detect(DBEnvObject
* self
, PyObject
* args
)
4200 int err
, atype
, flags
=0;
4203 if (!PyArg_ParseTuple(args
, "i|i:lock_detect", &atype
, &flags
))
4205 CHECK_ENV_NOT_CLOSED(self
);
4207 MYDB_BEGIN_ALLOW_THREADS
;
4209 err
= self
->db_env
->lock_detect(self
->db_env
, flags
, atype
, &aborted
);
4211 err
= lock_detect(self
->db_env
, flags
, atype
, &aborted
);
4213 MYDB_END_ALLOW_THREADS
;
4215 return PyInt_FromLong(aborted
);
4220 DBEnv_lock_get(DBEnvObject
* self
, PyObject
* args
)
4223 int locker
, lock_mode
;
4227 if (!PyArg_ParseTuple(args
, "iOi|i:lock_get", &locker
, &objobj
, &lock_mode
, &flags
))
4231 if (!make_dbt(objobj
, &obj
))
4234 return (PyObject
*)newDBLockObject(self
, locker
, &obj
, lock_mode
, flags
);
4239 DBEnv_lock_id(DBEnvObject
* self
, PyObject
* args
)
4244 if (!PyArg_ParseTuple(args
, ":lock_id"))
4247 CHECK_ENV_NOT_CLOSED(self
);
4248 MYDB_BEGIN_ALLOW_THREADS
;
4250 err
= self
->db_env
->lock_id(self
->db_env
, &theID
);
4252 err
= lock_id(self
->db_env
, &theID
);
4254 MYDB_END_ALLOW_THREADS
;
4257 return PyInt_FromLong((long)theID
);
4262 DBEnv_lock_id_free(DBEnvObject
* self
, PyObject
* args
)
4267 if (!PyArg_ParseTuple(args
, "I:lock_id_free", &theID
))
4270 CHECK_ENV_NOT_CLOSED(self
);
4271 MYDB_BEGIN_ALLOW_THREADS
;
4272 err
= self
->db_env
->lock_id_free(self
->db_env
, theID
);
4273 MYDB_END_ALLOW_THREADS
;
4280 DBEnv_lock_put(DBEnvObject
* self
, PyObject
* args
)
4283 DBLockObject
* dblockobj
;
4285 if (!PyArg_ParseTuple(args
, "O!:lock_put", &DBLock_Type
, &dblockobj
))
4288 CHECK_ENV_NOT_CLOSED(self
);
4289 MYDB_BEGIN_ALLOW_THREADS
;
4291 err
= self
->db_env
->lock_put(self
->db_env
, &dblockobj
->lock
);
4293 err
= lock_put(self
->db_env
, &dblockobj
->lock
);
4295 MYDB_END_ALLOW_THREADS
;
4302 DBEnv_lsn_reset(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4306 u_int32_t flags
= 0;
4307 static char* kwnames
[] = { "file", "flags", NULL
};
4309 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|i:lsn_reset", kwnames
,
4312 CHECK_ENV_NOT_CLOSED(self
);
4314 MYDB_BEGIN_ALLOW_THREADS
;
4315 err
= self
->db_env
->lsn_reset(self
->db_env
, file
, flags
);
4316 MYDB_END_ALLOW_THREADS
;
4320 #endif /* DBVER >= 4.4 */
4324 DBEnv_log_stat(DBEnvObject
* self
, PyObject
* args
)
4327 DB_LOG_STAT
* statp
= NULL
;
4329 u_int32_t flags
= 0;
4331 if (!PyArg_ParseTuple(args
, "|i:log_stat", &flags
))
4333 CHECK_ENV_NOT_CLOSED(self
);
4335 MYDB_BEGIN_ALLOW_THREADS
;
4336 err
= self
->db_env
->log_stat(self
->db_env
, &statp
, flags
);
4337 MYDB_END_ALLOW_THREADS
;
4340 /* Turn the stat structure into a dictionary */
4348 #define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
4351 MAKE_ENTRY(version
);
4353 MAKE_ENTRY(lg_bsize
);
4355 MAKE_ENTRY(lg_size
);
4361 MAKE_ENTRY(w_mbytes
);
4362 MAKE_ENTRY(w_bytes
);
4363 MAKE_ENTRY(wc_mbytes
);
4364 MAKE_ENTRY(wc_bytes
);
4366 MAKE_ENTRY(wcount_fill
);
4371 MAKE_ENTRY(cur_file
);
4372 MAKE_ENTRY(cur_offset
);
4373 MAKE_ENTRY(disk_file
);
4374 MAKE_ENTRY(disk_offset
);
4375 MAKE_ENTRY(maxcommitperflush
);
4376 MAKE_ENTRY(mincommitperflush
);
4377 MAKE_ENTRY(regsize
);
4378 MAKE_ENTRY(region_wait
);
4379 MAKE_ENTRY(region_nowait
);
4384 } /* DBEnv_log_stat */
4385 #endif /* DBVER >= 4.0 for log_stat method */
4389 DBEnv_lock_stat(DBEnvObject
* self
, PyObject
* args
)
4394 u_int32_t flags
= 0;
4396 if (!PyArg_ParseTuple(args
, "|i:lock_stat", &flags
))
4398 CHECK_ENV_NOT_CLOSED(self
);
4400 MYDB_BEGIN_ALLOW_THREADS
;
4402 err
= self
->db_env
->lock_stat(self
->db_env
, &sp
, flags
);
4405 err
= lock_stat(self
->db_env
, &sp
);
4407 err
= lock_stat(self
->db_env
, &sp
, NULL
);
4410 MYDB_END_ALLOW_THREADS
;
4413 /* Turn the stat structure into a dictionary */
4420 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4426 MAKE_ENTRY(maxlocks
);
4427 MAKE_ENTRY(maxlockers
);
4428 MAKE_ENTRY(maxobjects
);
4430 MAKE_ENTRY(maxnlocks
);
4431 MAKE_ENTRY(nlockers
);
4432 MAKE_ENTRY(maxnlockers
);
4433 MAKE_ENTRY(nobjects
);
4434 MAKE_ENTRY(maxnobjects
);
4435 MAKE_ENTRY(nrequests
);
4436 MAKE_ENTRY(nreleases
);
4438 MAKE_ENTRY(nnowaits
); /* these were renamed in 4.4 */
4439 MAKE_ENTRY(nconflicts
);
4441 MAKE_ENTRY(lock_nowait
);
4442 MAKE_ENTRY(lock_wait
);
4444 MAKE_ENTRY(ndeadlocks
);
4445 MAKE_ENTRY(regsize
);
4446 MAKE_ENTRY(region_wait
);
4447 MAKE_ENTRY(region_nowait
);
4456 DBEnv_log_archive(DBEnvObject
* self
, PyObject
* args
)
4460 char **log_list
= NULL
;
4462 PyObject
* item
= NULL
;
4464 if (!PyArg_ParseTuple(args
, "|i:log_archive", &flags
))
4467 CHECK_ENV_NOT_CLOSED(self
);
4468 MYDB_BEGIN_ALLOW_THREADS
;
4470 err
= self
->db_env
->log_archive(self
->db_env
, &log_list
, flags
);
4472 err
= log_archive(self
->db_env
, &log_list
, flags
);
4474 err
= log_archive(self
->db_env
, &log_list
, flags
, NULL
);
4476 MYDB_END_ALLOW_THREADS
;
4479 list
= PyList_New(0);
4487 char **log_list_start
;
4488 for (log_list_start
= log_list
; *log_list
!= NULL
; ++log_list
) {
4489 item
= PyString_FromString (*log_list
);
4495 PyList_Append(list
, item
);
4498 free(log_list_start
);
4505 DBEnv_txn_stat(DBEnvObject
* self
, PyObject
* args
)
4512 if (!PyArg_ParseTuple(args
, "|i:txn_stat", &flags
))
4514 CHECK_ENV_NOT_CLOSED(self
);
4516 MYDB_BEGIN_ALLOW_THREADS
;
4518 err
= self
->db_env
->txn_stat(self
->db_env
, &sp
, flags
);
4520 err
= txn_stat(self
->db_env
, &sp
);
4522 err
= txn_stat(self
->db_env
, &sp
, NULL
);
4524 MYDB_END_ALLOW_THREADS
;
4527 /* Turn the stat structure into a dictionary */
4534 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4535 #define MAKE_TIME_T_ENTRY(name)_addTimeTToDict(d, #name, sp->st_##name)
4537 MAKE_TIME_T_ENTRY(time_ckp
);
4538 MAKE_ENTRY(last_txnid
);
4539 MAKE_ENTRY(maxtxns
);
4540 MAKE_ENTRY(nactive
);
4541 MAKE_ENTRY(maxnactive
);
4542 MAKE_ENTRY(nbegins
);
4543 MAKE_ENTRY(naborts
);
4544 MAKE_ENTRY(ncommits
);
4545 MAKE_ENTRY(regsize
);
4546 MAKE_ENTRY(region_wait
);
4547 MAKE_ENTRY(region_nowait
);
4550 #undef MAKE_TIME_T_ENTRY
4557 DBEnv_set_get_returns_none(DBEnvObject
* self
, PyObject
* args
)
4562 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
4564 CHECK_ENV_NOT_CLOSED(self
);
4566 if (self
->moduleFlags
.getReturnsNone
)
4568 if (self
->moduleFlags
.cursorSetReturnsNone
)
4570 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
4571 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
4572 return PyInt_FromLong(oldValue
);
4576 /* --------------------------------------------------------------------- */
4581 DBTxn_commit(DBTxnObject
* self
, PyObject
* args
)
4586 if (!PyArg_ParseTuple(args
, "|i:commit", &flags
))
4590 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4591 "after txn_commit or txn_abort");
4592 PyErr_SetObject(DBError
, t
);
4597 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
4598 MYDB_BEGIN_ALLOW_THREADS
;
4600 err
= txn
->commit(txn
, flags
);
4602 err
= txn_commit(txn
, flags
);
4604 MYDB_END_ALLOW_THREADS
;
4610 DBTxn_prepare(DBTxnObject
* self
, PyObject
* args
)
4617 if (!PyArg_ParseTuple(args
, "s#:prepare", &gid
, &gid_size
))
4620 if (gid_size
!= DB_XIDDATASIZE
) {
4621 PyErr_SetString(PyExc_TypeError
,
4622 "gid must be DB_XIDDATASIZE bytes long");
4627 PyObject
*t
= Py_BuildValue("(is)", 0,"DBTxn must not be used "
4628 "after txn_commit or txn_abort");
4629 PyErr_SetObject(DBError
, t
);
4633 MYDB_BEGIN_ALLOW_THREADS
;
4635 err
= self
->txn
->prepare(self
->txn
, (u_int8_t
*)gid
);
4637 err
= txn_prepare(self
->txn
, (u_int8_t
*)gid
);
4639 MYDB_END_ALLOW_THREADS
;
4645 if (!PyArg_ParseTuple(args
, ":prepare"))
4649 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4650 "after txn_commit or txn_abort");
4651 PyErr_SetObject(DBError
, t
);
4655 MYDB_BEGIN_ALLOW_THREADS
;
4656 err
= txn_prepare(self
->txn
);
4657 MYDB_END_ALLOW_THREADS
;
4665 DBTxn_abort(DBTxnObject
* self
, PyObject
* args
)
4670 if (!PyArg_ParseTuple(args
, ":abort"))
4674 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4675 "after txn_commit or txn_abort");
4676 PyErr_SetObject(DBError
, t
);
4681 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
4682 MYDB_BEGIN_ALLOW_THREADS
;
4684 err
= txn
->abort(txn
);
4686 err
= txn_abort(txn
);
4688 MYDB_END_ALLOW_THREADS
;
4695 DBTxn_id(DBTxnObject
* self
, PyObject
* args
)
4699 if (!PyArg_ParseTuple(args
, ":id"))
4703 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4704 "after txn_commit or txn_abort");
4705 PyErr_SetObject(DBError
, t
);
4709 MYDB_BEGIN_ALLOW_THREADS
;
4711 id
= self
->txn
->id(self
->txn
);
4713 id
= txn_id(self
->txn
);
4715 MYDB_END_ALLOW_THREADS
;
4716 return PyInt_FromLong(id
);
4720 /* --------------------------------------------------------------------- */
4721 /* DBSequence methods */
4725 DBSequence_close(DBSequenceObject
* self
, PyObject
* args
)
4728 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
4730 CHECK_SEQUENCE_NOT_CLOSED(self
)
4732 MYDB_BEGIN_ALLOW_THREADS
4733 err
= self
->sequence
->close(self
->sequence
, flags
);
4734 self
->sequence
= NULL
;
4735 MYDB_END_ALLOW_THREADS
4743 DBSequence_get(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4748 PyObject
*txnobj
= NULL
;
4750 static char* kwnames
[] = {"delta", "txn", "flags", NULL
};
4751 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iOi:get", kwnames
, &delta
, &txnobj
, &flags
))
4753 CHECK_SEQUENCE_NOT_CLOSED(self
)
4755 if (!checkTxnObj(txnobj
, &txn
))
4758 MYDB_BEGIN_ALLOW_THREADS
4759 err
= self
->sequence
->get(self
->sequence
, txn
, delta
, &value
, flags
);
4760 MYDB_END_ALLOW_THREADS
4763 return PyLong_FromLongLong(value
);
4768 DBSequence_get_dbp(DBSequenceObject
* self
, PyObject
* args
)
4770 if (!PyArg_ParseTuple(args
,":get_dbp"))
4772 CHECK_SEQUENCE_NOT_CLOSED(self
)
4773 Py_INCREF(self
->mydb
);
4774 return (PyObject
* )self
->mydb
;
4778 DBSequence_get_key(DBSequenceObject
* self
, PyObject
* args
)
4782 PyObject
*retval
= NULL
;
4783 key
.flags
= DB_DBT_MALLOC
;
4784 CHECK_SEQUENCE_NOT_CLOSED(self
)
4785 MYDB_BEGIN_ALLOW_THREADS
4786 err
= self
->sequence
->get_key(self
->sequence
, &key
);
4787 MYDB_END_ALLOW_THREADS
4790 retval
= PyString_FromStringAndSize(key
.data
, key
.size
);
4799 DBSequence_init_value(DBSequenceObject
* self
, PyObject
* args
)
4803 if (!PyArg_ParseTuple(args
,"L:init_value", &value
))
4805 CHECK_SEQUENCE_NOT_CLOSED(self
)
4807 MYDB_BEGIN_ALLOW_THREADS
4808 err
= self
->sequence
->initial_value(self
->sequence
, value
);
4809 MYDB_END_ALLOW_THREADS
4817 DBSequence_open(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4821 PyObject
*txnobj
= NULL
;
4825 static char* kwnames
[] = {"key", "txn", "flags", NULL
};
4826 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:open", kwnames
, &keyobj
, &txnobj
, &flags
))
4829 if (!checkTxnObj(txnobj
, &txn
))
4832 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
4835 MYDB_BEGIN_ALLOW_THREADS
4836 err
= self
->sequence
->open(self
->sequence
, txn
, &key
, flags
);
4837 MYDB_END_ALLOW_THREADS
4846 DBSequence_remove(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4849 PyObject
*txnobj
= NULL
;
4852 static char* kwnames
[] = {"txn", "flags", NULL
};
4853 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:remove", kwnames
, &txnobj
, &flags
))
4856 if (!checkTxnObj(txnobj
, &txn
))
4859 CHECK_SEQUENCE_NOT_CLOSED(self
)
4861 MYDB_BEGIN_ALLOW_THREADS
4862 err
= self
->sequence
->remove(self
->sequence
, txn
, flags
);
4863 MYDB_END_ALLOW_THREADS
4870 DBSequence_set_cachesize(DBSequenceObject
* self
, PyObject
* args
)
4873 if (!PyArg_ParseTuple(args
,"i:set_cachesize", &size
))
4875 CHECK_SEQUENCE_NOT_CLOSED(self
)
4877 MYDB_BEGIN_ALLOW_THREADS
4878 err
= self
->sequence
->set_cachesize(self
->sequence
, size
);
4879 MYDB_END_ALLOW_THREADS
4886 DBSequence_get_cachesize(DBSequenceObject
* self
, PyObject
* args
)
4889 if (!PyArg_ParseTuple(args
,":get_cachesize"))
4891 CHECK_SEQUENCE_NOT_CLOSED(self
)
4893 MYDB_BEGIN_ALLOW_THREADS
4894 err
= self
->sequence
->get_cachesize(self
->sequence
, &size
);
4895 MYDB_END_ALLOW_THREADS
4898 return PyInt_FromLong(size
);
4902 DBSequence_set_flags(DBSequenceObject
* self
, PyObject
* args
)
4905 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
4907 CHECK_SEQUENCE_NOT_CLOSED(self
)
4909 MYDB_BEGIN_ALLOW_THREADS
4910 err
= self
->sequence
->set_flags(self
->sequence
, flags
);
4911 MYDB_END_ALLOW_THREADS
4919 DBSequence_get_flags(DBSequenceObject
* self
, PyObject
* args
)
4923 if (!PyArg_ParseTuple(args
,":get_flags"))
4925 CHECK_SEQUENCE_NOT_CLOSED(self
)
4927 MYDB_BEGIN_ALLOW_THREADS
4928 err
= self
->sequence
->get_flags(self
->sequence
, &flags
);
4929 MYDB_END_ALLOW_THREADS
4932 return PyInt_FromLong((int)flags
);
4936 DBSequence_set_range(DBSequenceObject
* self
, PyObject
* args
)
4940 if (!PyArg_ParseTuple(args
,"(LL):set_range", &min
, &max
))
4942 CHECK_SEQUENCE_NOT_CLOSED(self
)
4944 MYDB_BEGIN_ALLOW_THREADS
4945 err
= self
->sequence
->set_range(self
->sequence
, min
, max
);
4946 MYDB_END_ALLOW_THREADS
4953 DBSequence_get_range(DBSequenceObject
* self
, PyObject
* args
)
4957 if (!PyArg_ParseTuple(args
,":get_range"))
4959 CHECK_SEQUENCE_NOT_CLOSED(self
)
4961 MYDB_BEGIN_ALLOW_THREADS
4962 err
= self
->sequence
->get_range(self
->sequence
, &min
, &max
);
4963 MYDB_END_ALLOW_THREADS
4966 return Py_BuildValue("(LL)", min
, max
);
4970 DBSequence_stat(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4973 DB_SEQUENCE_STAT
* sp
= NULL
;
4974 PyObject
* dict_stat
;
4975 static char* kwnames
[] = {"flags", NULL
};
4976 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat", kwnames
, &flags
))
4978 CHECK_SEQUENCE_NOT_CLOSED(self
);
4980 MYDB_BEGIN_ALLOW_THREADS
;
4981 err
= self
->sequence
->stat(self
->sequence
, &sp
, flags
);
4982 MYDB_END_ALLOW_THREADS
;
4985 if ((dict_stat
= PyDict_New()) == NULL
) {
4991 #define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name)
4992 #define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
4994 MAKE_INT_ENTRY(wait
);
4995 MAKE_INT_ENTRY(nowait
);
4996 MAKE_LONG_LONG_ENTRY(current
);
4997 MAKE_LONG_LONG_ENTRY(value
);
4998 MAKE_LONG_LONG_ENTRY(last_value
);
4999 MAKE_LONG_LONG_ENTRY(min
);
5000 MAKE_LONG_LONG_ENTRY(max
);
5001 MAKE_INT_ENTRY(cache_size
);
5002 MAKE_INT_ENTRY(flags
);
5004 #undef MAKE_INT_ENTRY
5005 #undef MAKE_LONG_LONG_ENTRY
5013 /* --------------------------------------------------------------------- */
5014 /* Method definition tables and type objects */
5016 static PyMethodDef DB_methods
[] = {
5017 {"append", (PyCFunction
)DB_append
, METH_VARARGS
},
5019 {"associate", (PyCFunction
)DB_associate
, METH_VARARGS
|METH_KEYWORDS
},
5021 {"close", (PyCFunction
)DB_close
, METH_VARARGS
},
5022 {"consume", (PyCFunction
)DB_consume
, METH_VARARGS
|METH_KEYWORDS
},
5023 {"consume_wait", (PyCFunction
)DB_consume_wait
, METH_VARARGS
|METH_KEYWORDS
},
5024 {"cursor", (PyCFunction
)DB_cursor
, METH_VARARGS
|METH_KEYWORDS
},
5025 {"delete", (PyCFunction
)DB_delete
, METH_VARARGS
|METH_KEYWORDS
},
5026 {"fd", (PyCFunction
)DB_fd
, METH_VARARGS
},
5027 {"get", (PyCFunction
)DB_get
, METH_VARARGS
|METH_KEYWORDS
},
5029 {"pget", (PyCFunction
)DB_pget
, METH_VARARGS
|METH_KEYWORDS
},
5031 {"get_both", (PyCFunction
)DB_get_both
, METH_VARARGS
|METH_KEYWORDS
},
5032 {"get_byteswapped", (PyCFunction
)DB_get_byteswapped
,METH_VARARGS
},
5033 {"get_size", (PyCFunction
)DB_get_size
, METH_VARARGS
|METH_KEYWORDS
},
5034 {"get_type", (PyCFunction
)DB_get_type
, METH_VARARGS
},
5035 {"join", (PyCFunction
)DB_join
, METH_VARARGS
},
5036 {"key_range", (PyCFunction
)DB_key_range
, METH_VARARGS
|METH_KEYWORDS
},
5037 {"has_key", (PyCFunction
)DB_has_key
, METH_VARARGS
},
5038 {"items", (PyCFunction
)DB_items
, METH_VARARGS
},
5039 {"keys", (PyCFunction
)DB_keys
, METH_VARARGS
},
5040 {"open", (PyCFunction
)DB_open
, METH_VARARGS
|METH_KEYWORDS
},
5041 {"put", (PyCFunction
)DB_put
, METH_VARARGS
|METH_KEYWORDS
},
5042 {"remove", (PyCFunction
)DB_remove
, METH_VARARGS
|METH_KEYWORDS
},
5043 {"rename", (PyCFunction
)DB_rename
, METH_VARARGS
},
5044 {"set_bt_minkey", (PyCFunction
)DB_set_bt_minkey
, METH_VARARGS
},
5046 {"set_bt_compare", (PyCFunction
)DB_set_bt_compare
, METH_VARARGS
},
5048 {"set_cachesize", (PyCFunction
)DB_set_cachesize
, METH_VARARGS
},
5050 {"set_encrypt", (PyCFunction
)DB_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
5052 {"set_flags", (PyCFunction
)DB_set_flags
, METH_VARARGS
},
5053 {"set_h_ffactor", (PyCFunction
)DB_set_h_ffactor
, METH_VARARGS
},
5054 {"set_h_nelem", (PyCFunction
)DB_set_h_nelem
, METH_VARARGS
},
5055 {"set_lorder", (PyCFunction
)DB_set_lorder
, METH_VARARGS
},
5056 {"set_pagesize", (PyCFunction
)DB_set_pagesize
, METH_VARARGS
},
5057 {"set_re_delim", (PyCFunction
)DB_set_re_delim
, METH_VARARGS
},
5058 {"set_re_len", (PyCFunction
)DB_set_re_len
, METH_VARARGS
},
5059 {"set_re_pad", (PyCFunction
)DB_set_re_pad
, METH_VARARGS
},
5060 {"set_re_source", (PyCFunction
)DB_set_re_source
, METH_VARARGS
},
5061 {"set_q_extentsize",(PyCFunction
)DB_set_q_extentsize
,METH_VARARGS
},
5062 {"stat", (PyCFunction
)DB_stat
, METH_VARARGS
|METH_KEYWORDS
},
5063 {"sync", (PyCFunction
)DB_sync
, METH_VARARGS
},
5065 {"truncate", (PyCFunction
)DB_truncate
, METH_VARARGS
|METH_KEYWORDS
},
5067 {"type", (PyCFunction
)DB_get_type
, METH_VARARGS
},
5068 {"upgrade", (PyCFunction
)DB_upgrade
, METH_VARARGS
},
5069 {"values", (PyCFunction
)DB_values
, METH_VARARGS
},
5070 {"verify", (PyCFunction
)DB_verify
, METH_VARARGS
|METH_KEYWORDS
},
5071 {"set_get_returns_none",(PyCFunction
)DB_set_get_returns_none
, METH_VARARGS
},
5072 {NULL
, NULL
} /* sentinel */
5076 static PyMappingMethods DB_mapping
= {
5077 DB_length
, /*mp_length*/
5078 (binaryfunc
)DB_subscript
, /*mp_subscript*/
5079 (objobjargproc
)DB_ass_sub
, /*mp_ass_subscript*/
5083 static PyMethodDef DBCursor_methods
[] = {
5084 {"close", (PyCFunction
)DBC_close
, METH_VARARGS
},
5085 {"count", (PyCFunction
)DBC_count
, METH_VARARGS
},
5086 {"current", (PyCFunction
)DBC_current
, METH_VARARGS
|METH_KEYWORDS
},
5087 {"delete", (PyCFunction
)DBC_delete
, METH_VARARGS
},
5088 {"dup", (PyCFunction
)DBC_dup
, METH_VARARGS
},
5089 {"first", (PyCFunction
)DBC_first
, METH_VARARGS
|METH_KEYWORDS
},
5090 {"get", (PyCFunction
)DBC_get
, METH_VARARGS
|METH_KEYWORDS
},
5092 {"pget", (PyCFunction
)DBC_pget
, METH_VARARGS
|METH_KEYWORDS
},
5094 {"get_recno", (PyCFunction
)DBC_get_recno
, METH_VARARGS
},
5095 {"last", (PyCFunction
)DBC_last
, METH_VARARGS
|METH_KEYWORDS
},
5096 {"next", (PyCFunction
)DBC_next
, METH_VARARGS
|METH_KEYWORDS
},
5097 {"prev", (PyCFunction
)DBC_prev
, METH_VARARGS
|METH_KEYWORDS
},
5098 {"put", (PyCFunction
)DBC_put
, METH_VARARGS
|METH_KEYWORDS
},
5099 {"set", (PyCFunction
)DBC_set
, METH_VARARGS
|METH_KEYWORDS
},
5100 {"set_range", (PyCFunction
)DBC_set_range
, METH_VARARGS
|METH_KEYWORDS
},
5101 {"get_both", (PyCFunction
)DBC_get_both
, METH_VARARGS
},
5102 {"get_current_size",(PyCFunction
)DBC_get_current_size
, METH_VARARGS
},
5103 {"set_both", (PyCFunction
)DBC_set_both
, METH_VARARGS
},
5104 {"set_recno", (PyCFunction
)DBC_set_recno
, METH_VARARGS
|METH_KEYWORDS
},
5105 {"consume", (PyCFunction
)DBC_consume
, METH_VARARGS
|METH_KEYWORDS
},
5106 {"next_dup", (PyCFunction
)DBC_next_dup
, METH_VARARGS
|METH_KEYWORDS
},
5107 {"next_nodup", (PyCFunction
)DBC_next_nodup
, METH_VARARGS
|METH_KEYWORDS
},
5108 {"prev_nodup", (PyCFunction
)DBC_prev_nodup
, METH_VARARGS
|METH_KEYWORDS
},
5109 {"join_item", (PyCFunction
)DBC_join_item
, METH_VARARGS
},
5110 {NULL
, NULL
} /* sentinel */
5114 static PyMethodDef DBEnv_methods
[] = {
5115 {"close", (PyCFunction
)DBEnv_close
, METH_VARARGS
},
5116 {"open", (PyCFunction
)DBEnv_open
, METH_VARARGS
},
5117 {"remove", (PyCFunction
)DBEnv_remove
, METH_VARARGS
},
5119 {"dbremove", (PyCFunction
)DBEnv_dbremove
, METH_VARARGS
|METH_KEYWORDS
},
5120 {"dbrename", (PyCFunction
)DBEnv_dbrename
, METH_VARARGS
|METH_KEYWORDS
},
5121 {"set_encrypt", (PyCFunction
)DBEnv_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
5124 {"set_timeout", (PyCFunction
)DBEnv_set_timeout
, METH_VARARGS
|METH_KEYWORDS
},
5126 {"set_shm_key", (PyCFunction
)DBEnv_set_shm_key
, METH_VARARGS
},
5127 {"set_cachesize", (PyCFunction
)DBEnv_set_cachesize
, METH_VARARGS
},
5128 {"set_data_dir", (PyCFunction
)DBEnv_set_data_dir
, METH_VARARGS
},
5129 {"set_flags", (PyCFunction
)DBEnv_set_flags
, METH_VARARGS
},
5130 {"set_lg_bsize", (PyCFunction
)DBEnv_set_lg_bsize
, METH_VARARGS
},
5131 {"set_lg_dir", (PyCFunction
)DBEnv_set_lg_dir
, METH_VARARGS
},
5132 {"set_lg_max", (PyCFunction
)DBEnv_set_lg_max
, METH_VARARGS
},
5134 {"set_lg_regionmax",(PyCFunction
)DBEnv_set_lg_regionmax
, METH_VARARGS
},
5136 {"set_lk_detect", (PyCFunction
)DBEnv_set_lk_detect
, METH_VARARGS
},
5138 {"set_lk_max", (PyCFunction
)DBEnv_set_lk_max
, METH_VARARGS
},
5140 {"set_lk_max_locks", (PyCFunction
)DBEnv_set_lk_max_locks
, METH_VARARGS
},
5141 {"set_lk_max_lockers", (PyCFunction
)DBEnv_set_lk_max_lockers
, METH_VARARGS
},
5142 {"set_lk_max_objects", (PyCFunction
)DBEnv_set_lk_max_objects
, METH_VARARGS
},
5143 {"set_mp_mmapsize", (PyCFunction
)DBEnv_set_mp_mmapsize
, METH_VARARGS
},
5144 {"set_tmp_dir", (PyCFunction
)DBEnv_set_tmp_dir
, METH_VARARGS
},
5145 {"txn_begin", (PyCFunction
)DBEnv_txn_begin
, METH_VARARGS
|METH_KEYWORDS
},
5146 {"txn_checkpoint", (PyCFunction
)DBEnv_txn_checkpoint
, METH_VARARGS
},
5147 {"txn_stat", (PyCFunction
)DBEnv_txn_stat
, METH_VARARGS
},
5148 {"set_tx_max", (PyCFunction
)DBEnv_set_tx_max
, METH_VARARGS
},
5149 {"set_tx_timestamp", (PyCFunction
)DBEnv_set_tx_timestamp
, METH_VARARGS
},
5150 {"lock_detect", (PyCFunction
)DBEnv_lock_detect
, METH_VARARGS
},
5151 {"lock_get", (PyCFunction
)DBEnv_lock_get
, METH_VARARGS
},
5152 {"lock_id", (PyCFunction
)DBEnv_lock_id
, METH_VARARGS
},
5154 {"lock_id_free", (PyCFunction
)DBEnv_lock_id_free
, METH_VARARGS
},
5156 {"lock_put", (PyCFunction
)DBEnv_lock_put
, METH_VARARGS
},
5157 {"lock_stat", (PyCFunction
)DBEnv_lock_stat
, METH_VARARGS
},
5158 {"log_archive", (PyCFunction
)DBEnv_log_archive
, METH_VARARGS
},
5160 {"log_stat", (PyCFunction
)DBEnv_log_stat
, METH_VARARGS
},
5163 {"lsn_reset", (PyCFunction
)DBEnv_lsn_reset
, METH_VARARGS
|METH_KEYWORDS
},
5165 {"set_get_returns_none",(PyCFunction
)DBEnv_set_get_returns_none
, METH_VARARGS
},
5166 {NULL
, NULL
} /* sentinel */
5170 static PyMethodDef DBTxn_methods
[] = {
5171 {"commit", (PyCFunction
)DBTxn_commit
, METH_VARARGS
},
5172 {"prepare", (PyCFunction
)DBTxn_prepare
, METH_VARARGS
},
5173 {"abort", (PyCFunction
)DBTxn_abort
, METH_VARARGS
},
5174 {"id", (PyCFunction
)DBTxn_id
, METH_VARARGS
},
5175 {NULL
, NULL
} /* sentinel */
5180 static PyMethodDef DBSequence_methods
[] = {
5181 {"close", (PyCFunction
)DBSequence_close
, METH_VARARGS
},
5182 {"get", (PyCFunction
)DBSequence_get
, METH_VARARGS
|METH_KEYWORDS
},
5183 {"get_dbp", (PyCFunction
)DBSequence_get_dbp
, METH_VARARGS
},
5184 {"get_key", (PyCFunction
)DBSequence_get_key
, METH_VARARGS
},
5185 {"init_value", (PyCFunction
)DBSequence_init_value
, METH_VARARGS
},
5186 {"open", (PyCFunction
)DBSequence_open
, METH_VARARGS
|METH_KEYWORDS
},
5187 {"remove", (PyCFunction
)DBSequence_remove
, METH_VARARGS
|METH_KEYWORDS
},
5188 {"set_cachesize", (PyCFunction
)DBSequence_set_cachesize
, METH_VARARGS
},
5189 {"get_cachesize", (PyCFunction
)DBSequence_get_cachesize
, METH_VARARGS
},
5190 {"set_flags", (PyCFunction
)DBSequence_set_flags
, METH_VARARGS
},
5191 {"get_flags", (PyCFunction
)DBSequence_get_flags
, METH_VARARGS
},
5192 {"set_range", (PyCFunction
)DBSequence_set_range
, METH_VARARGS
},
5193 {"get_range", (PyCFunction
)DBSequence_get_range
, METH_VARARGS
},
5194 {"stat", (PyCFunction
)DBSequence_stat
, METH_VARARGS
|METH_KEYWORDS
},
5195 {NULL
, NULL
} /* sentinel */
5201 DB_getattr(DBObject
* self
, char *name
)
5203 return Py_FindMethod(DB_methods
, (PyObject
* )self
, name
);
5208 DBEnv_getattr(DBEnvObject
* self
, char *name
)
5210 if (!strcmp(name
, "db_home")) {
5211 CHECK_ENV_NOT_CLOSED(self
);
5212 if (self
->db_env
->db_home
== NULL
) {
5215 return PyString_FromString(self
->db_env
->db_home
);
5218 return Py_FindMethod(DBEnv_methods
, (PyObject
* )self
, name
);
5223 DBCursor_getattr(DBCursorObject
* self
, char *name
)
5225 return Py_FindMethod(DBCursor_methods
, (PyObject
* )self
, name
);
5229 DBTxn_getattr(DBTxnObject
* self
, char *name
)
5231 return Py_FindMethod(DBTxn_methods
, (PyObject
* )self
, name
);
5235 DBLock_getattr(DBLockObject
* self
, char *name
)
5242 DBSequence_getattr(DBSequenceObject
* self
, char *name
)
5244 return Py_FindMethod(DBSequence_methods
, (PyObject
* )self
, name
);
5248 statichere PyTypeObject DB_Type
= {
5249 PyObject_HEAD_INIT(NULL
)
5252 sizeof(DBObject
), /*tp_basicsize*/
5255 (destructor
)DB_dealloc
, /*tp_dealloc*/
5257 (getattrfunc
)DB_getattr
, /*tp_getattr*/
5262 0, /*tp_as_sequence*/
5263 &DB_mapping
,/*tp_as_mapping*/
5267 0, /* tp_getattro */
5268 0, /* tp_setattro */
5269 0, /* tp_as_buffer */
5270 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5272 0, /* tp_traverse */
5274 0, /* tp_richcompare */
5275 offsetof(DBObject
, in_weakreflist
), /* tp_weaklistoffset */
5279 statichere PyTypeObject DBCursor_Type
= {
5280 PyObject_HEAD_INIT(NULL
)
5282 "DBCursor", /*tp_name*/
5283 sizeof(DBCursorObject
), /*tp_basicsize*/
5286 (destructor
)DBCursor_dealloc
,/*tp_dealloc*/
5288 (getattrfunc
)DBCursor_getattr
, /*tp_getattr*/
5293 0, /*tp_as_sequence*/
5294 0, /*tp_as_mapping*/
5298 0, /* tp_getattro */
5299 0, /* tp_setattro */
5300 0, /* tp_as_buffer */
5301 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5303 0, /* tp_traverse */
5305 0, /* tp_richcompare */
5306 offsetof(DBCursorObject
, in_weakreflist
), /* tp_weaklistoffset */
5310 statichere PyTypeObject DBEnv_Type
= {
5311 PyObject_HEAD_INIT(NULL
)
5313 "DBEnv", /*tp_name*/
5314 sizeof(DBEnvObject
), /*tp_basicsize*/
5317 (destructor
)DBEnv_dealloc
, /*tp_dealloc*/
5319 (getattrfunc
)DBEnv_getattr
, /*tp_getattr*/
5324 0, /*tp_as_sequence*/
5325 0, /*tp_as_mapping*/
5329 0, /* tp_getattro */
5330 0, /* tp_setattro */
5331 0, /* tp_as_buffer */
5332 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5334 0, /* tp_traverse */
5336 0, /* tp_richcompare */
5337 offsetof(DBEnvObject
, in_weakreflist
), /* tp_weaklistoffset */
5340 statichere PyTypeObject DBTxn_Type
= {
5341 PyObject_HEAD_INIT(NULL
)
5343 "DBTxn", /*tp_name*/
5344 sizeof(DBTxnObject
), /*tp_basicsize*/
5347 (destructor
)DBTxn_dealloc
, /*tp_dealloc*/
5349 (getattrfunc
)DBTxn_getattr
, /*tp_getattr*/
5354 0, /*tp_as_sequence*/
5355 0, /*tp_as_mapping*/
5359 0, /* tp_getattro */
5360 0, /* tp_setattro */
5361 0, /* tp_as_buffer */
5362 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5364 0, /* tp_traverse */
5366 0, /* tp_richcompare */
5367 offsetof(DBTxnObject
, in_weakreflist
), /* tp_weaklistoffset */
5371 statichere PyTypeObject DBLock_Type
= {
5372 PyObject_HEAD_INIT(NULL
)
5374 "DBLock", /*tp_name*/
5375 sizeof(DBLockObject
), /*tp_basicsize*/
5378 (destructor
)DBLock_dealloc
, /*tp_dealloc*/
5380 (getattrfunc
)DBLock_getattr
, /*tp_getattr*/
5385 0, /*tp_as_sequence*/
5386 0, /*tp_as_mapping*/
5390 0, /* tp_getattro */
5391 0, /* tp_setattro */
5392 0, /* tp_as_buffer */
5393 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5395 0, /* tp_traverse */
5397 0, /* tp_richcompare */
5398 offsetof(DBLockObject
, in_weakreflist
), /* tp_weaklistoffset */
5402 statichere PyTypeObject DBSequence_Type
= {
5403 PyObject_HEAD_INIT(NULL
)
5405 "DBSequence", /*tp_name*/
5406 sizeof(DBSequenceObject
), /*tp_basicsize*/
5409 (destructor
)DBSequence_dealloc
, /*tp_dealloc*/
5411 (getattrfunc
)DBSequence_getattr
,/*tp_getattr*/
5416 0, /*tp_as_sequence*/
5417 0, /*tp_as_mapping*/
5421 0, /* tp_getattro */
5422 0, /* tp_setattro */
5423 0, /* tp_as_buffer */
5424 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5426 0, /* tp_traverse */
5428 0, /* tp_richcompare */
5429 offsetof(DBSequenceObject
, in_weakreflist
), /* tp_weaklistoffset */
5433 /* --------------------------------------------------------------------- */
5434 /* Module-level functions */
5437 DB_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5439 PyObject
* dbenvobj
= NULL
;
5441 static char* kwnames
[] = { "dbEnv", "flags", NULL
};
5443 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:DB", kwnames
,
5446 if (dbenvobj
== Py_None
)
5448 else if (dbenvobj
&& !DBEnvObject_Check(dbenvobj
)) {
5449 makeTypeError("DBEnv", dbenvobj
);
5453 return (PyObject
* )newDBObject((DBEnvObject
*)dbenvobj
, flags
);
5458 DBEnv_construct(PyObject
* self
, PyObject
* args
)
5461 if (!PyArg_ParseTuple(args
, "|i:DbEnv", &flags
)) return NULL
;
5462 return (PyObject
* )newDBEnvObject(flags
);
5467 DBSequence_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5471 static char* kwnames
[] = { "db", "flags", NULL
};
5473 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|i:DBSequence", kwnames
, &dbobj
, &flags
))
5475 if (!DBObject_Check(dbobj
)) {
5476 makeTypeError("DB", dbobj
);
5479 return (PyObject
* )newDBSequenceObject((DBObject
*)dbobj
, flags
);
5483 static char bsddb_version_doc
[] =
5484 "Returns a tuple of major, minor, and patch release numbers of the\n\
5485 underlying DB library.";
5488 bsddb_version(PyObject
* self
, PyObject
* args
)
5490 int major
, minor
, patch
;
5492 if (!PyArg_ParseTuple(args
, ":version"))
5494 db_version(&major
, &minor
, &patch
);
5495 return Py_BuildValue("(iii)", major
, minor
, patch
);
5499 /* List of functions defined in the module */
5501 static PyMethodDef bsddb_methods
[] = {
5502 {"DB", (PyCFunction
)DB_construct
, METH_VARARGS
| METH_KEYWORDS
},
5503 {"DBEnv", (PyCFunction
)DBEnv_construct
, METH_VARARGS
},
5505 {"DBSequence", (PyCFunction
)DBSequence_construct
, METH_VARARGS
| METH_KEYWORDS
},
5507 {"version", (PyCFunction
)bsddb_version
, METH_VARARGS
, bsddb_version_doc
},
5508 {NULL
, NULL
} /* sentinel */
5512 static BSDDB_api bsddb_api
;
5515 /* --------------------------------------------------------------------- */
5516 /* Module initialization */
5519 /* Convenience routine to export an integer value.
5520 * Errors are silently ignored, for better or for worse...
5522 #define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
5524 #define MODULE_NAME_MAX_LEN 11
5525 static char _bsddbModuleName
[MODULE_NAME_MAX_LEN
+1] = "_bsddb";
5527 DL_EXPORT(void) init_bsddb(void)
5531 PyObject
* pybsddb_version_s
= PyString_FromString( PY_BSDDB_VERSION
);
5532 PyObject
* db_version_s
= PyString_FromString( DB_VERSION_STRING
);
5533 PyObject
* cvsid_s
= PyString_FromString( rcs_id
);
5536 /* Initialize the type of the new type objects here; doing it here
5537 is required for portability to Windows without requiring C++. */
5538 Py_TYPE(&DB_Type
) = &PyType_Type
;
5539 Py_TYPE(&DBCursor_Type
) = &PyType_Type
;
5540 Py_TYPE(&DBEnv_Type
) = &PyType_Type
;
5541 Py_TYPE(&DBTxn_Type
) = &PyType_Type
;
5542 Py_TYPE(&DBLock_Type
) = &PyType_Type
;
5544 Py_TYPE(&DBSequence_Type
) = &PyType_Type
;
5548 #if defined(WITH_THREAD) && !defined(MYDB_USE_GILSTATE)
5549 /* Save the current interpreter, so callbacks can do the right thing. */
5550 _db_interpreterState
= PyThreadState_GET()->interp
;
5553 /* Create the module and add the functions */
5554 m
= Py_InitModule(_bsddbModuleName
, bsddb_methods
);
5558 /* Add some symbolic constants to the module */
5559 d
= PyModule_GetDict(m
);
5560 PyDict_SetItemString(d
, "__version__", pybsddb_version_s
);
5561 PyDict_SetItemString(d
, "cvsid", cvsid_s
);
5562 PyDict_SetItemString(d
, "DB_VERSION_STRING", db_version_s
);
5563 Py_DECREF(pybsddb_version_s
);
5564 pybsddb_version_s
= NULL
;
5567 Py_DECREF(db_version_s
);
5568 db_version_s
= NULL
;
5570 ADD_INT(d
, DB_VERSION_MAJOR
);
5571 ADD_INT(d
, DB_VERSION_MINOR
);
5572 ADD_INT(d
, DB_VERSION_PATCH
);
5574 ADD_INT(d
, DB_MAX_PAGES
);
5575 ADD_INT(d
, DB_MAX_RECORDS
);
5578 ADD_INT(d
, DB_RPCCLIENT
);
5580 ADD_INT(d
, DB_CLIENT
);
5581 /* allow apps to be written using DB_RPCCLIENT on older BerkeleyDB */
5582 _addIntToDict(d
, "DB_RPCCLIENT", DB_CLIENT
);
5584 ADD_INT(d
, DB_XA_CREATE
);
5586 ADD_INT(d
, DB_CREATE
);
5587 ADD_INT(d
, DB_NOMMAP
);
5588 ADD_INT(d
, DB_THREAD
);
5590 ADD_INT(d
, DB_FORCE
);
5591 ADD_INT(d
, DB_INIT_CDB
);
5592 ADD_INT(d
, DB_INIT_LOCK
);
5593 ADD_INT(d
, DB_INIT_LOG
);
5594 ADD_INT(d
, DB_INIT_MPOOL
);
5595 ADD_INT(d
, DB_INIT_TXN
);
5596 ADD_INT(d
, DB_JOINENV
);
5598 ADD_INT(d
, DB_RECOVER
);
5599 ADD_INT(d
, DB_RECOVER_FATAL
);
5600 ADD_INT(d
, DB_TXN_NOSYNC
);
5601 ADD_INT(d
, DB_USE_ENVIRON
);
5602 ADD_INT(d
, DB_USE_ENVIRON_ROOT
);
5604 ADD_INT(d
, DB_LOCKDOWN
);
5605 ADD_INT(d
, DB_PRIVATE
);
5606 ADD_INT(d
, DB_SYSTEM_MEM
);
5608 ADD_INT(d
, DB_TXN_SYNC
);
5609 ADD_INT(d
, DB_TXN_NOWAIT
);
5611 ADD_INT(d
, DB_EXCL
);
5612 ADD_INT(d
, DB_FCNTL_LOCKING
);
5613 ADD_INT(d
, DB_ODDFILESIZE
);
5614 ADD_INT(d
, DB_RDWRMASTER
);
5615 ADD_INT(d
, DB_RDONLY
);
5616 ADD_INT(d
, DB_TRUNCATE
);
5617 ADD_INT(d
, DB_EXTENT
);
5618 ADD_INT(d
, DB_CDB_ALLDB
);
5619 ADD_INT(d
, DB_VERIFY
);
5620 ADD_INT(d
, DB_UPGRADE
);
5622 ADD_INT(d
, DB_AGGRESSIVE
);
5623 ADD_INT(d
, DB_NOORDERCHK
);
5624 ADD_INT(d
, DB_ORDERCHKONLY
);
5625 ADD_INT(d
, DB_PR_PAGE
);
5627 ADD_INT(d
, DB_VRFY_FLAGMASK
);
5628 ADD_INT(d
, DB_PR_HEADERS
);
5630 ADD_INT(d
, DB_PR_RECOVERYTEST
);
5631 ADD_INT(d
, DB_SALVAGE
);
5633 ADD_INT(d
, DB_LOCK_NORUN
);
5634 ADD_INT(d
, DB_LOCK_DEFAULT
);
5635 ADD_INT(d
, DB_LOCK_OLDEST
);
5636 ADD_INT(d
, DB_LOCK_RANDOM
);
5637 ADD_INT(d
, DB_LOCK_YOUNGEST
);
5639 ADD_INT(d
, DB_LOCK_MAXLOCKS
);
5640 ADD_INT(d
, DB_LOCK_MINLOCKS
);
5641 ADD_INT(d
, DB_LOCK_MINWRITE
);
5646 /* docs say to use zero instead */
5647 _addIntToDict(d
, "DB_LOCK_CONFLICT", 0);
5649 ADD_INT(d
, DB_LOCK_CONFLICT
);
5652 ADD_INT(d
, DB_LOCK_DUMP
);
5653 ADD_INT(d
, DB_LOCK_GET
);
5654 ADD_INT(d
, DB_LOCK_INHERIT
);
5655 ADD_INT(d
, DB_LOCK_PUT
);
5656 ADD_INT(d
, DB_LOCK_PUT_ALL
);
5657 ADD_INT(d
, DB_LOCK_PUT_OBJ
);
5659 ADD_INT(d
, DB_LOCK_NG
);
5660 ADD_INT(d
, DB_LOCK_READ
);
5661 ADD_INT(d
, DB_LOCK_WRITE
);
5662 ADD_INT(d
, DB_LOCK_NOWAIT
);
5663 ADD_INT(d
, DB_LOCK_WAIT
);
5664 ADD_INT(d
, DB_LOCK_IWRITE
);
5665 ADD_INT(d
, DB_LOCK_IREAD
);
5666 ADD_INT(d
, DB_LOCK_IWR
);
5669 ADD_INT(d
, DB_LOCK_DIRTY
);
5671 ADD_INT(d
, DB_LOCK_READ_UNCOMMITTED
); /* renamed in 4.4 */
5673 ADD_INT(d
, DB_LOCK_WWRITE
);
5676 ADD_INT(d
, DB_LOCK_RECORD
);
5677 ADD_INT(d
, DB_LOCK_UPGRADE
);
5678 ADD_INT(d
, DB_LOCK_SWITCH
);
5680 ADD_INT(d
, DB_LOCK_UPGRADE_WRITE
);
5683 ADD_INT(d
, DB_LOCK_NOWAIT
);
5684 ADD_INT(d
, DB_LOCK_RECORD
);
5685 ADD_INT(d
, DB_LOCK_UPGRADE
);
5688 ADD_INT(d
, DB_LSTAT_ABORTED
);
5690 ADD_INT(d
, DB_LSTAT_ERR
);
5692 ADD_INT(d
, DB_LSTAT_FREE
);
5693 ADD_INT(d
, DB_LSTAT_HELD
);
5695 ADD_INT(d
, DB_LSTAT_NOGRANT
);
5697 ADD_INT(d
, DB_LSTAT_PENDING
);
5698 ADD_INT(d
, DB_LSTAT_WAITING
);
5701 ADD_INT(d
, DB_ARCH_ABS
);
5702 ADD_INT(d
, DB_ARCH_DATA
);
5703 ADD_INT(d
, DB_ARCH_LOG
);
5705 ADD_INT(d
, DB_ARCH_REMOVE
);
5708 ADD_INT(d
, DB_BTREE
);
5709 ADD_INT(d
, DB_HASH
);
5710 ADD_INT(d
, DB_RECNO
);
5711 ADD_INT(d
, DB_QUEUE
);
5712 ADD_INT(d
, DB_UNKNOWN
);
5715 ADD_INT(d
, DB_DUPSORT
);
5716 ADD_INT(d
, DB_RECNUM
);
5717 ADD_INT(d
, DB_RENUMBER
);
5718 ADD_INT(d
, DB_REVSPLITOFF
);
5719 ADD_INT(d
, DB_SNAPSHOT
);
5721 ADD_INT(d
, DB_JOIN_NOSORT
);
5723 ADD_INT(d
, DB_AFTER
);
5724 ADD_INT(d
, DB_APPEND
);
5725 ADD_INT(d
, DB_BEFORE
);
5727 ADD_INT(d
, DB_CACHED_COUNTS
);
5730 _addIntToDict(d
, "DB_CHECKPOINT", 0);
5732 ADD_INT(d
, DB_CHECKPOINT
);
5733 ADD_INT(d
, DB_CURLSN
);
5735 #if ((DBVER >= 33) && (DBVER <= 41))
5736 ADD_INT(d
, DB_COMMIT
);
5738 ADD_INT(d
, DB_CONSUME
);
5739 ADD_INT(d
, DB_CONSUME_WAIT
);
5740 ADD_INT(d
, DB_CURRENT
);
5742 ADD_INT(d
, DB_FAST_STAT
);
5744 ADD_INT(d
, DB_FIRST
);
5745 ADD_INT(d
, DB_FLUSH
);
5746 ADD_INT(d
, DB_GET_BOTH
);
5747 ADD_INT(d
, DB_GET_RECNO
);
5748 ADD_INT(d
, DB_JOIN_ITEM
);
5749 ADD_INT(d
, DB_KEYFIRST
);
5750 ADD_INT(d
, DB_KEYLAST
);
5751 ADD_INT(d
, DB_LAST
);
5752 ADD_INT(d
, DB_NEXT
);
5753 ADD_INT(d
, DB_NEXT_DUP
);
5754 ADD_INT(d
, DB_NEXT_NODUP
);
5755 ADD_INT(d
, DB_NODUPDATA
);
5756 ADD_INT(d
, DB_NOOVERWRITE
);
5757 ADD_INT(d
, DB_NOSYNC
);
5758 ADD_INT(d
, DB_POSITION
);
5759 ADD_INT(d
, DB_PREV
);
5760 ADD_INT(d
, DB_PREV_NODUP
);
5762 ADD_INT(d
, DB_RECORDCOUNT
);
5765 ADD_INT(d
, DB_SET_RANGE
);
5766 ADD_INT(d
, DB_SET_RECNO
);
5767 ADD_INT(d
, DB_WRITECURSOR
);
5769 ADD_INT(d
, DB_OPFLAGS_MASK
);
5772 ADD_INT(d
, DB_DIRTY_READ
);
5773 ADD_INT(d
, DB_MULTIPLE
);
5774 ADD_INT(d
, DB_MULTIPLE_KEY
);
5778 ADD_INT(d
, DB_READ_UNCOMMITTED
); /* replaces DB_DIRTY_READ in 4.4 */
5779 ADD_INT(d
, DB_READ_COMMITTED
);
5783 ADD_INT(d
, DB_DONOTINDEX
);
5787 _addIntToDict(d
, "DB_INCOMPLETE", 0);
5789 ADD_INT(d
, DB_INCOMPLETE
);
5791 ADD_INT(d
, DB_KEYEMPTY
);
5792 ADD_INT(d
, DB_KEYEXIST
);
5793 ADD_INT(d
, DB_LOCK_DEADLOCK
);
5794 ADD_INT(d
, DB_LOCK_NOTGRANTED
);
5795 ADD_INT(d
, DB_NOSERVER
);
5796 ADD_INT(d
, DB_NOSERVER_HOME
);
5797 ADD_INT(d
, DB_NOSERVER_ID
);
5798 ADD_INT(d
, DB_NOTFOUND
);
5799 ADD_INT(d
, DB_OLD_VERSION
);
5800 ADD_INT(d
, DB_RUNRECOVERY
);
5801 ADD_INT(d
, DB_VERIFY_BAD
);
5803 ADD_INT(d
, DB_PAGE_NOTFOUND
);
5804 ADD_INT(d
, DB_SECONDARY_BAD
);
5807 ADD_INT(d
, DB_STAT_CLEAR
);
5808 ADD_INT(d
, DB_REGION_INIT
);
5809 ADD_INT(d
, DB_NOLOCKING
);
5810 ADD_INT(d
, DB_YIELDCPU
);
5811 ADD_INT(d
, DB_PANIC_ENVIRONMENT
);
5812 ADD_INT(d
, DB_NOPANIC
);
5816 ADD_INT(d
, DB_REGISTER
);
5820 ADD_INT(d
, DB_TIME_NOTGRANTED
);
5821 ADD_INT(d
, DB_TXN_NOT_DURABLE
);
5822 ADD_INT(d
, DB_TXN_WRITE_NOSYNC
);
5823 ADD_INT(d
, DB_LOG_AUTOREMOVE
);
5824 ADD_INT(d
, DB_DIRECT_LOG
);
5825 ADD_INT(d
, DB_DIRECT_DB
);
5826 ADD_INT(d
, DB_INIT_REP
);
5827 ADD_INT(d
, DB_ENCRYPT
);
5828 ADD_INT(d
, DB_CHKSUM
);
5832 ADD_INT(d
, DB_LOG_INMEMORY
);
5833 ADD_INT(d
, DB_BUFFER_SMALL
);
5834 ADD_INT(d
, DB_SEQ_DEC
);
5835 ADD_INT(d
, DB_SEQ_INC
);
5836 ADD_INT(d
, DB_SEQ_WRAP
);
5840 ADD_INT(d
, DB_ENCRYPT_AES
);
5841 ADD_INT(d
, DB_AUTO_COMMIT
);
5843 /* allow berkeleydb 4.1 aware apps to run on older versions */
5844 _addIntToDict(d
, "DB_AUTO_COMMIT", 0);
5858 ADD_INT(d
, DB_SET_LOCK_TIMEOUT
);
5859 ADD_INT(d
, DB_SET_TXN_TIMEOUT
);
5862 /* The exception name must be correct for pickled exception *
5863 * objects to unpickle properly. */
5864 #ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
5865 #define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
5867 #define PYBSDDB_EXCEPTION_BASE "bsddb.db."
5870 /* All the rest of the exceptions derive only from DBError */
5871 #define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
5872 PyDict_SetItemString(d, #name, name)
5874 /* The base exception class is DBError */
5875 DBError
= NULL
; /* used in MAKE_EX so that it derives from nothing */
5878 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
5879 * from both DBError and KeyError, since the API only supports
5880 * using one base class. */
5881 PyDict_SetItemString(d
, "KeyError", PyExc_KeyError
);
5882 PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
5883 "class DBKeyEmptyError(DBError, KeyError): pass",
5884 Py_file_input
, d
, d
);
5885 DBNotFoundError
= PyDict_GetItemString(d
, "DBNotFoundError");
5886 DBKeyEmptyError
= PyDict_GetItemString(d
, "DBKeyEmptyError");
5887 PyDict_DelItemString(d
, "KeyError");
5890 #if !INCOMPLETE_IS_WARNING
5891 MAKE_EX(DBIncompleteError
);
5893 MAKE_EX(DBCursorClosedError
);
5894 MAKE_EX(DBKeyEmptyError
);
5895 MAKE_EX(DBKeyExistError
);
5896 MAKE_EX(DBLockDeadlockError
);
5897 MAKE_EX(DBLockNotGrantedError
);
5898 MAKE_EX(DBOldVersionError
);
5899 MAKE_EX(DBRunRecoveryError
);
5900 MAKE_EX(DBVerifyBadError
);
5901 MAKE_EX(DBNoServerError
);
5902 MAKE_EX(DBNoServerHomeError
);
5903 MAKE_EX(DBNoServerIDError
);
5905 MAKE_EX(DBPageNotFoundError
);
5906 MAKE_EX(DBSecondaryBadError
);
5909 MAKE_EX(DBInvalidArgError
);
5910 MAKE_EX(DBAccessError
);
5911 MAKE_EX(DBNoSpaceError
);
5912 MAKE_EX(DBNoMemoryError
);
5913 MAKE_EX(DBAgainError
);
5914 MAKE_EX(DBBusyError
);
5915 MAKE_EX(DBFileExistsError
);
5916 MAKE_EX(DBNoSuchFileError
);
5917 MAKE_EX(DBPermissionsError
);
5921 /* Initiliase the C API structure and add it to the module */
5922 bsddb_api
.db_type
= &DB_Type
;
5923 bsddb_api
.dbcursor_type
= &DBCursor_Type
;
5924 bsddb_api
.dbenv_type
= &DBEnv_Type
;
5925 bsddb_api
.dbtxn_type
= &DBTxn_Type
;
5926 bsddb_api
.dblock_type
= &DBLock_Type
;
5928 bsddb_api
.dbsequence_type
= &DBSequence_Type
;
5930 bsddb_api
.makeDBError
= makeDBError
;
5932 py_api
= PyCObject_FromVoidPtr((void*)&bsddb_api
, NULL
);
5933 PyDict_SetItemString(d
, "api", py_api
);
5936 /* Check for errors */
5937 if (PyErr_Occurred()) {
5939 Py_FatalError("can't initialize module _bsddb");
5943 /* allow this module to be named _pybsddb so that it can be installed
5944 * and imported on top of python >= 2.3 that includes its own older
5945 * copy of the library named _bsddb without importing the old version. */
5946 DL_EXPORT(void) init_pybsddb(void)
5948 strncpy(_bsddbModuleName
, "_pybsddb", MODULE_NAME_MAX_LEN
);