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.2.8"
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 */
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
; /* ENOMEM */
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 */
188 /* --------------------------------------------------------------------- */
189 /* Structure definitions */
191 #if PYTHON_API_VERSION >= 1010 /* python >= 2.1 support weak references */
197 /* if Python >= 2.1 better support warnings */
198 #if PYTHON_API_VERSION >= 1010
199 #define HAVE_WARNINGS
204 struct behaviourFlags
{
205 /* What is the default behaviour when DB->get or DBCursor->get returns a
206 DB_NOTFOUND error? Return None or raise an exception? */
207 unsigned int getReturnsNone
: 1;
208 /* What is the default behaviour for DBCursor.set* methods when DBCursor->get
209 * returns a DB_NOTFOUND error? Return None or raise an exception? */
210 unsigned int cursorSetReturnsNone
: 1;
213 #define DEFAULT_GET_RETURNS_NONE 1
214 #define DEFAULT_CURSOR_SET_RETURNS_NONE 1 /* 0 in pybsddb < 4.2, python < 2.4 */
219 u_int32_t flags
; /* saved flags from open() */
221 struct behaviourFlags moduleFlags
;
223 PyObject
*in_weakreflist
; /* List of weak references */
231 DBEnvObject
* myenvobj
; /* PyObject containing the DB_ENV */
232 u_int32_t flags
; /* saved flags from open() */
233 u_int32_t setflags
; /* saved flags from set_flags() */
235 struct behaviourFlags moduleFlags
;
237 PyObject
* associateCallback
;
241 PyObject
*in_weakreflist
; /* List of weak references */
251 PyObject
*in_weakreflist
; /* List of weak references */
260 PyObject
*in_weakreflist
; /* List of weak references */
269 PyObject
*in_weakreflist
; /* List of weak references */
275 staticforward PyTypeObject DB_Type
, DBCursor_Type
, DBEnv_Type
, DBTxn_Type
, DBLock_Type
;
277 #define DBObject_Check(v) ((v)->ob_type == &DB_Type)
278 #define DBCursorObject_Check(v) ((v)->ob_type == &DBCursor_Type)
279 #define DBEnvObject_Check(v) ((v)->ob_type == &DBEnv_Type)
280 #define DBTxnObject_Check(v) ((v)->ob_type == &DBTxn_Type)
281 #define DBLockObject_Check(v) ((v)->ob_type == &DBLock_Type)
284 /* --------------------------------------------------------------------- */
285 /* Utility macros and functions */
287 #define RETURN_IF_ERR() \
288 if (makeDBError(err)) { \
292 #define RETURN_NONE() Py_INCREF(Py_None); return Py_None;
294 #define _CHECK_OBJECT_NOT_CLOSED(nonNull, pyErrObj, name) \
295 if ((nonNull) == NULL) { \
296 PyObject *errTuple = NULL; \
297 errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
298 PyErr_SetObject((pyErrObj), errTuple); \
299 Py_DECREF(errTuple); \
303 #define CHECK_DB_NOT_CLOSED(dbobj) \
304 _CHECK_OBJECT_NOT_CLOSED(dbobj->db, DBError, DB)
306 #define CHECK_ENV_NOT_CLOSED(env) \
307 _CHECK_OBJECT_NOT_CLOSED(env->db_env, DBError, DBEnv)
309 #define CHECK_CURSOR_NOT_CLOSED(curs) \
310 _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)
313 #define CHECK_DBFLAG(mydb, flag) (((mydb)->flags & (flag)) || \
314 (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))
316 #define CLEAR_DBT(dbt) (memset(&(dbt), 0, sizeof(dbt)))
318 #define FREE_DBT(dbt) if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
319 dbt.data != NULL) { free(dbt.data); dbt.data = NULL; }
322 static int makeDBError(int err
);
325 /* Return the access method type of the DBObject */
326 static int _DB_get_type(DBObject
* self
)
331 err
= self
->db
->get_type(self
->db
, &type
);
332 if (makeDBError(err
)) {
337 return self
->db
->get_type(self
->db
);
342 /* Create a DBT structure (containing key and data values) from Python
343 strings. Returns 1 on success, 0 on an error. */
344 static int make_dbt(PyObject
* obj
, DBT
* dbt
)
347 if (obj
== Py_None
) {
348 /* no need to do anything, the structure has already been zeroed */
350 else if (!PyArg_Parse(obj
, "s#", &dbt
->data
, &dbt
->size
)) {
351 PyErr_SetString(PyExc_TypeError
,
352 "Data values must be of type string or None.");
359 /* Recno and Queue DBs can have integer keys. This function figures out
360 what's been given, verifies that it's allowed, and then makes the DBT.
362 Caller MUST call FREE_DBT(key) when done. */
364 make_key_dbt(DBObject
* self
, PyObject
* keyobj
, DBT
* key
, int* pflags
)
370 if (keyobj
== Py_None
) {
371 type
= _DB_get_type(self
);
374 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
377 "None keys not allowed for Recno and Queue DB's");
380 /* no need to do anything, the structure has already been zeroed */
383 else if (PyString_Check(keyobj
)) {
384 /* verify access method type */
385 type
= _DB_get_type(self
);
388 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
391 "String keys not allowed for Recno and Queue DB's");
395 key
->data
= PyString_AS_STRING(keyobj
);
396 key
->size
= PyString_GET_SIZE(keyobj
);
399 else if (PyInt_Check(keyobj
)) {
400 /* verify access method type */
401 type
= _DB_get_type(self
);
404 if (type
== DB_BTREE
&& pflags
!= NULL
) {
405 /* if BTREE then an Integer key is allowed with the
406 * DB_SET_RECNO flag */
407 *pflags
|= DB_SET_RECNO
;
409 else if (type
!= DB_RECNO
&& type
!= DB_QUEUE
) {
412 "Integer keys only allowed for Recno and Queue DB's");
416 /* Make a key out of the requested recno, use allocated space so DB
417 * will be able to realloc room for the real key if needed. */
418 recno
= PyInt_AS_LONG(keyobj
);
419 key
->data
= malloc(sizeof(db_recno_t
));
420 if (key
->data
== NULL
) {
421 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
424 key
->ulen
= key
->size
= sizeof(db_recno_t
);
425 memcpy(key
->data
, &recno
, sizeof(db_recno_t
));
426 key
->flags
= DB_DBT_REALLOC
;
429 PyErr_Format(PyExc_TypeError
,
430 "String or Integer object expected for key, %s found",
431 keyobj
->ob_type
->tp_name
);
439 /* Add partial record access to an existing DBT data struct.
440 If dlen and doff are set, then the DB_DBT_PARTIAL flag will be set
441 and the data storage/retrieval will be done using dlen and doff. */
442 static int add_partial_dbt(DBT
* d
, int dlen
, int doff
) {
443 /* if neither were set we do nothing (-1 is the default value) */
444 if ((dlen
== -1) && (doff
== -1)) {
448 if ((dlen
< 0) || (doff
< 0)) {
449 PyErr_SetString(PyExc_TypeError
, "dlen and doff must both be >= 0");
453 d
->flags
= d
->flags
| DB_DBT_PARTIAL
;
454 d
->dlen
= (unsigned int) dlen
;
455 d
->doff
= (unsigned int) doff
;
460 /* Callback used to save away more information about errors from the DB
462 static char _db_errmsg
[1024];
463 static void _db_errorCallback(const char* prefix
, char* msg
)
465 strcpy(_db_errmsg
, msg
);
469 /* make a nice exception object to raise for errors. */
470 static int makeDBError(int err
)
472 char errTxt
[2048]; /* really big, just in case... */
473 PyObject
*errObj
= NULL
;
474 PyObject
*errTuple
= NULL
;
475 int exceptionRaised
= 0;
478 case 0: /* successful, no error */ break;
482 #if INCOMPLETE_IS_WARNING
483 strcpy(errTxt
, db_strerror(err
));
485 strcat(errTxt
, " -- ");
486 strcat(errTxt
, _db_errmsg
);
490 exceptionRaised
= PyErr_Warn(PyExc_RuntimeWarning
, errTxt
);
492 fprintf(stderr
, errTxt
);
493 fprintf(stderr
, "\n");
496 #else /* do an exception instead */
497 errObj
= DBIncompleteError
;
500 #endif /* DBVER < 41 */
502 case DB_KEYEMPTY
: errObj
= DBKeyEmptyError
; break;
503 case DB_KEYEXIST
: errObj
= DBKeyExistError
; break;
504 case DB_LOCK_DEADLOCK
: errObj
= DBLockDeadlockError
; break;
505 case DB_LOCK_NOTGRANTED
: errObj
= DBLockNotGrantedError
; break;
506 case DB_NOTFOUND
: errObj
= DBNotFoundError
; break;
507 case DB_OLD_VERSION
: errObj
= DBOldVersionError
; break;
508 case DB_RUNRECOVERY
: errObj
= DBRunRecoveryError
; break;
509 case DB_VERIFY_BAD
: errObj
= DBVerifyBadError
; break;
510 case DB_NOSERVER
: errObj
= DBNoServerError
; break;
511 case DB_NOSERVER_HOME
: errObj
= DBNoServerHomeError
; break;
512 case DB_NOSERVER_ID
: errObj
= DBNoServerIDError
; break;
514 case DB_PAGE_NOTFOUND
: errObj
= DBPageNotFoundError
; break;
515 case DB_SECONDARY_BAD
: errObj
= DBSecondaryBadError
; break;
518 case EINVAL
: errObj
= DBInvalidArgError
; break;
519 case EACCES
: errObj
= DBAccessError
; break;
520 case ENOSPC
: errObj
= DBNoSpaceError
; break;
521 case ENOMEM
: errObj
= DBNoMemoryError
; break;
522 case EAGAIN
: errObj
= DBAgainError
; break;
523 case EBUSY
: errObj
= DBBusyError
; break;
524 case EEXIST
: errObj
= DBFileExistsError
; break;
525 case ENOENT
: errObj
= DBNoSuchFileError
; break;
526 case EPERM
: errObj
= DBPermissionsError
; break;
528 default: errObj
= DBError
; break;
531 if (errObj
!= NULL
) {
532 /* FIXME this needs proper bounds checking on errTxt */
533 strcpy(errTxt
, db_strerror(err
));
535 strcat(errTxt
, " -- ");
536 strcat(errTxt
, _db_errmsg
);
540 errTuple
= Py_BuildValue("(is)", err
, errTxt
);
541 PyErr_SetObject(errObj
, errTuple
);
545 return ((errObj
!= NULL
) || exceptionRaised
);
550 /* set a type exception */
551 static void makeTypeError(char* expected
, PyObject
* found
)
553 PyErr_Format(PyExc_TypeError
, "Expected %s argument, %s found.",
554 expected
, found
->ob_type
->tp_name
);
558 /* verify that an obj is either None or a DBTxn, and set the txn pointer */
559 static int checkTxnObj(PyObject
* txnobj
, DB_TXN
** txn
)
561 if (txnobj
== Py_None
|| txnobj
== NULL
) {
565 if (DBTxnObject_Check(txnobj
)) {
566 *txn
= ((DBTxnObject
*)txnobj
)->txn
;
570 makeTypeError("DBTxn", txnobj
);
575 /* Delete a key from a database
576 Returns 0 on success, -1 on an error. */
577 static int _DB_delete(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, int flags
)
581 MYDB_BEGIN_ALLOW_THREADS
;
582 err
= self
->db
->del(self
->db
, txn
, key
, 0);
583 MYDB_END_ALLOW_THREADS
;
584 if (makeDBError(err
)) {
592 /* Store a key into a database
593 Returns 0 on success, -1 on an error. */
594 static int _DB_put(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, DBT
*data
, int flags
)
598 MYDB_BEGIN_ALLOW_THREADS
;
599 err
= self
->db
->put(self
->db
, txn
, key
, data
, flags
);
600 MYDB_END_ALLOW_THREADS
;
601 if (makeDBError(err
)) {
608 /* Get a key/data pair from a cursor */
609 static PyObject
* _DBCursor_get(DBCursorObject
* self
, int extra_flags
,
610 PyObject
*args
, PyObject
*kwargs
, char *format
)
613 PyObject
* retval
= NULL
;
618 char* kwnames
[] = { "flags", "dlen", "doff", NULL
};
620 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, format
, kwnames
,
621 &flags
, &dlen
, &doff
))
624 CHECK_CURSOR_NOT_CLOSED(self
);
626 flags
|= extra_flags
;
629 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
630 /* Tell BerkeleyDB to malloc the return value (thread safe) */
631 data
.flags
= DB_DBT_MALLOC
;
632 key
.flags
= DB_DBT_MALLOC
;
634 if (!add_partial_dbt(&data
, dlen
, doff
))
637 MYDB_BEGIN_ALLOW_THREADS
;
638 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
639 MYDB_END_ALLOW_THREADS
;
641 if ((err
== DB_NOTFOUND
) && self
->mydb
->moduleFlags
.getReturnsNone
) {
645 else if (makeDBError(err
)) {
648 else { /* otherwise, success! */
650 /* if Recno or Queue, return the key as an Int */
651 switch (_DB_get_type(self
->mydb
)) {
658 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
659 data
.data
, data
.size
);
664 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
665 data
.data
, data
.size
);
677 /* add an integer to a dictionary using the given name as a key */
678 static void _addIntToDict(PyObject
* dict
, char *name
, int value
)
680 PyObject
* v
= PyInt_FromLong((long) value
);
681 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
690 /* --------------------------------------------------------------------- */
691 /* Allocators and deallocators */
694 newDBObject(DBEnvObject
* arg
, int flags
)
697 DB_ENV
* db_env
= NULL
;
700 #if PYTHON_API_VERSION <= 1007
701 /* 1.5 compatibility */
702 self
= PyObject_NEW(DBObject
, &DB_Type
);
704 self
= PyObject_New(DBObject
, &DB_Type
);
713 self
->myenvobj
= NULL
;
715 self
->associateCallback
= NULL
;
716 self
->primaryDBType
= 0;
719 self
->in_weakreflist
= NULL
;
722 /* keep a reference to our python DBEnv object */
725 self
->myenvobj
= arg
;
726 db_env
= arg
->db_env
;
730 self
->moduleFlags
= self
->myenvobj
->moduleFlags
;
732 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
733 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
735 MYDB_BEGIN_ALLOW_THREADS
;
736 err
= db_create(&self
->db
, db_env
, flags
);
737 self
->db
->set_errcall(self
->db
, _db_errorCallback
);
739 self
->db
->app_private
= (void*)self
;
741 MYDB_END_ALLOW_THREADS
;
742 /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
743 * list so that a DBEnv can refuse to close without aborting any open
744 * open DBTxns and closing any open DBs first. */
745 if (makeDBError(err
)) {
746 if (self
->myenvobj
) {
747 Py_DECREF(self
->myenvobj
);
748 self
->myenvobj
= NULL
;
757 DB_dealloc(DBObject
* self
)
759 if (self
->db
!= NULL
) {
760 /* avoid closing a DB when its DBEnv has been closed out from under
762 if (!self
->myenvobj
||
763 (self
->myenvobj
&& self
->myenvobj
->db_env
))
765 MYDB_BEGIN_ALLOW_THREADS
;
766 self
->db
->close(self
->db
, 0);
767 MYDB_END_ALLOW_THREADS
;
770 PyErr_Warn(PyExc_RuntimeWarning
,
771 "DB could not be closed in destructor: DBEnv already closed");
777 if (self
->in_weakreflist
!= NULL
) {
778 PyObject_ClearWeakRefs((PyObject
*) self
);
781 if (self
->myenvobj
) {
782 Py_DECREF(self
->myenvobj
);
783 self
->myenvobj
= NULL
;
786 if (self
->associateCallback
!= NULL
) {
787 Py_DECREF(self
->associateCallback
);
788 self
->associateCallback
= NULL
;
791 #if PYTHON_API_VERSION <= 1007
799 static DBCursorObject
*
800 newDBCursorObject(DBC
* dbc
, DBObject
* db
)
802 DBCursorObject
* self
;
803 #if PYTHON_API_VERSION <= 1007
804 self
= PyObject_NEW(DBCursorObject
, &DBCursor_Type
);
806 self
= PyObject_New(DBCursorObject
, &DBCursor_Type
);
814 self
->in_weakreflist
= NULL
;
816 Py_INCREF(self
->mydb
);
822 DBCursor_dealloc(DBCursorObject
* self
)
827 if (self
->in_weakreflist
!= NULL
) {
828 PyObject_ClearWeakRefs((PyObject
*) self
);
832 if (self
->dbc
!= NULL
) {
833 MYDB_BEGIN_ALLOW_THREADS
;
834 /* If the underlying database has been closed, we don't
835 need to do anything. If the environment has been closed
836 we need to leak, as BerkeleyDB will crash trying to access
837 the environment. There was an exception when the
838 user closed the environment even though there still was
840 if (self
->mydb
->db
&& self
->mydb
->myenvobj
&&
841 !self
->mydb
->myenvobj
->closed
)
842 err
= self
->dbc
->c_close(self
->dbc
);
844 MYDB_END_ALLOW_THREADS
;
846 Py_XDECREF( self
->mydb
);
847 #if PYTHON_API_VERSION <= 1007
856 newDBEnvObject(int flags
)
860 #if PYTHON_API_VERSION <= 1007
861 self
= PyObject_NEW(DBEnvObject
, &DBEnv_Type
);
863 self
= PyObject_New(DBEnvObject
, &DBEnv_Type
);
871 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
872 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
874 self
->in_weakreflist
= NULL
;
877 MYDB_BEGIN_ALLOW_THREADS
;
878 err
= db_env_create(&self
->db_env
, flags
);
879 MYDB_END_ALLOW_THREADS
;
880 if (makeDBError(err
)) {
884 self
->db_env
->set_errcall(self
->db_env
, _db_errorCallback
);
891 DBEnv_dealloc(DBEnvObject
* self
)
894 if (self
->in_weakreflist
!= NULL
) {
895 PyObject_ClearWeakRefs((PyObject
*) self
);
900 MYDB_BEGIN_ALLOW_THREADS
;
901 self
->db_env
->close(self
->db_env
, 0);
902 MYDB_END_ALLOW_THREADS
;
904 #if PYTHON_API_VERSION <= 1007
913 newDBTxnObject(DBEnvObject
* myenv
, DB_TXN
*parent
, int flags
)
918 #if PYTHON_API_VERSION <= 1007
919 self
= PyObject_NEW(DBTxnObject
, &DBTxn_Type
);
921 self
= PyObject_New(DBTxnObject
, &DBTxn_Type
);
926 self
->in_weakreflist
= NULL
;
929 MYDB_BEGIN_ALLOW_THREADS
;
931 err
= myenv
->db_env
->txn_begin(myenv
->db_env
, parent
, &(self
->txn
), flags
);
933 err
= txn_begin(myenv
->db_env
, parent
, &(self
->txn
), flags
);
935 /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
936 * list so that a DBEnv can refuse to close without aborting any open
937 * open DBTxns and closing any open DBs first. */
938 MYDB_END_ALLOW_THREADS
;
939 if (makeDBError(err
)) {
947 DBTxn_dealloc(DBTxnObject
* self
)
950 if (self
->in_weakreflist
!= NULL
) {
951 PyObject_ClearWeakRefs((PyObject
*) self
);
957 /* it hasn't been finalized, abort it! */
958 MYDB_BEGIN_ALLOW_THREADS
;
960 self
->txn
->abort(self
->txn
);
962 txn_abort(self
->txn
);
964 MYDB_END_ALLOW_THREADS
;
965 PyErr_Warn(PyExc_RuntimeWarning
,
966 "DBTxn aborted in destructor. No prior commit() or abort().");
970 #if PYTHON_API_VERSION <= 1007
979 newDBLockObject(DBEnvObject
* myenv
, u_int32_t locker
, DBT
* obj
,
980 db_lockmode_t lock_mode
, int flags
)
985 #if PYTHON_API_VERSION <= 1007
986 self
= PyObject_NEW(DBLockObject
, &DBLock_Type
);
988 self
= PyObject_New(DBLockObject
, &DBLock_Type
);
993 self
->in_weakreflist
= NULL
;
996 MYDB_BEGIN_ALLOW_THREADS
;
998 err
= myenv
->db_env
->lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
,
1001 err
= lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
, &self
->lock
);
1003 MYDB_END_ALLOW_THREADS
;
1004 if (makeDBError(err
)) {
1013 DBLock_dealloc(DBLockObject
* self
)
1016 if (self
->in_weakreflist
!= NULL
) {
1017 PyObject_ClearWeakRefs((PyObject
*) self
);
1020 /* TODO: is this lock held? should we release it? */
1022 #if PYTHON_API_VERSION <= 1007
1030 /* --------------------------------------------------------------------- */
1034 DB_append(DBObject
* self
, PyObject
* args
)
1036 PyObject
* txnobj
= NULL
;
1042 if (!PyArg_ParseTuple(args
, "O|O:append", &dataobj
, &txnobj
))
1045 CHECK_DB_NOT_CLOSED(self
);
1047 /* make a dummy key out of a recno */
1051 key
.size
= sizeof(recno
);
1052 key
.ulen
= key
.size
;
1053 key
.flags
= DB_DBT_USERMEM
;
1055 if (!make_dbt(dataobj
, &data
)) return NULL
;
1056 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1058 if (-1 == _DB_put(self
, txn
, &key
, &data
, DB_APPEND
))
1061 return PyInt_FromLong(recno
);
1068 _db_associateCallback(DB
* db
, const DBT
* priKey
, const DBT
* priData
,
1071 int retval
= DB_DONOTINDEX
;
1072 DBObject
* secondaryDB
= (DBObject
*)db
->app_private
;
1073 PyObject
* callback
= secondaryDB
->associateCallback
;
1074 int type
= secondaryDB
->primaryDBType
;
1081 if (callback
!= NULL
) {
1082 MYDB_BEGIN_BLOCK_THREADS
;
1084 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
1085 key
= PyInt_FromLong( *((db_recno_t
*)priKey
->data
));
1088 key
= PyString_FromStringAndSize(priKey
->data
, priKey
->size
);
1090 data
= PyString_FromStringAndSize(priData
->data
, priData
->size
);
1091 args
= PyTuple_New(2);
1092 PyTuple_SET_ITEM(args
, 0, key
); /* steals reference */
1093 PyTuple_SET_ITEM(args
, 1, data
); /* steals reference */
1095 result
= PyEval_CallObject(callback
, args
);
1097 if (result
== NULL
) {
1100 else if (result
== Py_None
) {
1101 retval
= DB_DONOTINDEX
;
1103 else if (PyInt_Check(result
)) {
1104 retval
= PyInt_AsLong(result
);
1106 else if (PyString_Check(result
)) {
1111 #if PYTHON_API_VERSION <= 1007
1112 /* 1.5 compatibility */
1113 size
= PyString_Size(result
);
1114 data
= PyString_AsString(result
);
1116 PyString_AsStringAndSize(result
, &data
, &size
);
1118 secKey
->flags
= DB_DBT_APPMALLOC
; /* DB will free */
1119 secKey
->data
= malloc(size
); /* TODO, check this */
1121 memcpy(secKey
->data
, data
, size
);
1122 secKey
->size
= size
;
1126 PyErr_SetString(PyExc_MemoryError
,
1127 "malloc failed in _db_associateCallback");
1134 "DB associate callback should return DB_DONOTINDEX or string.");
1143 MYDB_END_BLOCK_THREADS
;
1150 DB_associate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1153 DBObject
* secondaryDB
;
1156 PyObject
*txnobj
= NULL
;
1158 char* kwnames
[] = {"secondaryDB", "callback", "flags", "txn", NULL
};
1160 char* kwnames
[] = {"secondaryDB", "callback", "flags", NULL
};
1164 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iO:associate", kwnames
,
1165 &secondaryDB
, &callback
, &flags
,
1168 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|i:associate", kwnames
,
1169 &secondaryDB
, &callback
, &flags
)) {
1175 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1178 CHECK_DB_NOT_CLOSED(self
);
1179 if (!DBObject_Check(secondaryDB
)) {
1180 makeTypeError("DB", (PyObject
*)secondaryDB
);
1183 if (callback
== Py_None
) {
1186 else if (!PyCallable_Check(callback
)) {
1187 makeTypeError("Callable", callback
);
1191 /* Save a reference to the callback in the secondary DB. */
1192 if (self
->associateCallback
!= NULL
) {
1193 Py_DECREF(self
->associateCallback
);
1195 Py_INCREF(callback
);
1196 secondaryDB
->associateCallback
= callback
;
1197 secondaryDB
->primaryDBType
= _DB_get_type(self
);
1199 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1200 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1201 * The global interepreter lock is not initialized until the first
1202 * thread is created using thread.start_new_thread() or fork() is
1203 * called. that would cause the ALLOW_THREADS here to segfault due
1204 * to a null pointer reference if no threads or child processes
1205 * have been created. This works around that and is a no-op if
1206 * threads have already been initialized.
1207 * (see pybsddb-users mailing list post on 2002-08-07)
1210 PyEval_InitThreads();
1212 MYDB_BEGIN_ALLOW_THREADS
;
1214 err
= self
->db
->associate(self
->db
,
1217 _db_associateCallback
,
1220 err
= self
->db
->associate(self
->db
,
1222 _db_associateCallback
,
1225 MYDB_END_ALLOW_THREADS
;
1228 Py_DECREF(self
->associateCallback
);
1229 self
->associateCallback
= NULL
;
1230 secondaryDB
->primaryDBType
= 0;
1242 DB_close(DBObject
* self
, PyObject
* args
)
1245 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
1247 if (self
->db
!= NULL
) {
1249 CHECK_ENV_NOT_CLOSED(self
->myenvobj
);
1250 err
= self
->db
->close(self
->db
, flags
);
1260 _DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1262 int err
, flags
=0, type
;
1263 PyObject
* txnobj
= NULL
;
1264 PyObject
* retval
= NULL
;
1267 char* kwnames
[] = { "txn", "flags", NULL
};
1269 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:consume", kwnames
,
1273 CHECK_DB_NOT_CLOSED(self
);
1274 type
= _DB_get_type(self
);
1277 if (type
!= DB_QUEUE
) {
1278 PyErr_SetString(PyExc_TypeError
,
1279 "Consume methods only allowed for Queue DB's");
1282 if (!checkTxnObj(txnobj
, &txn
))
1287 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1288 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1289 data
.flags
= DB_DBT_MALLOC
;
1290 key
.flags
= DB_DBT_MALLOC
;
1293 MYDB_BEGIN_ALLOW_THREADS
;
1294 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
|consume_flag
);
1295 MYDB_END_ALLOW_THREADS
;
1297 if ((err
== DB_NOTFOUND
) && self
->moduleFlags
.getReturnsNone
) {
1303 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
1314 DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1316 return _DB_consume(self
, args
, kwargs
, DB_CONSUME
);
1320 DB_consume_wait(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
,
1323 return _DB_consume(self
, args
, kwargs
, DB_CONSUME_WAIT
);
1330 DB_cursor(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1334 PyObject
* txnobj
= NULL
;
1336 char* kwnames
[] = { "txn", "flags", NULL
};
1338 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
1341 CHECK_DB_NOT_CLOSED(self
);
1342 if (!checkTxnObj(txnobj
, &txn
))
1345 MYDB_BEGIN_ALLOW_THREADS
;
1346 err
= self
->db
->cursor(self
->db
, txn
, &dbc
, flags
);
1347 MYDB_END_ALLOW_THREADS
;
1349 return (PyObject
*) newDBCursorObject(dbc
, self
);
1354 DB_delete(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1356 PyObject
* txnobj
= NULL
;
1361 char* kwnames
[] = { "key", "txn", "flags", NULL
};
1363 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:delete", kwnames
,
1364 &keyobj
, &txnobj
, &flags
))
1366 CHECK_DB_NOT_CLOSED(self
);
1367 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1369 if (!checkTxnObj(txnobj
, &txn
)) {
1374 if (-1 == _DB_delete(self
, txn
, &key
, 0)) {
1385 DB_fd(DBObject
* self
, PyObject
* args
)
1389 if (!PyArg_ParseTuple(args
,":fd"))
1391 CHECK_DB_NOT_CLOSED(self
);
1393 MYDB_BEGIN_ALLOW_THREADS
;
1394 err
= self
->db
->fd(self
->db
, &the_fd
);
1395 MYDB_END_ALLOW_THREADS
;
1397 return PyInt_FromLong(the_fd
);
1402 DB_get(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1405 PyObject
* txnobj
= NULL
;
1407 PyObject
* dfltobj
= NULL
;
1408 PyObject
* retval
= NULL
;
1413 char* kwnames
[] = {"key", "default", "txn", "flags", "dlen", "doff", NULL
};
1415 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:get", kwnames
,
1416 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1420 CHECK_DB_NOT_CLOSED(self
);
1421 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1423 if (!checkTxnObj(txnobj
, &txn
)) {
1429 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1430 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1431 data
.flags
= DB_DBT_MALLOC
;
1433 if (!add_partial_dbt(&data
, dlen
, doff
)) {
1438 MYDB_BEGIN_ALLOW_THREADS
;
1439 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1440 MYDB_END_ALLOW_THREADS
;
1442 if ((err
== DB_NOTFOUND
) && (dfltobj
!= NULL
)) {
1447 else if ((err
== DB_NOTFOUND
) && self
->moduleFlags
.getReturnsNone
) {
1453 if (flags
& DB_SET_RECNO
) /* return both key and data */
1454 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
1456 else /* return just the data */
1457 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
1467 DB_pget(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1470 PyObject
* txnobj
= NULL
;
1472 PyObject
* dfltobj
= NULL
;
1473 PyObject
* retval
= NULL
;
1476 DBT key
, pkey
, data
;
1478 char* kwnames
[] = {"key", "default", "txn", "flags", "dlen", "doff", NULL
};
1480 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:pget", kwnames
,
1481 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1485 CHECK_DB_NOT_CLOSED(self
);
1486 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1488 if (!checkTxnObj(txnobj
, &txn
)) {
1494 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1495 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1496 data
.flags
= DB_DBT_MALLOC
;
1498 if (!add_partial_dbt(&data
, dlen
, doff
)) {
1504 pkey
.flags
= DB_DBT_MALLOC
;
1506 MYDB_BEGIN_ALLOW_THREADS
;
1507 err
= self
->db
->pget(self
->db
, txn
, &key
, &pkey
, &data
, flags
);
1508 MYDB_END_ALLOW_THREADS
;
1510 if ((err
== DB_NOTFOUND
) && (dfltobj
!= NULL
)) {
1515 else if ((err
== DB_NOTFOUND
) && self
->moduleFlags
.getReturnsNone
) {
1523 dataObj
= PyString_FromStringAndSize(data
.data
, data
.size
);
1525 if (self
->primaryDBType
== DB_RECNO
||
1526 self
->primaryDBType
== DB_QUEUE
)
1527 pkeyObj
= PyInt_FromLong(*(long *)pkey
.data
);
1529 pkeyObj
= PyString_FromStringAndSize(pkey
.data
, pkey
.size
);
1531 if (flags
& DB_SET_RECNO
) /* return key , pkey and data */
1534 int type
= _DB_get_type(self
);
1535 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
1536 keyObj
= PyInt_FromLong(*(long *)key
.data
);
1538 keyObj
= PyString_FromStringAndSize(key
.data
, key
.size
);
1539 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
1541 else /* return just the pkey and data */
1543 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
1555 /* Return size of entry */
1557 DB_get_size(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1560 PyObject
* txnobj
= NULL
;
1562 PyObject
* retval
= NULL
;
1565 char* kwnames
[] = { "key", "txn", NULL
};
1567 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O:get_size", kwnames
,
1570 CHECK_DB_NOT_CLOSED(self
);
1571 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1573 if (!checkTxnObj(txnobj
, &txn
)) {
1579 /* We don't allocate any memory, forcing a ENOMEM error and thus
1580 getting the record size. */
1581 data
.flags
= DB_DBT_USERMEM
;
1583 MYDB_BEGIN_ALLOW_THREADS
;
1584 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1585 MYDB_END_ALLOW_THREADS
;
1586 if (err
== ENOMEM
) {
1587 retval
= PyInt_FromLong((long)data
.size
);
1599 DB_get_both(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1602 PyObject
* txnobj
= NULL
;
1605 PyObject
* retval
= NULL
;
1608 char* kwnames
[] = { "key", "data", "txn", "flags", NULL
};
1611 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oi:get_both", kwnames
,
1612 &keyobj
, &dataobj
, &txnobj
, &flags
))
1615 CHECK_DB_NOT_CLOSED(self
);
1616 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1618 if ( !make_dbt(dataobj
, &data
) ||
1619 !checkTxnObj(txnobj
, &txn
) )
1625 flags
|= DB_GET_BOTH
;
1627 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1628 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1629 data
.flags
= DB_DBT_MALLOC
;
1630 /* TODO: Is this flag needed? We're passing a data object that should
1631 match what's in the DB, so there should be no need to malloc.
1632 We run the risk of freeing something twice! Check this. */
1635 MYDB_BEGIN_ALLOW_THREADS
;
1636 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1637 MYDB_END_ALLOW_THREADS
;
1639 if ((err
== DB_NOTFOUND
) && 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 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
;
1790 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL
};
1791 /* without dbname */
1792 char* kwnames_basic
[] = {
1793 "filename", "dbtype", "flags", "mode", "txn", NULL
};
1797 "filename", "dbname", "dbtype", "flags", "mode", NULL
};
1798 /* without dbname */
1799 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 char* kwnames
[] = { "key", "data", "txn", "flags", "dlen", "doff", NULL
};
1885 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oiii:put", kwnames
,
1886 &keyobj
, &dataobj
, &txnobj
, &flags
, &dlen
, &doff
))
1889 CHECK_DB_NOT_CLOSED(self
);
1890 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1892 if ( !make_dbt(dataobj
, &data
) ||
1893 !add_partial_dbt(&data
, dlen
, doff
) ||
1894 !checkTxnObj(txnobj
, &txn
) )
1900 if (-1 == _DB_put(self
, txn
, &key
, &data
, flags
)) {
1905 if (flags
& DB_APPEND
)
1906 retval
= PyInt_FromLong(*((db_recno_t
*)key
.data
));
1918 DB_remove(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1921 char* database
= NULL
;
1923 char* kwnames
[] = { "filename", "dbname", "flags", NULL
};
1925 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zi:remove", kwnames
,
1926 &filename
, &database
, &flags
))
1928 CHECK_DB_NOT_CLOSED(self
);
1930 err
= self
->db
->remove(self
->db
, filename
, database
, flags
);
1939 DB_rename(DBObject
* self
, PyObject
* args
)
1946 if (!PyArg_ParseTuple(args
, "sss|i:rename", &filename
, &database
, &newname
,
1949 CHECK_DB_NOT_CLOSED(self
);
1951 MYDB_BEGIN_ALLOW_THREADS
;
1952 err
= self
->db
->rename(self
->db
, filename
, database
, newname
, flags
);
1953 MYDB_END_ALLOW_THREADS
;
1960 DB_set_bt_minkey(DBObject
* self
, PyObject
* args
)
1964 if (!PyArg_ParseTuple(args
,"i:set_bt_minkey", &minkey
))
1966 CHECK_DB_NOT_CLOSED(self
);
1968 MYDB_BEGIN_ALLOW_THREADS
;
1969 err
= self
->db
->set_bt_minkey(self
->db
, minkey
);
1970 MYDB_END_ALLOW_THREADS
;
1977 DB_set_cachesize(DBObject
* self
, PyObject
* args
)
1980 int gbytes
= 0, bytes
= 0, ncache
= 0;
1982 if (!PyArg_ParseTuple(args
,"ii|i:set_cachesize",
1983 &gbytes
,&bytes
,&ncache
))
1985 CHECK_DB_NOT_CLOSED(self
);
1987 MYDB_BEGIN_ALLOW_THREADS
;
1988 err
= self
->db
->set_cachesize(self
->db
, gbytes
, bytes
, ncache
);
1989 MYDB_END_ALLOW_THREADS
;
1996 DB_set_flags(DBObject
* self
, PyObject
* args
)
2000 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
2002 CHECK_DB_NOT_CLOSED(self
);
2004 MYDB_BEGIN_ALLOW_THREADS
;
2005 err
= self
->db
->set_flags(self
->db
, flags
);
2006 MYDB_END_ALLOW_THREADS
;
2009 self
->setflags
|= flags
;
2015 DB_set_h_ffactor(DBObject
* self
, PyObject
* args
)
2019 if (!PyArg_ParseTuple(args
,"i:set_h_ffactor", &ffactor
))
2021 CHECK_DB_NOT_CLOSED(self
);
2023 MYDB_BEGIN_ALLOW_THREADS
;
2024 err
= self
->db
->set_h_ffactor(self
->db
, ffactor
);
2025 MYDB_END_ALLOW_THREADS
;
2032 DB_set_h_nelem(DBObject
* self
, PyObject
* args
)
2036 if (!PyArg_ParseTuple(args
,"i:set_h_nelem", &nelem
))
2038 CHECK_DB_NOT_CLOSED(self
);
2040 MYDB_BEGIN_ALLOW_THREADS
;
2041 err
= self
->db
->set_h_nelem(self
->db
, nelem
);
2042 MYDB_END_ALLOW_THREADS
;
2049 DB_set_lorder(DBObject
* self
, PyObject
* args
)
2053 if (!PyArg_ParseTuple(args
,"i:set_lorder", &lorder
))
2055 CHECK_DB_NOT_CLOSED(self
);
2057 MYDB_BEGIN_ALLOW_THREADS
;
2058 err
= self
->db
->set_lorder(self
->db
, lorder
);
2059 MYDB_END_ALLOW_THREADS
;
2066 DB_set_pagesize(DBObject
* self
, PyObject
* args
)
2070 if (!PyArg_ParseTuple(args
,"i:set_pagesize", &pagesize
))
2072 CHECK_DB_NOT_CLOSED(self
);
2074 MYDB_BEGIN_ALLOW_THREADS
;
2075 err
= self
->db
->set_pagesize(self
->db
, pagesize
);
2076 MYDB_END_ALLOW_THREADS
;
2083 DB_set_re_delim(DBObject
* self
, PyObject
* args
)
2088 if (!PyArg_ParseTuple(args
,"b:set_re_delim", &delim
)) {
2090 if (!PyArg_ParseTuple(args
,"c:set_re_delim", &delim
))
2094 CHECK_DB_NOT_CLOSED(self
);
2096 MYDB_BEGIN_ALLOW_THREADS
;
2097 err
= self
->db
->set_re_delim(self
->db
, delim
);
2098 MYDB_END_ALLOW_THREADS
;
2104 DB_set_re_len(DBObject
* self
, PyObject
* args
)
2108 if (!PyArg_ParseTuple(args
,"i:set_re_len", &len
))
2110 CHECK_DB_NOT_CLOSED(self
);
2112 MYDB_BEGIN_ALLOW_THREADS
;
2113 err
= self
->db
->set_re_len(self
->db
, len
);
2114 MYDB_END_ALLOW_THREADS
;
2121 DB_set_re_pad(DBObject
* self
, PyObject
* args
)
2126 if (!PyArg_ParseTuple(args
,"b:set_re_pad", &pad
)) {
2128 if (!PyArg_ParseTuple(args
,"c:set_re_pad", &pad
))
2131 CHECK_DB_NOT_CLOSED(self
);
2133 MYDB_BEGIN_ALLOW_THREADS
;
2134 err
= self
->db
->set_re_pad(self
->db
, pad
);
2135 MYDB_END_ALLOW_THREADS
;
2142 DB_set_re_source(DBObject
* self
, PyObject
* args
)
2147 if (!PyArg_ParseTuple(args
,"s:set_re_source", &re_source
))
2149 CHECK_DB_NOT_CLOSED(self
);
2151 MYDB_BEGIN_ALLOW_THREADS
;
2152 err
= self
->db
->set_re_source(self
->db
, re_source
);
2153 MYDB_END_ALLOW_THREADS
;
2161 DB_set_q_extentsize(DBObject
* self
, PyObject
* args
)
2166 if (!PyArg_ParseTuple(args
,"i:set_q_extentsize", &extentsize
))
2168 CHECK_DB_NOT_CLOSED(self
);
2170 MYDB_BEGIN_ALLOW_THREADS
;
2171 err
= self
->db
->set_q_extentsize(self
->db
, extentsize
);
2172 MYDB_END_ALLOW_THREADS
;
2179 DB_stat(DBObject
* self
, PyObject
* args
)
2181 int err
, flags
= 0, type
;
2186 if (!PyArg_ParseTuple(args
, "|i:stat", &flags
))
2188 CHECK_DB_NOT_CLOSED(self
);
2190 MYDB_BEGIN_ALLOW_THREADS
;
2192 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2194 err
= self
->db
->stat(self
->db
, &sp
, NULL
, flags
);
2196 MYDB_END_ALLOW_THREADS
;
2201 /* Turn the stat structure into a dictionary */
2202 type
= _DB_get_type(self
);
2203 if ((type
== -1) || ((d
= PyDict_New()) == NULL
)) {
2208 #define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
2209 #define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
2210 #define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
2214 MAKE_HASH_ENTRY(magic
);
2215 MAKE_HASH_ENTRY(version
);
2216 MAKE_HASH_ENTRY(nkeys
);
2217 MAKE_HASH_ENTRY(ndata
);
2218 MAKE_HASH_ENTRY(pagesize
);
2220 MAKE_HASH_ENTRY(nelem
);
2222 MAKE_HASH_ENTRY(ffactor
);
2223 MAKE_HASH_ENTRY(buckets
);
2224 MAKE_HASH_ENTRY(free
);
2225 MAKE_HASH_ENTRY(bfree
);
2226 MAKE_HASH_ENTRY(bigpages
);
2227 MAKE_HASH_ENTRY(big_bfree
);
2228 MAKE_HASH_ENTRY(overflows
);
2229 MAKE_HASH_ENTRY(ovfl_free
);
2230 MAKE_HASH_ENTRY(dup
);
2231 MAKE_HASH_ENTRY(dup_free
);
2236 MAKE_BT_ENTRY(magic
);
2237 MAKE_BT_ENTRY(version
);
2238 MAKE_BT_ENTRY(nkeys
);
2239 MAKE_BT_ENTRY(ndata
);
2240 MAKE_BT_ENTRY(pagesize
);
2241 MAKE_BT_ENTRY(minkey
);
2242 MAKE_BT_ENTRY(re_len
);
2243 MAKE_BT_ENTRY(re_pad
);
2244 MAKE_BT_ENTRY(levels
);
2245 MAKE_BT_ENTRY(int_pg
);
2246 MAKE_BT_ENTRY(leaf_pg
);
2247 MAKE_BT_ENTRY(dup_pg
);
2248 MAKE_BT_ENTRY(over_pg
);
2249 MAKE_BT_ENTRY(free
);
2250 MAKE_BT_ENTRY(int_pgfree
);
2251 MAKE_BT_ENTRY(leaf_pgfree
);
2252 MAKE_BT_ENTRY(dup_pgfree
);
2253 MAKE_BT_ENTRY(over_pgfree
);
2257 MAKE_QUEUE_ENTRY(magic
);
2258 MAKE_QUEUE_ENTRY(version
);
2259 MAKE_QUEUE_ENTRY(nkeys
);
2260 MAKE_QUEUE_ENTRY(ndata
);
2261 MAKE_QUEUE_ENTRY(pagesize
);
2262 MAKE_QUEUE_ENTRY(pages
);
2263 MAKE_QUEUE_ENTRY(re_len
);
2264 MAKE_QUEUE_ENTRY(re_pad
);
2265 MAKE_QUEUE_ENTRY(pgfree
);
2267 MAKE_QUEUE_ENTRY(start
);
2269 MAKE_QUEUE_ENTRY(first_recno
);
2270 MAKE_QUEUE_ENTRY(cur_recno
);
2274 PyErr_SetString(PyExc_TypeError
, "Unknown DB type, unable to stat");
2279 #undef MAKE_HASH_ENTRY
2280 #undef MAKE_BT_ENTRY
2281 #undef MAKE_QUEUE_ENTRY
2288 DB_sync(DBObject
* self
, PyObject
* args
)
2293 if (!PyArg_ParseTuple(args
,"|i:sync", &flags
))
2295 CHECK_DB_NOT_CLOSED(self
);
2297 MYDB_BEGIN_ALLOW_THREADS
;
2298 err
= self
->db
->sync(self
->db
, flags
);
2299 MYDB_END_ALLOW_THREADS
;
2307 DB_truncate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2311 PyObject
* txnobj
= NULL
;
2313 char* kwnames
[] = { "txn", "flags", NULL
};
2315 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
2318 CHECK_DB_NOT_CLOSED(self
);
2319 if (!checkTxnObj(txnobj
, &txn
))
2322 MYDB_BEGIN_ALLOW_THREADS
;
2323 err
= self
->db
->truncate(self
->db
, txn
, &count
, flags
);
2324 MYDB_END_ALLOW_THREADS
;
2326 return PyInt_FromLong(count
);
2332 DB_upgrade(DBObject
* self
, PyObject
* args
)
2337 if (!PyArg_ParseTuple(args
,"s|i:upgrade", &filename
, &flags
))
2339 CHECK_DB_NOT_CLOSED(self
);
2341 MYDB_BEGIN_ALLOW_THREADS
;
2342 err
= self
->db
->upgrade(self
->db
, filename
, flags
);
2343 MYDB_END_ALLOW_THREADS
;
2350 DB_verify(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2355 char* outFileName
=NULL
;
2357 char* kwnames
[] = { "filename", "dbname", "outfile", "flags", NULL
};
2359 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zzi:verify", kwnames
,
2360 &fileName
, &dbName
, &outFileName
, &flags
))
2363 CHECK_DB_NOT_CLOSED(self
);
2365 outFile
= fopen(outFileName
, "w");
2367 MYDB_BEGIN_ALLOW_THREADS
;
2368 err
= self
->db
->verify(self
->db
, fileName
, dbName
, outFile
, flags
);
2369 MYDB_END_ALLOW_THREADS
;
2373 /* DB.verify acts as a DB handle destructor (like close); this was
2374 * documented in BerkeleyDB 4.2 but had the undocumented effect
2375 * of not being safe in prior versions while still requiring an explicit
2376 * DB.close call afterwards. Lets call close for the user to emulate
2377 * the safe 4.2 behaviour. */
2379 self
->db
->close(self
->db
, 0);
2389 DB_set_get_returns_none(DBObject
* self
, PyObject
* args
)
2394 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
2396 CHECK_DB_NOT_CLOSED(self
);
2398 if (self
->moduleFlags
.getReturnsNone
)
2400 if (self
->moduleFlags
.cursorSetReturnsNone
)
2402 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
2403 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
2404 return PyInt_FromLong(oldValue
);
2409 DB_set_encrypt(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2413 char *passwd
= NULL
;
2414 char* kwnames
[] = { "passwd", "flags", NULL
};
2416 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
2421 MYDB_BEGIN_ALLOW_THREADS
;
2422 err
= self
->db
->set_encrypt(self
->db
, passwd
, flags
);
2423 MYDB_END_ALLOW_THREADS
;
2428 #endif /* DBVER >= 41 */
2431 /*-------------------------------------------------------------- */
2432 /* Mapping and Dictionary-like access routines */
2434 int DB_length(DBObject
* self
)
2441 if (self
->db
== NULL
) {
2442 PyErr_SetObject(DBError
,
2443 Py_BuildValue("(is)", 0, "DB object has been closed"));
2447 if (self
->haveStat
) { /* Has the stat function been called recently? If
2448 so, we can use the cached value. */
2449 flags
= DB_CACHED_COUNTS
;
2452 MYDB_BEGIN_ALLOW_THREADS
;
2454 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2456 err
= self
->db
->stat(self
->db
, &sp
, NULL
, flags
);
2458 MYDB_END_ALLOW_THREADS
;
2465 /* All the stat structures have matching fields upto the ndata field,
2466 so we can use any of them for the type cast */
2467 size
= ((DB_BTREE_STAT
*)sp
)->bt_ndata
;
2473 PyObject
* DB_subscript(DBObject
* self
, PyObject
* keyobj
)
2480 CHECK_DB_NOT_CLOSED(self
);
2481 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2485 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2486 /* Tell BerkeleyDB to malloc the return value (thread safe) */
2487 data
.flags
= DB_DBT_MALLOC
;
2489 MYDB_BEGIN_ALLOW_THREADS
;
2490 err
= self
->db
->get(self
->db
, NULL
, &key
, &data
, 0);
2491 MYDB_END_ALLOW_THREADS
;
2492 if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
2493 PyErr_SetObject(PyExc_KeyError
, keyobj
);
2496 else if (makeDBError(err
)) {
2500 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
2510 DB_ass_sub(DBObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
)
2516 if (self
->db
== NULL
) {
2517 PyErr_SetObject(DBError
,
2518 Py_BuildValue("(is)", 0, "DB object has been closed"));
2522 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2525 if (dataobj
!= NULL
) {
2526 if (!make_dbt(dataobj
, &data
))
2529 if (self
->setflags
& (DB_DUP
|DB_DUPSORT
))
2530 /* dictionaries shouldn't have duplicate keys */
2531 flags
= DB_NOOVERWRITE
;
2532 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2534 if ((retval
== -1) && (self
->setflags
& (DB_DUP
|DB_DUPSORT
))) {
2535 /* try deleting any old record that matches and then PUT it
2537 _DB_delete(self
, NULL
, &key
, 0);
2539 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2544 /* dataobj == NULL, so delete the key */
2545 retval
= _DB_delete(self
, NULL
, &key
, 0);
2553 DB_has_key(DBObject
* self
, PyObject
* args
)
2558 PyObject
* txnobj
= NULL
;
2561 if (!PyArg_ParseTuple(args
,"O|O:has_key", &keyobj
, &txnobj
))
2563 CHECK_DB_NOT_CLOSED(self
);
2564 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2566 if (!checkTxnObj(txnobj
, &txn
)) {
2571 /* This causes ENOMEM to be returned when the db has the key because
2572 it has a record but can't allocate a buffer for the data. This saves
2573 having to deal with data we won't be using.
2576 data
.flags
= DB_DBT_USERMEM
;
2578 MYDB_BEGIN_ALLOW_THREADS
;
2579 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, 0);
2580 MYDB_END_ALLOW_THREADS
;
2582 return PyInt_FromLong((err
== ENOMEM
) || (err
== 0));
2586 #define _KEYS_LIST 1
2587 #define _VALUES_LIST 2
2588 #define _ITEMS_LIST 3
2591 _DB_make_list(DBObject
* self
, DB_TXN
* txn
, int type
)
2598 PyObject
* item
= NULL
;
2600 CHECK_DB_NOT_CLOSED(self
);
2604 dbtype
= _DB_get_type(self
);
2608 list
= PyList_New(0);
2610 PyErr_SetString(PyExc_MemoryError
, "PyList_New failed");
2615 MYDB_BEGIN_ALLOW_THREADS
;
2616 err
= self
->db
->cursor(self
->db
, NULL
, &cursor
, 0);
2617 MYDB_END_ALLOW_THREADS
;
2620 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2621 key
.flags
= DB_DBT_REALLOC
;
2622 data
.flags
= DB_DBT_REALLOC
;
2625 while (1) { /* use the cursor to traverse the DB, collecting items */
2626 MYDB_BEGIN_ALLOW_THREADS
;
2627 err
= cursor
->c_get(cursor
, &key
, &data
, DB_NEXT
);
2628 MYDB_END_ALLOW_THREADS
;
2631 /* for any error, break out of the loop */
2641 item
= PyString_FromStringAndSize((char*)key
.data
, key
.size
);
2645 item
= PyInt_FromLong(*((db_recno_t
*)key
.data
));
2651 item
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
2659 item
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
2664 item
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
2665 data
.data
, data
.size
);
2672 PyErr_SetString(PyExc_MemoryError
, "List item creation failed");
2676 PyList_Append(list
, item
);
2680 /* DB_NOTFOUND is okay, it just means we got to the end */
2681 if (err
!= DB_NOTFOUND
&& makeDBError(err
)) {
2689 MYDB_BEGIN_ALLOW_THREADS
;
2690 cursor
->c_close(cursor
);
2691 MYDB_END_ALLOW_THREADS
;
2697 DB_keys(DBObject
* self
, PyObject
* args
)
2699 PyObject
* txnobj
= NULL
;
2702 if (!PyArg_ParseTuple(args
,"|O:keys", &txnobj
))
2704 if (!checkTxnObj(txnobj
, &txn
))
2706 return _DB_make_list(self
, txn
, _KEYS_LIST
);
2711 DB_items(DBObject
* self
, PyObject
* args
)
2713 PyObject
* txnobj
= NULL
;
2716 if (!PyArg_ParseTuple(args
,"|O:items", &txnobj
))
2718 if (!checkTxnObj(txnobj
, &txn
))
2720 return _DB_make_list(self
, txn
, _ITEMS_LIST
);
2725 DB_values(DBObject
* self
, PyObject
* args
)
2727 PyObject
* txnobj
= NULL
;
2730 if (!PyArg_ParseTuple(args
,"|O:values", &txnobj
))
2732 if (!checkTxnObj(txnobj
, &txn
))
2734 return _DB_make_list(self
, txn
, _VALUES_LIST
);
2737 /* --------------------------------------------------------------------- */
2738 /* DBCursor methods */
2742 DBC_close(DBCursorObject
* self
, PyObject
* args
)
2746 if (!PyArg_ParseTuple(args
, ":close"))
2749 if (self
->dbc
!= NULL
) {
2750 MYDB_BEGIN_ALLOW_THREADS
;
2751 err
= self
->dbc
->c_close(self
->dbc
);
2753 MYDB_END_ALLOW_THREADS
;
2761 DBC_count(DBCursorObject
* self
, PyObject
* args
)
2767 if (!PyArg_ParseTuple(args
, "|i:count", &flags
))
2770 CHECK_CURSOR_NOT_CLOSED(self
);
2772 MYDB_BEGIN_ALLOW_THREADS
;
2773 err
= self
->dbc
->c_count(self
->dbc
, &count
, flags
);
2774 MYDB_END_ALLOW_THREADS
;
2777 return PyInt_FromLong(count
);
2782 DBC_current(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2784 return _DBCursor_get(self
,DB_CURRENT
,args
,kwargs
,"|iii:current");
2789 DBC_delete(DBCursorObject
* self
, PyObject
* args
)
2793 if (!PyArg_ParseTuple(args
, "|i:delete", &flags
))
2796 CHECK_CURSOR_NOT_CLOSED(self
);
2798 MYDB_BEGIN_ALLOW_THREADS
;
2799 err
= self
->dbc
->c_del(self
->dbc
, flags
);
2800 MYDB_END_ALLOW_THREADS
;
2803 self
->mydb
->haveStat
= 0;
2809 DBC_dup(DBCursorObject
* self
, PyObject
* args
)
2814 if (!PyArg_ParseTuple(args
, "|i:dup", &flags
))
2817 CHECK_CURSOR_NOT_CLOSED(self
);
2819 MYDB_BEGIN_ALLOW_THREADS
;
2820 err
= self
->dbc
->c_dup(self
->dbc
, &dbc
, flags
);
2821 MYDB_END_ALLOW_THREADS
;
2824 return (PyObject
*) newDBCursorObject(dbc
, self
->mydb
);
2828 DBC_first(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2830 return _DBCursor_get(self
,DB_FIRST
,args
,kwargs
,"|iii:first");
2835 DBC_get(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2838 PyObject
* keyobj
= NULL
;
2839 PyObject
* dataobj
= NULL
;
2840 PyObject
* retval
= NULL
;
2844 char* kwnames
[] = { "key","data", "flags", "dlen", "doff", NULL
};
2848 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:get", &kwnames
[2],
2849 &flags
, &dlen
, &doff
))
2852 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:get",
2854 &keyobj
, &flags
, &dlen
, &doff
))
2857 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:get",
2858 kwnames
, &keyobj
, &dataobj
,
2859 &flags
, &dlen
, &doff
))
2866 CHECK_CURSOR_NOT_CLOSED(self
);
2868 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
2870 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
2871 (!add_partial_dbt(&data
, dlen
, doff
)) )
2877 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
2878 data
.flags
= DB_DBT_MALLOC
;
2879 if (!(key
.flags
& DB_DBT_REALLOC
)) {
2880 key
.flags
|= DB_DBT_MALLOC
;
2884 MYDB_BEGIN_ALLOW_THREADS
;
2885 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
2886 MYDB_END_ALLOW_THREADS
;
2888 if ((err
== DB_NOTFOUND
) && self
->mydb
->moduleFlags
.getReturnsNone
) {
2892 else if (makeDBError(err
)) {
2896 switch (_DB_get_type(self
->mydb
)) {
2903 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
2904 data
.data
, data
.size
);
2908 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
2909 data
.data
, data
.size
);
2919 DBC_pget(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2922 PyObject
* keyobj
= NULL
;
2923 PyObject
* dataobj
= NULL
;
2924 PyObject
* retval
= NULL
;
2927 DBT key
, pkey
, data
;
2928 char* kwnames
[] = { "key","data", "flags", "dlen", "doff", NULL
};
2932 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:pget", &kwnames
[2],
2933 &flags
, &dlen
, &doff
))
2936 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:pget",
2938 &keyobj
, &flags
, &dlen
, &doff
))
2941 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:pget",
2942 kwnames
, &keyobj
, &dataobj
,
2943 &flags
, &dlen
, &doff
))
2950 CHECK_CURSOR_NOT_CLOSED(self
);
2952 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
2954 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
2955 (!add_partial_dbt(&data
, dlen
, doff
)) ) {
2960 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
2961 data
.flags
= DB_DBT_MALLOC
;
2962 if (!(key
.flags
& DB_DBT_REALLOC
)) {
2963 key
.flags
|= DB_DBT_MALLOC
;
2968 pkey
.flags
= DB_DBT_MALLOC
;
2970 MYDB_BEGIN_ALLOW_THREADS
;
2971 err
= self
->dbc
->c_pget(self
->dbc
, &key
, &pkey
, &data
, flags
);
2972 MYDB_END_ALLOW_THREADS
;
2974 if ((err
== DB_NOTFOUND
) && self
->mydb
->moduleFlags
.getReturnsNone
) {
2978 else if (makeDBError(err
)) {
2984 dataObj
= PyString_FromStringAndSize(data
.data
, data
.size
);
2986 if (self
->mydb
->primaryDBType
== DB_RECNO
||
2987 self
->mydb
->primaryDBType
== DB_QUEUE
)
2988 pkeyObj
= PyInt_FromLong(*(long *)pkey
.data
);
2990 pkeyObj
= PyString_FromStringAndSize(pkey
.data
, pkey
.size
);
2992 if (flags
& DB_SET_RECNO
) /* return key, pkey and data */
2995 int type
= _DB_get_type(self
->mydb
);
2996 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
2997 keyObj
= PyInt_FromLong(*(long *)key
.data
);
2999 keyObj
= PyString_FromStringAndSize(key
.data
, key
.size
);
3000 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
3003 else /* return just the pkey and data */
3005 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
3010 /* the only time REALLOC should be set is if we used an integer
3011 * key that make_key_dbt malloc'd for us. always free these. */
3012 if (key
.flags
& DB_DBT_REALLOC
) {
3020 DBC_get_recno(DBCursorObject
* self
, PyObject
* args
)
3027 if (!PyArg_ParseTuple(args
, ":get_recno"))
3030 CHECK_CURSOR_NOT_CLOSED(self
);
3034 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3035 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3036 data
.flags
= DB_DBT_MALLOC
;
3037 key
.flags
= DB_DBT_MALLOC
;
3040 MYDB_BEGIN_ALLOW_THREADS
;
3041 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, DB_GET_RECNO
);
3042 MYDB_END_ALLOW_THREADS
;
3045 recno
= *((db_recno_t
*)data
.data
);
3048 return PyInt_FromLong(recno
);
3053 DBC_last(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3055 return _DBCursor_get(self
,DB_LAST
,args
,kwargs
,"|iii:last");
3060 DBC_next(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3062 return _DBCursor_get(self
,DB_NEXT
,args
,kwargs
,"|iii:next");
3067 DBC_prev(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3069 return _DBCursor_get(self
,DB_PREV
,args
,kwargs
,"|iii:prev");
3074 DBC_put(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3077 PyObject
* keyobj
, *dataobj
;
3079 char* kwnames
[] = { "key", "data", "flags", "dlen", "doff", NULL
};
3083 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iii:put", kwnames
,
3084 &keyobj
, &dataobj
, &flags
, &dlen
, &doff
))
3087 CHECK_CURSOR_NOT_CLOSED(self
);
3089 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3091 if (!make_dbt(dataobj
, &data
) ||
3092 !add_partial_dbt(&data
, dlen
, doff
) )
3098 MYDB_BEGIN_ALLOW_THREADS
;
3099 err
= self
->dbc
->c_put(self
->dbc
, &key
, &data
, flags
);
3100 MYDB_END_ALLOW_THREADS
;
3103 self
->mydb
->haveStat
= 0;
3109 DBC_set(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3113 PyObject
* retval
, *keyobj
;
3114 char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
3118 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set", kwnames
,
3119 &keyobj
, &flags
, &dlen
, &doff
))
3122 CHECK_CURSOR_NOT_CLOSED(self
);
3124 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3128 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3129 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3130 data
.flags
= DB_DBT_MALLOC
;
3132 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3137 MYDB_BEGIN_ALLOW_THREADS
;
3138 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET
);
3139 MYDB_END_ALLOW_THREADS
;
3140 if ((err
== DB_NOTFOUND
) && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3144 else if (makeDBError(err
)) {
3148 switch (_DB_get_type(self
->mydb
)) {
3155 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3156 data
.data
, data
.size
);
3160 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3161 data
.data
, data
.size
);
3167 /* the only time REALLOC should be set is if we used an integer
3168 * key that make_key_dbt malloc'd for us. always free these. */
3169 if (key
.flags
& DB_DBT_REALLOC
) {
3178 DBC_set_range(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3182 PyObject
* retval
, *keyobj
;
3183 char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
3187 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set_range", kwnames
,
3188 &keyobj
, &flags
, &dlen
, &doff
))
3191 CHECK_CURSOR_NOT_CLOSED(self
);
3193 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3197 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3201 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3202 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3203 data
.flags
|= DB_DBT_MALLOC
;
3204 /* only BTREE databases will return anything in the key */
3205 if (!(key
.flags
& DB_DBT_REALLOC
) && _DB_get_type(self
->mydb
) == DB_BTREE
) {
3206 key
.flags
|= DB_DBT_MALLOC
;
3209 MYDB_BEGIN_ALLOW_THREADS
;
3210 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RANGE
);
3211 MYDB_END_ALLOW_THREADS
;
3212 if ((err
== DB_NOTFOUND
) && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3216 else if (makeDBError(err
)) {
3220 switch (_DB_get_type(self
->mydb
)) {
3227 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3228 data
.data
, data
.size
);
3232 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3233 data
.data
, data
.size
);
3239 /* the only time REALLOC should be set is if we used an integer
3240 * key that make_key_dbt malloc'd for us. always free these. */
3241 if (key
.flags
& DB_DBT_REALLOC
) {
3249 _DBC_get_set_both(DBCursorObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
,
3250 int flags
, unsigned int returnsNone
)
3256 /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
3257 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3259 if (!make_dbt(dataobj
, &data
)) {
3264 MYDB_BEGIN_ALLOW_THREADS
;
3265 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_GET_BOTH
);
3266 MYDB_END_ALLOW_THREADS
;
3267 if ((err
== DB_NOTFOUND
) && returnsNone
) {
3271 else if (makeDBError(err
)) {
3275 switch (_DB_get_type(self
->mydb
)) {
3282 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3283 data
.data
, data
.size
);
3287 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3288 data
.data
, data
.size
);
3298 DBC_get_both(DBCursorObject
* self
, PyObject
* args
)
3301 PyObject
*keyobj
, *dataobj
;
3303 if (!PyArg_ParseTuple(args
, "OO|i:get_both", &keyobj
, &dataobj
, &flags
))
3306 /* if the cursor is closed, self->mydb may be invalid */
3307 CHECK_CURSOR_NOT_CLOSED(self
);
3309 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3310 self
->mydb
->moduleFlags
.getReturnsNone
);
3313 /* Return size of entry */
3315 DBC_get_current_size(DBCursorObject
* self
, PyObject
* args
)
3317 int err
, flags
=DB_CURRENT
;
3318 PyObject
* retval
= NULL
;
3321 if (!PyArg_ParseTuple(args
, ":get_current_size"))
3323 CHECK_CURSOR_NOT_CLOSED(self
);
3327 /* We don't allocate any memory, forcing a ENOMEM error and thus
3328 getting the record size. */
3329 data
.flags
= DB_DBT_USERMEM
;
3331 MYDB_BEGIN_ALLOW_THREADS
;
3332 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
3333 MYDB_END_ALLOW_THREADS
;
3334 if (err
== ENOMEM
|| !err
) {
3335 /* ENOMEM means positive size, !err means zero length value */
3336 retval
= PyInt_FromLong((long)data
.size
);
3347 DBC_set_both(DBCursorObject
* self
, PyObject
* args
)
3350 PyObject
*keyobj
, *dataobj
;
3352 if (!PyArg_ParseTuple(args
, "OO|i:set_both", &keyobj
, &dataobj
, &flags
))
3355 /* if the cursor is closed, self->mydb may be invalid */
3356 CHECK_CURSOR_NOT_CLOSED(self
);
3358 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3359 self
->mydb
->moduleFlags
.cursorSetReturnsNone
);
3364 DBC_set_recno(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3366 int err
, irecno
, flags
=0;
3372 char* kwnames
[] = { "recno","flags", "dlen", "doff", NULL
};
3374 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|iii:set_recno", kwnames
,
3375 &irecno
, &flags
, &dlen
, &doff
))
3378 CHECK_CURSOR_NOT_CLOSED(self
);
3381 recno
= (db_recno_t
) irecno
;
3382 /* use allocated space so DB will be able to realloc room for the real
3384 key
.data
= malloc(sizeof(db_recno_t
));
3385 if (key
.data
== NULL
) {
3386 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
3389 key
.size
= sizeof(db_recno_t
);
3390 key
.ulen
= key
.size
;
3391 memcpy(key
.data
, &recno
, sizeof(db_recno_t
));
3392 key
.flags
= DB_DBT_REALLOC
;
3395 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3396 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3397 data
.flags
= DB_DBT_MALLOC
;
3399 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3404 MYDB_BEGIN_ALLOW_THREADS
;
3405 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RECNO
);
3406 MYDB_END_ALLOW_THREADS
;
3407 if ((err
== DB_NOTFOUND
) && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3411 else if (makeDBError(err
)) {
3414 else { /* Can only be used for BTrees, so no need to return int key */
3415 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3416 data
.data
, data
.size
);
3426 DBC_consume(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3428 return _DBCursor_get(self
,DB_CONSUME
,args
,kwargs
,"|iii:consume");
3433 DBC_next_dup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3435 return _DBCursor_get(self
,DB_NEXT_DUP
,args
,kwargs
,"|iii:next_dup");
3440 DBC_next_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3442 return _DBCursor_get(self
,DB_NEXT_NODUP
,args
,kwargs
,"|iii:next_nodup");
3447 DBC_prev_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3449 return _DBCursor_get(self
,DB_PREV_NODUP
,args
,kwargs
,"|iii:prev_nodup");
3454 DBC_join_item(DBCursorObject
* self
, PyObject
* args
)
3460 if (!PyArg_ParseTuple(args
, "|i:join_item", &flags
))
3463 CHECK_CURSOR_NOT_CLOSED(self
);
3467 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3468 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3469 key
.flags
= DB_DBT_MALLOC
;
3472 MYDB_BEGIN_ALLOW_THREADS
;
3473 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
| DB_JOIN_ITEM
);
3474 MYDB_END_ALLOW_THREADS
;
3475 if ((err
== DB_NOTFOUND
) && self
->mydb
->moduleFlags
.getReturnsNone
) {
3479 else if (makeDBError(err
)) {
3483 retval
= Py_BuildValue("s#", key
.data
, key
.size
);
3492 /* --------------------------------------------------------------------- */
3497 DBEnv_close(DBEnvObject
* self
, PyObject
* args
)
3501 if (!PyArg_ParseTuple(args
, "|i:close", &flags
))
3503 if (!self
->closed
) { /* Don't close more than once */
3504 MYDB_BEGIN_ALLOW_THREADS
;
3505 err
= self
->db_env
->close(self
->db_env
, flags
);
3506 MYDB_END_ALLOW_THREADS
;
3507 /* after calling DBEnv->close, regardless of error, this DBEnv
3508 * may not be accessed again (BerkeleyDB docs). */
3510 self
->db_env
= NULL
;
3518 DBEnv_open(DBEnvObject
* self
, PyObject
* args
)
3520 int err
, flags
=0, mode
=0660;
3523 if (!PyArg_ParseTuple(args
, "z|ii:open", &db_home
, &flags
, &mode
))
3526 CHECK_ENV_NOT_CLOSED(self
);
3528 MYDB_BEGIN_ALLOW_THREADS
;
3529 err
= self
->db_env
->open(self
->db_env
, db_home
, flags
, mode
);
3530 MYDB_END_ALLOW_THREADS
;
3533 self
->flags
= flags
;
3539 DBEnv_remove(DBEnvObject
* self
, PyObject
* args
)
3544 if (!PyArg_ParseTuple(args
, "s|i:remove", &db_home
, &flags
))
3546 CHECK_ENV_NOT_CLOSED(self
);
3547 MYDB_BEGIN_ALLOW_THREADS
;
3548 err
= self
->db_env
->remove(self
->db_env
, db_home
, flags
);
3549 MYDB_END_ALLOW_THREADS
;
3556 DBEnv_dbremove(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3561 char *database
= NULL
;
3562 PyObject
*txnobj
= NULL
;
3564 char* kwnames
[] = { "file", "database", "txn", "flags", NULL
};
3566 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ss|Oi:dbremove", kwnames
,
3567 &file
, &database
, &txnobj
, &flags
)) {
3570 if (!checkTxnObj(txnobj
, &txn
)) {
3573 CHECK_ENV_NOT_CLOSED(self
);
3574 MYDB_BEGIN_ALLOW_THREADS
;
3575 err
= self
->db_env
->dbremove(self
->db_env
, txn
, file
, database
, flags
);
3576 MYDB_END_ALLOW_THREADS
;
3582 DBEnv_dbrename(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3587 char *database
= NULL
;
3588 char *newname
= NULL
;
3589 PyObject
*txnobj
= NULL
;
3591 char* kwnames
[] = { "file", "database", "newname", "txn", "flags", NULL
};
3593 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "sss|Oi:dbrename", kwnames
,
3594 &file
, &database
, &newname
, &txnobj
, &flags
)) {
3597 if (!checkTxnObj(txnobj
, &txn
)) {
3600 CHECK_ENV_NOT_CLOSED(self
);
3601 MYDB_BEGIN_ALLOW_THREADS
;
3602 err
= self
->db_env
->dbrename(self
->db_env
, txn
, file
, database
, newname
,
3604 MYDB_END_ALLOW_THREADS
;
3610 DBEnv_set_encrypt(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3614 char *passwd
= NULL
;
3615 char* kwnames
[] = { "passwd", "flags", NULL
};
3617 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
3622 MYDB_BEGIN_ALLOW_THREADS
;
3623 err
= self
->db_env
->set_encrypt(self
->db_env
, passwd
, flags
);
3624 MYDB_END_ALLOW_THREADS
;
3629 #endif /* DBVER >= 41 */
3633 DBEnv_set_timeout(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3637 u_int32_t timeout
= 0;
3638 char* kwnames
[] = { "timeout", "flags", NULL
};
3640 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ii:set_timeout", kwnames
,
3641 &timeout
, &flags
)) {
3645 MYDB_BEGIN_ALLOW_THREADS
;
3646 err
= self
->db_env
->set_timeout(self
->db_env
, (db_timeout_t
)timeout
, flags
);
3647 MYDB_END_ALLOW_THREADS
;
3652 #endif /* DBVER >= 40 */
3655 DBEnv_set_shm_key(DBEnvObject
* self
, PyObject
* args
)
3660 if (!PyArg_ParseTuple(args
, "l:set_shm_key", &shm_key
))
3662 CHECK_ENV_NOT_CLOSED(self
);
3664 err
= self
->db_env
->set_shm_key(self
->db_env
, shm_key
);
3670 DBEnv_set_cachesize(DBEnvObject
* self
, PyObject
* args
)
3672 int err
, gbytes
=0, bytes
=0, ncache
=0;
3674 if (!PyArg_ParseTuple(args
, "ii|i:set_cachesize",
3675 &gbytes
, &bytes
, &ncache
))
3677 CHECK_ENV_NOT_CLOSED(self
);
3679 MYDB_BEGIN_ALLOW_THREADS
;
3680 err
= self
->db_env
->set_cachesize(self
->db_env
, gbytes
, bytes
, ncache
);
3681 MYDB_END_ALLOW_THREADS
;
3689 DBEnv_set_flags(DBEnvObject
* self
, PyObject
* args
)
3691 int err
, flags
=0, onoff
=0;
3693 if (!PyArg_ParseTuple(args
, "ii:set_flags",
3696 CHECK_ENV_NOT_CLOSED(self
);
3698 MYDB_BEGIN_ALLOW_THREADS
;
3699 err
= self
->db_env
->set_flags(self
->db_env
, flags
, onoff
);
3700 MYDB_END_ALLOW_THREADS
;
3708 DBEnv_set_data_dir(DBEnvObject
* self
, PyObject
* args
)
3713 if (!PyArg_ParseTuple(args
, "s:set_data_dir", &dir
))
3715 CHECK_ENV_NOT_CLOSED(self
);
3717 MYDB_BEGIN_ALLOW_THREADS
;
3718 err
= self
->db_env
->set_data_dir(self
->db_env
, dir
);
3719 MYDB_END_ALLOW_THREADS
;
3726 DBEnv_set_lg_bsize(DBEnvObject
* self
, PyObject
* args
)
3730 if (!PyArg_ParseTuple(args
, "i:set_lg_bsize", &lg_bsize
))
3732 CHECK_ENV_NOT_CLOSED(self
);
3734 MYDB_BEGIN_ALLOW_THREADS
;
3735 err
= self
->db_env
->set_lg_bsize(self
->db_env
, lg_bsize
);
3736 MYDB_END_ALLOW_THREADS
;
3743 DBEnv_set_lg_dir(DBEnvObject
* self
, PyObject
* args
)
3748 if (!PyArg_ParseTuple(args
, "s:set_lg_dir", &dir
))
3750 CHECK_ENV_NOT_CLOSED(self
);
3752 MYDB_BEGIN_ALLOW_THREADS
;
3753 err
= self
->db_env
->set_lg_dir(self
->db_env
, dir
);
3754 MYDB_END_ALLOW_THREADS
;
3760 DBEnv_set_lg_max(DBEnvObject
* self
, PyObject
* args
)
3764 if (!PyArg_ParseTuple(args
, "i:set_lg_max", &lg_max
))
3766 CHECK_ENV_NOT_CLOSED(self
);
3768 MYDB_BEGIN_ALLOW_THREADS
;
3769 err
= self
->db_env
->set_lg_max(self
->db_env
, lg_max
);
3770 MYDB_END_ALLOW_THREADS
;
3777 DBEnv_set_lk_detect(DBEnvObject
* self
, PyObject
* args
)
3781 if (!PyArg_ParseTuple(args
, "i:set_lk_detect", &lk_detect
))
3783 CHECK_ENV_NOT_CLOSED(self
);
3785 MYDB_BEGIN_ALLOW_THREADS
;
3786 err
= self
->db_env
->set_lk_detect(self
->db_env
, lk_detect
);
3787 MYDB_END_ALLOW_THREADS
;
3794 DBEnv_set_lk_max(DBEnvObject
* self
, PyObject
* args
)
3798 if (!PyArg_ParseTuple(args
, "i:set_lk_max", &max
))
3800 CHECK_ENV_NOT_CLOSED(self
);
3802 MYDB_BEGIN_ALLOW_THREADS
;
3803 err
= self
->db_env
->set_lk_max(self
->db_env
, max
);
3804 MYDB_END_ALLOW_THREADS
;
3813 DBEnv_set_lk_max_locks(DBEnvObject
* self
, PyObject
* args
)
3817 if (!PyArg_ParseTuple(args
, "i:set_lk_max_locks", &max
))
3819 CHECK_ENV_NOT_CLOSED(self
);
3821 MYDB_BEGIN_ALLOW_THREADS
;
3822 err
= self
->db_env
->set_lk_max_locks(self
->db_env
, max
);
3823 MYDB_END_ALLOW_THREADS
;
3830 DBEnv_set_lk_max_lockers(DBEnvObject
* self
, PyObject
* args
)
3834 if (!PyArg_ParseTuple(args
, "i:set_lk_max_lockers", &max
))
3836 CHECK_ENV_NOT_CLOSED(self
);
3838 MYDB_BEGIN_ALLOW_THREADS
;
3839 err
= self
->db_env
->set_lk_max_lockers(self
->db_env
, max
);
3840 MYDB_END_ALLOW_THREADS
;
3847 DBEnv_set_lk_max_objects(DBEnvObject
* self
, PyObject
* args
)
3851 if (!PyArg_ParseTuple(args
, "i:set_lk_max_objects", &max
))
3853 CHECK_ENV_NOT_CLOSED(self
);
3855 MYDB_BEGIN_ALLOW_THREADS
;
3856 err
= self
->db_env
->set_lk_max_objects(self
->db_env
, max
);
3857 MYDB_END_ALLOW_THREADS
;
3866 DBEnv_set_mp_mmapsize(DBEnvObject
* self
, PyObject
* args
)
3868 int err
, mp_mmapsize
;
3870 if (!PyArg_ParseTuple(args
, "i:set_mp_mmapsize", &mp_mmapsize
))
3872 CHECK_ENV_NOT_CLOSED(self
);
3874 MYDB_BEGIN_ALLOW_THREADS
;
3875 err
= self
->db_env
->set_mp_mmapsize(self
->db_env
, mp_mmapsize
);
3876 MYDB_END_ALLOW_THREADS
;
3883 DBEnv_set_tmp_dir(DBEnvObject
* self
, PyObject
* args
)
3888 if (!PyArg_ParseTuple(args
, "s:set_tmp_dir", &dir
))
3890 CHECK_ENV_NOT_CLOSED(self
);
3892 MYDB_BEGIN_ALLOW_THREADS
;
3893 err
= self
->db_env
->set_tmp_dir(self
->db_env
, dir
);
3894 MYDB_END_ALLOW_THREADS
;
3901 DBEnv_txn_begin(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3904 PyObject
* txnobj
= NULL
;
3906 char* kwnames
[] = { "parent", "flags", NULL
};
3908 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:txn_begin", kwnames
,
3912 if (!checkTxnObj(txnobj
, &txn
))
3914 CHECK_ENV_NOT_CLOSED(self
);
3916 return (PyObject
*)newDBTxnObject(self
, txn
, flags
);
3921 DBEnv_txn_checkpoint(DBEnvObject
* self
, PyObject
* args
)
3923 int err
, kbyte
=0, min
=0, flags
=0;
3925 if (!PyArg_ParseTuple(args
, "|iii:txn_checkpoint", &kbyte
, &min
, &flags
))
3927 CHECK_ENV_NOT_CLOSED(self
);
3929 MYDB_BEGIN_ALLOW_THREADS
;
3931 err
= self
->db_env
->txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
3933 err
= txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
3935 MYDB_END_ALLOW_THREADS
;
3942 DBEnv_set_tx_max(DBEnvObject
* self
, PyObject
* args
)
3946 if (!PyArg_ParseTuple(args
, "i:set_tx_max", &max
))
3948 CHECK_ENV_NOT_CLOSED(self
);
3950 MYDB_BEGIN_ALLOW_THREADS
;
3951 err
= self
->db_env
->set_tx_max(self
->db_env
, max
);
3952 MYDB_END_ALLOW_THREADS
;
3959 DBEnv_lock_detect(DBEnvObject
* self
, PyObject
* args
)
3961 int err
, atype
, flags
=0;
3964 if (!PyArg_ParseTuple(args
, "i|i:lock_detect", &atype
, &flags
))
3966 CHECK_ENV_NOT_CLOSED(self
);
3968 MYDB_BEGIN_ALLOW_THREADS
;
3970 err
= self
->db_env
->lock_detect(self
->db_env
, flags
, atype
, &aborted
);
3972 err
= lock_detect(self
->db_env
, flags
, atype
, &aborted
);
3974 MYDB_END_ALLOW_THREADS
;
3976 return PyInt_FromLong(aborted
);
3981 DBEnv_lock_get(DBEnvObject
* self
, PyObject
* args
)
3984 int locker
, lock_mode
;
3988 if (!PyArg_ParseTuple(args
, "iOi|i:lock_get", &locker
, &objobj
, &lock_mode
, &flags
))
3992 if (!make_dbt(objobj
, &obj
))
3995 return (PyObject
*)newDBLockObject(self
, locker
, &obj
, lock_mode
, flags
);
4000 DBEnv_lock_id(DBEnvObject
* self
, PyObject
* args
)
4005 if (!PyArg_ParseTuple(args
, ":lock_id"))
4008 CHECK_ENV_NOT_CLOSED(self
);
4009 MYDB_BEGIN_ALLOW_THREADS
;
4011 err
= self
->db_env
->lock_id(self
->db_env
, &theID
);
4013 err
= lock_id(self
->db_env
, &theID
);
4015 MYDB_END_ALLOW_THREADS
;
4018 return PyInt_FromLong((long)theID
);
4023 DBEnv_lock_put(DBEnvObject
* self
, PyObject
* args
)
4026 DBLockObject
* dblockobj
;
4028 if (!PyArg_ParseTuple(args
, "O!:lock_put", &DBLock_Type
, &dblockobj
))
4031 CHECK_ENV_NOT_CLOSED(self
);
4032 MYDB_BEGIN_ALLOW_THREADS
;
4034 err
= self
->db_env
->lock_put(self
->db_env
, &dblockobj
->lock
);
4036 err
= lock_put(self
->db_env
, &dblockobj
->lock
);
4038 MYDB_END_ALLOW_THREADS
;
4045 DBEnv_lock_stat(DBEnvObject
* self
, PyObject
* args
)
4050 u_int32_t flags
= 0;
4052 if (!PyArg_ParseTuple(args
, "|i:lock_stat", &flags
))
4054 CHECK_ENV_NOT_CLOSED(self
);
4056 MYDB_BEGIN_ALLOW_THREADS
;
4058 err
= self
->db_env
->lock_stat(self
->db_env
, &sp
, flags
);
4061 err
= lock_stat(self
->db_env
, &sp
);
4063 err
= lock_stat(self
->db_env
, &sp
, NULL
);
4066 MYDB_END_ALLOW_THREADS
;
4069 /* Turn the stat structure into a dictionary */
4076 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4083 MAKE_ENTRY(maxlocks
);
4084 MAKE_ENTRY(maxlockers
);
4085 MAKE_ENTRY(maxobjects
);
4087 MAKE_ENTRY(maxnlocks
);
4089 MAKE_ENTRY(nlockers
);
4090 MAKE_ENTRY(maxnlockers
);
4092 MAKE_ENTRY(nobjects
);
4093 MAKE_ENTRY(maxnobjects
);
4095 MAKE_ENTRY(nrequests
);
4096 MAKE_ENTRY(nreleases
);
4097 MAKE_ENTRY(nnowaits
);
4098 MAKE_ENTRY(nconflicts
);
4099 MAKE_ENTRY(ndeadlocks
);
4100 MAKE_ENTRY(regsize
);
4101 MAKE_ENTRY(region_wait
);
4102 MAKE_ENTRY(region_nowait
);
4111 DBEnv_log_archive(DBEnvObject
* self
, PyObject
* args
)
4115 char **log_list_start
, **log_list
;
4117 PyObject
* item
= NULL
;
4119 if (!PyArg_ParseTuple(args
, "|i:log_archive", &flags
))
4122 CHECK_ENV_NOT_CLOSED(self
);
4123 MYDB_BEGIN_ALLOW_THREADS
;
4125 err
= self
->db_env
->log_archive(self
->db_env
, &log_list
, flags
);
4127 err
= log_archive(self
->db_env
, &log_list
, flags
);
4129 err
= log_archive(self
->db_env
, &log_list
, flags
, NULL
);
4131 MYDB_END_ALLOW_THREADS
;
4134 list
= PyList_New(0);
4136 PyErr_SetString(PyExc_MemoryError
, "PyList_New failed");
4141 for (log_list_start
= log_list
; *log_list
!= NULL
; ++log_list
) {
4142 item
= PyString_FromString (*log_list
);
4145 PyErr_SetString(PyExc_MemoryError
,
4146 "List item creation failed");
4150 PyList_Append(list
, item
);
4153 free(log_list_start
);
4160 DBEnv_txn_stat(DBEnvObject
* self
, PyObject
* args
)
4167 if (!PyArg_ParseTuple(args
, "|i:txn_stat", &flags
))
4169 CHECK_ENV_NOT_CLOSED(self
);
4171 MYDB_BEGIN_ALLOW_THREADS
;
4173 err
= self
->db_env
->txn_stat(self
->db_env
, &sp
, flags
);
4175 err
= txn_stat(self
->db_env
, &sp
);
4177 err
= txn_stat(self
->db_env
, &sp
, NULL
);
4179 MYDB_END_ALLOW_THREADS
;
4182 /* Turn the stat structure into a dictionary */
4189 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4191 MAKE_ENTRY(time_ckp
);
4192 MAKE_ENTRY(last_txnid
);
4193 MAKE_ENTRY(maxtxns
);
4194 MAKE_ENTRY(nactive
);
4195 MAKE_ENTRY(maxnactive
);
4196 MAKE_ENTRY(nbegins
);
4197 MAKE_ENTRY(naborts
);
4198 MAKE_ENTRY(ncommits
);
4199 MAKE_ENTRY(regsize
);
4200 MAKE_ENTRY(region_wait
);
4201 MAKE_ENTRY(region_nowait
);
4210 DBEnv_set_get_returns_none(DBEnvObject
* self
, PyObject
* args
)
4215 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
4217 CHECK_ENV_NOT_CLOSED(self
);
4219 if (self
->moduleFlags
.getReturnsNone
)
4221 if (self
->moduleFlags
.cursorSetReturnsNone
)
4223 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
4224 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
4225 return PyInt_FromLong(oldValue
);
4229 /* --------------------------------------------------------------------- */
4234 DBTxn_commit(DBTxnObject
* self
, PyObject
* args
)
4239 if (!PyArg_ParseTuple(args
, "|i:commit", &flags
))
4243 PyErr_SetObject(DBError
, Py_BuildValue("(is)", 0,
4244 "DBTxn must not be used after txn_commit or txn_abort"));
4248 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
4249 MYDB_BEGIN_ALLOW_THREADS
;
4251 err
= txn
->commit(txn
, flags
);
4253 err
= txn_commit(txn
, flags
);
4255 MYDB_END_ALLOW_THREADS
;
4261 DBTxn_prepare(DBTxnObject
* self
, PyObject
* args
)
4268 if (!PyArg_ParseTuple(args
, "s#:prepare", &gid
, &gid_size
))
4271 if (gid_size
!= DB_XIDDATASIZE
) {
4272 PyErr_SetString(PyExc_TypeError
,
4273 "gid must be DB_XIDDATASIZE bytes long");
4278 PyErr_SetObject(DBError
, Py_BuildValue("(is)", 0,
4279 "DBTxn must not be used after txn_commit or txn_abort"));
4282 MYDB_BEGIN_ALLOW_THREADS
;
4284 err
= self
->txn
->prepare(self
->txn
, (u_int8_t
*)gid
);
4286 err
= txn_prepare(self
->txn
, (u_int8_t
*)gid
);
4288 MYDB_END_ALLOW_THREADS
;
4294 if (!PyArg_ParseTuple(args
, ":prepare"))
4298 PyErr_SetObject(DBError
, Py_BuildValue("(is)", 0,
4299 "DBTxn must not be used after txn_commit or txn_abort"));
4302 MYDB_BEGIN_ALLOW_THREADS
;
4303 err
= txn_prepare(self
->txn
);
4304 MYDB_END_ALLOW_THREADS
;
4312 DBTxn_abort(DBTxnObject
* self
, PyObject
* args
)
4317 if (!PyArg_ParseTuple(args
, ":abort"))
4321 PyErr_SetObject(DBError
, Py_BuildValue("(is)", 0,
4322 "DBTxn must not be used after txn_commit or txn_abort"));
4326 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
4327 MYDB_BEGIN_ALLOW_THREADS
;
4329 err
= txn
->abort(txn
);
4331 err
= txn_abort(txn
);
4333 MYDB_END_ALLOW_THREADS
;
4340 DBTxn_id(DBTxnObject
* self
, PyObject
* args
)
4344 if (!PyArg_ParseTuple(args
, ":id"))
4348 PyErr_SetObject(DBError
, Py_BuildValue("(is)", 0,
4349 "DBTxn must not be used after txn_commit or txn_abort"));
4352 MYDB_BEGIN_ALLOW_THREADS
;
4354 id
= self
->txn
->id(self
->txn
);
4356 id
= txn_id(self
->txn
);
4358 MYDB_END_ALLOW_THREADS
;
4359 return PyInt_FromLong(id
);
4362 /* --------------------------------------------------------------------- */
4363 /* Method definition tables and type objects */
4365 static PyMethodDef DB_methods
[] = {
4366 {"append", (PyCFunction
)DB_append
, METH_VARARGS
},
4368 {"associate", (PyCFunction
)DB_associate
, METH_VARARGS
|METH_KEYWORDS
},
4370 {"close", (PyCFunction
)DB_close
, METH_VARARGS
},
4372 {"consume", (PyCFunction
)DB_consume
, METH_VARARGS
|METH_KEYWORDS
},
4373 {"consume_wait", (PyCFunction
)DB_consume_wait
, METH_VARARGS
|METH_KEYWORDS
},
4375 {"cursor", (PyCFunction
)DB_cursor
, METH_VARARGS
|METH_KEYWORDS
},
4376 {"delete", (PyCFunction
)DB_delete
, METH_VARARGS
|METH_KEYWORDS
},
4377 {"fd", (PyCFunction
)DB_fd
, METH_VARARGS
},
4378 {"get", (PyCFunction
)DB_get
, METH_VARARGS
|METH_KEYWORDS
},
4379 {"pget", (PyCFunction
)DB_pget
, METH_VARARGS
|METH_KEYWORDS
},
4380 {"get_both", (PyCFunction
)DB_get_both
, METH_VARARGS
|METH_KEYWORDS
},
4381 {"get_byteswapped", (PyCFunction
)DB_get_byteswapped
,METH_VARARGS
},
4382 {"get_size", (PyCFunction
)DB_get_size
, METH_VARARGS
|METH_KEYWORDS
},
4383 {"get_type", (PyCFunction
)DB_get_type
, METH_VARARGS
},
4384 {"join", (PyCFunction
)DB_join
, METH_VARARGS
},
4385 {"key_range", (PyCFunction
)DB_key_range
, METH_VARARGS
|METH_KEYWORDS
},
4386 {"has_key", (PyCFunction
)DB_has_key
, METH_VARARGS
},
4387 {"items", (PyCFunction
)DB_items
, METH_VARARGS
},
4388 {"keys", (PyCFunction
)DB_keys
, METH_VARARGS
},
4389 {"open", (PyCFunction
)DB_open
, METH_VARARGS
|METH_KEYWORDS
},
4390 {"put", (PyCFunction
)DB_put
, METH_VARARGS
|METH_KEYWORDS
},
4391 {"remove", (PyCFunction
)DB_remove
, METH_VARARGS
|METH_KEYWORDS
},
4392 {"rename", (PyCFunction
)DB_rename
, METH_VARARGS
},
4393 {"set_bt_minkey", (PyCFunction
)DB_set_bt_minkey
, METH_VARARGS
},
4394 {"set_cachesize", (PyCFunction
)DB_set_cachesize
, METH_VARARGS
},
4396 {"set_encrypt", (PyCFunction
)DB_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
4398 {"set_flags", (PyCFunction
)DB_set_flags
, METH_VARARGS
},
4399 {"set_h_ffactor", (PyCFunction
)DB_set_h_ffactor
, METH_VARARGS
},
4400 {"set_h_nelem", (PyCFunction
)DB_set_h_nelem
, METH_VARARGS
},
4401 {"set_lorder", (PyCFunction
)DB_set_lorder
, METH_VARARGS
},
4402 {"set_pagesize", (PyCFunction
)DB_set_pagesize
, METH_VARARGS
},
4403 {"set_re_delim", (PyCFunction
)DB_set_re_delim
, METH_VARARGS
},
4404 {"set_re_len", (PyCFunction
)DB_set_re_len
, METH_VARARGS
},
4405 {"set_re_pad", (PyCFunction
)DB_set_re_pad
, METH_VARARGS
},
4406 {"set_re_source", (PyCFunction
)DB_set_re_source
, METH_VARARGS
},
4408 {"set_q_extentsize",(PyCFunction
)DB_set_q_extentsize
,METH_VARARGS
},
4410 {"stat", (PyCFunction
)DB_stat
, METH_VARARGS
},
4411 {"sync", (PyCFunction
)DB_sync
, METH_VARARGS
},
4413 {"truncate", (PyCFunction
)DB_truncate
, METH_VARARGS
|METH_KEYWORDS
},
4415 {"type", (PyCFunction
)DB_get_type
, METH_VARARGS
},
4416 {"upgrade", (PyCFunction
)DB_upgrade
, METH_VARARGS
},
4417 {"values", (PyCFunction
)DB_values
, METH_VARARGS
},
4418 {"verify", (PyCFunction
)DB_verify
, METH_VARARGS
|METH_KEYWORDS
},
4419 {"set_get_returns_none",(PyCFunction
)DB_set_get_returns_none
, METH_VARARGS
},
4420 {NULL
, NULL
} /* sentinel */
4424 static PyMappingMethods DB_mapping
= {
4425 (inquiry
)DB_length
, /*mp_length*/
4426 (binaryfunc
)DB_subscript
, /*mp_subscript*/
4427 (objobjargproc
)DB_ass_sub
, /*mp_ass_subscript*/
4431 static PyMethodDef DBCursor_methods
[] = {
4432 {"close", (PyCFunction
)DBC_close
, METH_VARARGS
},
4433 {"count", (PyCFunction
)DBC_count
, METH_VARARGS
},
4434 {"current", (PyCFunction
)DBC_current
, METH_VARARGS
|METH_KEYWORDS
},
4435 {"delete", (PyCFunction
)DBC_delete
, METH_VARARGS
},
4436 {"dup", (PyCFunction
)DBC_dup
, METH_VARARGS
},
4437 {"first", (PyCFunction
)DBC_first
, METH_VARARGS
|METH_KEYWORDS
},
4438 {"get", (PyCFunction
)DBC_get
, METH_VARARGS
|METH_KEYWORDS
},
4439 {"pget", (PyCFunction
)DBC_pget
, METH_VARARGS
|METH_KEYWORDS
},
4440 {"get_recno", (PyCFunction
)DBC_get_recno
, METH_VARARGS
},
4441 {"last", (PyCFunction
)DBC_last
, METH_VARARGS
|METH_KEYWORDS
},
4442 {"next", (PyCFunction
)DBC_next
, METH_VARARGS
|METH_KEYWORDS
},
4443 {"prev", (PyCFunction
)DBC_prev
, METH_VARARGS
|METH_KEYWORDS
},
4444 {"put", (PyCFunction
)DBC_put
, METH_VARARGS
|METH_KEYWORDS
},
4445 {"set", (PyCFunction
)DBC_set
, METH_VARARGS
|METH_KEYWORDS
},
4446 {"set_range", (PyCFunction
)DBC_set_range
, METH_VARARGS
|METH_KEYWORDS
},
4447 {"get_both", (PyCFunction
)DBC_get_both
, METH_VARARGS
},
4448 {"get_current_size",(PyCFunction
)DBC_get_current_size
, METH_VARARGS
},
4449 {"set_both", (PyCFunction
)DBC_set_both
, METH_VARARGS
},
4450 {"set_recno", (PyCFunction
)DBC_set_recno
, METH_VARARGS
|METH_KEYWORDS
},
4451 {"consume", (PyCFunction
)DBC_consume
, METH_VARARGS
|METH_KEYWORDS
},
4452 {"next_dup", (PyCFunction
)DBC_next_dup
, METH_VARARGS
|METH_KEYWORDS
},
4453 {"next_nodup", (PyCFunction
)DBC_next_nodup
, METH_VARARGS
|METH_KEYWORDS
},
4454 {"prev_nodup", (PyCFunction
)DBC_prev_nodup
, METH_VARARGS
|METH_KEYWORDS
},
4455 {"join_item", (PyCFunction
)DBC_join_item
, METH_VARARGS
},
4456 {NULL
, NULL
} /* sentinel */
4460 static PyMethodDef DBEnv_methods
[] = {
4461 {"close", (PyCFunction
)DBEnv_close
, METH_VARARGS
},
4462 {"open", (PyCFunction
)DBEnv_open
, METH_VARARGS
},
4463 {"remove", (PyCFunction
)DBEnv_remove
, METH_VARARGS
},
4465 {"dbremove", (PyCFunction
)DBEnv_dbremove
, METH_VARARGS
|METH_KEYWORDS
},
4466 {"dbrename", (PyCFunction
)DBEnv_dbrename
, METH_VARARGS
|METH_KEYWORDS
},
4467 {"set_encrypt", (PyCFunction
)DBEnv_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
4470 {"set_timeout", (PyCFunction
)DBEnv_set_timeout
, METH_VARARGS
|METH_KEYWORDS
},
4472 {"set_shm_key", (PyCFunction
)DBEnv_set_shm_key
, METH_VARARGS
},
4473 {"set_cachesize", (PyCFunction
)DBEnv_set_cachesize
, METH_VARARGS
},
4474 {"set_data_dir", (PyCFunction
)DBEnv_set_data_dir
, METH_VARARGS
},
4476 {"set_flags", (PyCFunction
)DBEnv_set_flags
, METH_VARARGS
},
4478 {"set_lg_bsize", (PyCFunction
)DBEnv_set_lg_bsize
, METH_VARARGS
},
4479 {"set_lg_dir", (PyCFunction
)DBEnv_set_lg_dir
, METH_VARARGS
},
4480 {"set_lg_max", (PyCFunction
)DBEnv_set_lg_max
, METH_VARARGS
},
4481 {"set_lk_detect", (PyCFunction
)DBEnv_set_lk_detect
, METH_VARARGS
},
4482 {"set_lk_max", (PyCFunction
)DBEnv_set_lk_max
, METH_VARARGS
},
4484 {"set_lk_max_locks", (PyCFunction
)DBEnv_set_lk_max_locks
, METH_VARARGS
},
4485 {"set_lk_max_lockers", (PyCFunction
)DBEnv_set_lk_max_lockers
, METH_VARARGS
},
4486 {"set_lk_max_objects", (PyCFunction
)DBEnv_set_lk_max_objects
, METH_VARARGS
},
4488 {"set_mp_mmapsize", (PyCFunction
)DBEnv_set_mp_mmapsize
, METH_VARARGS
},
4489 {"set_tmp_dir", (PyCFunction
)DBEnv_set_tmp_dir
, METH_VARARGS
},
4490 {"txn_begin", (PyCFunction
)DBEnv_txn_begin
, METH_VARARGS
|METH_KEYWORDS
},
4491 {"txn_checkpoint", (PyCFunction
)DBEnv_txn_checkpoint
, METH_VARARGS
},
4492 {"txn_stat", (PyCFunction
)DBEnv_txn_stat
, METH_VARARGS
},
4493 {"set_tx_max", (PyCFunction
)DBEnv_set_tx_max
, METH_VARARGS
},
4494 {"lock_detect", (PyCFunction
)DBEnv_lock_detect
, METH_VARARGS
},
4495 {"lock_get", (PyCFunction
)DBEnv_lock_get
, METH_VARARGS
},
4496 {"lock_id", (PyCFunction
)DBEnv_lock_id
, METH_VARARGS
},
4497 {"lock_put", (PyCFunction
)DBEnv_lock_put
, METH_VARARGS
},
4498 {"lock_stat", (PyCFunction
)DBEnv_lock_stat
, METH_VARARGS
},
4499 {"log_archive", (PyCFunction
)DBEnv_log_archive
, METH_VARARGS
},
4500 {"set_get_returns_none",(PyCFunction
)DBEnv_set_get_returns_none
, METH_VARARGS
},
4501 {NULL
, NULL
} /* sentinel */
4505 static PyMethodDef DBTxn_methods
[] = {
4506 {"commit", (PyCFunction
)DBTxn_commit
, METH_VARARGS
},
4507 {"prepare", (PyCFunction
)DBTxn_prepare
, METH_VARARGS
},
4508 {"abort", (PyCFunction
)DBTxn_abort
, METH_VARARGS
},
4509 {"id", (PyCFunction
)DBTxn_id
, METH_VARARGS
},
4510 {NULL
, NULL
} /* sentinel */
4515 DB_getattr(DBObject
* self
, char *name
)
4517 return Py_FindMethod(DB_methods
, (PyObject
* )self
, name
);
4522 DBEnv_getattr(DBEnvObject
* self
, char *name
)
4524 if (!strcmp(name
, "db_home")) {
4525 CHECK_ENV_NOT_CLOSED(self
);
4526 if (self
->db_env
->db_home
== NULL
) {
4529 return PyString_FromString(self
->db_env
->db_home
);
4532 return Py_FindMethod(DBEnv_methods
, (PyObject
* )self
, name
);
4537 DBCursor_getattr(DBCursorObject
* self
, char *name
)
4539 return Py_FindMethod(DBCursor_methods
, (PyObject
* )self
, name
);
4543 DBTxn_getattr(DBTxnObject
* self
, char *name
)
4545 return Py_FindMethod(DBTxn_methods
, (PyObject
* )self
, name
);
4549 DBLock_getattr(DBLockObject
* self
, char *name
)
4554 statichere PyTypeObject DB_Type
= {
4555 PyObject_HEAD_INIT(NULL
)
4558 sizeof(DBObject
), /*tp_basicsize*/
4561 (destructor
)DB_dealloc
, /*tp_dealloc*/
4563 (getattrfunc
)DB_getattr
, /*tp_getattr*/
4568 0, /*tp_as_sequence*/
4569 &DB_mapping
,/*tp_as_mapping*/
4574 0, /* tp_getattro */
4575 0, /* tp_setattro */
4576 0, /* tp_as_buffer */
4577 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
4579 0, /* tp_traverse */
4581 0, /* tp_richcompare */
4582 offsetof(DBObject
, in_weakreflist
), /* tp_weaklistoffset */
4587 statichere PyTypeObject DBCursor_Type
= {
4588 PyObject_HEAD_INIT(NULL
)
4590 "DBCursor", /*tp_name*/
4591 sizeof(DBCursorObject
), /*tp_basicsize*/
4594 (destructor
)DBCursor_dealloc
,/*tp_dealloc*/
4596 (getattrfunc
)DBCursor_getattr
, /*tp_getattr*/
4601 0, /*tp_as_sequence*/
4602 0, /*tp_as_mapping*/
4607 0, /* tp_getattro */
4608 0, /* tp_setattro */
4609 0, /* tp_as_buffer */
4610 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
4612 0, /* tp_traverse */
4614 0, /* tp_richcompare */
4615 offsetof(DBCursorObject
, in_weakreflist
), /* tp_weaklistoffset */
4620 statichere PyTypeObject DBEnv_Type
= {
4621 PyObject_HEAD_INIT(NULL
)
4623 "DBEnv", /*tp_name*/
4624 sizeof(DBEnvObject
), /*tp_basicsize*/
4627 (destructor
)DBEnv_dealloc
, /*tp_dealloc*/
4629 (getattrfunc
)DBEnv_getattr
, /*tp_getattr*/
4634 0, /*tp_as_sequence*/
4635 0, /*tp_as_mapping*/
4640 0, /* tp_getattro */
4641 0, /* tp_setattro */
4642 0, /* tp_as_buffer */
4643 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
4645 0, /* tp_traverse */
4647 0, /* tp_richcompare */
4648 offsetof(DBEnvObject
, in_weakreflist
), /* tp_weaklistoffset */
4652 statichere PyTypeObject DBTxn_Type
= {
4653 PyObject_HEAD_INIT(NULL
)
4655 "DBTxn", /*tp_name*/
4656 sizeof(DBTxnObject
), /*tp_basicsize*/
4659 (destructor
)DBTxn_dealloc
, /*tp_dealloc*/
4661 (getattrfunc
)DBTxn_getattr
, /*tp_getattr*/
4666 0, /*tp_as_sequence*/
4667 0, /*tp_as_mapping*/
4672 0, /* tp_getattro */
4673 0, /* tp_setattro */
4674 0, /* tp_as_buffer */
4675 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
4677 0, /* tp_traverse */
4679 0, /* tp_richcompare */
4680 offsetof(DBTxnObject
, in_weakreflist
), /* tp_weaklistoffset */
4685 statichere PyTypeObject DBLock_Type
= {
4686 PyObject_HEAD_INIT(NULL
)
4688 "DBLock", /*tp_name*/
4689 sizeof(DBLockObject
), /*tp_basicsize*/
4692 (destructor
)DBLock_dealloc
, /*tp_dealloc*/
4694 (getattrfunc
)DBLock_getattr
, /*tp_getattr*/
4699 0, /*tp_as_sequence*/
4700 0, /*tp_as_mapping*/
4705 0, /* tp_getattro */
4706 0, /* tp_setattro */
4707 0, /* tp_as_buffer */
4708 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
4710 0, /* tp_traverse */
4712 0, /* tp_richcompare */
4713 offsetof(DBLockObject
, in_weakreflist
), /* tp_weaklistoffset */
4718 /* --------------------------------------------------------------------- */
4719 /* Module-level functions */
4722 DB_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4724 PyObject
* dbenvobj
= NULL
;
4726 char* kwnames
[] = { "dbEnv", "flags", NULL
};
4728 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:DB", kwnames
,
4731 if (dbenvobj
== Py_None
)
4733 else if (dbenvobj
&& !DBEnvObject_Check(dbenvobj
)) {
4734 makeTypeError("DBEnv", dbenvobj
);
4738 return (PyObject
* )newDBObject((DBEnvObject
*)dbenvobj
, flags
);
4743 DBEnv_construct(PyObject
* self
, PyObject
* args
)
4746 if (!PyArg_ParseTuple(args
, "|i:DbEnv", &flags
)) return NULL
;
4747 return (PyObject
* )newDBEnvObject(flags
);
4751 static char bsddb_version_doc
[] =
4752 "Returns a tuple of major, minor, and patch release numbers of the\n\
4753 underlying DB library.";
4756 bsddb_version(PyObject
* self
, PyObject
* args
)
4758 int major
, minor
, patch
;
4760 if (!PyArg_ParseTuple(args
, ":version"))
4762 db_version(&major
, &minor
, &patch
);
4763 return Py_BuildValue("(iii)", major
, minor
, patch
);
4767 /* List of functions defined in the module */
4769 static PyMethodDef bsddb_methods
[] = {
4770 {"DB", (PyCFunction
)DB_construct
, METH_VARARGS
| METH_KEYWORDS
},
4771 {"DBEnv", (PyCFunction
)DBEnv_construct
, METH_VARARGS
},
4772 {"version", (PyCFunction
)bsddb_version
, METH_VARARGS
, bsddb_version_doc
},
4773 {NULL
, NULL
} /* sentinel */
4777 /* --------------------------------------------------------------------- */
4778 /* Module initialization */
4781 /* Convenience routine to export an integer value.
4782 * Errors are silently ignored, for better or for worse...
4784 #define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
4786 #define MODULE_NAME_MAX_LEN 11
4787 static char _bsddbModuleName
[MODULE_NAME_MAX_LEN
+1] = "_bsddb";
4789 DL_EXPORT(void) init_bsddb(void)
4793 PyObject
* pybsddb_version_s
= PyString_FromString( PY_BSDDB_VERSION
);
4794 PyObject
* db_version_s
= PyString_FromString( DB_VERSION_STRING
);
4795 PyObject
* cvsid_s
= PyString_FromString( rcs_id
);
4797 /* Initialize the type of the new type objects here; doing it here
4798 is required for portability to Windows without requiring C++. */
4799 DB_Type
.ob_type
= &PyType_Type
;
4800 DBCursor_Type
.ob_type
= &PyType_Type
;
4801 DBEnv_Type
.ob_type
= &PyType_Type
;
4802 DBTxn_Type
.ob_type
= &PyType_Type
;
4803 DBLock_Type
.ob_type
= &PyType_Type
;
4806 #if defined(WITH_THREAD) && !defined(MYDB_USE_GILSTATE)
4807 /* Save the current interpreter, so callbacks can do the right thing. */
4808 _db_interpreterState
= PyThreadState_GET()->interp
;
4811 /* Create the module and add the functions */
4812 m
= Py_InitModule(_bsddbModuleName
, bsddb_methods
);
4814 /* Add some symbolic constants to the module */
4815 d
= PyModule_GetDict(m
);
4816 PyDict_SetItemString(d
, "__version__", pybsddb_version_s
);
4817 PyDict_SetItemString(d
, "cvsid", cvsid_s
);
4818 PyDict_SetItemString(d
, "DB_VERSION_STRING", db_version_s
);
4819 Py_DECREF(pybsddb_version_s
);
4820 pybsddb_version_s
= NULL
;
4823 Py_DECREF(db_version_s
);
4824 db_version_s
= NULL
;
4826 ADD_INT(d
, DB_VERSION_MAJOR
);
4827 ADD_INT(d
, DB_VERSION_MINOR
);
4828 ADD_INT(d
, DB_VERSION_PATCH
);
4830 ADD_INT(d
, DB_MAX_PAGES
);
4831 ADD_INT(d
, DB_MAX_RECORDS
);
4834 ADD_INT(d
, DB_RPCCLIENT
);
4836 ADD_INT(d
, DB_CLIENT
);
4837 /* allow apps to be written using DB_RPCCLIENT on older BerkeleyDB */
4838 _addIntToDict(d
, "DB_RPCCLIENT", DB_CLIENT
);
4840 ADD_INT(d
, DB_XA_CREATE
);
4842 ADD_INT(d
, DB_CREATE
);
4843 ADD_INT(d
, DB_NOMMAP
);
4844 ADD_INT(d
, DB_THREAD
);
4846 ADD_INT(d
, DB_FORCE
);
4847 ADD_INT(d
, DB_INIT_CDB
);
4848 ADD_INT(d
, DB_INIT_LOCK
);
4849 ADD_INT(d
, DB_INIT_LOG
);
4850 ADD_INT(d
, DB_INIT_MPOOL
);
4851 ADD_INT(d
, DB_INIT_TXN
);
4853 ADD_INT(d
, DB_JOINENV
);
4856 ADD_INT(d
, DB_RECOVER
);
4857 ADD_INT(d
, DB_RECOVER_FATAL
);
4858 ADD_INT(d
, DB_TXN_NOSYNC
);
4859 ADD_INT(d
, DB_USE_ENVIRON
);
4860 ADD_INT(d
, DB_USE_ENVIRON_ROOT
);
4862 ADD_INT(d
, DB_LOCKDOWN
);
4863 ADD_INT(d
, DB_PRIVATE
);
4864 ADD_INT(d
, DB_SYSTEM_MEM
);
4866 ADD_INT(d
, DB_TXN_SYNC
);
4867 ADD_INT(d
, DB_TXN_NOWAIT
);
4869 ADD_INT(d
, DB_EXCL
);
4870 ADD_INT(d
, DB_FCNTL_LOCKING
);
4871 ADD_INT(d
, DB_ODDFILESIZE
);
4872 ADD_INT(d
, DB_RDWRMASTER
);
4873 ADD_INT(d
, DB_RDONLY
);
4874 ADD_INT(d
, DB_TRUNCATE
);
4876 ADD_INT(d
, DB_EXTENT
);
4877 ADD_INT(d
, DB_CDB_ALLDB
);
4878 ADD_INT(d
, DB_VERIFY
);
4880 ADD_INT(d
, DB_UPGRADE
);
4882 ADD_INT(d
, DB_AGGRESSIVE
);
4883 ADD_INT(d
, DB_NOORDERCHK
);
4884 ADD_INT(d
, DB_ORDERCHKONLY
);
4885 ADD_INT(d
, DB_PR_PAGE
);
4887 ADD_INT(d
, DB_VRFY_FLAGMASK
);
4888 ADD_INT(d
, DB_PR_HEADERS
);
4890 ADD_INT(d
, DB_PR_RECOVERYTEST
);
4891 ADD_INT(d
, DB_SALVAGE
);
4893 ADD_INT(d
, DB_LOCK_NORUN
);
4894 ADD_INT(d
, DB_LOCK_DEFAULT
);
4895 ADD_INT(d
, DB_LOCK_OLDEST
);
4896 ADD_INT(d
, DB_LOCK_RANDOM
);
4897 ADD_INT(d
, DB_LOCK_YOUNGEST
);
4899 ADD_INT(d
, DB_LOCK_MAXLOCKS
);
4900 ADD_INT(d
, DB_LOCK_MINLOCKS
);
4901 ADD_INT(d
, DB_LOCK_MINWRITE
);
4906 /* docs say to use zero instead */
4907 _addIntToDict(d
, "DB_LOCK_CONFLICT", 0);
4909 ADD_INT(d
, DB_LOCK_CONFLICT
);
4912 ADD_INT(d
, DB_LOCK_DUMP
);
4913 ADD_INT(d
, DB_LOCK_GET
);
4914 ADD_INT(d
, DB_LOCK_INHERIT
);
4915 ADD_INT(d
, DB_LOCK_PUT
);
4916 ADD_INT(d
, DB_LOCK_PUT_ALL
);
4917 ADD_INT(d
, DB_LOCK_PUT_OBJ
);
4919 ADD_INT(d
, DB_LOCK_NG
);
4920 ADD_INT(d
, DB_LOCK_READ
);
4921 ADD_INT(d
, DB_LOCK_WRITE
);
4922 ADD_INT(d
, DB_LOCK_NOWAIT
);
4924 ADD_INT(d
, DB_LOCK_WAIT
);
4926 ADD_INT(d
, DB_LOCK_IWRITE
);
4927 ADD_INT(d
, DB_LOCK_IREAD
);
4928 ADD_INT(d
, DB_LOCK_IWR
);
4930 ADD_INT(d
, DB_LOCK_DIRTY
);
4931 ADD_INT(d
, DB_LOCK_WWRITE
);
4934 ADD_INT(d
, DB_LOCK_RECORD
);
4935 ADD_INT(d
, DB_LOCK_UPGRADE
);
4937 ADD_INT(d
, DB_LOCK_SWITCH
);
4940 ADD_INT(d
, DB_LOCK_UPGRADE_WRITE
);
4943 ADD_INT(d
, DB_LOCK_NOWAIT
);
4944 ADD_INT(d
, DB_LOCK_RECORD
);
4945 ADD_INT(d
, DB_LOCK_UPGRADE
);
4948 ADD_INT(d
, DB_LSTAT_ABORTED
);
4949 ADD_INT(d
, DB_LSTAT_ERR
);
4950 ADD_INT(d
, DB_LSTAT_FREE
);
4951 ADD_INT(d
, DB_LSTAT_HELD
);
4953 ADD_INT(d
, DB_LSTAT_NOGRANT
);
4955 ADD_INT(d
, DB_LSTAT_PENDING
);
4956 ADD_INT(d
, DB_LSTAT_WAITING
);
4959 ADD_INT(d
, DB_ARCH_ABS
);
4960 ADD_INT(d
, DB_ARCH_DATA
);
4961 ADD_INT(d
, DB_ARCH_LOG
);
4963 ADD_INT(d
, DB_BTREE
);
4964 ADD_INT(d
, DB_HASH
);
4965 ADD_INT(d
, DB_RECNO
);
4966 ADD_INT(d
, DB_QUEUE
);
4967 ADD_INT(d
, DB_UNKNOWN
);
4970 ADD_INT(d
, DB_DUPSORT
);
4971 ADD_INT(d
, DB_RECNUM
);
4972 ADD_INT(d
, DB_RENUMBER
);
4973 ADD_INT(d
, DB_REVSPLITOFF
);
4974 ADD_INT(d
, DB_SNAPSHOT
);
4976 ADD_INT(d
, DB_JOIN_NOSORT
);
4978 ADD_INT(d
, DB_AFTER
);
4979 ADD_INT(d
, DB_APPEND
);
4980 ADD_INT(d
, DB_BEFORE
);
4981 ADD_INT(d
, DB_CACHED_COUNTS
);
4983 _addIntToDict(d
, "DB_CHECKPOINT", 0);
4985 ADD_INT(d
, DB_CHECKPOINT
);
4986 ADD_INT(d
, DB_CURLSN
);
4988 #if ((DBVER >= 33) && (DBVER <= 41))
4989 ADD_INT(d
, DB_COMMIT
);
4991 ADD_INT(d
, DB_CONSUME
);
4993 ADD_INT(d
, DB_CONSUME_WAIT
);
4995 ADD_INT(d
, DB_CURRENT
);
4997 ADD_INT(d
, DB_FAST_STAT
);
4999 ADD_INT(d
, DB_FIRST
);
5000 ADD_INT(d
, DB_FLUSH
);
5001 ADD_INT(d
, DB_GET_BOTH
);
5002 ADD_INT(d
, DB_GET_RECNO
);
5003 ADD_INT(d
, DB_JOIN_ITEM
);
5004 ADD_INT(d
, DB_KEYFIRST
);
5005 ADD_INT(d
, DB_KEYLAST
);
5006 ADD_INT(d
, DB_LAST
);
5007 ADD_INT(d
, DB_NEXT
);
5008 ADD_INT(d
, DB_NEXT_DUP
);
5009 ADD_INT(d
, DB_NEXT_NODUP
);
5010 ADD_INT(d
, DB_NODUPDATA
);
5011 ADD_INT(d
, DB_NOOVERWRITE
);
5012 ADD_INT(d
, DB_NOSYNC
);
5013 ADD_INT(d
, DB_POSITION
);
5014 ADD_INT(d
, DB_PREV
);
5015 ADD_INT(d
, DB_PREV_NODUP
);
5016 ADD_INT(d
, DB_RECORDCOUNT
);
5018 ADD_INT(d
, DB_SET_RANGE
);
5019 ADD_INT(d
, DB_SET_RECNO
);
5020 ADD_INT(d
, DB_WRITECURSOR
);
5022 ADD_INT(d
, DB_OPFLAGS_MASK
);
5025 ADD_INT(d
, DB_DIRTY_READ
);
5026 ADD_INT(d
, DB_MULTIPLE
);
5027 ADD_INT(d
, DB_MULTIPLE_KEY
);
5031 ADD_INT(d
, DB_DONOTINDEX
);
5035 _addIntToDict(d
, "DB_INCOMPLETE", 0);
5037 ADD_INT(d
, DB_INCOMPLETE
);
5039 ADD_INT(d
, DB_KEYEMPTY
);
5040 ADD_INT(d
, DB_KEYEXIST
);
5041 ADD_INT(d
, DB_LOCK_DEADLOCK
);
5042 ADD_INT(d
, DB_LOCK_NOTGRANTED
);
5043 ADD_INT(d
, DB_NOSERVER
);
5044 ADD_INT(d
, DB_NOSERVER_HOME
);
5045 ADD_INT(d
, DB_NOSERVER_ID
);
5046 ADD_INT(d
, DB_NOTFOUND
);
5047 ADD_INT(d
, DB_OLD_VERSION
);
5048 ADD_INT(d
, DB_RUNRECOVERY
);
5049 ADD_INT(d
, DB_VERIFY_BAD
);
5051 ADD_INT(d
, DB_PAGE_NOTFOUND
);
5052 ADD_INT(d
, DB_SECONDARY_BAD
);
5055 ADD_INT(d
, DB_STAT_CLEAR
);
5056 ADD_INT(d
, DB_REGION_INIT
);
5057 ADD_INT(d
, DB_NOLOCKING
);
5058 ADD_INT(d
, DB_YIELDCPU
);
5059 ADD_INT(d
, DB_PANIC_ENVIRONMENT
);
5060 ADD_INT(d
, DB_NOPANIC
);
5064 ADD_INT(d
, DB_TIME_NOTGRANTED
);
5065 ADD_INT(d
, DB_TXN_NOT_DURABLE
);
5066 ADD_INT(d
, DB_TXN_WRITE_NOSYNC
);
5067 ADD_INT(d
, DB_LOG_AUTOREMOVE
);
5068 ADD_INT(d
, DB_DIRECT_LOG
);
5069 ADD_INT(d
, DB_DIRECT_DB
);
5070 ADD_INT(d
, DB_INIT_REP
);
5071 ADD_INT(d
, DB_ENCRYPT
);
5072 ADD_INT(d
, DB_CHKSUM
);
5076 ADD_INT(d
, DB_ENCRYPT_AES
);
5077 ADD_INT(d
, DB_AUTO_COMMIT
);
5079 /* allow berkeleydb 4.1 aware apps to run on older versions */
5080 _addIntToDict(d
, "DB_AUTO_COMMIT", 0);
5094 ADD_INT(d
, DB_SET_LOCK_TIMEOUT
);
5095 ADD_INT(d
, DB_SET_TXN_TIMEOUT
);
5098 /* The base exception class is DBError */
5099 DBError
= PyErr_NewException("bsddb._db.DBError", NULL
, NULL
);
5100 PyDict_SetItemString(d
, "DBError", DBError
);
5102 /* Some magic to make DBNotFoundError derive from both DBError and
5103 KeyError, since the API only supports using one base class. */
5104 PyDict_SetItemString(d
, "KeyError", PyExc_KeyError
);
5105 PyRun_String("class DBNotFoundError(DBError, KeyError): pass",
5106 Py_file_input
, d
, d
);
5107 DBNotFoundError
= PyDict_GetItemString(d
, "DBNotFoundError");
5108 PyDict_DelItemString(d
, "KeyError");
5111 /* All the rest of the exceptions derive only from DBError */
5112 #define MAKE_EX(name) name = PyErr_NewException("bsddb._db." #name, DBError, NULL); \
5113 PyDict_SetItemString(d, #name, name)
5115 #if !INCOMPLETE_IS_WARNING
5116 MAKE_EX(DBIncompleteError
);
5118 MAKE_EX(DBCursorClosedError
);
5119 MAKE_EX(DBKeyEmptyError
);
5120 MAKE_EX(DBKeyExistError
);
5121 MAKE_EX(DBLockDeadlockError
);
5122 MAKE_EX(DBLockNotGrantedError
);
5123 MAKE_EX(DBOldVersionError
);
5124 MAKE_EX(DBRunRecoveryError
);
5125 MAKE_EX(DBVerifyBadError
);
5126 MAKE_EX(DBNoServerError
);
5127 MAKE_EX(DBNoServerHomeError
);
5128 MAKE_EX(DBNoServerIDError
);
5130 MAKE_EX(DBPageNotFoundError
);
5131 MAKE_EX(DBSecondaryBadError
);
5134 MAKE_EX(DBInvalidArgError
);
5135 MAKE_EX(DBAccessError
);
5136 MAKE_EX(DBNoSpaceError
);
5137 MAKE_EX(DBNoMemoryError
);
5138 MAKE_EX(DBAgainError
);
5139 MAKE_EX(DBBusyError
);
5140 MAKE_EX(DBFileExistsError
);
5141 MAKE_EX(DBNoSuchFileError
);
5142 MAKE_EX(DBPermissionsError
);
5146 /* Check for errors */
5147 if (PyErr_Occurred()) {
5149 Py_FatalError("can't initialize module _bsddb");
5153 /* allow this module to be named _pybsddb so that it can be installed
5154 * and imported on top of python >= 2.3 that includes its own older
5155 * copy of the library named _bsddb without importing the old version. */
5156 DL_EXPORT(void) init_pybsddb(void)
5158 strncpy(_bsddbModuleName
, "_pybsddb", MODULE_NAME_MAX_LEN
);