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 <greg@electricrain.com> who
43 * based his work on a similar package by Robin Dunn <robin@alldunn.com>
44 * which wrapped Berkeley DB 2.7.x.
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@electricrain.com> 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 5 types:
67 * DBCursor (Database Cursor)
68 * DBEnv (database environment)
69 * DBTxn (An explicit database transaction)
70 * DBLock (A lock handle)
74 /* --------------------------------------------------------------------- */
77 * Portions of this module, associated unit tests and build scripts are the
78 * result of a contract with The Written Word (http://thewrittenword.com/)
79 * Many thanks go out to them for causing me to raise the bar on quality and
80 * functionality, resulting in a better bsddb3 package for all of us to use.
85 /* --------------------------------------------------------------------- */
87 #include <stddef.h> /* for offsetof() */
91 /* --------------------------------------------------------------------- */
92 /* Various macro definitions */
94 /* 40 = 4.0, 33 = 3.3; this will break if the second number is > 9 */
95 #define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
96 #if DB_VERSION_MINOR > 9
97 #error "eek! DBVER can't handle minor versions > 9"
100 #define PY_BSDDB_VERSION "4.3.3"
101 static char *rcs_id
= "$Id$";
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 /* python >= 2.1 support weak references */
200 /* if Python >= 2.1 better support warnings */
201 #if PYTHON_API_VERSION >= 1010
202 #define HAVE_WARNINGS
207 #if PYTHON_API_VERSION <= 1007
208 /* 1.5 compatibility */
209 #define PyObject_New PyObject_NEW
210 #define PyObject_Del PyMem_DEL
213 struct behaviourFlags
{
214 /* What is the default behaviour when DB->get or DBCursor->get returns a
215 DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise an exception? */
216 unsigned int getReturnsNone
: 1;
217 /* What is the default behaviour for DBCursor.set* methods when DBCursor->get
218 * returns a DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise? */
219 unsigned int cursorSetReturnsNone
: 1;
222 #define DEFAULT_GET_RETURNS_NONE 1
223 #define DEFAULT_CURSOR_SET_RETURNS_NONE 1 /* 0 in pybsddb < 4.2, python < 2.4 */
228 u_int32_t flags
; /* saved flags from open() */
230 struct behaviourFlags moduleFlags
;
232 PyObject
*in_weakreflist
; /* List of weak references */
240 DBEnvObject
* myenvobj
; /* PyObject containing the DB_ENV */
241 u_int32_t flags
; /* saved flags from open() */
242 u_int32_t setflags
; /* saved flags from set_flags() */
244 struct behaviourFlags moduleFlags
;
246 PyObject
* associateCallback
;
247 PyObject
* btCompareCallback
;
251 PyObject
*in_weakreflist
; /* List of weak references */
261 PyObject
*in_weakreflist
; /* List of weak references */
270 PyObject
*in_weakreflist
; /* List of weak references */
279 PyObject
*in_weakreflist
; /* List of weak references */
285 staticforward PyTypeObject DB_Type
, DBCursor_Type
, DBEnv_Type
, DBTxn_Type
, DBLock_Type
;
287 #define DBObject_Check(v) ((v)->ob_type == &DB_Type)
288 #define DBCursorObject_Check(v) ((v)->ob_type == &DBCursor_Type)
289 #define DBEnvObject_Check(v) ((v)->ob_type == &DBEnv_Type)
290 #define DBTxnObject_Check(v) ((v)->ob_type == &DBTxn_Type)
291 #define DBLockObject_Check(v) ((v)->ob_type == &DBLock_Type)
294 /* --------------------------------------------------------------------- */
295 /* Utility macros and functions */
297 #define RETURN_IF_ERR() \
298 if (makeDBError(err)) { \
302 #define RETURN_NONE() Py_INCREF(Py_None); return Py_None;
304 #define _CHECK_OBJECT_NOT_CLOSED(nonNull, pyErrObj, name) \
305 if ((nonNull) == NULL) { \
306 PyObject *errTuple = NULL; \
307 errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
308 PyErr_SetObject((pyErrObj), errTuple); \
309 Py_DECREF(errTuple); \
313 #define CHECK_DB_NOT_CLOSED(dbobj) \
314 _CHECK_OBJECT_NOT_CLOSED(dbobj->db, DBError, DB)
316 #define CHECK_ENV_NOT_CLOSED(env) \
317 _CHECK_OBJECT_NOT_CLOSED(env->db_env, DBError, DBEnv)
319 #define CHECK_CURSOR_NOT_CLOSED(curs) \
320 _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)
323 #define CHECK_DBFLAG(mydb, flag) (((mydb)->flags & (flag)) || \
324 (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))
326 #define CLEAR_DBT(dbt) (memset(&(dbt), 0, sizeof(dbt)))
328 #define FREE_DBT(dbt) if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
329 dbt.data != NULL) { free(dbt.data); dbt.data = NULL; }
332 static int makeDBError(int err
);
335 /* Return the access method type of the DBObject */
336 static int _DB_get_type(DBObject
* self
)
341 err
= self
->db
->get_type(self
->db
, &type
);
342 if (makeDBError(err
)) {
347 return self
->db
->get_type(self
->db
);
352 /* Create a DBT structure (containing key and data values) from Python
353 strings. Returns 1 on success, 0 on an error. */
354 static int make_dbt(PyObject
* obj
, DBT
* dbt
)
357 if (obj
== Py_None
) {
358 /* no need to do anything, the structure has already been zeroed */
360 else if (!PyArg_Parse(obj
, "s#", &dbt
->data
, &dbt
->size
)) {
361 PyErr_SetString(PyExc_TypeError
,
362 "Data values must be of type string or None.");
369 /* Recno and Queue DBs can have integer keys. This function figures out
370 what's been given, verifies that it's allowed, and then makes the DBT.
372 Caller MUST call FREE_DBT(key) when done. */
374 make_key_dbt(DBObject
* self
, PyObject
* keyobj
, DBT
* key
, int* pflags
)
380 if (keyobj
== Py_None
) {
381 type
= _DB_get_type(self
);
384 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
387 "None keys not allowed for Recno and Queue DB's");
390 /* no need to do anything, the structure has already been zeroed */
393 else if (PyString_Check(keyobj
)) {
394 /* verify access method type */
395 type
= _DB_get_type(self
);
398 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
401 "String keys not allowed for Recno and Queue DB's");
405 key
->data
= PyString_AS_STRING(keyobj
);
406 key
->size
= PyString_GET_SIZE(keyobj
);
409 else if (PyInt_Check(keyobj
)) {
410 /* verify access method type */
411 type
= _DB_get_type(self
);
414 if (type
== DB_BTREE
&& pflags
!= NULL
) {
415 /* if BTREE then an Integer key is allowed with the
416 * DB_SET_RECNO flag */
417 *pflags
|= DB_SET_RECNO
;
419 else if (type
!= DB_RECNO
&& type
!= DB_QUEUE
) {
422 "Integer keys only allowed for Recno and Queue DB's");
426 /* Make a key out of the requested recno, use allocated space so DB
427 * will be able to realloc room for the real key if needed. */
428 recno
= PyInt_AS_LONG(keyobj
);
429 key
->data
= malloc(sizeof(db_recno_t
));
430 if (key
->data
== NULL
) {
431 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
434 key
->ulen
= key
->size
= sizeof(db_recno_t
);
435 memcpy(key
->data
, &recno
, sizeof(db_recno_t
));
436 key
->flags
= DB_DBT_REALLOC
;
439 PyErr_Format(PyExc_TypeError
,
440 "String or Integer object expected for key, %s found",
441 keyobj
->ob_type
->tp_name
);
449 /* Add partial record access to an existing DBT data struct.
450 If dlen and doff are set, then the DB_DBT_PARTIAL flag will be set
451 and the data storage/retrieval will be done using dlen and doff. */
452 static int add_partial_dbt(DBT
* d
, int dlen
, int doff
) {
453 /* if neither were set we do nothing (-1 is the default value) */
454 if ((dlen
== -1) && (doff
== -1)) {
458 if ((dlen
< 0) || (doff
< 0)) {
459 PyErr_SetString(PyExc_TypeError
, "dlen and doff must both be >= 0");
463 d
->flags
= d
->flags
| DB_DBT_PARTIAL
;
464 d
->dlen
= (unsigned int) dlen
;
465 d
->doff
= (unsigned int) doff
;
469 /* a safe strcpy() without the zeroing behaviour and semantics of strncpy. */
470 /* TODO: make this use the native libc strlcpy() when available (BSD) */
471 unsigned int our_strlcpy(char* dest
, const char* src
, unsigned int n
)
473 unsigned int srclen
, copylen
;
475 srclen
= strlen(src
);
478 copylen
= (srclen
> n
-1) ? n
-1 : srclen
;
479 /* populate dest[0] thru dest[copylen-1] */
480 memcpy(dest
, src
, copylen
);
481 /* guarantee null termination */
487 /* Callback used to save away more information about errors from the DB
489 static char _db_errmsg
[1024];
491 static void _db_errorCallback(const char* prefix
, char* msg
)
493 static void _db_errorCallback(const DB_ENV
*db_env
,
494 const char* prefix
, const char* msg
)
497 our_strlcpy(_db_errmsg
, msg
, sizeof(_db_errmsg
));
501 /* make a nice exception object to raise for errors. */
502 static int makeDBError(int err
)
504 char errTxt
[2048]; /* really big, just in case... */
505 PyObject
*errObj
= NULL
;
506 PyObject
*errTuple
= NULL
;
507 int exceptionRaised
= 0;
510 case 0: /* successful, no error */ break;
514 #if INCOMPLETE_IS_WARNING
515 our_strlcpy(errTxt
, db_strerror(err
), sizeof(errTxt
));
517 strcat(errTxt
, " -- ");
518 strcat(errTxt
, _db_errmsg
);
522 exceptionRaised
= PyErr_Warn(PyExc_RuntimeWarning
, errTxt
);
524 fprintf(stderr
, errTxt
);
525 fprintf(stderr
, "\n");
528 #else /* do an exception instead */
529 errObj
= DBIncompleteError
;
532 #endif /* DBVER < 41 */
534 case DB_KEYEMPTY
: errObj
= DBKeyEmptyError
; break;
535 case DB_KEYEXIST
: errObj
= DBKeyExistError
; break;
536 case DB_LOCK_DEADLOCK
: errObj
= DBLockDeadlockError
; break;
537 case DB_LOCK_NOTGRANTED
: errObj
= DBLockNotGrantedError
; break;
538 case DB_NOTFOUND
: errObj
= DBNotFoundError
; break;
539 case DB_OLD_VERSION
: errObj
= DBOldVersionError
; break;
540 case DB_RUNRECOVERY
: errObj
= DBRunRecoveryError
; break;
541 case DB_VERIFY_BAD
: errObj
= DBVerifyBadError
; break;
542 case DB_NOSERVER
: errObj
= DBNoServerError
; break;
543 case DB_NOSERVER_HOME
: errObj
= DBNoServerHomeError
; break;
544 case DB_NOSERVER_ID
: errObj
= DBNoServerIDError
; break;
546 case DB_PAGE_NOTFOUND
: errObj
= DBPageNotFoundError
; break;
547 case DB_SECONDARY_BAD
: errObj
= DBSecondaryBadError
; break;
549 case DB_BUFFER_SMALL
: errObj
= DBNoMemoryError
; break;
552 /* ENOMEM and DB_BUFFER_SMALL were one and the same until 4.3 */
553 case ENOMEM
: errObj
= PyExc_MemoryError
; break;
555 case EINVAL
: errObj
= DBInvalidArgError
; break;
556 case EACCES
: errObj
= DBAccessError
; break;
557 case ENOSPC
: errObj
= DBNoSpaceError
; break;
558 case EAGAIN
: errObj
= DBAgainError
; break;
559 case EBUSY
: errObj
= DBBusyError
; break;
560 case EEXIST
: errObj
= DBFileExistsError
; break;
561 case ENOENT
: errObj
= DBNoSuchFileError
; break;
562 case EPERM
: errObj
= DBPermissionsError
; break;
564 default: errObj
= DBError
; break;
567 if (errObj
!= NULL
) {
568 our_strlcpy(errTxt
, db_strerror(err
), sizeof(errTxt
));
570 strcat(errTxt
, " -- ");
571 strcat(errTxt
, _db_errmsg
);
575 errTuple
= Py_BuildValue("(is)", err
, errTxt
);
576 PyErr_SetObject(errObj
, errTuple
);
580 return ((errObj
!= NULL
) || exceptionRaised
);
585 /* set a type exception */
586 static void makeTypeError(char* expected
, PyObject
* found
)
588 PyErr_Format(PyExc_TypeError
, "Expected %s argument, %s found.",
589 expected
, found
->ob_type
->tp_name
);
593 /* verify that an obj is either None or a DBTxn, and set the txn pointer */
594 static int checkTxnObj(PyObject
* txnobj
, DB_TXN
** txn
)
596 if (txnobj
== Py_None
|| txnobj
== NULL
) {
600 if (DBTxnObject_Check(txnobj
)) {
601 *txn
= ((DBTxnObject
*)txnobj
)->txn
;
605 makeTypeError("DBTxn", txnobj
);
610 /* Delete a key from a database
611 Returns 0 on success, -1 on an error. */
612 static int _DB_delete(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, int flags
)
616 MYDB_BEGIN_ALLOW_THREADS
;
617 err
= self
->db
->del(self
->db
, txn
, key
, 0);
618 MYDB_END_ALLOW_THREADS
;
619 if (makeDBError(err
)) {
627 /* Store a key into a database
628 Returns 0 on success, -1 on an error. */
629 static int _DB_put(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, DBT
*data
, int flags
)
633 MYDB_BEGIN_ALLOW_THREADS
;
634 err
= self
->db
->put(self
->db
, txn
, key
, data
, flags
);
635 MYDB_END_ALLOW_THREADS
;
636 if (makeDBError(err
)) {
643 /* Get a key/data pair from a cursor */
644 static PyObject
* _DBCursor_get(DBCursorObject
* self
, int extra_flags
,
645 PyObject
*args
, PyObject
*kwargs
, char *format
)
648 PyObject
* retval
= NULL
;
653 static const char* kwnames
[] = { "flags", "dlen", "doff", NULL
};
655 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, format
, kwnames
,
656 &flags
, &dlen
, &doff
))
659 CHECK_CURSOR_NOT_CLOSED(self
);
661 flags
|= extra_flags
;
664 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
665 /* Tell BerkeleyDB to malloc the return value (thread safe) */
666 data
.flags
= DB_DBT_MALLOC
;
667 key
.flags
= DB_DBT_MALLOC
;
669 if (!add_partial_dbt(&data
, dlen
, doff
))
672 MYDB_BEGIN_ALLOW_THREADS
;
673 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
674 MYDB_END_ALLOW_THREADS
;
676 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
677 && self
->mydb
->moduleFlags
.getReturnsNone
) {
681 else if (makeDBError(err
)) {
684 else { /* otherwise, success! */
686 /* if Recno or Queue, return the key as an Int */
687 switch (_DB_get_type(self
->mydb
)) {
694 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
695 data
.data
, data
.size
);
700 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
701 data
.data
, data
.size
);
713 /* add an integer to a dictionary using the given name as a key */
714 static void _addIntToDict(PyObject
* dict
, char *name
, int value
)
716 PyObject
* v
= PyInt_FromLong((long) value
);
717 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
726 /* --------------------------------------------------------------------- */
727 /* Allocators and deallocators */
730 newDBObject(DBEnvObject
* arg
, int flags
)
733 DB_ENV
* db_env
= NULL
;
736 self
= PyObject_New(DBObject
, &DB_Type
);
743 self
->myenvobj
= NULL
;
745 self
->associateCallback
= NULL
;
746 self
->btCompareCallback
= NULL
;
747 self
->primaryDBType
= 0;
750 self
->in_weakreflist
= NULL
;
753 /* keep a reference to our python DBEnv object */
756 self
->myenvobj
= arg
;
757 db_env
= arg
->db_env
;
761 self
->moduleFlags
= self
->myenvobj
->moduleFlags
;
763 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
764 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
766 MYDB_BEGIN_ALLOW_THREADS
;
767 err
= db_create(&self
->db
, db_env
, flags
);
768 self
->db
->set_errcall(self
->db
, _db_errorCallback
);
770 self
->db
->app_private
= (void*)self
;
772 MYDB_END_ALLOW_THREADS
;
773 /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
774 * list so that a DBEnv can refuse to close without aborting any open
775 * open DBTxns and closing any open DBs first. */
776 if (makeDBError(err
)) {
777 if (self
->myenvobj
) {
778 Py_DECREF(self
->myenvobj
);
779 self
->myenvobj
= NULL
;
788 DB_dealloc(DBObject
* self
)
790 if (self
->db
!= NULL
) {
791 /* avoid closing a DB when its DBEnv has been closed out from under
793 if (!self
->myenvobj
||
794 (self
->myenvobj
&& self
->myenvobj
->db_env
))
796 MYDB_BEGIN_ALLOW_THREADS
;
797 self
->db
->close(self
->db
, 0);
798 MYDB_END_ALLOW_THREADS
;
801 PyErr_Warn(PyExc_RuntimeWarning
,
802 "DB could not be closed in destructor: DBEnv already closed");
808 if (self
->in_weakreflist
!= NULL
) {
809 PyObject_ClearWeakRefs((PyObject
*) self
);
812 if (self
->myenvobj
) {
813 Py_DECREF(self
->myenvobj
);
814 self
->myenvobj
= NULL
;
817 if (self
->associateCallback
!= NULL
) {
818 Py_DECREF(self
->associateCallback
);
819 self
->associateCallback
= NULL
;
821 if (self
->btCompareCallback
!= NULL
) {
822 Py_DECREF(self
->btCompareCallback
);
823 self
->btCompareCallback
= NULL
;
830 static DBCursorObject
*
831 newDBCursorObject(DBC
* dbc
, DBObject
* db
)
833 DBCursorObject
* self
= PyObject_New(DBCursorObject
, &DBCursor_Type
);
840 self
->in_weakreflist
= NULL
;
842 Py_INCREF(self
->mydb
);
848 DBCursor_dealloc(DBCursorObject
* self
)
853 if (self
->in_weakreflist
!= NULL
) {
854 PyObject_ClearWeakRefs((PyObject
*) self
);
858 if (self
->dbc
!= NULL
) {
859 MYDB_BEGIN_ALLOW_THREADS
;
860 /* If the underlying database has been closed, we don't
861 need to do anything. If the environment has been closed
862 we need to leak, as BerkeleyDB will crash trying to access
863 the environment. There was an exception when the
864 user closed the environment even though there still was
866 if (self
->mydb
->db
&& self
->mydb
->myenvobj
&&
867 !self
->mydb
->myenvobj
->closed
)
868 err
= self
->dbc
->c_close(self
->dbc
);
870 MYDB_END_ALLOW_THREADS
;
872 Py_XDECREF( self
->mydb
);
878 newDBEnvObject(int flags
)
881 DBEnvObject
* self
= PyObject_New(DBEnvObject
, &DBEnv_Type
);
887 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
888 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
890 self
->in_weakreflist
= NULL
;
893 MYDB_BEGIN_ALLOW_THREADS
;
894 err
= db_env_create(&self
->db_env
, flags
);
895 MYDB_END_ALLOW_THREADS
;
896 if (makeDBError(err
)) {
900 self
->db_env
->set_errcall(self
->db_env
, _db_errorCallback
);
907 DBEnv_dealloc(DBEnvObject
* self
)
910 if (self
->in_weakreflist
!= NULL
) {
911 PyObject_ClearWeakRefs((PyObject
*) self
);
916 MYDB_BEGIN_ALLOW_THREADS
;
917 self
->db_env
->close(self
->db_env
, 0);
918 MYDB_END_ALLOW_THREADS
;
925 newDBTxnObject(DBEnvObject
* myenv
, DB_TXN
*parent
, int flags
)
928 DBTxnObject
* self
= PyObject_New(DBTxnObject
, &DBTxn_Type
);
932 self
->in_weakreflist
= NULL
;
935 MYDB_BEGIN_ALLOW_THREADS
;
937 err
= myenv
->db_env
->txn_begin(myenv
->db_env
, parent
, &(self
->txn
), flags
);
939 err
= txn_begin(myenv
->db_env
, parent
, &(self
->txn
), flags
);
941 /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
942 * list so that a DBEnv can refuse to close without aborting any open
943 * open DBTxns and closing any open DBs first. */
944 MYDB_END_ALLOW_THREADS
;
945 if (makeDBError(err
)) {
953 DBTxn_dealloc(DBTxnObject
* self
)
956 if (self
->in_weakreflist
!= NULL
) {
957 PyObject_ClearWeakRefs((PyObject
*) self
);
963 /* it hasn't been finalized, abort it! */
964 MYDB_BEGIN_ALLOW_THREADS
;
966 self
->txn
->abort(self
->txn
);
968 txn_abort(self
->txn
);
970 MYDB_END_ALLOW_THREADS
;
971 PyErr_Warn(PyExc_RuntimeWarning
,
972 "DBTxn aborted in destructor. No prior commit() or abort().");
981 newDBLockObject(DBEnvObject
* myenv
, u_int32_t locker
, DBT
* obj
,
982 db_lockmode_t lock_mode
, int flags
)
985 DBLockObject
* self
= PyObject_New(DBLockObject
, &DBLock_Type
);
989 self
->in_weakreflist
= NULL
;
992 MYDB_BEGIN_ALLOW_THREADS
;
994 err
= myenv
->db_env
->lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
,
997 err
= lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
, &self
->lock
);
999 MYDB_END_ALLOW_THREADS
;
1000 if (makeDBError(err
)) {
1009 DBLock_dealloc(DBLockObject
* self
)
1012 if (self
->in_weakreflist
!= NULL
) {
1013 PyObject_ClearWeakRefs((PyObject
*) self
);
1016 /* TODO: is this lock held? should we release it? */
1022 /* --------------------------------------------------------------------- */
1026 DB_append(DBObject
* self
, PyObject
* args
)
1028 PyObject
* txnobj
= NULL
;
1034 if (!PyArg_ParseTuple(args
, "O|O:append", &dataobj
, &txnobj
))
1037 CHECK_DB_NOT_CLOSED(self
);
1039 /* make a dummy key out of a recno */
1043 key
.size
= sizeof(recno
);
1044 key
.ulen
= key
.size
;
1045 key
.flags
= DB_DBT_USERMEM
;
1047 if (!make_dbt(dataobj
, &data
)) return NULL
;
1048 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1050 if (-1 == _DB_put(self
, txn
, &key
, &data
, DB_APPEND
))
1053 return PyInt_FromLong(recno
);
1060 _db_associateCallback(DB
* db
, const DBT
* priKey
, const DBT
* priData
,
1063 int retval
= DB_DONOTINDEX
;
1064 DBObject
* secondaryDB
= (DBObject
*)db
->app_private
;
1065 PyObject
* callback
= secondaryDB
->associateCallback
;
1066 int type
= secondaryDB
->primaryDBType
;
1073 if (callback
!= NULL
) {
1074 MYDB_BEGIN_BLOCK_THREADS
;
1076 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
1077 key
= PyInt_FromLong( *((db_recno_t
*)priKey
->data
));
1080 key
= PyString_FromStringAndSize(priKey
->data
, priKey
->size
);
1082 data
= PyString_FromStringAndSize(priData
->data
, priData
->size
);
1083 args
= PyTuple_New(2);
1084 PyTuple_SET_ITEM(args
, 0, key
); /* steals reference */
1085 PyTuple_SET_ITEM(args
, 1, data
); /* steals reference */
1087 result
= PyEval_CallObject(callback
, args
);
1089 if (result
== NULL
) {
1092 else if (result
== Py_None
) {
1093 retval
= DB_DONOTINDEX
;
1095 else if (PyInt_Check(result
)) {
1096 retval
= PyInt_AsLong(result
);
1098 else if (PyString_Check(result
)) {
1103 #if PYTHON_API_VERSION <= 1007
1104 /* 1.5 compatibility */
1105 size
= PyString_Size(result
);
1106 data
= PyString_AsString(result
);
1108 PyString_AsStringAndSize(result
, &data
, &size
);
1110 secKey
->flags
= DB_DBT_APPMALLOC
; /* DB will free */
1111 secKey
->data
= malloc(size
); /* TODO, check this */
1113 memcpy(secKey
->data
, data
, size
);
1114 secKey
->size
= size
;
1118 PyErr_SetString(PyExc_MemoryError
,
1119 "malloc failed in _db_associateCallback");
1126 "DB associate callback should return DB_DONOTINDEX or string.");
1135 MYDB_END_BLOCK_THREADS
;
1142 DB_associate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1145 DBObject
* secondaryDB
;
1148 PyObject
*txnobj
= NULL
;
1150 static const char* kwnames
[] = {"secondaryDB", "callback", "flags", "txn",
1153 static const char* kwnames
[] = {"secondaryDB", "callback", "flags", NULL
};
1157 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iO:associate", kwnames
,
1158 &secondaryDB
, &callback
, &flags
,
1161 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|i:associate", kwnames
,
1162 &secondaryDB
, &callback
, &flags
)) {
1168 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1171 CHECK_DB_NOT_CLOSED(self
);
1172 if (!DBObject_Check(secondaryDB
)) {
1173 makeTypeError("DB", (PyObject
*)secondaryDB
);
1176 CHECK_DB_NOT_CLOSED(secondaryDB
);
1177 if (callback
== Py_None
) {
1180 else if (!PyCallable_Check(callback
)) {
1181 makeTypeError("Callable", callback
);
1185 /* Save a reference to the callback in the secondary DB. */
1186 Py_XDECREF(secondaryDB
->associateCallback
);
1187 Py_INCREF(callback
);
1188 secondaryDB
->associateCallback
= callback
;
1189 secondaryDB
->primaryDBType
= _DB_get_type(self
);
1191 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1192 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1193 * The global interepreter lock is not initialized until the first
1194 * thread is created using thread.start_new_thread() or fork() is
1195 * called. that would cause the ALLOW_THREADS here to segfault due
1196 * to a null pointer reference if no threads or child processes
1197 * have been created. This works around that and is a no-op if
1198 * threads have already been initialized.
1199 * (see pybsddb-users mailing list post on 2002-08-07)
1202 PyEval_InitThreads();
1204 MYDB_BEGIN_ALLOW_THREADS
;
1206 err
= self
->db
->associate(self
->db
,
1209 _db_associateCallback
,
1212 err
= self
->db
->associate(self
->db
,
1214 _db_associateCallback
,
1217 MYDB_END_ALLOW_THREADS
;
1220 Py_XDECREF(secondaryDB
->associateCallback
);
1221 secondaryDB
->associateCallback
= NULL
;
1222 secondaryDB
->primaryDBType
= 0;
1234 DB_close(DBObject
* self
, PyObject
* args
)
1237 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
1239 if (self
->db
!= NULL
) {
1241 CHECK_ENV_NOT_CLOSED(self
->myenvobj
);
1242 err
= self
->db
->close(self
->db
, flags
);
1252 _DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1254 int err
, flags
=0, type
;
1255 PyObject
* txnobj
= NULL
;
1256 PyObject
* retval
= NULL
;
1259 static const char* kwnames
[] = { "txn", "flags", NULL
};
1261 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:consume", kwnames
,
1265 CHECK_DB_NOT_CLOSED(self
);
1266 type
= _DB_get_type(self
);
1269 if (type
!= DB_QUEUE
) {
1270 PyErr_SetString(PyExc_TypeError
,
1271 "Consume methods only allowed for Queue DB's");
1274 if (!checkTxnObj(txnobj
, &txn
))
1279 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1280 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1281 data
.flags
= DB_DBT_MALLOC
;
1282 key
.flags
= DB_DBT_MALLOC
;
1285 MYDB_BEGIN_ALLOW_THREADS
;
1286 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
|consume_flag
);
1287 MYDB_END_ALLOW_THREADS
;
1289 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1290 && self
->moduleFlags
.getReturnsNone
) {
1296 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
1307 DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1309 return _DB_consume(self
, args
, kwargs
, DB_CONSUME
);
1313 DB_consume_wait(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
,
1316 return _DB_consume(self
, args
, kwargs
, DB_CONSUME_WAIT
);
1323 DB_cursor(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1327 PyObject
* txnobj
= NULL
;
1329 static const char* kwnames
[] = { "txn", "flags", NULL
};
1331 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
1334 CHECK_DB_NOT_CLOSED(self
);
1335 if (!checkTxnObj(txnobj
, &txn
))
1338 MYDB_BEGIN_ALLOW_THREADS
;
1339 err
= self
->db
->cursor(self
->db
, txn
, &dbc
, flags
);
1340 MYDB_END_ALLOW_THREADS
;
1342 return (PyObject
*) newDBCursorObject(dbc
, self
);
1347 DB_delete(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1349 PyObject
* txnobj
= NULL
;
1354 static const char* kwnames
[] = { "key", "txn", "flags", NULL
};
1356 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:delete", kwnames
,
1357 &keyobj
, &txnobj
, &flags
))
1359 CHECK_DB_NOT_CLOSED(self
);
1360 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1362 if (!checkTxnObj(txnobj
, &txn
)) {
1367 if (-1 == _DB_delete(self
, txn
, &key
, 0)) {
1378 DB_fd(DBObject
* self
, PyObject
* args
)
1382 if (!PyArg_ParseTuple(args
,":fd"))
1384 CHECK_DB_NOT_CLOSED(self
);
1386 MYDB_BEGIN_ALLOW_THREADS
;
1387 err
= self
->db
->fd(self
->db
, &the_fd
);
1388 MYDB_END_ALLOW_THREADS
;
1390 return PyInt_FromLong(the_fd
);
1395 DB_get(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1398 PyObject
* txnobj
= NULL
;
1400 PyObject
* dfltobj
= NULL
;
1401 PyObject
* retval
= NULL
;
1406 static const char* kwnames
[] = {"key", "default", "txn", "flags", "dlen",
1409 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:get", kwnames
,
1410 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1414 CHECK_DB_NOT_CLOSED(self
);
1415 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1417 if (!checkTxnObj(txnobj
, &txn
)) {
1423 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1424 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1425 data
.flags
= DB_DBT_MALLOC
;
1427 if (!add_partial_dbt(&data
, dlen
, doff
)) {
1432 MYDB_BEGIN_ALLOW_THREADS
;
1433 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1434 MYDB_END_ALLOW_THREADS
;
1436 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && (dfltobj
!= NULL
)) {
1441 else if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1442 && self
->moduleFlags
.getReturnsNone
) {
1448 if (flags
& DB_SET_RECNO
) /* return both key and data */
1449 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
1451 else /* return just the data */
1452 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
1463 DB_pget(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1466 PyObject
* txnobj
= NULL
;
1468 PyObject
* dfltobj
= NULL
;
1469 PyObject
* retval
= NULL
;
1472 DBT key
, pkey
, data
;
1474 static const char* kwnames
[] = {"key", "default", "txn", "flags", "dlen",
1477 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:pget", kwnames
,
1478 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1482 CHECK_DB_NOT_CLOSED(self
);
1483 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1485 if (!checkTxnObj(txnobj
, &txn
)) {
1491 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1492 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1493 data
.flags
= DB_DBT_MALLOC
;
1495 if (!add_partial_dbt(&data
, dlen
, doff
)) {
1501 pkey
.flags
= DB_DBT_MALLOC
;
1503 MYDB_BEGIN_ALLOW_THREADS
;
1504 err
= self
->db
->pget(self
->db
, txn
, &key
, &pkey
, &data
, flags
);
1505 MYDB_END_ALLOW_THREADS
;
1507 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && (dfltobj
!= NULL
)) {
1512 else if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1513 && self
->moduleFlags
.getReturnsNone
) {
1521 dataObj
= PyString_FromStringAndSize(data
.data
, data
.size
);
1523 if (self
->primaryDBType
== DB_RECNO
||
1524 self
->primaryDBType
== DB_QUEUE
)
1525 pkeyObj
= PyInt_FromLong(*(int *)pkey
.data
);
1527 pkeyObj
= PyString_FromStringAndSize(pkey
.data
, pkey
.size
);
1529 if (flags
& DB_SET_RECNO
) /* return key , pkey and data */
1532 int type
= _DB_get_type(self
);
1533 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
1534 keyObj
= PyInt_FromLong(*(int *)key
.data
);
1536 keyObj
= PyString_FromStringAndSize(key
.data
, key
.size
);
1537 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
1539 else /* return just the pkey and data */
1541 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
1554 /* Return size of entry */
1556 DB_get_size(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1559 PyObject
* txnobj
= NULL
;
1561 PyObject
* retval
= NULL
;
1564 static const char* kwnames
[] = { "key", "txn", NULL
};
1566 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O:get_size", kwnames
,
1569 CHECK_DB_NOT_CLOSED(self
);
1570 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1572 if (!checkTxnObj(txnobj
, &txn
)) {
1578 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
1579 thus getting the record size. */
1580 data
.flags
= DB_DBT_USERMEM
;
1582 MYDB_BEGIN_ALLOW_THREADS
;
1583 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1584 MYDB_END_ALLOW_THREADS
;
1585 if (err
== DB_BUFFER_SMALL
) {
1586 retval
= PyInt_FromLong((long)data
.size
);
1598 DB_get_both(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1601 PyObject
* txnobj
= NULL
;
1604 PyObject
* retval
= NULL
;
1607 static const char* kwnames
[] = { "key", "data", "txn", "flags", NULL
};
1610 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oi:get_both", kwnames
,
1611 &keyobj
, &dataobj
, &txnobj
, &flags
))
1614 CHECK_DB_NOT_CLOSED(self
);
1615 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1617 if ( !make_dbt(dataobj
, &data
) ||
1618 !checkTxnObj(txnobj
, &txn
) )
1624 flags
|= DB_GET_BOTH
;
1626 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1627 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1628 data
.flags
= DB_DBT_MALLOC
;
1629 /* TODO: Is this flag needed? We're passing a data object that should
1630 match what's in the DB, so there should be no need to malloc.
1631 We run the risk of freeing something twice! Check this. */
1634 MYDB_BEGIN_ALLOW_THREADS
;
1635 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1636 MYDB_END_ALLOW_THREADS
;
1638 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1639 && self
->moduleFlags
.getReturnsNone
) {
1645 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
1646 FREE_DBT(data
); /* Only if retrieval was successful */
1656 DB_get_byteswapped(DBObject
* self
, PyObject
* args
)
1663 if (!PyArg_ParseTuple(args
,":get_byteswapped"))
1665 CHECK_DB_NOT_CLOSED(self
);
1668 MYDB_BEGIN_ALLOW_THREADS
;
1669 err
= self
->db
->get_byteswapped(self
->db
, &retval
);
1670 MYDB_END_ALLOW_THREADS
;
1673 MYDB_BEGIN_ALLOW_THREADS
;
1674 retval
= self
->db
->get_byteswapped(self
->db
);
1675 MYDB_END_ALLOW_THREADS
;
1677 return PyInt_FromLong(retval
);
1682 DB_get_type(DBObject
* self
, PyObject
* args
)
1686 if (!PyArg_ParseTuple(args
,":get_type"))
1688 CHECK_DB_NOT_CLOSED(self
);
1690 MYDB_BEGIN_ALLOW_THREADS
;
1691 type
= _DB_get_type(self
);
1692 MYDB_END_ALLOW_THREADS
;
1695 return PyInt_FromLong(type
);
1700 DB_join(DBObject
* self
, PyObject
* args
)
1704 PyObject
* cursorsObj
;
1709 if (!PyArg_ParseTuple(args
,"O|i:join", &cursorsObj
, &flags
))
1712 CHECK_DB_NOT_CLOSED(self
);
1714 if (!PySequence_Check(cursorsObj
)) {
1715 PyErr_SetString(PyExc_TypeError
,
1716 "Sequence of DBCursor objects expected");
1720 length
= PyObject_Length(cursorsObj
);
1721 cursors
= malloc((length
+1) * sizeof(DBC
*));
1722 cursors
[length
] = NULL
;
1723 for (x
=0; x
<length
; x
++) {
1724 PyObject
* item
= PySequence_GetItem(cursorsObj
, x
);
1725 if (!DBCursorObject_Check(item
)) {
1726 PyErr_SetString(PyExc_TypeError
,
1727 "Sequence of DBCursor objects expected");
1731 cursors
[x
] = ((DBCursorObject
*)item
)->dbc
;
1734 MYDB_BEGIN_ALLOW_THREADS
;
1735 err
= self
->db
->join(self
->db
, cursors
, &dbc
, flags
);
1736 MYDB_END_ALLOW_THREADS
;
1740 /* FIXME: this is a buggy interface. The returned cursor
1741 contains internal references to the passed in cursors
1742 but does not hold python references to them or prevent
1743 them from being closed prematurely. This can cause
1744 python to crash when things are done in the wrong order. */
1745 return (PyObject
*) newDBCursorObject(dbc
, self
);
1750 DB_key_range(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1753 PyObject
* txnobj
= NULL
;
1758 static const char* kwnames
[] = { "key", "txn", "flags", NULL
};
1760 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:key_range", kwnames
,
1761 &keyobj
, &txnobj
, &flags
))
1763 CHECK_DB_NOT_CLOSED(self
);
1764 if (!make_dbt(keyobj
, &key
))
1765 /* BTree only, don't need to allow for an int key */
1767 if (!checkTxnObj(txnobj
, &txn
))
1770 MYDB_BEGIN_ALLOW_THREADS
;
1771 err
= self
->db
->key_range(self
->db
, txn
, &key
, &range
, flags
);
1772 MYDB_END_ALLOW_THREADS
;
1775 return Py_BuildValue("ddd", range
.less
, range
.equal
, range
.greater
);
1780 DB_open(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1782 int err
, type
= DB_UNKNOWN
, flags
=0, mode
=0660;
1783 char* filename
= NULL
;
1784 char* dbname
= NULL
;
1786 PyObject
*txnobj
= NULL
;
1789 static const char* kwnames
[] = {
1790 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL
};
1791 /* without dbname */
1792 static const char* kwnames_basic
[] = {
1793 "filename", "dbtype", "flags", "mode", "txn", NULL
};
1796 static const char* kwnames
[] = {
1797 "filename", "dbname", "dbtype", "flags", "mode", NULL
};
1798 /* without dbname */
1799 static const char* kwnames_basic
[] = {
1800 "filename", "dbtype", "flags", "mode", NULL
};
1804 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziiiO:open", kwnames
,
1805 &filename
, &dbname
, &type
, &flags
, &mode
,
1808 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziii:open", kwnames
,
1809 &filename
, &dbname
, &type
, &flags
,
1814 type
= DB_UNKNOWN
; flags
= 0; mode
= 0660;
1815 filename
= NULL
; dbname
= NULL
;
1817 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iiiO:open",
1819 &filename
, &type
, &flags
, &mode
,
1823 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iii:open",
1825 &filename
, &type
, &flags
, &mode
))
1831 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1834 if (NULL
== self
->db
) {
1835 PyErr_SetObject(DBError
, Py_BuildValue("(is)", 0,
1836 "Cannot call open() twice for DB object"));
1840 #if 0 && (DBVER >= 41)
1841 if ((!txn
) && (txnobj
!= Py_None
) && self
->myenvobj
1842 && (self
->myenvobj
->flags
& DB_INIT_TXN
))
1844 /* If no 'txn' parameter was supplied (no DbTxn object and None was not
1845 * explicitly passed) but we are in a transaction ready environment:
1846 * add DB_AUTO_COMMIT to allow for older pybsddb apps using transactions
1847 * to work on BerkeleyDB 4.1 without needing to modify their
1848 * DBEnv or DB open calls.
1849 * TODO make this behaviour of the library configurable.
1851 flags
|= DB_AUTO_COMMIT
;
1855 MYDB_BEGIN_ALLOW_THREADS
;
1857 err
= self
->db
->open(self
->db
, txn
, filename
, dbname
, type
, flags
, mode
);
1859 err
= self
->db
->open(self
->db
, filename
, dbname
, type
, flags
, mode
);
1861 MYDB_END_ALLOW_THREADS
;
1862 if (makeDBError(err
)) {
1863 self
->db
->close(self
->db
, 0);
1868 self
->flags
= flags
;
1874 DB_put(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1877 PyObject
* txnobj
= NULL
;
1880 PyObject
* keyobj
, *dataobj
, *retval
;
1883 static const char* kwnames
[] = { "key", "data", "txn", "flags", "dlen",
1886 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oiii:put", kwnames
,
1887 &keyobj
, &dataobj
, &txnobj
, &flags
, &dlen
, &doff
))
1890 CHECK_DB_NOT_CLOSED(self
);
1891 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1893 if ( !make_dbt(dataobj
, &data
) ||
1894 !add_partial_dbt(&data
, dlen
, doff
) ||
1895 !checkTxnObj(txnobj
, &txn
) )
1901 if (-1 == _DB_put(self
, txn
, &key
, &data
, flags
)) {
1906 if (flags
& DB_APPEND
)
1907 retval
= PyInt_FromLong(*((db_recno_t
*)key
.data
));
1919 DB_remove(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1922 char* database
= NULL
;
1924 static const char* kwnames
[] = { "filename", "dbname", "flags", NULL
};
1926 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zi:remove", kwnames
,
1927 &filename
, &database
, &flags
))
1929 CHECK_DB_NOT_CLOSED(self
);
1931 err
= self
->db
->remove(self
->db
, filename
, database
, flags
);
1940 DB_rename(DBObject
* self
, PyObject
* args
)
1947 if (!PyArg_ParseTuple(args
, "sss|i:rename", &filename
, &database
, &newname
,
1950 CHECK_DB_NOT_CLOSED(self
);
1952 MYDB_BEGIN_ALLOW_THREADS
;
1953 err
= self
->db
->rename(self
->db
, filename
, database
, newname
, flags
);
1954 MYDB_END_ALLOW_THREADS
;
1961 DB_set_bt_minkey(DBObject
* self
, PyObject
* args
)
1965 if (!PyArg_ParseTuple(args
,"i:set_bt_minkey", &minkey
))
1967 CHECK_DB_NOT_CLOSED(self
);
1969 MYDB_BEGIN_ALLOW_THREADS
;
1970 err
= self
->db
->set_bt_minkey(self
->db
, minkey
);
1971 MYDB_END_ALLOW_THREADS
;
1978 _default_cmp (const DBT
*leftKey
,
1979 const DBT
*rightKey
)
1982 int lsize
= leftKey
->size
, rsize
= rightKey
->size
;
1984 res
= memcmp (leftKey
->data
, rightKey
->data
,
1985 lsize
< rsize
? lsize
: rsize
);
1988 if (lsize
< rsize
) {
1991 else if (lsize
> rsize
) {
1999 _db_compareCallback (DB
* db
,
2001 const DBT
*rightKey
)
2006 PyObject
*leftObject
;
2007 PyObject
*rightObject
;
2008 DBObject
*self
= (DBObject
*) db
->app_private
;
2010 if (self
== NULL
|| self
->btCompareCallback
== NULL
) {
2011 MYDB_BEGIN_BLOCK_THREADS
;
2012 PyErr_SetString (PyExc_TypeError
,
2014 ? "DB_bt_compare db is NULL."
2015 : "DB_bt_compare callback is NULL."));
2016 /* we're in a callback within the DB code, we can't raise */
2018 res
= _default_cmp (leftKey
, rightKey
);
2019 MYDB_END_BLOCK_THREADS
;
2022 MYDB_BEGIN_BLOCK_THREADS
;
2024 leftObject
= PyString_FromStringAndSize (leftKey
->data
, leftKey
->size
);
2025 rightObject
= PyString_FromStringAndSize (rightKey
->data
, rightKey
->size
);
2027 args
= PyTuple_New (2);
2029 PyTuple_SET_ITEM (args
, 0, leftObject
); /* steals reference */
2030 PyTuple_SET_ITEM (args
, 1, rightObject
); /* steals reference */
2032 result
= PyEval_CallObject (self
->btCompareCallback
, args
);
2034 /* we're in a callback within the DB code, we can't raise */
2036 res
= _default_cmp (leftKey
, rightKey
);
2038 else if (PyInt_Check (result
)) {
2039 res
= PyInt_AsLong (result
);
2042 PyErr_SetString (PyExc_TypeError
,
2043 "DB_bt_compare callback MUST return an int.");
2044 /* we're in a callback within the DB code, we can't raise */
2046 res
= _default_cmp (leftKey
, rightKey
);
2050 Py_XDECREF (result
);
2052 MYDB_END_BLOCK_THREADS
;
2058 DB_set_bt_compare (DBObject
* self
, PyObject
* args
)
2061 PyObject
*comparator
;
2062 PyObject
*tuple
, *emptyStr
, *result
;
2064 if (!PyArg_ParseTuple(args
,"O:set_bt_compare", &comparator
))
2067 CHECK_DB_NOT_CLOSED (self
);
2069 if (! PyCallable_Check (comparator
)) {
2070 makeTypeError ("Callable", comparator
);
2075 * Perform a test call of the comparator function with two empty
2076 * string objects here. verify that it returns an int (0).
2079 tuple
= PyTuple_New (2);
2081 emptyStr
= PyString_FromStringAndSize (NULL
, 0);
2082 Py_INCREF(emptyStr
);
2083 PyTuple_SET_ITEM (tuple
, 0, emptyStr
);
2084 PyTuple_SET_ITEM (tuple
, 1, emptyStr
); /* steals reference */
2085 result
= PyEval_CallObject (comparator
, tuple
);
2087 if (result
== 0 || !PyInt_Check(result
)) {
2088 PyErr_SetString (PyExc_TypeError
,
2089 "callback MUST return an int");
2092 else if (PyInt_AsLong(result
) != 0) {
2093 PyErr_SetString (PyExc_TypeError
,
2094 "callback failed to return 0 on two empty strings");
2098 /* We don't accept multiple set_bt_compare operations, in order to
2099 * simplify the code. This would have no real use, as one cannot
2100 * change the function once the db is opened anyway */
2101 if (self
->btCompareCallback
!= NULL
) {
2102 PyErr_SetString (PyExc_RuntimeError
, "set_bt_compare () cannot be called more than once");
2106 Py_INCREF (comparator
);
2107 self
->btCompareCallback
= comparator
;
2109 /* This is to workaround a problem with un-initialized threads (see
2110 comment in DB_associate) */
2112 PyEval_InitThreads();
2115 err
= self
->db
->set_bt_compare (self
->db
,
2116 (comparator
!= NULL
?
2117 _db_compareCallback
: NULL
));
2120 /* restore the old state in case of error */
2121 Py_DECREF (comparator
);
2122 self
->btCompareCallback
= NULL
;
2128 #endif /* DBVER >= 33 */
2132 DB_set_cachesize(DBObject
* self
, PyObject
* args
)
2135 int gbytes
= 0, bytes
= 0, ncache
= 0;
2137 if (!PyArg_ParseTuple(args
,"ii|i:set_cachesize",
2138 &gbytes
,&bytes
,&ncache
))
2140 CHECK_DB_NOT_CLOSED(self
);
2142 MYDB_BEGIN_ALLOW_THREADS
;
2143 err
= self
->db
->set_cachesize(self
->db
, gbytes
, bytes
, ncache
);
2144 MYDB_END_ALLOW_THREADS
;
2151 DB_set_flags(DBObject
* self
, PyObject
* args
)
2155 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
2157 CHECK_DB_NOT_CLOSED(self
);
2159 MYDB_BEGIN_ALLOW_THREADS
;
2160 err
= self
->db
->set_flags(self
->db
, flags
);
2161 MYDB_END_ALLOW_THREADS
;
2164 self
->setflags
|= flags
;
2170 DB_set_h_ffactor(DBObject
* self
, PyObject
* args
)
2174 if (!PyArg_ParseTuple(args
,"i:set_h_ffactor", &ffactor
))
2176 CHECK_DB_NOT_CLOSED(self
);
2178 MYDB_BEGIN_ALLOW_THREADS
;
2179 err
= self
->db
->set_h_ffactor(self
->db
, ffactor
);
2180 MYDB_END_ALLOW_THREADS
;
2187 DB_set_h_nelem(DBObject
* self
, PyObject
* args
)
2191 if (!PyArg_ParseTuple(args
,"i:set_h_nelem", &nelem
))
2193 CHECK_DB_NOT_CLOSED(self
);
2195 MYDB_BEGIN_ALLOW_THREADS
;
2196 err
= self
->db
->set_h_nelem(self
->db
, nelem
);
2197 MYDB_END_ALLOW_THREADS
;
2204 DB_set_lorder(DBObject
* self
, PyObject
* args
)
2208 if (!PyArg_ParseTuple(args
,"i:set_lorder", &lorder
))
2210 CHECK_DB_NOT_CLOSED(self
);
2212 MYDB_BEGIN_ALLOW_THREADS
;
2213 err
= self
->db
->set_lorder(self
->db
, lorder
);
2214 MYDB_END_ALLOW_THREADS
;
2221 DB_set_pagesize(DBObject
* self
, PyObject
* args
)
2225 if (!PyArg_ParseTuple(args
,"i:set_pagesize", &pagesize
))
2227 CHECK_DB_NOT_CLOSED(self
);
2229 MYDB_BEGIN_ALLOW_THREADS
;
2230 err
= self
->db
->set_pagesize(self
->db
, pagesize
);
2231 MYDB_END_ALLOW_THREADS
;
2238 DB_set_re_delim(DBObject
* self
, PyObject
* args
)
2243 if (!PyArg_ParseTuple(args
,"b:set_re_delim", &delim
)) {
2245 if (!PyArg_ParseTuple(args
,"c:set_re_delim", &delim
))
2249 CHECK_DB_NOT_CLOSED(self
);
2251 MYDB_BEGIN_ALLOW_THREADS
;
2252 err
= self
->db
->set_re_delim(self
->db
, delim
);
2253 MYDB_END_ALLOW_THREADS
;
2259 DB_set_re_len(DBObject
* self
, PyObject
* args
)
2263 if (!PyArg_ParseTuple(args
,"i:set_re_len", &len
))
2265 CHECK_DB_NOT_CLOSED(self
);
2267 MYDB_BEGIN_ALLOW_THREADS
;
2268 err
= self
->db
->set_re_len(self
->db
, len
);
2269 MYDB_END_ALLOW_THREADS
;
2276 DB_set_re_pad(DBObject
* self
, PyObject
* args
)
2281 if (!PyArg_ParseTuple(args
,"b:set_re_pad", &pad
)) {
2283 if (!PyArg_ParseTuple(args
,"c:set_re_pad", &pad
))
2286 CHECK_DB_NOT_CLOSED(self
);
2288 MYDB_BEGIN_ALLOW_THREADS
;
2289 err
= self
->db
->set_re_pad(self
->db
, pad
);
2290 MYDB_END_ALLOW_THREADS
;
2297 DB_set_re_source(DBObject
* self
, PyObject
* args
)
2302 if (!PyArg_ParseTuple(args
,"s:set_re_source", &re_source
))
2304 CHECK_DB_NOT_CLOSED(self
);
2306 MYDB_BEGIN_ALLOW_THREADS
;
2307 err
= self
->db
->set_re_source(self
->db
, re_source
);
2308 MYDB_END_ALLOW_THREADS
;
2316 DB_set_q_extentsize(DBObject
* self
, PyObject
* args
)
2321 if (!PyArg_ParseTuple(args
,"i:set_q_extentsize", &extentsize
))
2323 CHECK_DB_NOT_CLOSED(self
);
2325 MYDB_BEGIN_ALLOW_THREADS
;
2326 err
= self
->db
->set_q_extentsize(self
->db
, extentsize
);
2327 MYDB_END_ALLOW_THREADS
;
2334 DB_stat(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2336 int err
, flags
= 0, type
;
2340 PyObject
* txnobj
= NULL
;
2342 static const char* kwnames
[] = { "txn", "flags", NULL
};
2344 static const char* kwnames
[] = { "flags", NULL
};
2348 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iO:stat", kwnames
,
2351 if (!checkTxnObj(txnobj
, &txn
))
2354 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat", kwnames
, &flags
))
2357 CHECK_DB_NOT_CLOSED(self
);
2359 MYDB_BEGIN_ALLOW_THREADS
;
2361 err
= self
->db
->stat(self
->db
, txn
, &sp
, flags
);
2363 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2365 err
= self
->db
->stat(self
->db
, &sp
, NULL
, flags
);
2367 MYDB_END_ALLOW_THREADS
;
2372 /* Turn the stat structure into a dictionary */
2373 type
= _DB_get_type(self
);
2374 if ((type
== -1) || ((d
= PyDict_New()) == NULL
)) {
2379 #define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
2380 #define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
2381 #define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
2385 MAKE_HASH_ENTRY(magic
);
2386 MAKE_HASH_ENTRY(version
);
2387 MAKE_HASH_ENTRY(nkeys
);
2388 MAKE_HASH_ENTRY(ndata
);
2389 MAKE_HASH_ENTRY(pagesize
);
2391 MAKE_HASH_ENTRY(nelem
);
2393 MAKE_HASH_ENTRY(ffactor
);
2394 MAKE_HASH_ENTRY(buckets
);
2395 MAKE_HASH_ENTRY(free
);
2396 MAKE_HASH_ENTRY(bfree
);
2397 MAKE_HASH_ENTRY(bigpages
);
2398 MAKE_HASH_ENTRY(big_bfree
);
2399 MAKE_HASH_ENTRY(overflows
);
2400 MAKE_HASH_ENTRY(ovfl_free
);
2401 MAKE_HASH_ENTRY(dup
);
2402 MAKE_HASH_ENTRY(dup_free
);
2407 MAKE_BT_ENTRY(magic
);
2408 MAKE_BT_ENTRY(version
);
2409 MAKE_BT_ENTRY(nkeys
);
2410 MAKE_BT_ENTRY(ndata
);
2411 MAKE_BT_ENTRY(pagesize
);
2412 MAKE_BT_ENTRY(minkey
);
2413 MAKE_BT_ENTRY(re_len
);
2414 MAKE_BT_ENTRY(re_pad
);
2415 MAKE_BT_ENTRY(levels
);
2416 MAKE_BT_ENTRY(int_pg
);
2417 MAKE_BT_ENTRY(leaf_pg
);
2418 MAKE_BT_ENTRY(dup_pg
);
2419 MAKE_BT_ENTRY(over_pg
);
2420 MAKE_BT_ENTRY(free
);
2421 MAKE_BT_ENTRY(int_pgfree
);
2422 MAKE_BT_ENTRY(leaf_pgfree
);
2423 MAKE_BT_ENTRY(dup_pgfree
);
2424 MAKE_BT_ENTRY(over_pgfree
);
2428 MAKE_QUEUE_ENTRY(magic
);
2429 MAKE_QUEUE_ENTRY(version
);
2430 MAKE_QUEUE_ENTRY(nkeys
);
2431 MAKE_QUEUE_ENTRY(ndata
);
2432 MAKE_QUEUE_ENTRY(pagesize
);
2433 MAKE_QUEUE_ENTRY(pages
);
2434 MAKE_QUEUE_ENTRY(re_len
);
2435 MAKE_QUEUE_ENTRY(re_pad
);
2436 MAKE_QUEUE_ENTRY(pgfree
);
2438 MAKE_QUEUE_ENTRY(start
);
2440 MAKE_QUEUE_ENTRY(first_recno
);
2441 MAKE_QUEUE_ENTRY(cur_recno
);
2445 PyErr_SetString(PyExc_TypeError
, "Unknown DB type, unable to stat");
2450 #undef MAKE_HASH_ENTRY
2451 #undef MAKE_BT_ENTRY
2452 #undef MAKE_QUEUE_ENTRY
2459 DB_sync(DBObject
* self
, PyObject
* args
)
2464 if (!PyArg_ParseTuple(args
,"|i:sync", &flags
))
2466 CHECK_DB_NOT_CLOSED(self
);
2468 MYDB_BEGIN_ALLOW_THREADS
;
2469 err
= self
->db
->sync(self
->db
, flags
);
2470 MYDB_END_ALLOW_THREADS
;
2478 DB_truncate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2482 PyObject
* txnobj
= NULL
;
2484 static const char* kwnames
[] = { "txn", "flags", NULL
};
2486 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
2489 CHECK_DB_NOT_CLOSED(self
);
2490 if (!checkTxnObj(txnobj
, &txn
))
2493 MYDB_BEGIN_ALLOW_THREADS
;
2494 err
= self
->db
->truncate(self
->db
, txn
, &count
, flags
);
2495 MYDB_END_ALLOW_THREADS
;
2497 return PyInt_FromLong(count
);
2503 DB_upgrade(DBObject
* self
, PyObject
* args
)
2508 if (!PyArg_ParseTuple(args
,"s|i:upgrade", &filename
, &flags
))
2510 CHECK_DB_NOT_CLOSED(self
);
2512 MYDB_BEGIN_ALLOW_THREADS
;
2513 err
= self
->db
->upgrade(self
->db
, filename
, flags
);
2514 MYDB_END_ALLOW_THREADS
;
2521 DB_verify(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2526 char* outFileName
=NULL
;
2528 static const char* kwnames
[] = { "filename", "dbname", "outfile", "flags",
2531 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zzi:verify", kwnames
,
2532 &fileName
, &dbName
, &outFileName
, &flags
))
2535 CHECK_DB_NOT_CLOSED(self
);
2537 outFile
= fopen(outFileName
, "w");
2539 MYDB_BEGIN_ALLOW_THREADS
;
2540 err
= self
->db
->verify(self
->db
, fileName
, dbName
, outFile
, flags
);
2541 MYDB_END_ALLOW_THREADS
;
2545 /* DB.verify acts as a DB handle destructor (like close); this was
2546 * documented in BerkeleyDB 4.2 but had the undocumented effect
2547 * of not being safe in prior versions while still requiring an explicit
2548 * DB.close call afterwards. Lets call close for the user to emulate
2549 * the safe 4.2 behaviour. */
2551 self
->db
->close(self
->db
, 0);
2561 DB_set_get_returns_none(DBObject
* self
, PyObject
* args
)
2566 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
2568 CHECK_DB_NOT_CLOSED(self
);
2570 if (self
->moduleFlags
.getReturnsNone
)
2572 if (self
->moduleFlags
.cursorSetReturnsNone
)
2574 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
2575 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
2576 return PyInt_FromLong(oldValue
);
2581 DB_set_encrypt(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2585 char *passwd
= NULL
;
2586 static const char* kwnames
[] = { "passwd", "flags", NULL
};
2588 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
2593 MYDB_BEGIN_ALLOW_THREADS
;
2594 err
= self
->db
->set_encrypt(self
->db
, passwd
, flags
);
2595 MYDB_END_ALLOW_THREADS
;
2600 #endif /* DBVER >= 41 */
2603 /*-------------------------------------------------------------- */
2604 /* Mapping and Dictionary-like access routines */
2606 int DB_length(DBObject
* self
)
2613 if (self
->db
== NULL
) {
2614 PyErr_SetObject(DBError
,
2615 Py_BuildValue("(is)", 0, "DB object has been closed"));
2619 if (self
->haveStat
) { /* Has the stat function been called recently? If
2620 so, we can use the cached value. */
2621 flags
= DB_CACHED_COUNTS
;
2624 MYDB_BEGIN_ALLOW_THREADS
;
2626 err
= self
->db
->stat(self
->db
, /*txnid*/ NULL
, &sp
, flags
);
2628 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2630 err
= self
->db
->stat(self
->db
, &sp
, NULL
, flags
);
2632 MYDB_END_ALLOW_THREADS
;
2639 /* All the stat structures have matching fields upto the ndata field,
2640 so we can use any of them for the type cast */
2641 size
= ((DB_BTREE_STAT
*)sp
)->bt_ndata
;
2647 PyObject
* DB_subscript(DBObject
* self
, PyObject
* keyobj
)
2654 CHECK_DB_NOT_CLOSED(self
);
2655 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2659 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2660 /* Tell BerkeleyDB to malloc the return value (thread safe) */
2661 data
.flags
= DB_DBT_MALLOC
;
2663 MYDB_BEGIN_ALLOW_THREADS
;
2664 err
= self
->db
->get(self
->db
, NULL
, &key
, &data
, 0);
2665 MYDB_END_ALLOW_THREADS
;
2666 if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
2667 PyErr_SetObject(PyExc_KeyError
, keyobj
);
2670 else if (makeDBError(err
)) {
2674 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
2684 DB_ass_sub(DBObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
)
2690 if (self
->db
== NULL
) {
2691 PyErr_SetObject(DBError
,
2692 Py_BuildValue("(is)", 0, "DB object has been closed"));
2696 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2699 if (dataobj
!= NULL
) {
2700 if (!make_dbt(dataobj
, &data
))
2703 if (self
->setflags
& (DB_DUP
|DB_DUPSORT
))
2704 /* dictionaries shouldn't have duplicate keys */
2705 flags
= DB_NOOVERWRITE
;
2706 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2708 if ((retval
== -1) && (self
->setflags
& (DB_DUP
|DB_DUPSORT
))) {
2709 /* try deleting any old record that matches and then PUT it
2711 _DB_delete(self
, NULL
, &key
, 0);
2713 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2718 /* dataobj == NULL, so delete the key */
2719 retval
= _DB_delete(self
, NULL
, &key
, 0);
2727 DB_has_key(DBObject
* self
, PyObject
* args
)
2732 PyObject
* txnobj
= NULL
;
2735 if (!PyArg_ParseTuple(args
,"O|O:has_key", &keyobj
, &txnobj
))
2737 CHECK_DB_NOT_CLOSED(self
);
2738 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2740 if (!checkTxnObj(txnobj
, &txn
)) {
2745 /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
2746 it has a record but can't allocate a buffer for the data. This saves
2747 having to deal with data we won't be using.
2750 data
.flags
= DB_DBT_USERMEM
;
2752 MYDB_BEGIN_ALLOW_THREADS
;
2753 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, 0);
2754 MYDB_END_ALLOW_THREADS
;
2757 if (err
== DB_BUFFER_SMALL
|| err
== 0) {
2758 return PyInt_FromLong(1);
2759 } else if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
2760 return PyInt_FromLong(0);
2768 #define _KEYS_LIST 1
2769 #define _VALUES_LIST 2
2770 #define _ITEMS_LIST 3
2773 _DB_make_list(DBObject
* self
, DB_TXN
* txn
, int type
)
2780 PyObject
* item
= NULL
;
2782 CHECK_DB_NOT_CLOSED(self
);
2786 dbtype
= _DB_get_type(self
);
2790 list
= PyList_New(0);
2792 PyErr_SetString(PyExc_MemoryError
, "PyList_New failed");
2797 MYDB_BEGIN_ALLOW_THREADS
;
2798 err
= self
->db
->cursor(self
->db
, txn
, &cursor
, 0);
2799 MYDB_END_ALLOW_THREADS
;
2802 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2803 key
.flags
= DB_DBT_REALLOC
;
2804 data
.flags
= DB_DBT_REALLOC
;
2807 while (1) { /* use the cursor to traverse the DB, collecting items */
2808 MYDB_BEGIN_ALLOW_THREADS
;
2809 err
= cursor
->c_get(cursor
, &key
, &data
, DB_NEXT
);
2810 MYDB_END_ALLOW_THREADS
;
2813 /* for any error, break out of the loop */
2823 item
= PyString_FromStringAndSize((char*)key
.data
, key
.size
);
2827 item
= PyInt_FromLong(*((db_recno_t
*)key
.data
));
2833 item
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
2841 item
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
2846 item
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
2847 data
.data
, data
.size
);
2854 PyErr_SetString(PyExc_MemoryError
, "List item creation failed");
2858 PyList_Append(list
, item
);
2862 /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
2863 if (err
!= DB_NOTFOUND
&& err
!= DB_KEYEMPTY
&& makeDBError(err
)) {
2871 MYDB_BEGIN_ALLOW_THREADS
;
2872 cursor
->c_close(cursor
);
2873 MYDB_END_ALLOW_THREADS
;
2879 DB_keys(DBObject
* self
, PyObject
* args
)
2881 PyObject
* txnobj
= NULL
;
2884 if (!PyArg_ParseTuple(args
,"|O:keys", &txnobj
))
2886 if (!checkTxnObj(txnobj
, &txn
))
2888 return _DB_make_list(self
, txn
, _KEYS_LIST
);
2893 DB_items(DBObject
* self
, PyObject
* args
)
2895 PyObject
* txnobj
= NULL
;
2898 if (!PyArg_ParseTuple(args
,"|O:items", &txnobj
))
2900 if (!checkTxnObj(txnobj
, &txn
))
2902 return _DB_make_list(self
, txn
, _ITEMS_LIST
);
2907 DB_values(DBObject
* self
, PyObject
* args
)
2909 PyObject
* txnobj
= NULL
;
2912 if (!PyArg_ParseTuple(args
,"|O:values", &txnobj
))
2914 if (!checkTxnObj(txnobj
, &txn
))
2916 return _DB_make_list(self
, txn
, _VALUES_LIST
);
2919 /* --------------------------------------------------------------------- */
2920 /* DBCursor methods */
2924 DBC_close(DBCursorObject
* self
, PyObject
* args
)
2928 if (!PyArg_ParseTuple(args
, ":close"))
2931 if (self
->dbc
!= NULL
) {
2932 MYDB_BEGIN_ALLOW_THREADS
;
2933 err
= self
->dbc
->c_close(self
->dbc
);
2935 MYDB_END_ALLOW_THREADS
;
2943 DBC_count(DBCursorObject
* self
, PyObject
* args
)
2949 if (!PyArg_ParseTuple(args
, "|i:count", &flags
))
2952 CHECK_CURSOR_NOT_CLOSED(self
);
2954 MYDB_BEGIN_ALLOW_THREADS
;
2955 err
= self
->dbc
->c_count(self
->dbc
, &count
, flags
);
2956 MYDB_END_ALLOW_THREADS
;
2959 return PyInt_FromLong(count
);
2964 DBC_current(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2966 return _DBCursor_get(self
,DB_CURRENT
,args
,kwargs
,"|iii:current");
2971 DBC_delete(DBCursorObject
* self
, PyObject
* args
)
2975 if (!PyArg_ParseTuple(args
, "|i:delete", &flags
))
2978 CHECK_CURSOR_NOT_CLOSED(self
);
2980 MYDB_BEGIN_ALLOW_THREADS
;
2981 err
= self
->dbc
->c_del(self
->dbc
, flags
);
2982 MYDB_END_ALLOW_THREADS
;
2985 self
->mydb
->haveStat
= 0;
2991 DBC_dup(DBCursorObject
* self
, PyObject
* args
)
2996 if (!PyArg_ParseTuple(args
, "|i:dup", &flags
))
2999 CHECK_CURSOR_NOT_CLOSED(self
);
3001 MYDB_BEGIN_ALLOW_THREADS
;
3002 err
= self
->dbc
->c_dup(self
->dbc
, &dbc
, flags
);
3003 MYDB_END_ALLOW_THREADS
;
3006 return (PyObject
*) newDBCursorObject(dbc
, self
->mydb
);
3010 DBC_first(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3012 return _DBCursor_get(self
,DB_FIRST
,args
,kwargs
,"|iii:first");
3017 DBC_get(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3020 PyObject
* keyobj
= NULL
;
3021 PyObject
* dataobj
= NULL
;
3022 PyObject
* retval
= NULL
;
3026 static const char* kwnames
[] = { "key","data", "flags", "dlen", "doff",
3031 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:get", &kwnames
[2],
3032 &flags
, &dlen
, &doff
))
3035 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:get",
3037 &keyobj
, &flags
, &dlen
, &doff
))
3040 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:get",
3041 kwnames
, &keyobj
, &dataobj
,
3042 &flags
, &dlen
, &doff
))
3049 CHECK_CURSOR_NOT_CLOSED(self
);
3051 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3053 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
3054 (!add_partial_dbt(&data
, dlen
, doff
)) )
3060 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3061 data
.flags
= DB_DBT_MALLOC
;
3062 if (!(key
.flags
& DB_DBT_REALLOC
)) {
3063 key
.flags
|= DB_DBT_MALLOC
;
3067 MYDB_BEGIN_ALLOW_THREADS
;
3068 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
3069 MYDB_END_ALLOW_THREADS
;
3071 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3072 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3076 else if (makeDBError(err
)) {
3080 switch (_DB_get_type(self
->mydb
)) {
3087 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3088 data
.data
, data
.size
);
3092 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3093 data
.data
, data
.size
);
3104 DBC_pget(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3107 PyObject
* keyobj
= NULL
;
3108 PyObject
* dataobj
= NULL
;
3109 PyObject
* retval
= NULL
;
3112 DBT key
, pkey
, data
;
3113 static const char* kwnames
[] = { "key","data", "flags", "dlen", "doff",
3118 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:pget", &kwnames
[2],
3119 &flags
, &dlen
, &doff
))
3122 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:pget",
3124 &keyobj
, &flags
, &dlen
, &doff
))
3127 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:pget",
3128 kwnames
, &keyobj
, &dataobj
,
3129 &flags
, &dlen
, &doff
))
3136 CHECK_CURSOR_NOT_CLOSED(self
);
3138 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3140 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
3141 (!add_partial_dbt(&data
, dlen
, doff
)) ) {
3146 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3147 data
.flags
= DB_DBT_MALLOC
;
3148 if (!(key
.flags
& DB_DBT_REALLOC
)) {
3149 key
.flags
|= DB_DBT_MALLOC
;
3154 pkey
.flags
= DB_DBT_MALLOC
;
3156 MYDB_BEGIN_ALLOW_THREADS
;
3157 err
= self
->dbc
->c_pget(self
->dbc
, &key
, &pkey
, &data
, flags
);
3158 MYDB_END_ALLOW_THREADS
;
3160 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3161 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3165 else if (makeDBError(err
)) {
3171 dataObj
= PyString_FromStringAndSize(data
.data
, data
.size
);
3173 if (self
->mydb
->primaryDBType
== DB_RECNO
||
3174 self
->mydb
->primaryDBType
== DB_QUEUE
)
3175 pkeyObj
= PyInt_FromLong(*(int *)pkey
.data
);
3177 pkeyObj
= PyString_FromStringAndSize(pkey
.data
, pkey
.size
);
3179 if (flags
& DB_SET_RECNO
) /* return key, pkey and data */
3182 int type
= _DB_get_type(self
->mydb
);
3183 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
3184 keyObj
= PyInt_FromLong(*(int *)key
.data
);
3186 keyObj
= PyString_FromStringAndSize(key
.data
, key
.size
);
3187 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
3190 else /* return just the pkey and data */
3192 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
3197 /* the only time REALLOC should be set is if we used an integer
3198 * key that make_key_dbt malloc'd for us. always free these. */
3199 if (key
.flags
& DB_DBT_REALLOC
) {
3208 DBC_get_recno(DBCursorObject
* self
, PyObject
* args
)
3215 if (!PyArg_ParseTuple(args
, ":get_recno"))
3218 CHECK_CURSOR_NOT_CLOSED(self
);
3222 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3223 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3224 data
.flags
= DB_DBT_MALLOC
;
3225 key
.flags
= DB_DBT_MALLOC
;
3228 MYDB_BEGIN_ALLOW_THREADS
;
3229 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, DB_GET_RECNO
);
3230 MYDB_END_ALLOW_THREADS
;
3233 recno
= *((db_recno_t
*)data
.data
);
3236 return PyInt_FromLong(recno
);
3241 DBC_last(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3243 return _DBCursor_get(self
,DB_LAST
,args
,kwargs
,"|iii:last");
3248 DBC_next(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3250 return _DBCursor_get(self
,DB_NEXT
,args
,kwargs
,"|iii:next");
3255 DBC_prev(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3257 return _DBCursor_get(self
,DB_PREV
,args
,kwargs
,"|iii:prev");
3262 DBC_put(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3265 PyObject
* keyobj
, *dataobj
;
3267 static const char* kwnames
[] = { "key", "data", "flags", "dlen", "doff",
3272 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iii:put", kwnames
,
3273 &keyobj
, &dataobj
, &flags
, &dlen
, &doff
))
3276 CHECK_CURSOR_NOT_CLOSED(self
);
3278 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3280 if (!make_dbt(dataobj
, &data
) ||
3281 !add_partial_dbt(&data
, dlen
, doff
) )
3287 MYDB_BEGIN_ALLOW_THREADS
;
3288 err
= self
->dbc
->c_put(self
->dbc
, &key
, &data
, flags
);
3289 MYDB_END_ALLOW_THREADS
;
3292 self
->mydb
->haveStat
= 0;
3298 DBC_set(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3302 PyObject
* retval
, *keyobj
;
3303 static const char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
3307 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set", kwnames
,
3308 &keyobj
, &flags
, &dlen
, &doff
))
3311 CHECK_CURSOR_NOT_CLOSED(self
);
3313 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3317 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3318 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3319 data
.flags
= DB_DBT_MALLOC
;
3321 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3326 MYDB_BEGIN_ALLOW_THREADS
;
3327 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET
);
3328 MYDB_END_ALLOW_THREADS
;
3329 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3330 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3334 else if (makeDBError(err
)) {
3338 switch (_DB_get_type(self
->mydb
)) {
3345 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3346 data
.data
, data
.size
);
3350 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3351 data
.data
, data
.size
);
3357 /* the only time REALLOC should be set is if we used an integer
3358 * key that make_key_dbt malloc'd for us. always free these. */
3359 if (key
.flags
& DB_DBT_REALLOC
) {
3368 DBC_set_range(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3372 PyObject
* retval
, *keyobj
;
3373 static const char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
3377 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set_range", kwnames
,
3378 &keyobj
, &flags
, &dlen
, &doff
))
3381 CHECK_CURSOR_NOT_CLOSED(self
);
3383 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3387 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3391 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3392 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3393 data
.flags
|= DB_DBT_MALLOC
;
3394 /* only BTREE databases will return anything in the key */
3395 if (!(key
.flags
& DB_DBT_REALLOC
) && _DB_get_type(self
->mydb
) == DB_BTREE
) {
3396 key
.flags
|= DB_DBT_MALLOC
;
3399 MYDB_BEGIN_ALLOW_THREADS
;
3400 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RANGE
);
3401 MYDB_END_ALLOW_THREADS
;
3402 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3403 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3407 else if (makeDBError(err
)) {
3411 switch (_DB_get_type(self
->mydb
)) {
3418 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3419 data
.data
, data
.size
);
3423 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3424 data
.data
, data
.size
);
3430 /* the only time REALLOC should be set is if we used an integer
3431 * key that make_key_dbt malloc'd for us. always free these. */
3432 if (key
.flags
& DB_DBT_REALLOC
) {
3440 _DBC_get_set_both(DBCursorObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
,
3441 int flags
, unsigned int returnsNone
)
3447 /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
3448 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3450 if (!make_dbt(dataobj
, &data
)) {
3455 MYDB_BEGIN_ALLOW_THREADS
;
3456 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_GET_BOTH
);
3457 MYDB_END_ALLOW_THREADS
;
3458 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && returnsNone
) {
3462 else if (makeDBError(err
)) {
3466 switch (_DB_get_type(self
->mydb
)) {
3473 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3474 data
.data
, data
.size
);
3478 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3479 data
.data
, data
.size
);
3489 DBC_get_both(DBCursorObject
* self
, PyObject
* args
)
3492 PyObject
*keyobj
, *dataobj
;
3494 if (!PyArg_ParseTuple(args
, "OO|i:get_both", &keyobj
, &dataobj
, &flags
))
3497 /* if the cursor is closed, self->mydb may be invalid */
3498 CHECK_CURSOR_NOT_CLOSED(self
);
3500 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3501 self
->mydb
->moduleFlags
.getReturnsNone
);
3504 /* Return size of entry */
3506 DBC_get_current_size(DBCursorObject
* self
, PyObject
* args
)
3508 int err
, flags
=DB_CURRENT
;
3509 PyObject
* retval
= NULL
;
3512 if (!PyArg_ParseTuple(args
, ":get_current_size"))
3514 CHECK_CURSOR_NOT_CLOSED(self
);
3518 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
3519 getting the record size. */
3520 data
.flags
= DB_DBT_USERMEM
;
3522 MYDB_BEGIN_ALLOW_THREADS
;
3523 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
3524 MYDB_END_ALLOW_THREADS
;
3525 if (err
== DB_BUFFER_SMALL
|| !err
) {
3526 /* DB_BUFFER_SMALL means positive size, !err means zero length value */
3527 retval
= PyInt_FromLong((long)data
.size
);
3538 DBC_set_both(DBCursorObject
* self
, PyObject
* args
)
3541 PyObject
*keyobj
, *dataobj
;
3543 if (!PyArg_ParseTuple(args
, "OO|i:set_both", &keyobj
, &dataobj
, &flags
))
3546 /* if the cursor is closed, self->mydb may be invalid */
3547 CHECK_CURSOR_NOT_CLOSED(self
);
3549 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3550 self
->mydb
->moduleFlags
.cursorSetReturnsNone
);
3555 DBC_set_recno(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3557 int err
, irecno
, flags
=0;
3563 static const char* kwnames
[] = { "recno","flags", "dlen", "doff", NULL
};
3565 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|iii:set_recno", kwnames
,
3566 &irecno
, &flags
, &dlen
, &doff
))
3569 CHECK_CURSOR_NOT_CLOSED(self
);
3572 recno
= (db_recno_t
) irecno
;
3573 /* use allocated space so DB will be able to realloc room for the real
3575 key
.data
= malloc(sizeof(db_recno_t
));
3576 if (key
.data
== NULL
) {
3577 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
3580 key
.size
= sizeof(db_recno_t
);
3581 key
.ulen
= key
.size
;
3582 memcpy(key
.data
, &recno
, sizeof(db_recno_t
));
3583 key
.flags
= DB_DBT_REALLOC
;
3586 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3587 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3588 data
.flags
= DB_DBT_MALLOC
;
3590 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3595 MYDB_BEGIN_ALLOW_THREADS
;
3596 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RECNO
);
3597 MYDB_END_ALLOW_THREADS
;
3598 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3599 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3603 else if (makeDBError(err
)) {
3606 else { /* Can only be used for BTrees, so no need to return int key */
3607 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3608 data
.data
, data
.size
);
3618 DBC_consume(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3620 return _DBCursor_get(self
,DB_CONSUME
,args
,kwargs
,"|iii:consume");
3625 DBC_next_dup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3627 return _DBCursor_get(self
,DB_NEXT_DUP
,args
,kwargs
,"|iii:next_dup");
3632 DBC_next_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3634 return _DBCursor_get(self
,DB_NEXT_NODUP
,args
,kwargs
,"|iii:next_nodup");
3639 DBC_prev_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3641 return _DBCursor_get(self
,DB_PREV_NODUP
,args
,kwargs
,"|iii:prev_nodup");
3646 DBC_join_item(DBCursorObject
* self
, PyObject
* args
)
3652 if (!PyArg_ParseTuple(args
, "|i:join_item", &flags
))
3655 CHECK_CURSOR_NOT_CLOSED(self
);
3659 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3660 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3661 key
.flags
= DB_DBT_MALLOC
;
3664 MYDB_BEGIN_ALLOW_THREADS
;
3665 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
| DB_JOIN_ITEM
);
3666 MYDB_END_ALLOW_THREADS
;
3667 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3668 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3672 else if (makeDBError(err
)) {
3676 retval
= Py_BuildValue("s#", key
.data
, key
.size
);
3685 /* --------------------------------------------------------------------- */
3690 DBEnv_close(DBEnvObject
* self
, PyObject
* args
)
3694 if (!PyArg_ParseTuple(args
, "|i:close", &flags
))
3696 if (!self
->closed
) { /* Don't close more than once */
3697 MYDB_BEGIN_ALLOW_THREADS
;
3698 err
= self
->db_env
->close(self
->db_env
, flags
);
3699 MYDB_END_ALLOW_THREADS
;
3700 /* after calling DBEnv->close, regardless of error, this DBEnv
3701 * may not be accessed again (BerkeleyDB docs). */
3703 self
->db_env
= NULL
;
3711 DBEnv_open(DBEnvObject
* self
, PyObject
* args
)
3713 int err
, flags
=0, mode
=0660;
3716 if (!PyArg_ParseTuple(args
, "z|ii:open", &db_home
, &flags
, &mode
))
3719 CHECK_ENV_NOT_CLOSED(self
);
3721 MYDB_BEGIN_ALLOW_THREADS
;
3722 err
= self
->db_env
->open(self
->db_env
, db_home
, flags
, mode
);
3723 MYDB_END_ALLOW_THREADS
;
3726 self
->flags
= flags
;
3732 DBEnv_remove(DBEnvObject
* self
, PyObject
* args
)
3737 if (!PyArg_ParseTuple(args
, "s|i:remove", &db_home
, &flags
))
3739 CHECK_ENV_NOT_CLOSED(self
);
3740 MYDB_BEGIN_ALLOW_THREADS
;
3741 err
= self
->db_env
->remove(self
->db_env
, db_home
, flags
);
3742 MYDB_END_ALLOW_THREADS
;
3749 DBEnv_dbremove(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3754 char *database
= NULL
;
3755 PyObject
*txnobj
= NULL
;
3757 static const char* kwnames
[] = { "file", "database", "txn", "flags",
3760 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ss|Oi:dbremove", kwnames
,
3761 &file
, &database
, &txnobj
, &flags
)) {
3764 if (!checkTxnObj(txnobj
, &txn
)) {
3767 CHECK_ENV_NOT_CLOSED(self
);
3768 MYDB_BEGIN_ALLOW_THREADS
;
3769 err
= self
->db_env
->dbremove(self
->db_env
, txn
, file
, database
, flags
);
3770 MYDB_END_ALLOW_THREADS
;
3776 DBEnv_dbrename(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3781 char *database
= NULL
;
3782 char *newname
= NULL
;
3783 PyObject
*txnobj
= NULL
;
3785 static const char* kwnames
[] = { "file", "database", "newname", "txn",
3788 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "sss|Oi:dbrename", kwnames
,
3789 &file
, &database
, &newname
, &txnobj
, &flags
)) {
3792 if (!checkTxnObj(txnobj
, &txn
)) {
3795 CHECK_ENV_NOT_CLOSED(self
);
3796 MYDB_BEGIN_ALLOW_THREADS
;
3797 err
= self
->db_env
->dbrename(self
->db_env
, txn
, file
, database
, newname
,
3799 MYDB_END_ALLOW_THREADS
;
3805 DBEnv_set_encrypt(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3809 char *passwd
= NULL
;
3810 static const char* kwnames
[] = { "passwd", "flags", NULL
};
3812 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
3817 MYDB_BEGIN_ALLOW_THREADS
;
3818 err
= self
->db_env
->set_encrypt(self
->db_env
, passwd
, flags
);
3819 MYDB_END_ALLOW_THREADS
;
3824 #endif /* DBVER >= 41 */
3828 DBEnv_set_timeout(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3832 u_int32_t timeout
= 0;
3833 static const char* kwnames
[] = { "timeout", "flags", NULL
};
3835 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ii:set_timeout", kwnames
,
3836 &timeout
, &flags
)) {
3840 MYDB_BEGIN_ALLOW_THREADS
;
3841 err
= self
->db_env
->set_timeout(self
->db_env
, (db_timeout_t
)timeout
, flags
);
3842 MYDB_END_ALLOW_THREADS
;
3847 #endif /* DBVER >= 40 */
3850 DBEnv_set_shm_key(DBEnvObject
* self
, PyObject
* args
)
3855 if (!PyArg_ParseTuple(args
, "l:set_shm_key", &shm_key
))
3857 CHECK_ENV_NOT_CLOSED(self
);
3859 err
= self
->db_env
->set_shm_key(self
->db_env
, shm_key
);
3865 DBEnv_set_cachesize(DBEnvObject
* self
, PyObject
* args
)
3867 int err
, gbytes
=0, bytes
=0, ncache
=0;
3869 if (!PyArg_ParseTuple(args
, "ii|i:set_cachesize",
3870 &gbytes
, &bytes
, &ncache
))
3872 CHECK_ENV_NOT_CLOSED(self
);
3874 MYDB_BEGIN_ALLOW_THREADS
;
3875 err
= self
->db_env
->set_cachesize(self
->db_env
, gbytes
, bytes
, ncache
);
3876 MYDB_END_ALLOW_THREADS
;
3884 DBEnv_set_flags(DBEnvObject
* self
, PyObject
* args
)
3886 int err
, flags
=0, onoff
=0;
3888 if (!PyArg_ParseTuple(args
, "ii:set_flags",
3891 CHECK_ENV_NOT_CLOSED(self
);
3893 MYDB_BEGIN_ALLOW_THREADS
;
3894 err
= self
->db_env
->set_flags(self
->db_env
, flags
, onoff
);
3895 MYDB_END_ALLOW_THREADS
;
3903 DBEnv_set_data_dir(DBEnvObject
* self
, PyObject
* args
)
3908 if (!PyArg_ParseTuple(args
, "s:set_data_dir", &dir
))
3910 CHECK_ENV_NOT_CLOSED(self
);
3912 MYDB_BEGIN_ALLOW_THREADS
;
3913 err
= self
->db_env
->set_data_dir(self
->db_env
, dir
);
3914 MYDB_END_ALLOW_THREADS
;
3921 DBEnv_set_lg_bsize(DBEnvObject
* self
, PyObject
* args
)
3925 if (!PyArg_ParseTuple(args
, "i:set_lg_bsize", &lg_bsize
))
3927 CHECK_ENV_NOT_CLOSED(self
);
3929 MYDB_BEGIN_ALLOW_THREADS
;
3930 err
= self
->db_env
->set_lg_bsize(self
->db_env
, lg_bsize
);
3931 MYDB_END_ALLOW_THREADS
;
3938 DBEnv_set_lg_dir(DBEnvObject
* self
, PyObject
* args
)
3943 if (!PyArg_ParseTuple(args
, "s:set_lg_dir", &dir
))
3945 CHECK_ENV_NOT_CLOSED(self
);
3947 MYDB_BEGIN_ALLOW_THREADS
;
3948 err
= self
->db_env
->set_lg_dir(self
->db_env
, dir
);
3949 MYDB_END_ALLOW_THREADS
;
3955 DBEnv_set_lg_max(DBEnvObject
* self
, PyObject
* args
)
3959 if (!PyArg_ParseTuple(args
, "i:set_lg_max", &lg_max
))
3961 CHECK_ENV_NOT_CLOSED(self
);
3963 MYDB_BEGIN_ALLOW_THREADS
;
3964 err
= self
->db_env
->set_lg_max(self
->db_env
, lg_max
);
3965 MYDB_END_ALLOW_THREADS
;
3973 DBEnv_set_lg_regionmax(DBEnvObject
* self
, PyObject
* args
)
3977 if (!PyArg_ParseTuple(args
, "i:set_lg_regionmax", &lg_max
))
3979 CHECK_ENV_NOT_CLOSED(self
);
3981 MYDB_BEGIN_ALLOW_THREADS
;
3982 err
= self
->db_env
->set_lg_regionmax(self
->db_env
, lg_max
);
3983 MYDB_END_ALLOW_THREADS
;
3991 DBEnv_set_lk_detect(DBEnvObject
* self
, PyObject
* args
)
3995 if (!PyArg_ParseTuple(args
, "i:set_lk_detect", &lk_detect
))
3997 CHECK_ENV_NOT_CLOSED(self
);
3999 MYDB_BEGIN_ALLOW_THREADS
;
4000 err
= self
->db_env
->set_lk_detect(self
->db_env
, lk_detect
);
4001 MYDB_END_ALLOW_THREADS
;
4008 DBEnv_set_lk_max(DBEnvObject
* self
, PyObject
* args
)
4012 if (!PyArg_ParseTuple(args
, "i:set_lk_max", &max
))
4014 CHECK_ENV_NOT_CLOSED(self
);
4016 MYDB_BEGIN_ALLOW_THREADS
;
4017 err
= self
->db_env
->set_lk_max(self
->db_env
, max
);
4018 MYDB_END_ALLOW_THREADS
;
4027 DBEnv_set_lk_max_locks(DBEnvObject
* self
, PyObject
* args
)
4031 if (!PyArg_ParseTuple(args
, "i:set_lk_max_locks", &max
))
4033 CHECK_ENV_NOT_CLOSED(self
);
4035 MYDB_BEGIN_ALLOW_THREADS
;
4036 err
= self
->db_env
->set_lk_max_locks(self
->db_env
, max
);
4037 MYDB_END_ALLOW_THREADS
;
4044 DBEnv_set_lk_max_lockers(DBEnvObject
* self
, PyObject
* args
)
4048 if (!PyArg_ParseTuple(args
, "i:set_lk_max_lockers", &max
))
4050 CHECK_ENV_NOT_CLOSED(self
);
4052 MYDB_BEGIN_ALLOW_THREADS
;
4053 err
= self
->db_env
->set_lk_max_lockers(self
->db_env
, max
);
4054 MYDB_END_ALLOW_THREADS
;
4061 DBEnv_set_lk_max_objects(DBEnvObject
* self
, PyObject
* args
)
4065 if (!PyArg_ParseTuple(args
, "i:set_lk_max_objects", &max
))
4067 CHECK_ENV_NOT_CLOSED(self
);
4069 MYDB_BEGIN_ALLOW_THREADS
;
4070 err
= self
->db_env
->set_lk_max_objects(self
->db_env
, max
);
4071 MYDB_END_ALLOW_THREADS
;
4080 DBEnv_set_mp_mmapsize(DBEnvObject
* self
, PyObject
* args
)
4082 int err
, mp_mmapsize
;
4084 if (!PyArg_ParseTuple(args
, "i:set_mp_mmapsize", &mp_mmapsize
))
4086 CHECK_ENV_NOT_CLOSED(self
);
4088 MYDB_BEGIN_ALLOW_THREADS
;
4089 err
= self
->db_env
->set_mp_mmapsize(self
->db_env
, mp_mmapsize
);
4090 MYDB_END_ALLOW_THREADS
;
4097 DBEnv_set_tmp_dir(DBEnvObject
* self
, PyObject
* args
)
4102 if (!PyArg_ParseTuple(args
, "s:set_tmp_dir", &dir
))
4104 CHECK_ENV_NOT_CLOSED(self
);
4106 MYDB_BEGIN_ALLOW_THREADS
;
4107 err
= self
->db_env
->set_tmp_dir(self
->db_env
, dir
);
4108 MYDB_END_ALLOW_THREADS
;
4115 DBEnv_txn_begin(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4118 PyObject
* txnobj
= NULL
;
4120 static const char* kwnames
[] = { "parent", "flags", NULL
};
4122 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:txn_begin", kwnames
,
4126 if (!checkTxnObj(txnobj
, &txn
))
4128 CHECK_ENV_NOT_CLOSED(self
);
4130 return (PyObject
*)newDBTxnObject(self
, txn
, flags
);
4135 DBEnv_txn_checkpoint(DBEnvObject
* self
, PyObject
* args
)
4137 int err
, kbyte
=0, min
=0, flags
=0;
4139 if (!PyArg_ParseTuple(args
, "|iii:txn_checkpoint", &kbyte
, &min
, &flags
))
4141 CHECK_ENV_NOT_CLOSED(self
);
4143 MYDB_BEGIN_ALLOW_THREADS
;
4145 err
= self
->db_env
->txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
4147 err
= txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
4149 MYDB_END_ALLOW_THREADS
;
4156 DBEnv_set_tx_max(DBEnvObject
* self
, PyObject
* args
)
4160 if (!PyArg_ParseTuple(args
, "i:set_tx_max", &max
))
4162 CHECK_ENV_NOT_CLOSED(self
);
4164 MYDB_BEGIN_ALLOW_THREADS
;
4165 err
= self
->db_env
->set_tx_max(self
->db_env
, max
);
4166 MYDB_END_ALLOW_THREADS
;
4173 DBEnv_lock_detect(DBEnvObject
* self
, PyObject
* args
)
4175 int err
, atype
, flags
=0;
4178 if (!PyArg_ParseTuple(args
, "i|i:lock_detect", &atype
, &flags
))
4180 CHECK_ENV_NOT_CLOSED(self
);
4182 MYDB_BEGIN_ALLOW_THREADS
;
4184 err
= self
->db_env
->lock_detect(self
->db_env
, flags
, atype
, &aborted
);
4186 err
= lock_detect(self
->db_env
, flags
, atype
, &aborted
);
4188 MYDB_END_ALLOW_THREADS
;
4190 return PyInt_FromLong(aborted
);
4195 DBEnv_lock_get(DBEnvObject
* self
, PyObject
* args
)
4198 int locker
, lock_mode
;
4202 if (!PyArg_ParseTuple(args
, "iOi|i:lock_get", &locker
, &objobj
, &lock_mode
, &flags
))
4206 if (!make_dbt(objobj
, &obj
))
4209 return (PyObject
*)newDBLockObject(self
, locker
, &obj
, lock_mode
, flags
);
4214 DBEnv_lock_id(DBEnvObject
* self
, PyObject
* args
)
4219 if (!PyArg_ParseTuple(args
, ":lock_id"))
4222 CHECK_ENV_NOT_CLOSED(self
);
4223 MYDB_BEGIN_ALLOW_THREADS
;
4225 err
= self
->db_env
->lock_id(self
->db_env
, &theID
);
4227 err
= lock_id(self
->db_env
, &theID
);
4229 MYDB_END_ALLOW_THREADS
;
4232 return PyInt_FromLong((long)theID
);
4237 DBEnv_lock_put(DBEnvObject
* self
, PyObject
* args
)
4240 DBLockObject
* dblockobj
;
4242 if (!PyArg_ParseTuple(args
, "O!:lock_put", &DBLock_Type
, &dblockobj
))
4245 CHECK_ENV_NOT_CLOSED(self
);
4246 MYDB_BEGIN_ALLOW_THREADS
;
4248 err
= self
->db_env
->lock_put(self
->db_env
, &dblockobj
->lock
);
4250 err
= lock_put(self
->db_env
, &dblockobj
->lock
);
4252 MYDB_END_ALLOW_THREADS
;
4259 DBEnv_lock_stat(DBEnvObject
* self
, PyObject
* args
)
4264 u_int32_t flags
= 0;
4266 if (!PyArg_ParseTuple(args
, "|i:lock_stat", &flags
))
4268 CHECK_ENV_NOT_CLOSED(self
);
4270 MYDB_BEGIN_ALLOW_THREADS
;
4272 err
= self
->db_env
->lock_stat(self
->db_env
, &sp
, flags
);
4275 err
= lock_stat(self
->db_env
, &sp
);
4277 err
= lock_stat(self
->db_env
, &sp
, NULL
);
4280 MYDB_END_ALLOW_THREADS
;
4283 /* Turn the stat structure into a dictionary */
4290 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4297 MAKE_ENTRY(maxlocks
);
4298 MAKE_ENTRY(maxlockers
);
4299 MAKE_ENTRY(maxobjects
);
4301 MAKE_ENTRY(maxnlocks
);
4303 MAKE_ENTRY(nlockers
);
4304 MAKE_ENTRY(maxnlockers
);
4306 MAKE_ENTRY(nobjects
);
4307 MAKE_ENTRY(maxnobjects
);
4309 MAKE_ENTRY(nrequests
);
4310 MAKE_ENTRY(nreleases
);
4311 MAKE_ENTRY(nnowaits
);
4312 MAKE_ENTRY(nconflicts
);
4313 MAKE_ENTRY(ndeadlocks
);
4314 MAKE_ENTRY(regsize
);
4315 MAKE_ENTRY(region_wait
);
4316 MAKE_ENTRY(region_nowait
);
4325 DBEnv_log_archive(DBEnvObject
* self
, PyObject
* args
)
4329 char **log_list_start
, **log_list
;
4331 PyObject
* item
= NULL
;
4333 if (!PyArg_ParseTuple(args
, "|i:log_archive", &flags
))
4336 CHECK_ENV_NOT_CLOSED(self
);
4337 MYDB_BEGIN_ALLOW_THREADS
;
4339 err
= self
->db_env
->log_archive(self
->db_env
, &log_list
, flags
);
4341 err
= log_archive(self
->db_env
, &log_list
, flags
);
4343 err
= log_archive(self
->db_env
, &log_list
, flags
, NULL
);
4345 MYDB_END_ALLOW_THREADS
;
4348 list
= PyList_New(0);
4350 PyErr_SetString(PyExc_MemoryError
, "PyList_New failed");
4355 for (log_list_start
= log_list
; *log_list
!= NULL
; ++log_list
) {
4356 item
= PyString_FromString (*log_list
);
4359 PyErr_SetString(PyExc_MemoryError
,
4360 "List item creation failed");
4364 PyList_Append(list
, item
);
4367 free(log_list_start
);
4374 DBEnv_txn_stat(DBEnvObject
* self
, PyObject
* args
)
4381 if (!PyArg_ParseTuple(args
, "|i:txn_stat", &flags
))
4383 CHECK_ENV_NOT_CLOSED(self
);
4385 MYDB_BEGIN_ALLOW_THREADS
;
4387 err
= self
->db_env
->txn_stat(self
->db_env
, &sp
, flags
);
4389 err
= txn_stat(self
->db_env
, &sp
);
4391 err
= txn_stat(self
->db_env
, &sp
, NULL
);
4393 MYDB_END_ALLOW_THREADS
;
4396 /* Turn the stat structure into a dictionary */
4403 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4405 MAKE_ENTRY(time_ckp
);
4406 MAKE_ENTRY(last_txnid
);
4407 MAKE_ENTRY(maxtxns
);
4408 MAKE_ENTRY(nactive
);
4409 MAKE_ENTRY(maxnactive
);
4410 MAKE_ENTRY(nbegins
);
4411 MAKE_ENTRY(naborts
);
4412 MAKE_ENTRY(ncommits
);
4413 MAKE_ENTRY(regsize
);
4414 MAKE_ENTRY(region_wait
);
4415 MAKE_ENTRY(region_nowait
);
4424 DBEnv_set_get_returns_none(DBEnvObject
* self
, PyObject
* args
)
4429 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
4431 CHECK_ENV_NOT_CLOSED(self
);
4433 if (self
->moduleFlags
.getReturnsNone
)
4435 if (self
->moduleFlags
.cursorSetReturnsNone
)
4437 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
4438 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
4439 return PyInt_FromLong(oldValue
);
4443 /* --------------------------------------------------------------------- */
4448 DBTxn_commit(DBTxnObject
* self
, PyObject
* args
)
4453 if (!PyArg_ParseTuple(args
, "|i:commit", &flags
))
4457 PyErr_SetObject(DBError
, Py_BuildValue("(is)", 0,
4458 "DBTxn must not be used after txn_commit or txn_abort"));
4462 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
4463 MYDB_BEGIN_ALLOW_THREADS
;
4465 err
= txn
->commit(txn
, flags
);
4467 err
= txn_commit(txn
, flags
);
4469 MYDB_END_ALLOW_THREADS
;
4475 DBTxn_prepare(DBTxnObject
* self
, PyObject
* args
)
4482 if (!PyArg_ParseTuple(args
, "s#:prepare", &gid
, &gid_size
))
4485 if (gid_size
!= DB_XIDDATASIZE
) {
4486 PyErr_SetString(PyExc_TypeError
,
4487 "gid must be DB_XIDDATASIZE bytes long");
4492 PyErr_SetObject(DBError
, Py_BuildValue("(is)", 0,
4493 "DBTxn must not be used after txn_commit or txn_abort"));
4496 MYDB_BEGIN_ALLOW_THREADS
;
4498 err
= self
->txn
->prepare(self
->txn
, (u_int8_t
*)gid
);
4500 err
= txn_prepare(self
->txn
, (u_int8_t
*)gid
);
4502 MYDB_END_ALLOW_THREADS
;
4508 if (!PyArg_ParseTuple(args
, ":prepare"))
4512 PyErr_SetObject(DBError
, Py_BuildValue("(is)", 0,
4513 "DBTxn must not be used after txn_commit or txn_abort"));
4516 MYDB_BEGIN_ALLOW_THREADS
;
4517 err
= txn_prepare(self
->txn
);
4518 MYDB_END_ALLOW_THREADS
;
4526 DBTxn_abort(DBTxnObject
* self
, PyObject
* args
)
4531 if (!PyArg_ParseTuple(args
, ":abort"))
4535 PyErr_SetObject(DBError
, Py_BuildValue("(is)", 0,
4536 "DBTxn must not be used after txn_commit or txn_abort"));
4540 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
4541 MYDB_BEGIN_ALLOW_THREADS
;
4543 err
= txn
->abort(txn
);
4545 err
= txn_abort(txn
);
4547 MYDB_END_ALLOW_THREADS
;
4554 DBTxn_id(DBTxnObject
* self
, PyObject
* args
)
4558 if (!PyArg_ParseTuple(args
, ":id"))
4562 PyErr_SetObject(DBError
, Py_BuildValue("(is)", 0,
4563 "DBTxn must not be used after txn_commit or txn_abort"));
4566 MYDB_BEGIN_ALLOW_THREADS
;
4568 id
= self
->txn
->id(self
->txn
);
4570 id
= txn_id(self
->txn
);
4572 MYDB_END_ALLOW_THREADS
;
4573 return PyInt_FromLong(id
);
4576 /* --------------------------------------------------------------------- */
4577 /* Method definition tables and type objects */
4579 static PyMethodDef DB_methods
[] = {
4580 {"append", (PyCFunction
)DB_append
, METH_VARARGS
},
4582 {"associate", (PyCFunction
)DB_associate
, METH_VARARGS
|METH_KEYWORDS
},
4584 {"close", (PyCFunction
)DB_close
, METH_VARARGS
},
4586 {"consume", (PyCFunction
)DB_consume
, METH_VARARGS
|METH_KEYWORDS
},
4587 {"consume_wait", (PyCFunction
)DB_consume_wait
, METH_VARARGS
|METH_KEYWORDS
},
4589 {"cursor", (PyCFunction
)DB_cursor
, METH_VARARGS
|METH_KEYWORDS
},
4590 {"delete", (PyCFunction
)DB_delete
, METH_VARARGS
|METH_KEYWORDS
},
4591 {"fd", (PyCFunction
)DB_fd
, METH_VARARGS
},
4592 {"get", (PyCFunction
)DB_get
, METH_VARARGS
|METH_KEYWORDS
},
4594 {"pget", (PyCFunction
)DB_pget
, METH_VARARGS
|METH_KEYWORDS
},
4596 {"get_both", (PyCFunction
)DB_get_both
, METH_VARARGS
|METH_KEYWORDS
},
4597 {"get_byteswapped", (PyCFunction
)DB_get_byteswapped
,METH_VARARGS
},
4598 {"get_size", (PyCFunction
)DB_get_size
, METH_VARARGS
|METH_KEYWORDS
},
4599 {"get_type", (PyCFunction
)DB_get_type
, METH_VARARGS
},
4600 {"join", (PyCFunction
)DB_join
, METH_VARARGS
},
4601 {"key_range", (PyCFunction
)DB_key_range
, METH_VARARGS
|METH_KEYWORDS
},
4602 {"has_key", (PyCFunction
)DB_has_key
, METH_VARARGS
},
4603 {"items", (PyCFunction
)DB_items
, METH_VARARGS
},
4604 {"keys", (PyCFunction
)DB_keys
, METH_VARARGS
},
4605 {"open", (PyCFunction
)DB_open
, METH_VARARGS
|METH_KEYWORDS
},
4606 {"put", (PyCFunction
)DB_put
, METH_VARARGS
|METH_KEYWORDS
},
4607 {"remove", (PyCFunction
)DB_remove
, METH_VARARGS
|METH_KEYWORDS
},
4608 {"rename", (PyCFunction
)DB_rename
, METH_VARARGS
},
4609 {"set_bt_minkey", (PyCFunction
)DB_set_bt_minkey
, METH_VARARGS
},
4611 {"set_bt_compare", (PyCFunction
)DB_set_bt_compare
, METH_VARARGS
},
4613 {"set_cachesize", (PyCFunction
)DB_set_cachesize
, METH_VARARGS
},
4615 {"set_encrypt", (PyCFunction
)DB_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
4617 {"set_flags", (PyCFunction
)DB_set_flags
, METH_VARARGS
},
4618 {"set_h_ffactor", (PyCFunction
)DB_set_h_ffactor
, METH_VARARGS
},
4619 {"set_h_nelem", (PyCFunction
)DB_set_h_nelem
, METH_VARARGS
},
4620 {"set_lorder", (PyCFunction
)DB_set_lorder
, METH_VARARGS
},
4621 {"set_pagesize", (PyCFunction
)DB_set_pagesize
, METH_VARARGS
},
4622 {"set_re_delim", (PyCFunction
)DB_set_re_delim
, METH_VARARGS
},
4623 {"set_re_len", (PyCFunction
)DB_set_re_len
, METH_VARARGS
},
4624 {"set_re_pad", (PyCFunction
)DB_set_re_pad
, METH_VARARGS
},
4625 {"set_re_source", (PyCFunction
)DB_set_re_source
, METH_VARARGS
},
4627 {"set_q_extentsize",(PyCFunction
)DB_set_q_extentsize
,METH_VARARGS
},
4629 {"stat", (PyCFunction
)DB_stat
, METH_VARARGS
|METH_KEYWORDS
},
4630 {"sync", (PyCFunction
)DB_sync
, METH_VARARGS
},
4632 {"truncate", (PyCFunction
)DB_truncate
, METH_VARARGS
|METH_KEYWORDS
},
4634 {"type", (PyCFunction
)DB_get_type
, METH_VARARGS
},
4635 {"upgrade", (PyCFunction
)DB_upgrade
, METH_VARARGS
},
4636 {"values", (PyCFunction
)DB_values
, METH_VARARGS
},
4637 {"verify", (PyCFunction
)DB_verify
, METH_VARARGS
|METH_KEYWORDS
},
4638 {"set_get_returns_none",(PyCFunction
)DB_set_get_returns_none
, METH_VARARGS
},
4639 {NULL
, NULL
} /* sentinel */
4643 static PyMappingMethods DB_mapping
= {
4644 (inquiry
)DB_length
, /*mp_length*/
4645 (binaryfunc
)DB_subscript
, /*mp_subscript*/
4646 (objobjargproc
)DB_ass_sub
, /*mp_ass_subscript*/
4650 static PyMethodDef DBCursor_methods
[] = {
4651 {"close", (PyCFunction
)DBC_close
, METH_VARARGS
},
4652 {"count", (PyCFunction
)DBC_count
, METH_VARARGS
},
4653 {"current", (PyCFunction
)DBC_current
, METH_VARARGS
|METH_KEYWORDS
},
4654 {"delete", (PyCFunction
)DBC_delete
, METH_VARARGS
},
4655 {"dup", (PyCFunction
)DBC_dup
, METH_VARARGS
},
4656 {"first", (PyCFunction
)DBC_first
, METH_VARARGS
|METH_KEYWORDS
},
4657 {"get", (PyCFunction
)DBC_get
, METH_VARARGS
|METH_KEYWORDS
},
4659 {"pget", (PyCFunction
)DBC_pget
, METH_VARARGS
|METH_KEYWORDS
},
4661 {"get_recno", (PyCFunction
)DBC_get_recno
, METH_VARARGS
},
4662 {"last", (PyCFunction
)DBC_last
, METH_VARARGS
|METH_KEYWORDS
},
4663 {"next", (PyCFunction
)DBC_next
, METH_VARARGS
|METH_KEYWORDS
},
4664 {"prev", (PyCFunction
)DBC_prev
, METH_VARARGS
|METH_KEYWORDS
},
4665 {"put", (PyCFunction
)DBC_put
, METH_VARARGS
|METH_KEYWORDS
},
4666 {"set", (PyCFunction
)DBC_set
, METH_VARARGS
|METH_KEYWORDS
},
4667 {"set_range", (PyCFunction
)DBC_set_range
, METH_VARARGS
|METH_KEYWORDS
},
4668 {"get_both", (PyCFunction
)DBC_get_both
, METH_VARARGS
},
4669 {"get_current_size",(PyCFunction
)DBC_get_current_size
, METH_VARARGS
},
4670 {"set_both", (PyCFunction
)DBC_set_both
, METH_VARARGS
},
4671 {"set_recno", (PyCFunction
)DBC_set_recno
, METH_VARARGS
|METH_KEYWORDS
},
4672 {"consume", (PyCFunction
)DBC_consume
, METH_VARARGS
|METH_KEYWORDS
},
4673 {"next_dup", (PyCFunction
)DBC_next_dup
, METH_VARARGS
|METH_KEYWORDS
},
4674 {"next_nodup", (PyCFunction
)DBC_next_nodup
, METH_VARARGS
|METH_KEYWORDS
},
4675 {"prev_nodup", (PyCFunction
)DBC_prev_nodup
, METH_VARARGS
|METH_KEYWORDS
},
4676 {"join_item", (PyCFunction
)DBC_join_item
, METH_VARARGS
},
4677 {NULL
, NULL
} /* sentinel */
4681 static PyMethodDef DBEnv_methods
[] = {
4682 {"close", (PyCFunction
)DBEnv_close
, METH_VARARGS
},
4683 {"open", (PyCFunction
)DBEnv_open
, METH_VARARGS
},
4684 {"remove", (PyCFunction
)DBEnv_remove
, METH_VARARGS
},
4686 {"dbremove", (PyCFunction
)DBEnv_dbremove
, METH_VARARGS
|METH_KEYWORDS
},
4687 {"dbrename", (PyCFunction
)DBEnv_dbrename
, METH_VARARGS
|METH_KEYWORDS
},
4688 {"set_encrypt", (PyCFunction
)DBEnv_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
4691 {"set_timeout", (PyCFunction
)DBEnv_set_timeout
, METH_VARARGS
|METH_KEYWORDS
},
4693 {"set_shm_key", (PyCFunction
)DBEnv_set_shm_key
, METH_VARARGS
},
4694 {"set_cachesize", (PyCFunction
)DBEnv_set_cachesize
, METH_VARARGS
},
4695 {"set_data_dir", (PyCFunction
)DBEnv_set_data_dir
, METH_VARARGS
},
4697 {"set_flags", (PyCFunction
)DBEnv_set_flags
, METH_VARARGS
},
4699 {"set_lg_bsize", (PyCFunction
)DBEnv_set_lg_bsize
, METH_VARARGS
},
4700 {"set_lg_dir", (PyCFunction
)DBEnv_set_lg_dir
, METH_VARARGS
},
4701 {"set_lg_max", (PyCFunction
)DBEnv_set_lg_max
, METH_VARARGS
},
4703 {"set_lg_regionmax",(PyCFunction
)DBEnv_set_lg_regionmax
, METH_VARARGS
},
4705 {"set_lk_detect", (PyCFunction
)DBEnv_set_lk_detect
, METH_VARARGS
},
4706 {"set_lk_max", (PyCFunction
)DBEnv_set_lk_max
, METH_VARARGS
},
4708 {"set_lk_max_locks", (PyCFunction
)DBEnv_set_lk_max_locks
, METH_VARARGS
},
4709 {"set_lk_max_lockers", (PyCFunction
)DBEnv_set_lk_max_lockers
, METH_VARARGS
},
4710 {"set_lk_max_objects", (PyCFunction
)DBEnv_set_lk_max_objects
, METH_VARARGS
},
4712 {"set_mp_mmapsize", (PyCFunction
)DBEnv_set_mp_mmapsize
, METH_VARARGS
},
4713 {"set_tmp_dir", (PyCFunction
)DBEnv_set_tmp_dir
, METH_VARARGS
},
4714 {"txn_begin", (PyCFunction
)DBEnv_txn_begin
, METH_VARARGS
|METH_KEYWORDS
},
4715 {"txn_checkpoint", (PyCFunction
)DBEnv_txn_checkpoint
, METH_VARARGS
},
4716 {"txn_stat", (PyCFunction
)DBEnv_txn_stat
, METH_VARARGS
},
4717 {"set_tx_max", (PyCFunction
)DBEnv_set_tx_max
, METH_VARARGS
},
4718 {"lock_detect", (PyCFunction
)DBEnv_lock_detect
, METH_VARARGS
},
4719 {"lock_get", (PyCFunction
)DBEnv_lock_get
, METH_VARARGS
},
4720 {"lock_id", (PyCFunction
)DBEnv_lock_id
, METH_VARARGS
},
4721 {"lock_put", (PyCFunction
)DBEnv_lock_put
, METH_VARARGS
},
4722 {"lock_stat", (PyCFunction
)DBEnv_lock_stat
, METH_VARARGS
},
4723 {"log_archive", (PyCFunction
)DBEnv_log_archive
, METH_VARARGS
},
4724 {"set_get_returns_none",(PyCFunction
)DBEnv_set_get_returns_none
, METH_VARARGS
},
4725 {NULL
, NULL
} /* sentinel */
4729 static PyMethodDef DBTxn_methods
[] = {
4730 {"commit", (PyCFunction
)DBTxn_commit
, METH_VARARGS
},
4731 {"prepare", (PyCFunction
)DBTxn_prepare
, METH_VARARGS
},
4732 {"abort", (PyCFunction
)DBTxn_abort
, METH_VARARGS
},
4733 {"id", (PyCFunction
)DBTxn_id
, METH_VARARGS
},
4734 {NULL
, NULL
} /* sentinel */
4739 DB_getattr(DBObject
* self
, char *name
)
4741 return Py_FindMethod(DB_methods
, (PyObject
* )self
, name
);
4746 DBEnv_getattr(DBEnvObject
* self
, char *name
)
4748 if (!strcmp(name
, "db_home")) {
4749 CHECK_ENV_NOT_CLOSED(self
);
4750 if (self
->db_env
->db_home
== NULL
) {
4753 return PyString_FromString(self
->db_env
->db_home
);
4756 return Py_FindMethod(DBEnv_methods
, (PyObject
* )self
, name
);
4761 DBCursor_getattr(DBCursorObject
* self
, char *name
)
4763 return Py_FindMethod(DBCursor_methods
, (PyObject
* )self
, name
);
4767 DBTxn_getattr(DBTxnObject
* self
, char *name
)
4769 return Py_FindMethod(DBTxn_methods
, (PyObject
* )self
, name
);
4773 DBLock_getattr(DBLockObject
* self
, char *name
)
4778 statichere PyTypeObject DB_Type
= {
4779 PyObject_HEAD_INIT(NULL
)
4782 sizeof(DBObject
), /*tp_basicsize*/
4785 (destructor
)DB_dealloc
, /*tp_dealloc*/
4787 (getattrfunc
)DB_getattr
, /*tp_getattr*/
4792 0, /*tp_as_sequence*/
4793 &DB_mapping
,/*tp_as_mapping*/
4798 0, /* tp_getattro */
4799 0, /* tp_setattro */
4800 0, /* tp_as_buffer */
4801 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
4803 0, /* tp_traverse */
4805 0, /* tp_richcompare */
4806 offsetof(DBObject
, in_weakreflist
), /* tp_weaklistoffset */
4811 statichere PyTypeObject DBCursor_Type
= {
4812 PyObject_HEAD_INIT(NULL
)
4814 "DBCursor", /*tp_name*/
4815 sizeof(DBCursorObject
), /*tp_basicsize*/
4818 (destructor
)DBCursor_dealloc
,/*tp_dealloc*/
4820 (getattrfunc
)DBCursor_getattr
, /*tp_getattr*/
4825 0, /*tp_as_sequence*/
4826 0, /*tp_as_mapping*/
4831 0, /* tp_getattro */
4832 0, /* tp_setattro */
4833 0, /* tp_as_buffer */
4834 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
4836 0, /* tp_traverse */
4838 0, /* tp_richcompare */
4839 offsetof(DBCursorObject
, in_weakreflist
), /* tp_weaklistoffset */
4844 statichere PyTypeObject DBEnv_Type
= {
4845 PyObject_HEAD_INIT(NULL
)
4847 "DBEnv", /*tp_name*/
4848 sizeof(DBEnvObject
), /*tp_basicsize*/
4851 (destructor
)DBEnv_dealloc
, /*tp_dealloc*/
4853 (getattrfunc
)DBEnv_getattr
, /*tp_getattr*/
4858 0, /*tp_as_sequence*/
4859 0, /*tp_as_mapping*/
4864 0, /* tp_getattro */
4865 0, /* tp_setattro */
4866 0, /* tp_as_buffer */
4867 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
4869 0, /* tp_traverse */
4871 0, /* tp_richcompare */
4872 offsetof(DBEnvObject
, in_weakreflist
), /* tp_weaklistoffset */
4876 statichere PyTypeObject DBTxn_Type
= {
4877 PyObject_HEAD_INIT(NULL
)
4879 "DBTxn", /*tp_name*/
4880 sizeof(DBTxnObject
), /*tp_basicsize*/
4883 (destructor
)DBTxn_dealloc
, /*tp_dealloc*/
4885 (getattrfunc
)DBTxn_getattr
, /*tp_getattr*/
4890 0, /*tp_as_sequence*/
4891 0, /*tp_as_mapping*/
4896 0, /* tp_getattro */
4897 0, /* tp_setattro */
4898 0, /* tp_as_buffer */
4899 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
4901 0, /* tp_traverse */
4903 0, /* tp_richcompare */
4904 offsetof(DBTxnObject
, in_weakreflist
), /* tp_weaklistoffset */
4909 statichere PyTypeObject DBLock_Type
= {
4910 PyObject_HEAD_INIT(NULL
)
4912 "DBLock", /*tp_name*/
4913 sizeof(DBLockObject
), /*tp_basicsize*/
4916 (destructor
)DBLock_dealloc
, /*tp_dealloc*/
4918 (getattrfunc
)DBLock_getattr
, /*tp_getattr*/
4923 0, /*tp_as_sequence*/
4924 0, /*tp_as_mapping*/
4929 0, /* tp_getattro */
4930 0, /* tp_setattro */
4931 0, /* tp_as_buffer */
4932 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
4934 0, /* tp_traverse */
4936 0, /* tp_richcompare */
4937 offsetof(DBLockObject
, in_weakreflist
), /* tp_weaklistoffset */
4942 /* --------------------------------------------------------------------- */
4943 /* Module-level functions */
4946 DB_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4948 PyObject
* dbenvobj
= NULL
;
4950 static const char* kwnames
[] = { "dbEnv", "flags", NULL
};
4952 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:DB", kwnames
,
4955 if (dbenvobj
== Py_None
)
4957 else if (dbenvobj
&& !DBEnvObject_Check(dbenvobj
)) {
4958 makeTypeError("DBEnv", dbenvobj
);
4962 return (PyObject
* )newDBObject((DBEnvObject
*)dbenvobj
, flags
);
4967 DBEnv_construct(PyObject
* self
, PyObject
* args
)
4970 if (!PyArg_ParseTuple(args
, "|i:DbEnv", &flags
)) return NULL
;
4971 return (PyObject
* )newDBEnvObject(flags
);
4975 static char bsddb_version_doc
[] =
4976 "Returns a tuple of major, minor, and patch release numbers of the\n\
4977 underlying DB library.";
4980 bsddb_version(PyObject
* self
, PyObject
* args
)
4982 int major
, minor
, patch
;
4984 if (!PyArg_ParseTuple(args
, ":version"))
4986 db_version(&major
, &minor
, &patch
);
4987 return Py_BuildValue("(iii)", major
, minor
, patch
);
4991 /* List of functions defined in the module */
4993 static PyMethodDef bsddb_methods
[] = {
4994 {"DB", (PyCFunction
)DB_construct
, METH_VARARGS
| METH_KEYWORDS
},
4995 {"DBEnv", (PyCFunction
)DBEnv_construct
, METH_VARARGS
},
4996 {"version", (PyCFunction
)bsddb_version
, METH_VARARGS
, bsddb_version_doc
},
4997 {NULL
, NULL
} /* sentinel */
5001 /* --------------------------------------------------------------------- */
5002 /* Module initialization */
5005 /* Convenience routine to export an integer value.
5006 * Errors are silently ignored, for better or for worse...
5008 #define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
5010 #define MODULE_NAME_MAX_LEN 11
5011 static char _bsddbModuleName
[MODULE_NAME_MAX_LEN
+1] = "_bsddb";
5013 DL_EXPORT(void) init_bsddb(void)
5017 PyObject
* pybsddb_version_s
= PyString_FromString( PY_BSDDB_VERSION
);
5018 PyObject
* db_version_s
= PyString_FromString( DB_VERSION_STRING
);
5019 PyObject
* cvsid_s
= PyString_FromString( rcs_id
);
5021 /* Initialize the type of the new type objects here; doing it here
5022 is required for portability to Windows without requiring C++. */
5023 DB_Type
.ob_type
= &PyType_Type
;
5024 DBCursor_Type
.ob_type
= &PyType_Type
;
5025 DBEnv_Type
.ob_type
= &PyType_Type
;
5026 DBTxn_Type
.ob_type
= &PyType_Type
;
5027 DBLock_Type
.ob_type
= &PyType_Type
;
5030 #if defined(WITH_THREAD) && !defined(MYDB_USE_GILSTATE)
5031 /* Save the current interpreter, so callbacks can do the right thing. */
5032 _db_interpreterState
= PyThreadState_GET()->interp
;
5035 /* Create the module and add the functions */
5036 m
= Py_InitModule(_bsddbModuleName
, bsddb_methods
);
5038 /* Add some symbolic constants to the module */
5039 d
= PyModule_GetDict(m
);
5040 PyDict_SetItemString(d
, "__version__", pybsddb_version_s
);
5041 PyDict_SetItemString(d
, "cvsid", cvsid_s
);
5042 PyDict_SetItemString(d
, "DB_VERSION_STRING", db_version_s
);
5043 Py_DECREF(pybsddb_version_s
);
5044 pybsddb_version_s
= NULL
;
5047 Py_DECREF(db_version_s
);
5048 db_version_s
= NULL
;
5050 ADD_INT(d
, DB_VERSION_MAJOR
);
5051 ADD_INT(d
, DB_VERSION_MINOR
);
5052 ADD_INT(d
, DB_VERSION_PATCH
);
5054 ADD_INT(d
, DB_MAX_PAGES
);
5055 ADD_INT(d
, DB_MAX_RECORDS
);
5058 ADD_INT(d
, DB_RPCCLIENT
);
5060 ADD_INT(d
, DB_CLIENT
);
5061 /* allow apps to be written using DB_RPCCLIENT on older BerkeleyDB */
5062 _addIntToDict(d
, "DB_RPCCLIENT", DB_CLIENT
);
5064 ADD_INT(d
, DB_XA_CREATE
);
5066 ADD_INT(d
, DB_CREATE
);
5067 ADD_INT(d
, DB_NOMMAP
);
5068 ADD_INT(d
, DB_THREAD
);
5070 ADD_INT(d
, DB_FORCE
);
5071 ADD_INT(d
, DB_INIT_CDB
);
5072 ADD_INT(d
, DB_INIT_LOCK
);
5073 ADD_INT(d
, DB_INIT_LOG
);
5074 ADD_INT(d
, DB_INIT_MPOOL
);
5075 ADD_INT(d
, DB_INIT_TXN
);
5077 ADD_INT(d
, DB_JOINENV
);
5080 ADD_INT(d
, DB_RECOVER
);
5081 ADD_INT(d
, DB_RECOVER_FATAL
);
5082 ADD_INT(d
, DB_TXN_NOSYNC
);
5083 ADD_INT(d
, DB_USE_ENVIRON
);
5084 ADD_INT(d
, DB_USE_ENVIRON_ROOT
);
5086 ADD_INT(d
, DB_LOCKDOWN
);
5087 ADD_INT(d
, DB_PRIVATE
);
5088 ADD_INT(d
, DB_SYSTEM_MEM
);
5090 ADD_INT(d
, DB_TXN_SYNC
);
5091 ADD_INT(d
, DB_TXN_NOWAIT
);
5093 ADD_INT(d
, DB_EXCL
);
5094 ADD_INT(d
, DB_FCNTL_LOCKING
);
5095 ADD_INT(d
, DB_ODDFILESIZE
);
5096 ADD_INT(d
, DB_RDWRMASTER
);
5097 ADD_INT(d
, DB_RDONLY
);
5098 ADD_INT(d
, DB_TRUNCATE
);
5100 ADD_INT(d
, DB_EXTENT
);
5101 ADD_INT(d
, DB_CDB_ALLDB
);
5102 ADD_INT(d
, DB_VERIFY
);
5104 ADD_INT(d
, DB_UPGRADE
);
5106 ADD_INT(d
, DB_AGGRESSIVE
);
5107 ADD_INT(d
, DB_NOORDERCHK
);
5108 ADD_INT(d
, DB_ORDERCHKONLY
);
5109 ADD_INT(d
, DB_PR_PAGE
);
5111 ADD_INT(d
, DB_VRFY_FLAGMASK
);
5112 ADD_INT(d
, DB_PR_HEADERS
);
5114 ADD_INT(d
, DB_PR_RECOVERYTEST
);
5115 ADD_INT(d
, DB_SALVAGE
);
5117 ADD_INT(d
, DB_LOCK_NORUN
);
5118 ADD_INT(d
, DB_LOCK_DEFAULT
);
5119 ADD_INT(d
, DB_LOCK_OLDEST
);
5120 ADD_INT(d
, DB_LOCK_RANDOM
);
5121 ADD_INT(d
, DB_LOCK_YOUNGEST
);
5123 ADD_INT(d
, DB_LOCK_MAXLOCKS
);
5124 ADD_INT(d
, DB_LOCK_MINLOCKS
);
5125 ADD_INT(d
, DB_LOCK_MINWRITE
);
5130 /* docs say to use zero instead */
5131 _addIntToDict(d
, "DB_LOCK_CONFLICT", 0);
5133 ADD_INT(d
, DB_LOCK_CONFLICT
);
5136 ADD_INT(d
, DB_LOCK_DUMP
);
5137 ADD_INT(d
, DB_LOCK_GET
);
5138 ADD_INT(d
, DB_LOCK_INHERIT
);
5139 ADD_INT(d
, DB_LOCK_PUT
);
5140 ADD_INT(d
, DB_LOCK_PUT_ALL
);
5141 ADD_INT(d
, DB_LOCK_PUT_OBJ
);
5143 ADD_INT(d
, DB_LOCK_NG
);
5144 ADD_INT(d
, DB_LOCK_READ
);
5145 ADD_INT(d
, DB_LOCK_WRITE
);
5146 ADD_INT(d
, DB_LOCK_NOWAIT
);
5148 ADD_INT(d
, DB_LOCK_WAIT
);
5150 ADD_INT(d
, DB_LOCK_IWRITE
);
5151 ADD_INT(d
, DB_LOCK_IREAD
);
5152 ADD_INT(d
, DB_LOCK_IWR
);
5154 ADD_INT(d
, DB_LOCK_DIRTY
);
5155 ADD_INT(d
, DB_LOCK_WWRITE
);
5158 ADD_INT(d
, DB_LOCK_RECORD
);
5159 ADD_INT(d
, DB_LOCK_UPGRADE
);
5161 ADD_INT(d
, DB_LOCK_SWITCH
);
5164 ADD_INT(d
, DB_LOCK_UPGRADE_WRITE
);
5167 ADD_INT(d
, DB_LOCK_NOWAIT
);
5168 ADD_INT(d
, DB_LOCK_RECORD
);
5169 ADD_INT(d
, DB_LOCK_UPGRADE
);
5172 ADD_INT(d
, DB_LSTAT_ABORTED
);
5174 ADD_INT(d
, DB_LSTAT_ERR
);
5176 ADD_INT(d
, DB_LSTAT_FREE
);
5177 ADD_INT(d
, DB_LSTAT_HELD
);
5179 ADD_INT(d
, DB_LSTAT_NOGRANT
);
5181 ADD_INT(d
, DB_LSTAT_PENDING
);
5182 ADD_INT(d
, DB_LSTAT_WAITING
);
5185 ADD_INT(d
, DB_ARCH_ABS
);
5186 ADD_INT(d
, DB_ARCH_DATA
);
5187 ADD_INT(d
, DB_ARCH_LOG
);
5189 ADD_INT(d
, DB_BTREE
);
5190 ADD_INT(d
, DB_HASH
);
5191 ADD_INT(d
, DB_RECNO
);
5192 ADD_INT(d
, DB_QUEUE
);
5193 ADD_INT(d
, DB_UNKNOWN
);
5196 ADD_INT(d
, DB_DUPSORT
);
5197 ADD_INT(d
, DB_RECNUM
);
5198 ADD_INT(d
, DB_RENUMBER
);
5199 ADD_INT(d
, DB_REVSPLITOFF
);
5200 ADD_INT(d
, DB_SNAPSHOT
);
5202 ADD_INT(d
, DB_JOIN_NOSORT
);
5204 ADD_INT(d
, DB_AFTER
);
5205 ADD_INT(d
, DB_APPEND
);
5206 ADD_INT(d
, DB_BEFORE
);
5207 ADD_INT(d
, DB_CACHED_COUNTS
);
5209 _addIntToDict(d
, "DB_CHECKPOINT", 0);
5211 ADD_INT(d
, DB_CHECKPOINT
);
5212 ADD_INT(d
, DB_CURLSN
);
5214 #if ((DBVER >= 33) && (DBVER <= 41))
5215 ADD_INT(d
, DB_COMMIT
);
5217 ADD_INT(d
, DB_CONSUME
);
5219 ADD_INT(d
, DB_CONSUME_WAIT
);
5221 ADD_INT(d
, DB_CURRENT
);
5223 ADD_INT(d
, DB_FAST_STAT
);
5225 ADD_INT(d
, DB_FIRST
);
5226 ADD_INT(d
, DB_FLUSH
);
5227 ADD_INT(d
, DB_GET_BOTH
);
5228 ADD_INT(d
, DB_GET_RECNO
);
5229 ADD_INT(d
, DB_JOIN_ITEM
);
5230 ADD_INT(d
, DB_KEYFIRST
);
5231 ADD_INT(d
, DB_KEYLAST
);
5232 ADD_INT(d
, DB_LAST
);
5233 ADD_INT(d
, DB_NEXT
);
5234 ADD_INT(d
, DB_NEXT_DUP
);
5235 ADD_INT(d
, DB_NEXT_NODUP
);
5236 ADD_INT(d
, DB_NODUPDATA
);
5237 ADD_INT(d
, DB_NOOVERWRITE
);
5238 ADD_INT(d
, DB_NOSYNC
);
5239 ADD_INT(d
, DB_POSITION
);
5240 ADD_INT(d
, DB_PREV
);
5241 ADD_INT(d
, DB_PREV_NODUP
);
5242 ADD_INT(d
, DB_RECORDCOUNT
);
5244 ADD_INT(d
, DB_SET_RANGE
);
5245 ADD_INT(d
, DB_SET_RECNO
);
5246 ADD_INT(d
, DB_WRITECURSOR
);
5248 ADD_INT(d
, DB_OPFLAGS_MASK
);
5251 ADD_INT(d
, DB_DIRTY_READ
);
5252 ADD_INT(d
, DB_MULTIPLE
);
5253 ADD_INT(d
, DB_MULTIPLE_KEY
);
5257 ADD_INT(d
, DB_DONOTINDEX
);
5261 _addIntToDict(d
, "DB_INCOMPLETE", 0);
5263 ADD_INT(d
, DB_INCOMPLETE
);
5265 ADD_INT(d
, DB_KEYEMPTY
);
5266 ADD_INT(d
, DB_KEYEXIST
);
5267 ADD_INT(d
, DB_LOCK_DEADLOCK
);
5268 ADD_INT(d
, DB_LOCK_NOTGRANTED
);
5269 ADD_INT(d
, DB_NOSERVER
);
5270 ADD_INT(d
, DB_NOSERVER_HOME
);
5271 ADD_INT(d
, DB_NOSERVER_ID
);
5272 ADD_INT(d
, DB_NOTFOUND
);
5273 ADD_INT(d
, DB_OLD_VERSION
);
5274 ADD_INT(d
, DB_RUNRECOVERY
);
5275 ADD_INT(d
, DB_VERIFY_BAD
);
5277 ADD_INT(d
, DB_PAGE_NOTFOUND
);
5278 ADD_INT(d
, DB_SECONDARY_BAD
);
5281 ADD_INT(d
, DB_STAT_CLEAR
);
5282 ADD_INT(d
, DB_REGION_INIT
);
5283 ADD_INT(d
, DB_NOLOCKING
);
5284 ADD_INT(d
, DB_YIELDCPU
);
5285 ADD_INT(d
, DB_PANIC_ENVIRONMENT
);
5286 ADD_INT(d
, DB_NOPANIC
);
5290 ADD_INT(d
, DB_TIME_NOTGRANTED
);
5291 ADD_INT(d
, DB_TXN_NOT_DURABLE
);
5292 ADD_INT(d
, DB_TXN_WRITE_NOSYNC
);
5293 ADD_INT(d
, DB_LOG_AUTOREMOVE
);
5294 ADD_INT(d
, DB_DIRECT_LOG
);
5295 ADD_INT(d
, DB_DIRECT_DB
);
5296 ADD_INT(d
, DB_INIT_REP
);
5297 ADD_INT(d
, DB_ENCRYPT
);
5298 ADD_INT(d
, DB_CHKSUM
);
5302 ADD_INT(d
, DB_LOG_INMEMORY
);
5303 ADD_INT(d
, DB_BUFFER_SMALL
);
5307 ADD_INT(d
, DB_ENCRYPT_AES
);
5308 ADD_INT(d
, DB_AUTO_COMMIT
);
5310 /* allow berkeleydb 4.1 aware apps to run on older versions */
5311 _addIntToDict(d
, "DB_AUTO_COMMIT", 0);
5325 ADD_INT(d
, DB_SET_LOCK_TIMEOUT
);
5326 ADD_INT(d
, DB_SET_TXN_TIMEOUT
);
5329 /* The base exception class is DBError */
5330 DBError
= PyErr_NewException("bsddb._db.DBError", NULL
, NULL
);
5331 PyDict_SetItemString(d
, "DBError", DBError
);
5333 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
5334 * from both DBError and KeyError, since the API only supports
5335 * using one base class. */
5336 PyDict_SetItemString(d
, "KeyError", PyExc_KeyError
);
5337 PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
5338 "class DBKeyEmptyError(DBError, KeyError): pass",
5339 Py_file_input
, d
, d
);
5340 DBNotFoundError
= PyDict_GetItemString(d
, "DBNotFoundError");
5341 DBKeyEmptyError
= PyDict_GetItemString(d
, "DBKeyEmptyError");
5342 PyDict_DelItemString(d
, "KeyError");
5345 /* All the rest of the exceptions derive only from DBError */
5346 #define MAKE_EX(name) name = PyErr_NewException("bsddb._db." #name, DBError, NULL); \
5347 PyDict_SetItemString(d, #name, name)
5349 #if !INCOMPLETE_IS_WARNING
5350 MAKE_EX(DBIncompleteError
);
5352 MAKE_EX(DBCursorClosedError
);
5353 MAKE_EX(DBKeyEmptyError
);
5354 MAKE_EX(DBKeyExistError
);
5355 MAKE_EX(DBLockDeadlockError
);
5356 MAKE_EX(DBLockNotGrantedError
);
5357 MAKE_EX(DBOldVersionError
);
5358 MAKE_EX(DBRunRecoveryError
);
5359 MAKE_EX(DBVerifyBadError
);
5360 MAKE_EX(DBNoServerError
);
5361 MAKE_EX(DBNoServerHomeError
);
5362 MAKE_EX(DBNoServerIDError
);
5364 MAKE_EX(DBPageNotFoundError
);
5365 MAKE_EX(DBSecondaryBadError
);
5368 MAKE_EX(DBInvalidArgError
);
5369 MAKE_EX(DBAccessError
);
5370 MAKE_EX(DBNoSpaceError
);
5371 MAKE_EX(DBNoMemoryError
);
5372 MAKE_EX(DBAgainError
);
5373 MAKE_EX(DBBusyError
);
5374 MAKE_EX(DBFileExistsError
);
5375 MAKE_EX(DBNoSuchFileError
);
5376 MAKE_EX(DBPermissionsError
);
5380 /* Check for errors */
5381 if (PyErr_Occurred()) {
5383 Py_FatalError("can't initialize module _bsddb");
5387 /* allow this module to be named _pybsddb so that it can be installed
5388 * and imported on top of python >= 2.3 that includes its own older
5389 * copy of the library named _bsddb without importing the old version. */
5390 DL_EXPORT(void) init_pybsddb(void)
5392 strncpy(_bsddbModuleName
, "_pybsddb", MODULE_NAME_MAX_LEN
);