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.1.
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.
56 * This module contains 5 types:
59 * DBCursor (Database Cursor)
60 * DBEnv (database environment)
61 * DBTxn (An explicit database transaction)
62 * DBLock (A lock handle)
66 /* --------------------------------------------------------------------- */
69 * Portions of this module, associated unit tests and build scripts are the
70 * result of a contract with The Written Word (http://thewrittenword.com/)
71 * Many thanks go out to them for causing me to raise the bar on quality and
72 * functionality, resulting in a better bsddb3 package for all of us to use.
77 /* --------------------------------------------------------------------- */
82 /* --------------------------------------------------------------------- */
83 /* Various macro definitions */
85 /* 40 = 4.0, 33 = 3.3; this will break if the second number is > 9 */
86 #define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
88 #define PY_BSDDB_VERSION "4.1.1"
89 static char *rcs_id
= "$Id$";
94 /* These are for when calling Python --> C */
95 #define MYDB_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS;
96 #define MYDB_END_ALLOW_THREADS Py_END_ALLOW_THREADS;
98 /* and these are for calling C --> Python */
99 static PyInterpreterState
* _db_interpreterState
= NULL
;
100 #define MYDB_BEGIN_BLOCK_THREADS { \
101 PyThreadState* prevState; \
102 PyThreadState* newState; \
103 PyEval_AcquireLock(); \
104 newState = PyThreadState_New(_db_interpreterState); \
105 prevState = PyThreadState_Swap(newState);
107 #define MYDB_END_BLOCK_THREADS \
108 newState = PyThreadState_Swap(prevState); \
109 PyThreadState_Clear(newState); \
110 PyEval_ReleaseLock(); \
111 PyThreadState_Delete(newState); \
116 #define MYDB_BEGIN_ALLOW_THREADS
117 #define MYDB_END_ALLOW_THREADS
118 #define MYDB_BEGIN_BLOCK_THREADS
119 #define MYDB_END_BLOCK_THREADS
124 /* What is the default behaviour when DB->get or DBCursor->get returns a
125 DB_NOTFOUND error? Return None or raise an exception? */
126 #define GET_RETURNS_NONE_DEFAULT 1
129 /* Should DB_INCOMPLETE be turned into a warning or an exception? */
130 #define INCOMPLETE_IS_WARNING 1
132 /* --------------------------------------------------------------------- */
135 static PyObject
* DBError
; /* Base class, all others derive from this */
136 static PyObject
* DBKeyEmptyError
; /* DB_KEYEMPTY */
137 static PyObject
* DBKeyExistError
; /* DB_KEYEXIST */
138 static PyObject
* DBLockDeadlockError
; /* DB_LOCK_DEADLOCK */
139 static PyObject
* DBLockNotGrantedError
; /* DB_LOCK_NOTGRANTED */
140 static PyObject
* DBNotFoundError
; /* DB_NOTFOUND: also derives from KeyError */
141 static PyObject
* DBOldVersionError
; /* DB_OLD_VERSION */
142 static PyObject
* DBRunRecoveryError
; /* DB_RUNRECOVERY */
143 static PyObject
* DBVerifyBadError
; /* DB_VERIFY_BAD */
144 static PyObject
* DBNoServerError
; /* DB_NOSERVER */
145 static PyObject
* DBNoServerHomeError
; /* DB_NOSERVER_HOME */
146 static PyObject
* DBNoServerIDError
; /* DB_NOSERVER_ID */
148 static PyObject
* DBPageNotFoundError
; /* DB_PAGE_NOTFOUND */
149 static PyObject
* DBSecondaryBadError
; /* DB_SECONDARY_BAD */
152 #if !INCOMPLETE_IS_WARNING
153 static PyObject
* DBIncompleteError
; /* DB_INCOMPLETE */
156 static PyObject
* DBInvalidArgError
; /* EINVAL */
157 static PyObject
* DBAccessError
; /* EACCES */
158 static PyObject
* DBNoSpaceError
; /* ENOSPC */
159 static PyObject
* DBNoMemoryError
; /* ENOMEM */
160 static PyObject
* DBAgainError
; /* EAGAIN */
161 static PyObject
* DBBusyError
; /* EBUSY */
162 static PyObject
* DBFileExistsError
; /* EEXIST */
163 static PyObject
* DBNoSuchFileError
; /* ENOENT */
164 static PyObject
* DBPermissionsError
; /* EPERM */
168 /* --------------------------------------------------------------------- */
169 /* Structure definitions */
174 u_int32_t flags
; /* saved flags from open() */
183 DBEnvObject
* myenvobj
; /* PyObject containing the DB_ENV */
184 u_int32_t flags
; /* saved flags from open() */
185 u_int32_t setflags
; /* saved flags from set_flags() */
189 PyObject
* associateCallback
;
215 staticforward PyTypeObject DB_Type
, DBCursor_Type
, DBEnv_Type
, DBTxn_Type
, DBLock_Type
;
217 #define DBObject_Check(v) ((v)->ob_type == &DB_Type)
218 #define DBCursorObject_Check(v) ((v)->ob_type == &DBCursor_Type)
219 #define DBEnvObject_Check(v) ((v)->ob_type == &DBEnv_Type)
220 #define DBTxnObject_Check(v) ((v)->ob_type == &DBTxn_Type)
221 #define DBLockObject_Check(v) ((v)->ob_type == &DBLock_Type)
224 /* --------------------------------------------------------------------- */
225 /* Utility macros and functions */
227 #define RETURN_IF_ERR() \
228 if (makeDBError(err)) { \
232 #define RETURN_NONE() Py_INCREF(Py_None); return Py_None;
234 #define CHECK_DB_NOT_CLOSED(dbobj) \
235 if (dbobj->db == NULL) { \
236 PyErr_SetObject(DBError, Py_BuildValue("(is)", 0, \
237 "DB object has been closed")); \
241 #define CHECK_ENV_NOT_CLOSED(env) \
242 if (env->db_env == NULL) { \
243 PyErr_SetObject(DBError, Py_BuildValue("(is)", 0, \
244 "DBEnv object has been closed"));\
248 #define CHECK_CURSOR_NOT_CLOSED(curs) \
249 if (curs->dbc == NULL) { \
250 PyErr_SetObject(DBError, Py_BuildValue("(is)", 0, \
251 "DBCursor object has been closed"));\
257 #define CHECK_DBFLAG(mydb, flag) (((mydb)->flags & (flag)) || \
258 (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))
260 #define CLEAR_DBT(dbt) (memset(&(dbt), 0, sizeof(dbt)))
262 #define FREE_DBT(dbt) if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
263 dbt.data != NULL) { free(dbt.data); }
266 static int makeDBError(int err
);
269 /* Return the access method type of the DBObject */
270 static int _DB_get_type(DBObject
* self
)
275 err
= self
->db
->get_type(self
->db
, &type
);
276 if (makeDBError(err
)) {
281 return self
->db
->get_type(self
->db
);
286 /* Create a DBT structure (containing key and data values) from Python
287 strings. Returns 1 on success, 0 on an error. */
288 static int make_dbt(PyObject
* obj
, DBT
* dbt
)
291 if (obj
== Py_None
) {
292 /* no need to do anything, the structure has already been zeroed */
294 else if (!PyArg_Parse(obj
, "s#", &dbt
->data
, &dbt
->size
)) {
295 PyErr_SetString(PyExc_TypeError
,
296 "Key and Data values must be of type string or None.");
303 /* Recno and Queue DBs can have integer keys. This function figures out
304 what's been given, verifies that it's allowed, and then makes the DBT.
306 Caller should call FREE_DBT(key) when done. */
308 make_key_dbt(DBObject
* self
, PyObject
* keyobj
, DBT
* key
, int* pflags
)
314 if (keyobj
== Py_None
) { /* TODO: is None really okay for keys? */
315 /* no need to do anything, the structure has already been zeroed */
318 else if (PyString_Check(keyobj
)) {
319 /* verify access method type */
320 type
= _DB_get_type(self
);
323 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
326 "String keys not allowed for Recno and Queue DB's");
330 key
->data
= PyString_AS_STRING(keyobj
);
331 key
->size
= PyString_GET_SIZE(keyobj
);
334 else if (PyInt_Check(keyobj
)) {
335 /* verify access method type */
336 type
= _DB_get_type(self
);
339 if (type
== DB_BTREE
&& pflags
!= NULL
) {
340 /* if BTREE then an Integer key is allowed with the
341 * DB_SET_RECNO flag */
342 *pflags
|= DB_SET_RECNO
;
344 else if (type
!= DB_RECNO
&& type
!= DB_QUEUE
) {
347 "Integer keys only allowed for Recno and Queue DB's");
351 /* Make a key out of the requested recno, use allocated space so DB
352 * will be able to realloc room for the real key if needed. */
353 recno
= PyInt_AS_LONG(keyobj
);
354 key
->data
= malloc(sizeof(db_recno_t
));
355 if (key
->data
== NULL
) {
356 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
359 key
->ulen
= key
->size
= sizeof(db_recno_t
);
360 memcpy(key
->data
, &recno
, sizeof(db_recno_t
));
361 key
->flags
= DB_DBT_REALLOC
;
364 PyErr_Format(PyExc_TypeError
,
365 "String or Integer object expected for key, %s found",
366 keyobj
->ob_type
->tp_name
);
374 /* Add partial record access to an existing DBT data struct.
375 If dlen and doff are set, then the DB_DBT_PARTIAL flag will be set
376 and the data storage/retrieval will be done using dlen and doff. */
377 static int add_partial_dbt(DBT
* d
, int dlen
, int doff
) {
378 /* if neither were set we do nothing (-1 is the default value) */
379 if ((dlen
== -1) && (doff
== -1)) {
383 if ((dlen
< 0) || (doff
< 0)) {
384 PyErr_SetString(PyExc_TypeError
, "dlen and doff must both be >= 0");
388 d
->flags
= d
->flags
| DB_DBT_PARTIAL
;
389 d
->dlen
= (unsigned int) dlen
;
390 d
->doff
= (unsigned int) doff
;
395 /* Callback used to save away more information about errors from the DB
397 static char _db_errmsg
[1024];
398 static void _db_errorCallback(const char* prefix
, char* msg
)
400 strcpy(_db_errmsg
, msg
);
404 /* make a nice exception object to raise for errors. */
405 static int makeDBError(int err
)
407 char errTxt
[2048]; /* really big, just in case... */
408 PyObject
*errObj
= NULL
;
409 PyObject
*errTuple
= NULL
;
410 int exceptionRaised
= 0;
413 case 0: /* successful, no error */ break;
417 #if INCOMPLETE_IS_WARNING
418 strcpy(errTxt
, db_strerror(err
));
420 strcat(errTxt
, " -- ");
421 strcat(errTxt
, _db_errmsg
);
424 /* if Python 2.1 or better use warning framework */
425 #if PYTHON_API_VERSION >= 1010
426 exceptionRaised
= PyErr_Warn(PyExc_RuntimeWarning
, errTxt
);
428 fprintf(stderr
, errTxt
);
429 fprintf(stderr
, "\n");
432 #else /* do an exception instead */
433 errObj
= DBIncompleteError
;
436 #endif /* DBVER < 41 */
438 case DB_KEYEMPTY
: errObj
= DBKeyEmptyError
; break;
439 case DB_KEYEXIST
: errObj
= DBKeyExistError
; break;
440 case DB_LOCK_DEADLOCK
: errObj
= DBLockDeadlockError
; break;
441 case DB_LOCK_NOTGRANTED
: errObj
= DBLockNotGrantedError
; break;
442 case DB_NOTFOUND
: errObj
= DBNotFoundError
; break;
443 case DB_OLD_VERSION
: errObj
= DBOldVersionError
; break;
444 case DB_RUNRECOVERY
: errObj
= DBRunRecoveryError
; break;
445 case DB_VERIFY_BAD
: errObj
= DBVerifyBadError
; break;
446 case DB_NOSERVER
: errObj
= DBNoServerError
; break;
447 case DB_NOSERVER_HOME
: errObj
= DBNoServerHomeError
; break;
448 case DB_NOSERVER_ID
: errObj
= DBNoServerIDError
; break;
450 case DB_PAGE_NOTFOUND
: errObj
= DBPageNotFoundError
; break;
451 case DB_SECONDARY_BAD
: errObj
= DBSecondaryBadError
; break;
454 case EINVAL
: errObj
= DBInvalidArgError
; break;
455 case EACCES
: errObj
= DBAccessError
; break;
456 case ENOSPC
: errObj
= DBNoSpaceError
; break;
457 case ENOMEM
: errObj
= DBNoMemoryError
; break;
458 case EAGAIN
: errObj
= DBAgainError
; break;
459 case EBUSY
: errObj
= DBBusyError
; break;
460 case EEXIST
: errObj
= DBFileExistsError
; break;
461 case ENOENT
: errObj
= DBNoSuchFileError
; break;
462 case EPERM
: errObj
= DBPermissionsError
; break;
464 default: errObj
= DBError
; break;
467 if (errObj
!= NULL
) {
468 strcpy(errTxt
, db_strerror(err
));
470 strcat(errTxt
, " -- ");
471 strcat(errTxt
, _db_errmsg
);
475 errTuple
= Py_BuildValue("(is)", err
, errTxt
);
476 PyErr_SetObject(errObj
, errTuple
);
480 return ((errObj
!= NULL
) || exceptionRaised
);
485 /* set a type exception */
486 static void makeTypeError(char* expected
, PyObject
* found
)
488 PyErr_Format(PyExc_TypeError
, "Expected %s argument, %s found.",
489 expected
, found
->ob_type
->tp_name
);
493 /* verify that an obj is either None or a DBTxn, and set the txn pointer */
494 static int checkTxnObj(PyObject
* txnobj
, DB_TXN
** txn
)
496 if (txnobj
== Py_None
|| txnobj
== NULL
) {
500 if (DBTxnObject_Check(txnobj
)) {
501 *txn
= ((DBTxnObject
*)txnobj
)->txn
;
505 makeTypeError("DBTxn", txnobj
);
510 /* Delete a key from a database
511 Returns 0 on success, -1 on an error. */
512 static int _DB_delete(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, int flags
)
516 MYDB_BEGIN_ALLOW_THREADS
;
517 err
= self
->db
->del(self
->db
, txn
, key
, 0);
518 MYDB_END_ALLOW_THREADS
;
519 if (makeDBError(err
)) {
527 /* Store a key into a database
528 Returns 0 on success, -1 on an error. */
529 static int _DB_put(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, DBT
*data
, int flags
)
533 MYDB_BEGIN_ALLOW_THREADS
;
534 err
= self
->db
->put(self
->db
, txn
, key
, data
, flags
);
535 MYDB_END_ALLOW_THREADS
;
536 if (makeDBError(err
)) {
543 /* Get a key/data pair from a cursor */
544 static PyObject
* _DBCursor_get(DBCursorObject
* self
, int extra_flags
,
545 PyObject
*args
, PyObject
*kwargs
, char *format
)
548 PyObject
* retval
= NULL
;
553 char* kwnames
[] = { "flags", "dlen", "doff", NULL
};
555 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, format
, kwnames
,
556 &flags
, &dlen
, &doff
))
559 CHECK_CURSOR_NOT_CLOSED(self
);
561 flags
|= extra_flags
;
564 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
565 /* Tell BerkeleyDB to malloc the return value (thread safe) */
566 data
.flags
= DB_DBT_MALLOC
;
567 key
.flags
= DB_DBT_MALLOC
;
569 if (!add_partial_dbt(&data
, dlen
, doff
))
572 MYDB_BEGIN_ALLOW_THREADS
;
573 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
574 MYDB_END_ALLOW_THREADS
;
576 if ((err
== DB_NOTFOUND
) && self
->mydb
->getReturnsNone
) {
580 else if (makeDBError(err
)) {
583 else { /* otherwise, success! */
585 /* if Recno or Queue, return the key as an Int */
586 switch (_DB_get_type(self
->mydb
)) {
593 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
594 data
.data
, data
.size
);
599 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
600 data
.data
, data
.size
);
612 /* add an integer to a dictionary using the given name as a key */
613 static void _addIntToDict(PyObject
* dict
, char *name
, int value
)
615 PyObject
* v
= PyInt_FromLong((long) value
);
616 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
625 /* --------------------------------------------------------------------- */
626 /* Allocators and deallocators */
629 newDBObject(DBEnvObject
* arg
, int flags
)
632 DB_ENV
* db_env
= NULL
;
635 #if PYTHON_API_VERSION <= 1007
636 /* 1.5 compatibility */
637 self
= PyObject_NEW(DBObject
, &DB_Type
);
639 self
= PyObject_New(DBObject
, &DB_Type
);
648 self
->myenvobj
= NULL
;
650 self
->associateCallback
= NULL
;
651 self
->primaryDBType
= 0;
654 /* keep a reference to our python DBEnv object */
657 self
->myenvobj
= arg
;
658 db_env
= arg
->db_env
;
662 self
->getReturnsNone
= self
->myenvobj
->getReturnsNone
;
664 self
->getReturnsNone
= GET_RETURNS_NONE_DEFAULT
;
666 MYDB_BEGIN_ALLOW_THREADS
;
667 err
= db_create(&self
->db
, db_env
, flags
);
668 self
->db
->set_errcall(self
->db
, _db_errorCallback
);
670 self
->db
->app_private
= (void*)self
;
672 MYDB_END_ALLOW_THREADS
;
673 if (makeDBError(err
)) {
674 if (self
->myenvobj
) {
675 Py_DECREF(self
->myenvobj
);
676 self
->myenvobj
= NULL
;
685 DB_dealloc(DBObject
* self
)
687 if (self
->db
!= NULL
) {
688 /* avoid closing a DB when its DBEnv has been closed out from under
690 if (!self
->myenvobj
||
691 (self
->myenvobj
&& self
->myenvobj
->db_env
))
693 MYDB_BEGIN_ALLOW_THREADS
;
694 self
->db
->close(self
->db
, 0);
695 MYDB_END_ALLOW_THREADS
;
696 /* if Python 2.1 or better use warning framework */
697 #if PYTHON_API_VERSION >= 1010
699 PyErr_Warn(PyExc_RuntimeWarning
,
700 "DB could not be closed in destructor: DBEnv already closed");
705 if (self
->myenvobj
) {
706 Py_DECREF(self
->myenvobj
);
707 self
->myenvobj
= NULL
;
710 if (self
->associateCallback
!= NULL
) {
711 Py_DECREF(self
->associateCallback
);
712 self
->associateCallback
= NULL
;
715 #if PYTHON_API_VERSION <= 1007
723 static DBCursorObject
*
724 newDBCursorObject(DBC
* dbc
, DBObject
* db
)
726 DBCursorObject
* self
;
727 #if PYTHON_API_VERSION <= 1007
728 self
= PyObject_NEW(DBCursorObject
, &DBCursor_Type
);
730 self
= PyObject_New(DBCursorObject
, &DBCursor_Type
);
737 Py_INCREF(self
->mydb
);
743 DBCursor_dealloc(DBCursorObject
* self
)
746 if (self
->dbc
!= NULL
) {
747 MYDB_BEGIN_ALLOW_THREADS
;
748 err
= self
->dbc
->c_close(self
->dbc
);
750 MYDB_END_ALLOW_THREADS
;
752 Py_XDECREF( self
->mydb
);
753 #if PYTHON_API_VERSION <= 1007
762 newDBEnvObject(int flags
)
766 #if PYTHON_API_VERSION <= 1007
767 self
= PyObject_NEW(DBEnvObject
, &DBEnv_Type
);
769 self
= PyObject_New(DBEnvObject
, &DBEnv_Type
);
777 self
->getReturnsNone
= GET_RETURNS_NONE_DEFAULT
;
779 MYDB_BEGIN_ALLOW_THREADS
;
780 err
= db_env_create(&self
->db_env
, flags
);
781 MYDB_END_ALLOW_THREADS
;
782 if (makeDBError(err
)) {
786 self
->db_env
->set_errcall(self
->db_env
, _db_errorCallback
);
793 DBEnv_dealloc(DBEnvObject
* self
)
796 MYDB_BEGIN_ALLOW_THREADS
;
797 self
->db_env
->close(self
->db_env
, 0);
798 MYDB_END_ALLOW_THREADS
;
800 #if PYTHON_API_VERSION <= 1007
809 newDBTxnObject(DBEnvObject
* myenv
, DB_TXN
*parent
, int flags
)
814 #if PYTHON_API_VERSION <= 1007
815 self
= PyObject_NEW(DBTxnObject
, &DBTxn_Type
);
817 self
= PyObject_New(DBTxnObject
, &DBTxn_Type
);
822 MYDB_BEGIN_ALLOW_THREADS
;
824 err
= myenv
->db_env
->txn_begin(myenv
->db_env
, parent
, &(self
->txn
), flags
);
826 err
= txn_begin(myenv
->db_env
, parent
, &(self
->txn
), flags
);
828 MYDB_END_ALLOW_THREADS
;
829 if (makeDBError(err
)) {
837 DBTxn_dealloc(DBTxnObject
* self
)
839 /* XXX nothing to do for transaction objects?!? */
841 /* TODO: if it hasn't been commited, should we abort it? */
843 #if PYTHON_API_VERSION <= 1007
852 newDBLockObject(DBEnvObject
* myenv
, u_int32_t locker
, DBT
* obj
,
853 db_lockmode_t lock_mode
, int flags
)
858 #if PYTHON_API_VERSION <= 1007
859 self
= PyObject_NEW(DBLockObject
, &DBLock_Type
);
861 self
= PyObject_New(DBLockObject
, &DBLock_Type
);
866 MYDB_BEGIN_ALLOW_THREADS
;
868 err
= myenv
->db_env
->lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
,
871 err
= lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
, &self
->lock
);
873 MYDB_END_ALLOW_THREADS
;
874 if (makeDBError(err
)) {
883 DBLock_dealloc(DBLockObject
* self
)
885 /* TODO: if it hasn't been released, should we do it? */
887 #if PYTHON_API_VERSION <= 1007
895 /* --------------------------------------------------------------------- */
899 DB_append(DBObject
* self
, PyObject
* args
)
901 PyObject
* txnobj
= NULL
;
907 if (!PyArg_ParseTuple(args
, "O|O:append", &dataobj
, &txnobj
))
910 CHECK_DB_NOT_CLOSED(self
);
912 /* make a dummy key out of a recno */
916 key
.size
= sizeof(recno
);
918 key
.flags
= DB_DBT_USERMEM
;
920 if (!make_dbt(dataobj
, &data
)) return NULL
;
921 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
923 if (-1 == _DB_put(self
, txn
, &key
, &data
, DB_APPEND
))
926 return PyInt_FromLong(recno
);
933 _db_associateCallback(DB
* db
, const DBT
* priKey
, const DBT
* priData
,
936 int retval
= DB_DONOTINDEX
;
937 DBObject
* secondaryDB
= (DBObject
*)db
->app_private
;
938 PyObject
* callback
= secondaryDB
->associateCallback
;
939 int type
= secondaryDB
->primaryDBType
;
946 if (callback
!= NULL
) {
947 MYDB_BEGIN_BLOCK_THREADS
;
949 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
950 key
= PyInt_FromLong( *((db_recno_t
*)priKey
->data
));
953 key
= PyString_FromStringAndSize(priKey
->data
, priKey
->size
);
955 data
= PyString_FromStringAndSize(priData
->data
, priData
->size
);
956 args
= PyTuple_New(2);
957 PyTuple_SET_ITEM(args
, 0, key
); /* steals reference */
958 PyTuple_SET_ITEM(args
, 1, data
); /* steals reference */
960 result
= PyEval_CallObject(callback
, args
);
962 if (result
== NULL
) {
965 else if (result
== Py_None
) {
966 retval
= DB_DONOTINDEX
;
968 else if (PyInt_Check(result
)) {
969 retval
= PyInt_AsLong(result
);
971 else if (PyString_Check(result
)) {
976 #if PYTHON_API_VERSION <= 1007
977 /* 1.5 compatibility */
978 size
= PyString_Size(result
);
979 data
= PyString_AsString(result
);
981 PyString_AsStringAndSize(result
, &data
, &size
);
983 secKey
->flags
= DB_DBT_APPMALLOC
; /* DB will free */
984 secKey
->data
= malloc(size
); /* TODO, check this */
986 memcpy(secKey
->data
, data
, size
);
991 PyErr_SetString(PyExc_MemoryError
,
992 "malloc failed in _db_associateCallback");
999 "DB associate callback should return DB_DONOTINDEX or string.");
1008 MYDB_END_BLOCK_THREADS
;
1015 DB_associate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1018 DBObject
* secondaryDB
;
1021 PyObject
*txnobj
= NULL
;
1023 char* kwnames
[] = {"secondaryDB", "callback", "flags", "txn", NULL
};
1025 char* kwnames
[] = {"secondaryDB", "callback", "flags", NULL
};
1029 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iO:associate", kwnames
,
1030 &secondaryDB
, &callback
, &flags
,
1033 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|i:associate", kwnames
,
1034 &secondaryDB
, &callback
, &flags
)) {
1040 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1043 CHECK_DB_NOT_CLOSED(self
);
1044 if (!DBObject_Check(secondaryDB
)) {
1045 makeTypeError("DB", (PyObject
*)secondaryDB
);
1048 if (callback
== Py_None
) {
1051 else if (!PyCallable_Check(callback
)) {
1052 makeTypeError("Callable", callback
);
1056 /* Save a reference to the callback in the secondary DB. */
1057 if (self
->associateCallback
!= NULL
) {
1058 Py_DECREF(self
->associateCallback
);
1060 Py_INCREF(callback
);
1061 secondaryDB
->associateCallback
= callback
;
1062 secondaryDB
->primaryDBType
= _DB_get_type(self
);
1064 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1065 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1066 * The global interepreter lock is not initialized until the first
1067 * thread is created using thread.start_new_thread() or fork() is
1068 * called. that would cause the ALLOW_THREADS here to segfault due
1069 * to a null pointer reference if no threads or child processes
1070 * have been created. This works around that and is a no-op if
1071 * threads have already been initialized.
1072 * (see pybsddb-users mailing list post on 2002-08-07)
1074 PyEval_InitThreads();
1075 MYDB_BEGIN_ALLOW_THREADS
;
1077 err
= self
->db
->associate(self
->db
,
1080 _db_associateCallback
,
1083 err
= self
->db
->associate(self
->db
,
1085 _db_associateCallback
,
1088 MYDB_END_ALLOW_THREADS
;
1091 Py_DECREF(self
->associateCallback
);
1092 self
->associateCallback
= NULL
;
1093 secondaryDB
->primaryDBType
= 0;
1105 DB_close(DBObject
* self
, PyObject
* args
)
1108 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
1110 if (self
->db
!= NULL
) {
1112 CHECK_ENV_NOT_CLOSED(self
->myenvobj
);
1113 MYDB_BEGIN_ALLOW_THREADS
;
1114 err
= self
->db
->close(self
->db
, flags
);
1115 MYDB_END_ALLOW_THREADS
;
1125 _DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1127 int err
, flags
=0, type
;
1128 PyObject
* txnobj
= NULL
;
1129 PyObject
* retval
= NULL
;
1132 char* kwnames
[] = { "txn", "flags", NULL
};
1134 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:consume", kwnames
,
1138 CHECK_DB_NOT_CLOSED(self
);
1139 type
= _DB_get_type(self
);
1142 if (type
!= DB_QUEUE
) {
1143 PyErr_SetString(PyExc_TypeError
,
1144 "Consume methods only allowed for Queue DB's");
1147 if (!checkTxnObj(txnobj
, &txn
))
1152 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1153 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1154 data
.flags
= DB_DBT_MALLOC
;
1155 key
.flags
= DB_DBT_MALLOC
;
1158 MYDB_BEGIN_ALLOW_THREADS
;
1159 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
|consume_flag
);
1160 MYDB_END_ALLOW_THREADS
;
1162 if ((err
== DB_NOTFOUND
) && self
->getReturnsNone
) {
1168 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
1179 DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1181 return _DB_consume(self
, args
, kwargs
, DB_CONSUME
);
1185 DB_consume_wait(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
,
1188 return _DB_consume(self
, args
, kwargs
, DB_CONSUME_WAIT
);
1195 DB_cursor(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1199 PyObject
* txnobj
= NULL
;
1201 char* kwnames
[] = { "txn", "flags", NULL
};
1203 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
1206 CHECK_DB_NOT_CLOSED(self
);
1207 if (!checkTxnObj(txnobj
, &txn
))
1210 MYDB_BEGIN_ALLOW_THREADS
;
1211 err
= self
->db
->cursor(self
->db
, txn
, &dbc
, flags
);
1212 MYDB_END_ALLOW_THREADS
;
1214 return (PyObject
*) newDBCursorObject(dbc
, self
);
1219 DB_delete(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1221 PyObject
* txnobj
= NULL
;
1226 char* kwnames
[] = { "key", "txn", "flags", NULL
};
1228 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:delete", kwnames
,
1229 &keyobj
, &txnobj
, &flags
))
1231 CHECK_DB_NOT_CLOSED(self
);
1232 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1234 if (!checkTxnObj(txnobj
, &txn
))
1237 if (-1 == _DB_delete(self
, txn
, &key
, 0))
1246 DB_fd(DBObject
* self
, PyObject
* args
)
1250 if (!PyArg_ParseTuple(args
,":fd"))
1252 CHECK_DB_NOT_CLOSED(self
);
1254 MYDB_BEGIN_ALLOW_THREADS
;
1255 err
= self
->db
->fd(self
->db
, &the_fd
);
1256 MYDB_END_ALLOW_THREADS
;
1258 return PyInt_FromLong(the_fd
);
1263 DB_get(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1266 PyObject
* txnobj
= NULL
;
1268 PyObject
* dfltobj
= NULL
;
1269 PyObject
* retval
= NULL
;
1274 char* kwnames
[] = {"key", "default", "txn", "flags", "dlen", "doff", NULL
};
1276 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:get", kwnames
,
1277 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1281 CHECK_DB_NOT_CLOSED(self
);
1282 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1284 if (!checkTxnObj(txnobj
, &txn
))
1288 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1289 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1290 data
.flags
= DB_DBT_MALLOC
;
1292 if (!add_partial_dbt(&data
, dlen
, doff
))
1295 MYDB_BEGIN_ALLOW_THREADS
;
1296 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1297 MYDB_END_ALLOW_THREADS
;
1299 if ((err
== DB_NOTFOUND
) && (dfltobj
!= NULL
)) {
1304 else if ((err
== DB_NOTFOUND
) && self
->getReturnsNone
) {
1310 if (flags
& DB_SET_RECNO
) /* return both key and data */
1311 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
1313 else /* return just the data */
1314 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
1324 /* Return size of entry */
1326 DB_get_size(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1329 PyObject
* txnobj
= NULL
;
1331 PyObject
* retval
= NULL
;
1334 char* kwnames
[] = { "key", "txn", NULL
};
1336 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O:get_size", kwnames
,
1339 CHECK_DB_NOT_CLOSED(self
);
1340 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1342 if (!checkTxnObj(txnobj
, &txn
))
1346 /* We don't allocate any memory, forcing a ENOMEM error and thus
1347 getting the record size. */
1348 data
.flags
= DB_DBT_USERMEM
;
1350 MYDB_BEGIN_ALLOW_THREADS
;
1351 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1352 MYDB_END_ALLOW_THREADS
;
1353 if (err
== ENOMEM
) {
1354 retval
= PyInt_FromLong((long)data
.size
);
1366 DB_get_both(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1369 PyObject
* txnobj
= NULL
;
1372 PyObject
* retval
= NULL
;
1375 char* kwnames
[] = { "key", "data", "txn", "flags", NULL
};
1378 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oi:get_both", kwnames
,
1379 &keyobj
, &dataobj
, &txnobj
, &flags
))
1382 CHECK_DB_NOT_CLOSED(self
);
1383 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1385 if (!make_dbt(dataobj
, &data
))
1387 if (!checkTxnObj(txnobj
, &txn
))
1390 flags
|= DB_GET_BOTH
;
1392 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1393 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1394 data
.flags
= DB_DBT_MALLOC
;
1395 /* TODO: Is this flag needed? We're passing a data object that should
1396 match what's in the DB, so there should be no need to malloc.
1397 We run the risk of freeing something twice! Check this. */
1400 MYDB_BEGIN_ALLOW_THREADS
;
1401 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1402 MYDB_END_ALLOW_THREADS
;
1404 if ((err
== DB_NOTFOUND
) && self
->getReturnsNone
) {
1410 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
1411 FREE_DBT(data
); /* Only if retrieval was successful */
1421 DB_get_byteswapped(DBObject
* self
, PyObject
* args
)
1428 if (!PyArg_ParseTuple(args
,":get_byteswapped"))
1430 CHECK_DB_NOT_CLOSED(self
);
1433 MYDB_BEGIN_ALLOW_THREADS
;
1434 err
= self
->db
->get_byteswapped(self
->db
, &retval
);
1435 MYDB_END_ALLOW_THREADS
;
1438 MYDB_BEGIN_ALLOW_THREADS
;
1439 retval
= self
->db
->get_byteswapped(self
->db
);
1440 MYDB_END_ALLOW_THREADS
;
1442 return PyInt_FromLong(retval
);
1447 DB_get_type(DBObject
* self
, PyObject
* args
)
1451 if (!PyArg_ParseTuple(args
,":get_type"))
1453 CHECK_DB_NOT_CLOSED(self
);
1455 MYDB_BEGIN_ALLOW_THREADS
;
1456 type
= _DB_get_type(self
);
1457 MYDB_END_ALLOW_THREADS
;
1460 return PyInt_FromLong(type
);
1465 DB_join(DBObject
* self
, PyObject
* args
)
1469 PyObject
* cursorsObj
;
1474 if (!PyArg_ParseTuple(args
,"O|i:join", &cursorsObj
, &flags
))
1477 CHECK_DB_NOT_CLOSED(self
);
1479 if (!PySequence_Check(cursorsObj
)) {
1480 PyErr_SetString(PyExc_TypeError
,
1481 "Sequence of DBCursor objects expected");
1485 length
= PyObject_Length(cursorsObj
);
1486 cursors
= malloc((length
+1) * sizeof(DBC
*));
1487 cursors
[length
] = NULL
;
1488 for (x
=0; x
<length
; x
++) {
1489 PyObject
* item
= PySequence_GetItem(cursorsObj
, x
);
1490 if (!DBCursorObject_Check(item
)) {
1491 PyErr_SetString(PyExc_TypeError
,
1492 "Sequence of DBCursor objects expected");
1496 cursors
[x
] = ((DBCursorObject
*)item
)->dbc
;
1499 MYDB_BEGIN_ALLOW_THREADS
;
1500 err
= self
->db
->join(self
->db
, cursors
, &dbc
, flags
);
1501 MYDB_END_ALLOW_THREADS
;
1505 return (PyObject
*) newDBCursorObject(dbc
, self
);
1510 DB_key_range(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1513 PyObject
* txnobj
= NULL
;
1518 char* kwnames
[] = { "key", "txn", "flags", NULL
};
1520 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:key_range", kwnames
,
1521 &keyobj
, &txnobj
, &flags
))
1523 CHECK_DB_NOT_CLOSED(self
);
1524 if (!make_dbt(keyobj
, &key
))
1525 /* BTree only, don't need to allow for an int key */
1527 if (!checkTxnObj(txnobj
, &txn
))
1530 MYDB_BEGIN_ALLOW_THREADS
;
1531 err
= self
->db
->key_range(self
->db
, txn
, &key
, &range
, flags
);
1532 MYDB_END_ALLOW_THREADS
;
1535 return Py_BuildValue("ddd", range
.less
, range
.equal
, range
.greater
);
1540 DB_open(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1542 int err
, type
= DB_UNKNOWN
, flags
=0, mode
=0660;
1543 char* filename
= NULL
;
1544 char* dbname
= NULL
;
1546 PyObject
*txnobj
= NULL
;
1550 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL
};
1551 /* without dbname */
1552 char* kwnames_basic
[] = {
1553 "filename", "dbtype", "flags", "mode", "txn", NULL
};
1557 "filename", "dbname", "dbtype", "flags", "mode", NULL
};
1558 /* without dbname */
1559 char* kwnames_basic
[] = {
1560 "filename", "dbtype", "flags", "mode", NULL
};
1564 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziiiO:open", kwnames
,
1565 &filename
, &dbname
, &type
, &flags
, &mode
,
1568 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziii:open", kwnames
,
1569 &filename
, &dbname
, &type
, &flags
,
1574 type
= DB_UNKNOWN
; flags
= 0; mode
= 0660;
1575 filename
= NULL
; dbname
= NULL
;
1577 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iiiO:open",
1579 &filename
, &type
, &flags
, &mode
,
1583 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iii:open",
1585 &filename
, &type
, &flags
, &mode
))
1591 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1594 if (NULL
== self
->db
) {
1595 PyErr_SetObject(DBError
, Py_BuildValue("(is)", 0,
1596 "Cannot call open() twice for DB object"));
1600 #if 0 && (DBVER >= 41)
1601 if ((!txn
) && (txnobj
!= Py_None
) && self
->myenvobj
1602 && (self
->myenvobj
->flags
& DB_INIT_TXN
))
1604 /* If no 'txn' parameter was supplied (no DbTxn object and None was not
1605 * explicitly passed) but we are in a transaction ready environment:
1606 * add DB_AUTO_COMMIT to allow for older pybsddb apps using transactions
1607 * to work on BerkeleyDB 4.1 without needing to modify their
1608 * DBEnv or DB open calls.
1609 * TODO make this behaviour of the library configurable.
1611 flags
|= DB_AUTO_COMMIT
;
1615 MYDB_BEGIN_ALLOW_THREADS
;
1617 err
= self
->db
->open(self
->db
, txn
, filename
, dbname
, type
, flags
, mode
);
1619 err
= self
->db
->open(self
->db
, filename
, dbname
, type
, flags
, mode
);
1621 MYDB_END_ALLOW_THREADS
;
1622 if (makeDBError(err
)) {
1627 self
->flags
= flags
;
1633 DB_put(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1636 PyObject
* txnobj
= NULL
;
1639 PyObject
* keyobj
, *dataobj
, *retval
;
1642 char* kwnames
[] = { "key", "data", "txn", "flags", "dlen", "doff", NULL
};
1644 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oiii:put", kwnames
,
1645 &keyobj
, &dataobj
, &txnobj
, &flags
, &dlen
, &doff
))
1648 CHECK_DB_NOT_CLOSED(self
);
1649 if (!make_key_dbt(self
, keyobj
, &key
, NULL
)) return NULL
;
1650 if (!make_dbt(dataobj
, &data
)) return NULL
;
1651 if (!add_partial_dbt(&data
, dlen
, doff
)) return NULL
;
1652 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1654 if (-1 == _DB_put(self
, txn
, &key
, &data
, flags
)) {
1659 if (flags
& DB_APPEND
)
1660 retval
= PyInt_FromLong(*((db_recno_t
*)key
.data
));
1672 DB_remove(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1675 char* database
= NULL
;
1677 char* kwnames
[] = { "filename", "dbname", "flags", NULL
};
1679 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zi:remove", kwnames
,
1680 &filename
, &database
, &flags
))
1682 CHECK_DB_NOT_CLOSED(self
);
1684 MYDB_BEGIN_ALLOW_THREADS
;
1685 err
= self
->db
->remove(self
->db
, filename
, database
, flags
);
1686 MYDB_END_ALLOW_THREADS
;
1694 DB_rename(DBObject
* self
, PyObject
* args
)
1701 if (!PyArg_ParseTuple(args
, "sss|i:rename", &filename
, &database
, &newname
,
1704 CHECK_DB_NOT_CLOSED(self
);
1706 MYDB_BEGIN_ALLOW_THREADS
;
1707 err
= self
->db
->rename(self
->db
, filename
, database
, newname
, flags
);
1708 MYDB_END_ALLOW_THREADS
;
1715 DB_set_bt_minkey(DBObject
* self
, PyObject
* args
)
1719 if (!PyArg_ParseTuple(args
,"i:set_bt_minkey", &minkey
))
1721 CHECK_DB_NOT_CLOSED(self
);
1723 MYDB_BEGIN_ALLOW_THREADS
;
1724 err
= self
->db
->set_bt_minkey(self
->db
, minkey
);
1725 MYDB_END_ALLOW_THREADS
;
1732 DB_set_cachesize(DBObject
* self
, PyObject
* args
)
1735 int gbytes
= 0, bytes
= 0, ncache
= 0;
1737 if (!PyArg_ParseTuple(args
,"ii|i:set_cachesize",
1738 &gbytes
,&bytes
,&ncache
))
1740 CHECK_DB_NOT_CLOSED(self
);
1742 MYDB_BEGIN_ALLOW_THREADS
;
1743 err
= self
->db
->set_cachesize(self
->db
, gbytes
, bytes
, ncache
);
1744 MYDB_END_ALLOW_THREADS
;
1751 DB_set_flags(DBObject
* self
, PyObject
* args
)
1755 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
1757 CHECK_DB_NOT_CLOSED(self
);
1759 MYDB_BEGIN_ALLOW_THREADS
;
1760 err
= self
->db
->set_flags(self
->db
, flags
);
1761 MYDB_END_ALLOW_THREADS
;
1764 self
->setflags
|= flags
;
1770 DB_set_h_ffactor(DBObject
* self
, PyObject
* args
)
1774 if (!PyArg_ParseTuple(args
,"i:set_h_ffactor", &ffactor
))
1776 CHECK_DB_NOT_CLOSED(self
);
1778 MYDB_BEGIN_ALLOW_THREADS
;
1779 err
= self
->db
->set_h_ffactor(self
->db
, ffactor
);
1780 MYDB_END_ALLOW_THREADS
;
1787 DB_set_h_nelem(DBObject
* self
, PyObject
* args
)
1791 if (!PyArg_ParseTuple(args
,"i:set_h_nelem", &nelem
))
1793 CHECK_DB_NOT_CLOSED(self
);
1795 MYDB_BEGIN_ALLOW_THREADS
;
1796 err
= self
->db
->set_h_nelem(self
->db
, nelem
);
1797 MYDB_END_ALLOW_THREADS
;
1804 DB_set_lorder(DBObject
* self
, PyObject
* args
)
1808 if (!PyArg_ParseTuple(args
,"i:set_lorder", &lorder
))
1810 CHECK_DB_NOT_CLOSED(self
);
1812 MYDB_BEGIN_ALLOW_THREADS
;
1813 err
= self
->db
->set_lorder(self
->db
, lorder
);
1814 MYDB_END_ALLOW_THREADS
;
1821 DB_set_pagesize(DBObject
* self
, PyObject
* args
)
1825 if (!PyArg_ParseTuple(args
,"i:set_pagesize", &pagesize
))
1827 CHECK_DB_NOT_CLOSED(self
);
1829 MYDB_BEGIN_ALLOW_THREADS
;
1830 err
= self
->db
->set_pagesize(self
->db
, pagesize
);
1831 MYDB_END_ALLOW_THREADS
;
1838 DB_set_re_delim(DBObject
* self
, PyObject
* args
)
1843 if (!PyArg_ParseTuple(args
,"b:set_re_delim", &delim
)) {
1845 if (!PyArg_ParseTuple(args
,"c:set_re_delim", &delim
))
1849 CHECK_DB_NOT_CLOSED(self
);
1851 MYDB_BEGIN_ALLOW_THREADS
;
1852 err
= self
->db
->set_re_delim(self
->db
, delim
);
1853 MYDB_END_ALLOW_THREADS
;
1859 DB_set_re_len(DBObject
* self
, PyObject
* args
)
1863 if (!PyArg_ParseTuple(args
,"i:set_re_len", &len
))
1865 CHECK_DB_NOT_CLOSED(self
);
1867 MYDB_BEGIN_ALLOW_THREADS
;
1868 err
= self
->db
->set_re_len(self
->db
, len
);
1869 MYDB_END_ALLOW_THREADS
;
1876 DB_set_re_pad(DBObject
* self
, PyObject
* args
)
1881 if (!PyArg_ParseTuple(args
,"b:set_re_pad", &pad
)) {
1883 if (!PyArg_ParseTuple(args
,"c:set_re_pad", &pad
))
1886 CHECK_DB_NOT_CLOSED(self
);
1888 MYDB_BEGIN_ALLOW_THREADS
;
1889 err
= self
->db
->set_re_pad(self
->db
, pad
);
1890 MYDB_END_ALLOW_THREADS
;
1897 DB_set_re_source(DBObject
* self
, PyObject
* args
)
1902 if (!PyArg_ParseTuple(args
,"s:set_re_source", &re_source
))
1904 CHECK_DB_NOT_CLOSED(self
);
1906 MYDB_BEGIN_ALLOW_THREADS
;
1907 err
= self
->db
->set_re_source(self
->db
, re_source
);
1908 MYDB_END_ALLOW_THREADS
;
1916 DB_set_q_extentsize(DBObject
* self
, PyObject
* args
)
1921 if (!PyArg_ParseTuple(args
,"i:set_q_extentsize", &extentsize
))
1923 CHECK_DB_NOT_CLOSED(self
);
1925 MYDB_BEGIN_ALLOW_THREADS
;
1926 err
= self
->db
->set_q_extentsize(self
->db
, extentsize
);
1927 MYDB_END_ALLOW_THREADS
;
1934 DB_stat(DBObject
* self
, PyObject
* args
)
1936 int err
, flags
= 0, type
;
1941 if (!PyArg_ParseTuple(args
, "|i:stat", &flags
))
1943 CHECK_DB_NOT_CLOSED(self
);
1945 MYDB_BEGIN_ALLOW_THREADS
;
1947 err
= self
->db
->stat(self
->db
, &sp
, flags
);
1949 err
= self
->db
->stat(self
->db
, &sp
, NULL
, flags
);
1951 MYDB_END_ALLOW_THREADS
;
1956 /* Turn the stat structure into a dictionary */
1957 type
= _DB_get_type(self
);
1958 if ((type
== -1) || ((d
= PyDict_New()) == NULL
)) {
1963 #define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
1964 #define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
1965 #define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
1969 MAKE_HASH_ENTRY(magic
);
1970 MAKE_HASH_ENTRY(version
);
1971 MAKE_HASH_ENTRY(nkeys
);
1972 MAKE_HASH_ENTRY(ndata
);
1973 MAKE_HASH_ENTRY(pagesize
);
1975 MAKE_HASH_ENTRY(nelem
);
1977 MAKE_HASH_ENTRY(ffactor
);
1978 MAKE_HASH_ENTRY(buckets
);
1979 MAKE_HASH_ENTRY(free
);
1980 MAKE_HASH_ENTRY(bfree
);
1981 MAKE_HASH_ENTRY(bigpages
);
1982 MAKE_HASH_ENTRY(big_bfree
);
1983 MAKE_HASH_ENTRY(overflows
);
1984 MAKE_HASH_ENTRY(ovfl_free
);
1985 MAKE_HASH_ENTRY(dup
);
1986 MAKE_HASH_ENTRY(dup_free
);
1991 MAKE_BT_ENTRY(magic
);
1992 MAKE_BT_ENTRY(version
);
1993 MAKE_BT_ENTRY(nkeys
);
1994 MAKE_BT_ENTRY(ndata
);
1995 MAKE_BT_ENTRY(pagesize
);
1996 MAKE_BT_ENTRY(minkey
);
1997 MAKE_BT_ENTRY(re_len
);
1998 MAKE_BT_ENTRY(re_pad
);
1999 MAKE_BT_ENTRY(levels
);
2000 MAKE_BT_ENTRY(int_pg
);
2001 MAKE_BT_ENTRY(leaf_pg
);
2002 MAKE_BT_ENTRY(dup_pg
);
2003 MAKE_BT_ENTRY(over_pg
);
2004 MAKE_BT_ENTRY(free
);
2005 MAKE_BT_ENTRY(int_pgfree
);
2006 MAKE_BT_ENTRY(leaf_pgfree
);
2007 MAKE_BT_ENTRY(dup_pgfree
);
2008 MAKE_BT_ENTRY(over_pgfree
);
2012 MAKE_QUEUE_ENTRY(magic
);
2013 MAKE_QUEUE_ENTRY(version
);
2014 MAKE_QUEUE_ENTRY(nkeys
);
2015 MAKE_QUEUE_ENTRY(ndata
);
2016 MAKE_QUEUE_ENTRY(pagesize
);
2017 MAKE_QUEUE_ENTRY(pages
);
2018 MAKE_QUEUE_ENTRY(re_len
);
2019 MAKE_QUEUE_ENTRY(re_pad
);
2020 MAKE_QUEUE_ENTRY(pgfree
);
2022 MAKE_QUEUE_ENTRY(start
);
2024 MAKE_QUEUE_ENTRY(first_recno
);
2025 MAKE_QUEUE_ENTRY(cur_recno
);
2029 PyErr_SetString(PyExc_TypeError
, "Unknown DB type, unable to stat");
2034 #undef MAKE_HASH_ENTRY
2035 #undef MAKE_BT_ENTRY
2036 #undef MAKE_QUEUE_ENTRY
2043 DB_sync(DBObject
* self
, PyObject
* args
)
2048 if (!PyArg_ParseTuple(args
,"|i:sync", &flags
))
2050 CHECK_DB_NOT_CLOSED(self
);
2052 MYDB_BEGIN_ALLOW_THREADS
;
2053 err
= self
->db
->sync(self
->db
, flags
);
2054 MYDB_END_ALLOW_THREADS
;
2062 DB_truncate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2066 PyObject
* txnobj
= NULL
;
2068 char* kwnames
[] = { "txn", "flags", NULL
};
2070 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
2073 CHECK_DB_NOT_CLOSED(self
);
2074 if (!checkTxnObj(txnobj
, &txn
))
2077 MYDB_BEGIN_ALLOW_THREADS
;
2078 err
= self
->db
->truncate(self
->db
, txn
, &count
, flags
);
2079 MYDB_END_ALLOW_THREADS
;
2081 return PyInt_FromLong(count
);
2087 DB_upgrade(DBObject
* self
, PyObject
* args
)
2092 if (!PyArg_ParseTuple(args
,"s|i:upgrade", &filename
, &flags
))
2094 CHECK_DB_NOT_CLOSED(self
);
2096 MYDB_BEGIN_ALLOW_THREADS
;
2097 err
= self
->db
->upgrade(self
->db
, filename
, flags
);
2098 MYDB_END_ALLOW_THREADS
;
2105 DB_verify(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2110 char* outFileName
=NULL
;
2112 char* kwnames
[] = { "filename", "dbname", "outfile", "flags", NULL
};
2114 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zzi:verify", kwnames
,
2115 &fileName
, &dbName
, &outFileName
, &flags
))
2118 CHECK_DB_NOT_CLOSED(self
);
2120 outFile
= fopen(outFileName
, "w");
2122 MYDB_BEGIN_ALLOW_THREADS
;
2123 err
= self
->db
->verify(self
->db
, fileName
, dbName
, outFile
, flags
);
2124 MYDB_END_ALLOW_THREADS
;
2133 DB_set_get_returns_none(DBObject
* self
, PyObject
* args
)
2138 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
2140 CHECK_DB_NOT_CLOSED(self
);
2142 oldValue
= self
->getReturnsNone
;
2143 self
->getReturnsNone
= flags
;
2144 return PyInt_FromLong(oldValue
);
2149 DB_set_encrypt(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2153 char *passwd
= NULL
;
2154 char* kwnames
[] = { "passwd", "flags", NULL
};
2156 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
2161 MYDB_BEGIN_ALLOW_THREADS
;
2162 err
= self
->db
->set_encrypt(self
->db
, passwd
, flags
);
2163 MYDB_END_ALLOW_THREADS
;
2168 #endif /* DBVER >= 41 */
2171 /*-------------------------------------------------------------- */
2172 /* Mapping and Dictionary-like access routines */
2174 int DB_length(DBObject
* self
)
2181 if (self
->db
== NULL
) {
2182 PyErr_SetObject(DBError
,
2183 Py_BuildValue("(is)", 0, "DB object has been closed"));
2187 if (self
->haveStat
) { /* Has the stat function been called recently? If
2188 so, we can use the cached value. */
2189 flags
= DB_CACHED_COUNTS
;
2192 MYDB_BEGIN_ALLOW_THREADS
;
2194 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2196 err
= self
->db
->stat(self
->db
, &sp
, NULL
, flags
);
2198 MYDB_END_ALLOW_THREADS
;
2205 /* All the stat structures have matching fields upto the ndata field,
2206 so we can use any of them for the type cast */
2207 size
= ((DB_BTREE_STAT
*)sp
)->bt_ndata
;
2213 PyObject
* DB_subscript(DBObject
* self
, PyObject
* keyobj
)
2220 CHECK_DB_NOT_CLOSED(self
);
2221 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2225 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2226 /* Tell BerkeleyDB to malloc the return value (thread safe) */
2227 data
.flags
= DB_DBT_MALLOC
;
2229 MYDB_BEGIN_ALLOW_THREADS
;
2230 err
= self
->db
->get(self
->db
, NULL
, &key
, &data
, 0);
2231 MYDB_END_ALLOW_THREADS
;
2232 if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
2233 PyErr_SetObject(PyExc_KeyError
, keyobj
);
2236 else if (makeDBError(err
)) {
2240 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
2250 DB_ass_sub(DBObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
)
2256 if (self
->db
== NULL
) {
2257 PyErr_SetObject(DBError
,
2258 Py_BuildValue("(is)", 0, "DB object has been closed"));
2262 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2265 if (dataobj
!= NULL
) {
2266 if (!make_dbt(dataobj
, &data
))
2269 if (self
->setflags
& (DB_DUP
|DB_DUPSORT
))
2270 /* dictionaries shouldn't have duplicate keys */
2271 flags
= DB_NOOVERWRITE
;
2272 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2274 if ((retval
== -1) && (self
->setflags
& (DB_DUP
|DB_DUPSORT
))) {
2275 /* try deleting any old record that matches and then PUT it
2277 _DB_delete(self
, NULL
, &key
, 0);
2279 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2284 /* dataobj == NULL, so delete the key */
2285 retval
= _DB_delete(self
, NULL
, &key
, 0);
2293 DB_has_key(DBObject
* self
, PyObject
* args
)
2298 PyObject
* txnobj
= NULL
;
2301 if (!PyArg_ParseTuple(args
,"O|O:has_key", &keyobj
, &txnobj
))
2303 CHECK_DB_NOT_CLOSED(self
);
2304 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2306 if (!checkTxnObj(txnobj
, &txn
))
2309 /* This causes ENOMEM to be returned when the db has the key because
2310 it has a record but can't allocate a buffer for the data. This saves
2311 having to deal with data we won't be using.
2314 data
.flags
= DB_DBT_USERMEM
;
2316 MYDB_BEGIN_ALLOW_THREADS
;
2317 err
= self
->db
->get(self
->db
, NULL
, &key
, &data
, 0);
2318 MYDB_END_ALLOW_THREADS
;
2320 return PyInt_FromLong((err
== ENOMEM
) || (err
== 0));
2324 #define _KEYS_LIST 1
2325 #define _VALUES_LIST 2
2326 #define _ITEMS_LIST 3
2329 _DB_make_list(DBObject
* self
, DB_TXN
* txn
, int type
)
2336 PyObject
* item
= NULL
;
2338 CHECK_DB_NOT_CLOSED(self
);
2342 dbtype
= _DB_get_type(self
);
2346 list
= PyList_New(0);
2348 PyErr_SetString(PyExc_MemoryError
, "PyList_New failed");
2353 MYDB_BEGIN_ALLOW_THREADS
;
2354 err
= self
->db
->cursor(self
->db
, NULL
, &cursor
, 0);
2355 MYDB_END_ALLOW_THREADS
;
2358 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2359 key
.flags
= DB_DBT_REALLOC
;
2360 data
.flags
= DB_DBT_REALLOC
;
2363 while (1) { /* use the cursor to traverse the DB, collecting items */
2364 MYDB_BEGIN_ALLOW_THREADS
;
2365 err
= cursor
->c_get(cursor
, &key
, &data
, DB_NEXT
);
2366 MYDB_END_ALLOW_THREADS
;
2369 /* for any error, break out of the loop */
2379 item
= PyString_FromStringAndSize((char*)key
.data
, key
.size
);
2383 item
= PyInt_FromLong(*((db_recno_t
*)key
.data
));
2389 item
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
2397 item
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
2402 item
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
2403 data
.data
, data
.size
);
2410 PyErr_SetString(PyExc_MemoryError
, "List item creation failed");
2414 PyList_Append(list
, item
);
2418 /* DB_NOTFOUND is okay, it just means we got to the end */
2419 if (err
!= DB_NOTFOUND
&& makeDBError(err
)) {
2427 MYDB_BEGIN_ALLOW_THREADS
;
2428 cursor
->c_close(cursor
);
2429 MYDB_END_ALLOW_THREADS
;
2435 DB_keys(DBObject
* self
, PyObject
* args
)
2437 PyObject
* txnobj
= NULL
;
2440 if (!PyArg_ParseTuple(args
,"|O:keys", &txnobj
))
2442 if (!checkTxnObj(txnobj
, &txn
))
2444 return _DB_make_list(self
, txn
, _KEYS_LIST
);
2449 DB_items(DBObject
* self
, PyObject
* args
)
2451 PyObject
* txnobj
= NULL
;
2454 if (!PyArg_ParseTuple(args
,"|O:items", &txnobj
))
2456 if (!checkTxnObj(txnobj
, &txn
))
2458 return _DB_make_list(self
, txn
, _ITEMS_LIST
);
2463 DB_values(DBObject
* self
, PyObject
* args
)
2465 PyObject
* txnobj
= NULL
;
2468 if (!PyArg_ParseTuple(args
,"|O:values", &txnobj
))
2470 if (!checkTxnObj(txnobj
, &txn
))
2472 return _DB_make_list(self
, txn
, _VALUES_LIST
);
2475 /* --------------------------------------------------------------------- */
2476 /* DBCursor methods */
2480 DBC_close(DBCursorObject
* self
, PyObject
* args
)
2484 if (!PyArg_ParseTuple(args
, ":close"))
2487 if (self
->dbc
!= NULL
) {
2488 MYDB_BEGIN_ALLOW_THREADS
;
2489 err
= self
->dbc
->c_close(self
->dbc
);
2491 MYDB_END_ALLOW_THREADS
;
2499 DBC_count(DBCursorObject
* self
, PyObject
* args
)
2505 if (!PyArg_ParseTuple(args
, "|i:count", &flags
))
2508 CHECK_CURSOR_NOT_CLOSED(self
);
2510 MYDB_BEGIN_ALLOW_THREADS
;
2511 err
= self
->dbc
->c_count(self
->dbc
, &count
, flags
);
2512 MYDB_END_ALLOW_THREADS
;
2515 return PyInt_FromLong(count
);
2520 DBC_current(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2522 return _DBCursor_get(self
,DB_CURRENT
,args
,kwargs
,"|iii:current");
2527 DBC_delete(DBCursorObject
* self
, PyObject
* args
)
2531 if (!PyArg_ParseTuple(args
, "|i:delete", &flags
))
2534 CHECK_CURSOR_NOT_CLOSED(self
);
2536 MYDB_BEGIN_ALLOW_THREADS
;
2537 err
= self
->dbc
->c_del(self
->dbc
, flags
);
2538 MYDB_END_ALLOW_THREADS
;
2541 self
->mydb
->haveStat
= 0;
2547 DBC_dup(DBCursorObject
* self
, PyObject
* args
)
2552 if (!PyArg_ParseTuple(args
, "|i:dup", &flags
))
2555 CHECK_CURSOR_NOT_CLOSED(self
);
2557 MYDB_BEGIN_ALLOW_THREADS
;
2558 err
= self
->dbc
->c_dup(self
->dbc
, &dbc
, flags
);
2559 MYDB_END_ALLOW_THREADS
;
2562 return (PyObject
*) newDBCursorObject(dbc
, self
->mydb
);
2566 DBC_first(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2568 return _DBCursor_get(self
,DB_FIRST
,args
,kwargs
,"|iii:first");
2573 DBC_get(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2576 PyObject
* keyobj
= NULL
;
2577 PyObject
* dataobj
= NULL
;
2578 PyObject
* retval
= NULL
;
2582 char* kwnames
[] = { "key","data", "flags", "dlen", "doff", NULL
};
2586 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:get", &kwnames
[2],
2587 &flags
, &dlen
, &doff
))
2590 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:get",
2592 &keyobj
, &flags
, &dlen
, &doff
))
2595 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:get",
2596 kwnames
, &keyobj
, &dataobj
,
2597 &flags
, &dlen
, &doff
))
2604 CHECK_CURSOR_NOT_CLOSED(self
);
2606 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
2608 if (dataobj
&& !make_dbt(dataobj
, &data
))
2610 if (!add_partial_dbt(&data
, dlen
, doff
))
2613 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
2614 data
.flags
= DB_DBT_MALLOC
;
2615 key
.flags
= DB_DBT_MALLOC
;
2618 MYDB_BEGIN_ALLOW_THREADS
;
2619 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
2620 MYDB_END_ALLOW_THREADS
;
2623 if ((err
== DB_NOTFOUND
) && self
->mydb
->getReturnsNone
) {
2627 else if (makeDBError(err
)) {
2631 switch (_DB_get_type(self
->mydb
)) {
2638 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
2639 data
.data
, data
.size
);
2643 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
2644 data
.data
, data
.size
);
2655 DBC_get_recno(DBCursorObject
* self
, PyObject
* args
)
2662 if (!PyArg_ParseTuple(args
, ":get_recno"))
2665 CHECK_CURSOR_NOT_CLOSED(self
);
2669 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
2670 /* Tell BerkeleyDB to malloc the return value (thread safe) */
2671 data
.flags
= DB_DBT_MALLOC
;
2672 key
.flags
= DB_DBT_MALLOC
;
2675 MYDB_BEGIN_ALLOW_THREADS
;
2676 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, DB_GET_RECNO
);
2677 MYDB_END_ALLOW_THREADS
;
2680 recno
= *((db_recno_t
*)data
.data
);
2683 return PyInt_FromLong(recno
);
2688 DBC_last(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2690 return _DBCursor_get(self
,DB_LAST
,args
,kwargs
,"|iii:last");
2695 DBC_next(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2697 return _DBCursor_get(self
,DB_NEXT
,args
,kwargs
,"|iii:next");
2702 DBC_prev(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2704 return _DBCursor_get(self
,DB_PREV
,args
,kwargs
,"|iii:prev");
2709 DBC_put(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2712 PyObject
* keyobj
, *dataobj
;
2714 char* kwnames
[] = { "key", "data", "flags", "dlen", "doff", NULL
};
2718 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iii:put", kwnames
,
2719 &keyobj
, &dataobj
, &flags
, &dlen
, &doff
))
2722 CHECK_CURSOR_NOT_CLOSED(self
);
2724 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
2726 if (!make_dbt(dataobj
, &data
))
2728 if (!add_partial_dbt(&data
, dlen
, doff
)) return NULL
;
2730 MYDB_BEGIN_ALLOW_THREADS
;
2731 err
= self
->dbc
->c_put(self
->dbc
, &key
, &data
, flags
);
2732 MYDB_END_ALLOW_THREADS
;
2735 self
->mydb
->haveStat
= 0;
2741 DBC_set(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2745 PyObject
* retval
, *keyobj
;
2746 char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
2750 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set", kwnames
,
2751 &keyobj
, &flags
, &dlen
, &doff
))
2754 CHECK_CURSOR_NOT_CLOSED(self
);
2756 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
2760 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
2761 /* Tell BerkeleyDB to malloc the return value (thread safe) */
2762 data
.flags
= DB_DBT_MALLOC
;
2764 if (!add_partial_dbt(&data
, dlen
, doff
))
2767 MYDB_BEGIN_ALLOW_THREADS
;
2768 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET
);
2769 MYDB_END_ALLOW_THREADS
;
2770 if (makeDBError(err
)) {
2774 switch (_DB_get_type(self
->mydb
)) {
2781 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
2782 data
.data
, data
.size
);
2786 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
2787 data
.data
, data
.size
);
2799 DBC_set_range(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2803 PyObject
* retval
, *keyobj
;
2804 char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
2808 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set_range", kwnames
,
2809 &keyobj
, &flags
, &dlen
, &doff
))
2812 CHECK_CURSOR_NOT_CLOSED(self
);
2814 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
2818 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
2819 /* Tell BerkeleyDB to malloc the return value (thread safe) */
2820 data
.flags
= DB_DBT_MALLOC
;
2821 key
.flags
= DB_DBT_MALLOC
;
2823 if (!add_partial_dbt(&data
, dlen
, doff
))
2825 MYDB_BEGIN_ALLOW_THREADS
;
2826 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RANGE
);
2827 MYDB_END_ALLOW_THREADS
;
2828 if (makeDBError(err
)) {
2832 switch (_DB_get_type(self
->mydb
)) {
2839 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
2840 data
.data
, data
.size
);
2844 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
2845 data
.data
, data
.size
);
2857 DBC_get_both(DBCursorObject
* self
, PyObject
* args
)
2861 PyObject
* retval
, *keyobj
, *dataobj
;
2863 if (!PyArg_ParseTuple(args
, "OO|i:get_both", &keyobj
, &dataobj
, &flags
))
2866 CHECK_CURSOR_NOT_CLOSED(self
);
2868 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
2870 if (!make_dbt(dataobj
, &data
))
2873 MYDB_BEGIN_ALLOW_THREADS
;
2874 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_GET_BOTH
);
2875 MYDB_END_ALLOW_THREADS
;
2876 if (makeDBError(err
)) {
2880 switch (_DB_get_type(self
->mydb
)) {
2887 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
2888 data
.data
, data
.size
);
2892 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
2893 data
.data
, data
.size
);
2904 DBC_set_recno(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2906 int err
, irecno
, flags
=0;
2912 char* kwnames
[] = { "recno","flags", "dlen", "doff", NULL
};
2914 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|iii:set_recno", kwnames
,
2915 &irecno
, &flags
, &dlen
, &doff
))
2918 CHECK_CURSOR_NOT_CLOSED(self
);
2921 recno
= (db_recno_t
) irecno
;
2922 /* use allocated space so DB will be able to realloc room for the real
2924 key
.data
= malloc(sizeof(db_recno_t
));
2925 if (key
.data
== NULL
) {
2926 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
2929 key
.size
= sizeof(db_recno_t
);
2930 key
.ulen
= key
.size
;
2931 memcpy(key
.data
, &recno
, sizeof(db_recno_t
));
2932 key
.flags
= DB_DBT_REALLOC
;
2935 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
2936 /* Tell BerkeleyDB to malloc the return value (thread safe) */
2937 data
.flags
= DB_DBT_MALLOC
;
2939 if (!add_partial_dbt(&data
, dlen
, doff
))
2942 MYDB_BEGIN_ALLOW_THREADS
;
2943 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RECNO
);
2944 MYDB_END_ALLOW_THREADS
;
2945 if (makeDBError(err
)) {
2948 else { /* Can only be used for BTrees, so no need to return int key */
2949 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
2950 data
.data
, data
.size
);
2960 DBC_consume(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2962 return _DBCursor_get(self
,DB_CONSUME
,args
,kwargs
,"|iii:consume");
2967 DBC_next_dup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2969 return _DBCursor_get(self
,DB_NEXT_DUP
,args
,kwargs
,"|iii:next_dup");
2974 DBC_next_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2976 return _DBCursor_get(self
,DB_NEXT_NODUP
,args
,kwargs
,"|iii:next_nodup");
2981 DBC_prev_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2983 return _DBCursor_get(self
,DB_PREV_NODUP
,args
,kwargs
,"|iii:prev_nodup");
2988 DBC_join_item(DBCursorObject
* self
, PyObject
* args
)
2994 if (!PyArg_ParseTuple(args
, ":join_item"))
2997 CHECK_CURSOR_NOT_CLOSED(self
);
3001 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3002 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3003 key
.flags
= DB_DBT_MALLOC
;
3006 MYDB_BEGIN_ALLOW_THREADS
;
3007 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, DB_JOIN_ITEM
);
3008 MYDB_END_ALLOW_THREADS
;
3009 if (makeDBError(err
)) {
3013 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
);
3022 /* --------------------------------------------------------------------- */
3027 DBEnv_close(DBEnvObject
* self
, PyObject
* args
)
3031 if (!PyArg_ParseTuple(args
, "|i:close", &flags
))
3033 if (!self
->closed
) { /* Don't close more than once */
3034 MYDB_BEGIN_ALLOW_THREADS
;
3035 err
= self
->db_env
->close(self
->db_env
, flags
);
3036 MYDB_END_ALLOW_THREADS
;
3037 /* after calling DBEnv->close, regardless of error, this DBEnv
3038 * may not be accessed again (BerkeleyDB docs). */
3040 self
->db_env
= NULL
;
3048 DBEnv_open(DBEnvObject
* self
, PyObject
* args
)
3050 int err
, flags
=0, mode
=0660;
3053 if (!PyArg_ParseTuple(args
, "z|ii:open", &db_home
, &flags
, &mode
))
3056 CHECK_ENV_NOT_CLOSED(self
);
3058 MYDB_BEGIN_ALLOW_THREADS
;
3059 err
= self
->db_env
->open(self
->db_env
, db_home
, flags
, mode
);
3060 MYDB_END_ALLOW_THREADS
;
3063 self
->flags
= flags
;
3069 DBEnv_remove(DBEnvObject
* self
, PyObject
* args
)
3074 if (!PyArg_ParseTuple(args
, "s|i:remove", &db_home
, &flags
))
3076 CHECK_ENV_NOT_CLOSED(self
);
3077 MYDB_BEGIN_ALLOW_THREADS
;
3078 err
= self
->db_env
->remove(self
->db_env
, db_home
, flags
);
3079 MYDB_END_ALLOW_THREADS
;
3086 DBEnv_dbremove(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3091 char *database
= NULL
;
3092 PyObject
*txnobj
= NULL
;
3094 char* kwnames
[] = { "file", "database", "txn", "flags", NULL
};
3096 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ss|Oi:dbremove", kwnames
,
3097 &file
, &database
, &txnobj
, &flags
)) {
3100 if (!checkTxnObj(txnobj
, &txn
)) {
3103 CHECK_ENV_NOT_CLOSED(self
);
3104 MYDB_BEGIN_ALLOW_THREADS
;
3105 err
= self
->db_env
->dbremove(self
->db_env
, txn
, file
, database
, flags
);
3106 MYDB_END_ALLOW_THREADS
;
3112 DBEnv_dbrename(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3117 char *database
= NULL
;
3118 char *newname
= NULL
;
3119 PyObject
*txnobj
= NULL
;
3121 char* kwnames
[] = { "file", "database", "newname", "txn", "flags", NULL
};
3123 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "sss|Oi:dbrename", kwnames
,
3124 &file
, &database
, &newname
, &txnobj
, &flags
)) {
3127 if (!checkTxnObj(txnobj
, &txn
)) {
3130 CHECK_ENV_NOT_CLOSED(self
);
3131 MYDB_BEGIN_ALLOW_THREADS
;
3132 err
= self
->db_env
->dbrename(self
->db_env
, txn
, file
, database
, newname
,
3134 MYDB_END_ALLOW_THREADS
;
3140 DBEnv_set_encrypt(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3144 char *passwd
= NULL
;
3145 char* kwnames
[] = { "passwd", "flags", NULL
};
3147 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
3152 MYDB_BEGIN_ALLOW_THREADS
;
3153 err
= self
->db_env
->set_encrypt(self
->db_env
, passwd
, flags
);
3154 MYDB_END_ALLOW_THREADS
;
3159 #endif /* DBVER >= 41 */
3162 DBEnv_set_cachesize(DBEnvObject
* self
, PyObject
* args
)
3164 int err
, gbytes
=0, bytes
=0, ncache
=0;
3166 if (!PyArg_ParseTuple(args
, "ii|i:set_cachesize",
3167 &gbytes
, &bytes
, &ncache
))
3169 CHECK_ENV_NOT_CLOSED(self
);
3171 MYDB_BEGIN_ALLOW_THREADS
;
3172 err
= self
->db_env
->set_cachesize(self
->db_env
, gbytes
, bytes
, ncache
);
3173 MYDB_END_ALLOW_THREADS
;
3181 DBEnv_set_flags(DBEnvObject
* self
, PyObject
* args
)
3183 int err
, flags
=0, onoff
=0;
3185 if (!PyArg_ParseTuple(args
, "ii:set_flags",
3188 CHECK_ENV_NOT_CLOSED(self
);
3190 MYDB_BEGIN_ALLOW_THREADS
;
3191 err
= self
->db_env
->set_flags(self
->db_env
, flags
, onoff
);
3192 MYDB_END_ALLOW_THREADS
;
3200 DBEnv_set_data_dir(DBEnvObject
* self
, PyObject
* args
)
3205 if (!PyArg_ParseTuple(args
, "s:set_data_dir", &dir
))
3207 CHECK_ENV_NOT_CLOSED(self
);
3209 MYDB_BEGIN_ALLOW_THREADS
;
3210 err
= self
->db_env
->set_data_dir(self
->db_env
, dir
);
3211 MYDB_END_ALLOW_THREADS
;
3218 DBEnv_set_lg_bsize(DBEnvObject
* self
, PyObject
* args
)
3222 if (!PyArg_ParseTuple(args
, "i:set_lg_bsize", &lg_bsize
))
3224 CHECK_ENV_NOT_CLOSED(self
);
3226 MYDB_BEGIN_ALLOW_THREADS
;
3227 err
= self
->db_env
->set_lg_bsize(self
->db_env
, lg_bsize
);
3228 MYDB_END_ALLOW_THREADS
;
3235 DBEnv_set_lg_dir(DBEnvObject
* self
, PyObject
* args
)
3240 if (!PyArg_ParseTuple(args
, "s:set_lg_dir", &dir
))
3242 CHECK_ENV_NOT_CLOSED(self
);
3244 MYDB_BEGIN_ALLOW_THREADS
;
3245 err
= self
->db_env
->set_lg_dir(self
->db_env
, dir
);
3246 MYDB_END_ALLOW_THREADS
;
3252 DBEnv_set_lg_max(DBEnvObject
* self
, PyObject
* args
)
3256 if (!PyArg_ParseTuple(args
, "i:set_lg_max", &lg_max
))
3258 CHECK_ENV_NOT_CLOSED(self
);
3260 MYDB_BEGIN_ALLOW_THREADS
;
3261 err
= self
->db_env
->set_lg_max(self
->db_env
, lg_max
);
3262 MYDB_END_ALLOW_THREADS
;
3269 DBEnv_set_lk_detect(DBEnvObject
* self
, PyObject
* args
)
3273 if (!PyArg_ParseTuple(args
, "i:set_lk_detect", &lk_detect
))
3275 CHECK_ENV_NOT_CLOSED(self
);
3277 MYDB_BEGIN_ALLOW_THREADS
;
3278 err
= self
->db_env
->set_lk_detect(self
->db_env
, lk_detect
);
3279 MYDB_END_ALLOW_THREADS
;
3286 DBEnv_set_lk_max(DBEnvObject
* self
, PyObject
* args
)
3290 if (!PyArg_ParseTuple(args
, "i:set_lk_max", &max
))
3292 CHECK_ENV_NOT_CLOSED(self
);
3294 MYDB_BEGIN_ALLOW_THREADS
;
3295 err
= self
->db_env
->set_lk_max(self
->db_env
, max
);
3296 MYDB_END_ALLOW_THREADS
;
3305 DBEnv_set_lk_max_locks(DBEnvObject
* self
, PyObject
* args
)
3309 if (!PyArg_ParseTuple(args
, "i:set_lk_max_locks", &max
))
3311 CHECK_ENV_NOT_CLOSED(self
);
3313 MYDB_BEGIN_ALLOW_THREADS
;
3314 err
= self
->db_env
->set_lk_max_locks(self
->db_env
, max
);
3315 MYDB_END_ALLOW_THREADS
;
3322 DBEnv_set_lk_max_lockers(DBEnvObject
* self
, PyObject
* args
)
3326 if (!PyArg_ParseTuple(args
, "i:set_lk_max_lockers", &max
))
3328 CHECK_ENV_NOT_CLOSED(self
);
3330 MYDB_BEGIN_ALLOW_THREADS
;
3331 err
= self
->db_env
->set_lk_max_lockers(self
->db_env
, max
);
3332 MYDB_END_ALLOW_THREADS
;
3339 DBEnv_set_lk_max_objects(DBEnvObject
* self
, PyObject
* args
)
3343 if (!PyArg_ParseTuple(args
, "i:set_lk_max_objects", &max
))
3345 CHECK_ENV_NOT_CLOSED(self
);
3347 MYDB_BEGIN_ALLOW_THREADS
;
3348 err
= self
->db_env
->set_lk_max_objects(self
->db_env
, max
);
3349 MYDB_END_ALLOW_THREADS
;
3358 DBEnv_set_mp_mmapsize(DBEnvObject
* self
, PyObject
* args
)
3360 int err
, mp_mmapsize
;
3362 if (!PyArg_ParseTuple(args
, "i:set_mp_mmapsize", &mp_mmapsize
))
3364 CHECK_ENV_NOT_CLOSED(self
);
3366 MYDB_BEGIN_ALLOW_THREADS
;
3367 err
= self
->db_env
->set_mp_mmapsize(self
->db_env
, mp_mmapsize
);
3368 MYDB_END_ALLOW_THREADS
;
3375 DBEnv_set_tmp_dir(DBEnvObject
* self
, PyObject
* args
)
3380 if (!PyArg_ParseTuple(args
, "s:set_tmp_dir", &dir
))
3382 CHECK_ENV_NOT_CLOSED(self
);
3384 MYDB_BEGIN_ALLOW_THREADS
;
3385 err
= self
->db_env
->set_tmp_dir(self
->db_env
, dir
);
3386 MYDB_END_ALLOW_THREADS
;
3393 DBEnv_txn_begin(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3396 PyObject
* txnobj
= NULL
;
3398 char* kwnames
[] = { "parent", "flags", NULL
};
3400 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:txn_begin", kwnames
,
3404 if (!checkTxnObj(txnobj
, &txn
))
3406 CHECK_ENV_NOT_CLOSED(self
);
3408 return (PyObject
*)newDBTxnObject(self
, txn
, flags
);
3413 DBEnv_txn_checkpoint(DBEnvObject
* self
, PyObject
* args
)
3415 int err
, kbyte
=0, min
=0, flags
=0;
3417 if (!PyArg_ParseTuple(args
, "|iii:txn_checkpoint", &kbyte
, &min
, &flags
))
3419 CHECK_ENV_NOT_CLOSED(self
);
3421 MYDB_BEGIN_ALLOW_THREADS
;
3423 err
= self
->db_env
->txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
3425 err
= txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
3427 MYDB_END_ALLOW_THREADS
;
3434 DBEnv_set_tx_max(DBEnvObject
* self
, PyObject
* args
)
3438 if (!PyArg_ParseTuple(args
, "i:set_tx_max", &max
))
3440 CHECK_ENV_NOT_CLOSED(self
);
3442 MYDB_BEGIN_ALLOW_THREADS
;
3443 err
= self
->db_env
->set_tx_max(self
->db_env
, max
);
3444 MYDB_END_ALLOW_THREADS
;
3451 DBEnv_lock_detect(DBEnvObject
* self
, PyObject
* args
)
3453 int err
, atype
, flags
=0;
3456 if (!PyArg_ParseTuple(args
, "i|i:lock_detect", &atype
, &flags
))
3458 CHECK_ENV_NOT_CLOSED(self
);
3460 MYDB_BEGIN_ALLOW_THREADS
;
3462 err
= self
->db_env
->lock_detect(self
->db_env
, flags
, atype
, &aborted
);
3464 err
= lock_detect(self
->db_env
, flags
, atype
, &aborted
);
3466 MYDB_END_ALLOW_THREADS
;
3468 return PyInt_FromLong(aborted
);
3473 DBEnv_lock_get(DBEnvObject
* self
, PyObject
* args
)
3476 int locker
, lock_mode
;
3480 if (!PyArg_ParseTuple(args
, "iOi|i:lock_get", &locker
, &objobj
, &lock_mode
, &flags
))
3484 if (!make_dbt(objobj
, &obj
))
3487 return (PyObject
*)newDBLockObject(self
, locker
, &obj
, lock_mode
, flags
);
3492 DBEnv_lock_id(DBEnvObject
* self
, PyObject
* args
)
3497 if (!PyArg_ParseTuple(args
, ":lock_id"))
3500 CHECK_ENV_NOT_CLOSED(self
);
3501 MYDB_BEGIN_ALLOW_THREADS
;
3503 err
= self
->db_env
->lock_id(self
->db_env
, &theID
);
3505 err
= lock_id(self
->db_env
, &theID
);
3507 MYDB_END_ALLOW_THREADS
;
3510 return PyInt_FromLong((long)theID
);
3515 DBEnv_lock_put(DBEnvObject
* self
, PyObject
* args
)
3518 DBLockObject
* dblockobj
;
3520 if (!PyArg_ParseTuple(args
, "O!:lock_put", &DBLock_Type
, &dblockobj
))
3523 CHECK_ENV_NOT_CLOSED(self
);
3524 MYDB_BEGIN_ALLOW_THREADS
;
3526 err
= self
->db_env
->lock_put(self
->db_env
, &dblockobj
->lock
);
3528 err
= lock_put(self
->db_env
, &dblockobj
->lock
);
3530 MYDB_END_ALLOW_THREADS
;
3537 DBEnv_lock_stat(DBEnvObject
* self
, PyObject
* args
)
3542 u_int32_t flags
= 0;
3544 if (!PyArg_ParseTuple(args
, "|i:lock_stat", &flags
))
3546 CHECK_ENV_NOT_CLOSED(self
);
3548 MYDB_BEGIN_ALLOW_THREADS
;
3550 err
= self
->db_env
->lock_stat(self
->db_env
, &sp
, flags
);
3553 err
= lock_stat(self
->db_env
, &sp
);
3555 err
= lock_stat(self
->db_env
, &sp
, NULL
);
3558 MYDB_END_ALLOW_THREADS
;
3561 /* Turn the stat structure into a dictionary */
3568 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
3575 MAKE_ENTRY(maxlocks
);
3576 MAKE_ENTRY(maxlockers
);
3577 MAKE_ENTRY(maxobjects
);
3579 MAKE_ENTRY(maxnlocks
);
3581 MAKE_ENTRY(nlockers
);
3582 MAKE_ENTRY(maxnlockers
);
3584 MAKE_ENTRY(nobjects
);
3585 MAKE_ENTRY(maxnobjects
);
3587 MAKE_ENTRY(nrequests
);
3588 MAKE_ENTRY(nreleases
);
3589 MAKE_ENTRY(nnowaits
);
3590 MAKE_ENTRY(nconflicts
);
3591 MAKE_ENTRY(ndeadlocks
);
3592 MAKE_ENTRY(regsize
);
3593 MAKE_ENTRY(region_wait
);
3594 MAKE_ENTRY(region_nowait
);
3603 DBEnv_log_archive(DBEnvObject
* self
, PyObject
* args
)
3607 char **log_list_start
, **log_list
;
3609 PyObject
* item
= NULL
;
3611 if (!PyArg_ParseTuple(args
, "|i:log_archive", &flags
))
3614 CHECK_ENV_NOT_CLOSED(self
);
3615 MYDB_BEGIN_ALLOW_THREADS
;
3617 err
= self
->db_env
->log_archive(self
->db_env
, &log_list
, flags
);
3619 err
= log_archive(self
->db_env
, &log_list
, flags
);
3621 err
= log_archive(self
->db_env
, &log_list
, flags
, NULL
);
3623 MYDB_END_ALLOW_THREADS
;
3626 list
= PyList_New(0);
3628 PyErr_SetString(PyExc_MemoryError
, "PyList_New failed");
3633 for (log_list_start
= log_list
; *log_list
!= NULL
; ++log_list
) {
3634 item
= PyString_FromString (*log_list
);
3637 PyErr_SetString(PyExc_MemoryError
,
3638 "List item creation failed");
3642 PyList_Append(list
, item
);
3645 free(log_list_start
);
3652 DBEnv_txn_stat(DBEnvObject
* self
, PyObject
* args
)
3659 if (!PyArg_ParseTuple(args
, "|i:txn_stat", &flags
))
3661 CHECK_ENV_NOT_CLOSED(self
);
3663 MYDB_BEGIN_ALLOW_THREADS
;
3665 err
= self
->db_env
->txn_stat(self
->db_env
, &sp
, flags
);
3667 err
= txn_stat(self
->db_env
, &sp
);
3669 err
= txn_stat(self
->db_env
, &sp
, NULL
);
3671 MYDB_END_ALLOW_THREADS
;
3674 /* Turn the stat structure into a dictionary */
3681 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
3683 MAKE_ENTRY(time_ckp
);
3684 MAKE_ENTRY(last_txnid
);
3685 MAKE_ENTRY(maxtxns
);
3686 MAKE_ENTRY(nactive
);
3687 MAKE_ENTRY(maxnactive
);
3688 MAKE_ENTRY(nbegins
);
3689 MAKE_ENTRY(naborts
);
3690 MAKE_ENTRY(ncommits
);
3691 MAKE_ENTRY(regsize
);
3692 MAKE_ENTRY(region_wait
);
3693 MAKE_ENTRY(region_nowait
);
3702 DBEnv_set_get_returns_none(DBEnvObject
* self
, PyObject
* args
)
3707 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
3709 CHECK_ENV_NOT_CLOSED(self
);
3711 oldValue
= self
->getReturnsNone
;
3712 self
->getReturnsNone
= flags
;
3713 return PyInt_FromLong(oldValue
);
3717 /* --------------------------------------------------------------------- */
3722 DBTxn_commit(DBTxnObject
* self
, PyObject
* args
)
3726 if (!PyArg_ParseTuple(args
, "|i:commit", &flags
))
3729 MYDB_BEGIN_ALLOW_THREADS
;
3731 err
= self
->txn
->commit(self
->txn
, flags
);
3733 err
= txn_commit(self
->txn
, flags
);
3735 MYDB_END_ALLOW_THREADS
;
3741 DBTxn_prepare(DBTxnObject
* self
, PyObject
* args
)
3748 if (!PyArg_ParseTuple(args
, "s#:prepare", &gid
, &gid_size
))
3751 if (gid_size
!= DB_XIDDATASIZE
) {
3752 PyErr_SetString(PyExc_TypeError
,
3753 "gid must be DB_XIDDATASIZE bytes long");
3757 MYDB_BEGIN_ALLOW_THREADS
;
3759 err
= self
->txn
->prepare(self
->txn
, (u_int8_t
*)gid
);
3761 err
= txn_prepare(self
->txn
, (u_int8_t
*)gid
);
3763 MYDB_END_ALLOW_THREADS
;
3769 if (!PyArg_ParseTuple(args
, ":prepare"))
3772 MYDB_BEGIN_ALLOW_THREADS
;
3773 err
= txn_prepare(self
->txn
);
3774 MYDB_END_ALLOW_THREADS
;
3782 DBTxn_abort(DBTxnObject
* self
, PyObject
* args
)
3786 if (!PyArg_ParseTuple(args
, ":abort"))
3789 MYDB_BEGIN_ALLOW_THREADS
;
3791 err
= self
->txn
->abort(self
->txn
);
3793 err
= txn_abort(self
->txn
);
3795 MYDB_END_ALLOW_THREADS
;
3802 DBTxn_id(DBTxnObject
* self
, PyObject
* args
)
3806 if (!PyArg_ParseTuple(args
, ":id"))
3809 MYDB_BEGIN_ALLOW_THREADS
;
3811 id
= self
->txn
->id(self
->txn
);
3813 id
= txn_id(self
->txn
);
3815 MYDB_END_ALLOW_THREADS
;
3816 return PyInt_FromLong(id
);
3819 /* --------------------------------------------------------------------- */
3820 /* Method definition tables and type objects */
3822 static PyMethodDef DB_methods
[] = {
3823 {"append", (PyCFunction
)DB_append
, METH_VARARGS
},
3825 {"associate", (PyCFunction
)DB_associate
, METH_VARARGS
|METH_KEYWORDS
},
3827 {"close", (PyCFunction
)DB_close
, METH_VARARGS
},
3829 {"consume", (PyCFunction
)DB_consume
, METH_VARARGS
|METH_KEYWORDS
},
3830 {"consume_wait", (PyCFunction
)DB_consume_wait
, METH_VARARGS
|METH_KEYWORDS
},
3832 {"cursor", (PyCFunction
)DB_cursor
, METH_VARARGS
|METH_KEYWORDS
},
3833 {"delete", (PyCFunction
)DB_delete
, METH_VARARGS
|METH_KEYWORDS
},
3834 {"fd", (PyCFunction
)DB_fd
, METH_VARARGS
},
3835 {"get", (PyCFunction
)DB_get
, METH_VARARGS
|METH_KEYWORDS
},
3836 {"get_both", (PyCFunction
)DB_get_both
, METH_VARARGS
|METH_KEYWORDS
},
3837 {"get_byteswapped", (PyCFunction
)DB_get_byteswapped
,METH_VARARGS
},
3838 {"get_size", (PyCFunction
)DB_get_size
, METH_VARARGS
|METH_KEYWORDS
},
3839 {"get_type", (PyCFunction
)DB_get_type
, METH_VARARGS
},
3840 {"join", (PyCFunction
)DB_join
, METH_VARARGS
},
3841 {"key_range", (PyCFunction
)DB_key_range
, METH_VARARGS
|METH_KEYWORDS
},
3842 {"has_key", (PyCFunction
)DB_has_key
, METH_VARARGS
},
3843 {"items", (PyCFunction
)DB_items
, METH_VARARGS
},
3844 {"keys", (PyCFunction
)DB_keys
, METH_VARARGS
},
3845 {"open", (PyCFunction
)DB_open
, METH_VARARGS
|METH_KEYWORDS
},
3846 {"put", (PyCFunction
)DB_put
, METH_VARARGS
|METH_KEYWORDS
},
3847 {"remove", (PyCFunction
)DB_remove
, METH_VARARGS
|METH_KEYWORDS
},
3848 {"rename", (PyCFunction
)DB_rename
, METH_VARARGS
},
3849 {"set_bt_minkey", (PyCFunction
)DB_set_bt_minkey
, METH_VARARGS
},
3850 {"set_cachesize", (PyCFunction
)DB_set_cachesize
, METH_VARARGS
},
3852 {"set_encrypt", (PyCFunction
)DB_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
3854 {"set_flags", (PyCFunction
)DB_set_flags
, METH_VARARGS
},
3855 {"set_h_ffactor", (PyCFunction
)DB_set_h_ffactor
, METH_VARARGS
},
3856 {"set_h_nelem", (PyCFunction
)DB_set_h_nelem
, METH_VARARGS
},
3857 {"set_lorder", (PyCFunction
)DB_set_lorder
, METH_VARARGS
},
3858 {"set_pagesize", (PyCFunction
)DB_set_pagesize
, METH_VARARGS
},
3859 {"set_re_delim", (PyCFunction
)DB_set_re_delim
, METH_VARARGS
},
3860 {"set_re_len", (PyCFunction
)DB_set_re_len
, METH_VARARGS
},
3861 {"set_re_pad", (PyCFunction
)DB_set_re_pad
, METH_VARARGS
},
3862 {"set_re_source", (PyCFunction
)DB_set_re_source
, METH_VARARGS
},
3864 {"set_q_extentsize",(PyCFunction
)DB_set_q_extentsize
,METH_VARARGS
},
3866 {"stat", (PyCFunction
)DB_stat
, METH_VARARGS
},
3867 {"sync", (PyCFunction
)DB_sync
, METH_VARARGS
},
3869 {"truncate", (PyCFunction
)DB_truncate
, METH_VARARGS
|METH_KEYWORDS
},
3871 {"type", (PyCFunction
)DB_get_type
, METH_VARARGS
},
3872 {"upgrade", (PyCFunction
)DB_upgrade
, METH_VARARGS
},
3873 {"values", (PyCFunction
)DB_values
, METH_VARARGS
},
3874 {"verify", (PyCFunction
)DB_verify
, METH_VARARGS
|METH_KEYWORDS
},
3875 {"set_get_returns_none",(PyCFunction
)DB_set_get_returns_none
, METH_VARARGS
},
3876 {NULL
, NULL
} /* sentinel */
3880 static PyMappingMethods DB_mapping
= {
3881 (inquiry
)DB_length
, /*mp_length*/
3882 (binaryfunc
)DB_subscript
, /*mp_subscript*/
3883 (objobjargproc
)DB_ass_sub
, /*mp_ass_subscript*/
3887 static PyMethodDef DBCursor_methods
[] = {
3888 {"close", (PyCFunction
)DBC_close
, METH_VARARGS
},
3889 {"count", (PyCFunction
)DBC_count
, METH_VARARGS
},
3890 {"current", (PyCFunction
)DBC_current
, METH_VARARGS
|METH_KEYWORDS
},
3891 {"delete", (PyCFunction
)DBC_delete
, METH_VARARGS
},
3892 {"dup", (PyCFunction
)DBC_dup
, METH_VARARGS
},
3893 {"first", (PyCFunction
)DBC_first
, METH_VARARGS
|METH_KEYWORDS
},
3894 {"get", (PyCFunction
)DBC_get
, METH_VARARGS
|METH_KEYWORDS
},
3895 {"get_recno", (PyCFunction
)DBC_get_recno
, METH_VARARGS
},
3896 {"last", (PyCFunction
)DBC_last
, METH_VARARGS
|METH_KEYWORDS
},
3897 {"next", (PyCFunction
)DBC_next
, METH_VARARGS
|METH_KEYWORDS
},
3898 {"prev", (PyCFunction
)DBC_prev
, METH_VARARGS
|METH_KEYWORDS
},
3899 {"put", (PyCFunction
)DBC_put
, METH_VARARGS
|METH_KEYWORDS
},
3900 {"set", (PyCFunction
)DBC_set
, METH_VARARGS
|METH_KEYWORDS
},
3901 {"set_range", (PyCFunction
)DBC_set_range
, METH_VARARGS
|METH_KEYWORDS
},
3902 {"get_both", (PyCFunction
)DBC_get_both
, METH_VARARGS
},
3903 {"set_both", (PyCFunction
)DBC_get_both
, METH_VARARGS
},
3904 {"set_recno", (PyCFunction
)DBC_set_recno
, METH_VARARGS
|METH_KEYWORDS
},
3905 {"consume", (PyCFunction
)DBC_consume
, METH_VARARGS
|METH_KEYWORDS
},
3906 {"next_dup", (PyCFunction
)DBC_next_dup
, METH_VARARGS
|METH_KEYWORDS
},
3907 {"next_nodup", (PyCFunction
)DBC_next_nodup
, METH_VARARGS
|METH_KEYWORDS
},
3908 {"prev_nodup", (PyCFunction
)DBC_prev_nodup
, METH_VARARGS
|METH_KEYWORDS
},
3909 {"join_item", (PyCFunction
)DBC_join_item
, METH_VARARGS
},
3910 {NULL
, NULL
} /* sentinel */
3914 static PyMethodDef DBEnv_methods
[] = {
3915 {"close", (PyCFunction
)DBEnv_close
, METH_VARARGS
},
3916 {"open", (PyCFunction
)DBEnv_open
, METH_VARARGS
},
3917 {"remove", (PyCFunction
)DBEnv_remove
, METH_VARARGS
},
3919 {"dbremove", (PyCFunction
)DBEnv_dbremove
, METH_VARARGS
|METH_KEYWORDS
},
3920 {"dbrename", (PyCFunction
)DBEnv_dbrename
, METH_VARARGS
|METH_KEYWORDS
},
3921 {"set_encrypt", (PyCFunction
)DBEnv_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
3923 {"set_cachesize", (PyCFunction
)DBEnv_set_cachesize
, METH_VARARGS
},
3924 {"set_data_dir", (PyCFunction
)DBEnv_set_data_dir
, METH_VARARGS
},
3926 {"set_flags", (PyCFunction
)DBEnv_set_flags
, METH_VARARGS
},
3928 {"set_lg_bsize", (PyCFunction
)DBEnv_set_lg_bsize
, METH_VARARGS
},
3929 {"set_lg_dir", (PyCFunction
)DBEnv_set_lg_dir
, METH_VARARGS
},
3930 {"set_lg_max", (PyCFunction
)DBEnv_set_lg_max
, METH_VARARGS
},
3931 {"set_lk_detect", (PyCFunction
)DBEnv_set_lk_detect
, METH_VARARGS
},
3932 {"set_lk_max", (PyCFunction
)DBEnv_set_lk_max
, METH_VARARGS
},
3934 {"set_lk_max_locks", (PyCFunction
)DBEnv_set_lk_max_locks
, METH_VARARGS
},
3935 {"set_lk_max_lockers", (PyCFunction
)DBEnv_set_lk_max_lockers
, METH_VARARGS
},
3936 {"set_lk_max_objects", (PyCFunction
)DBEnv_set_lk_max_objects
, METH_VARARGS
},
3938 {"set_mp_mmapsize", (PyCFunction
)DBEnv_set_mp_mmapsize
, METH_VARARGS
},
3939 {"set_tmp_dir", (PyCFunction
)DBEnv_set_tmp_dir
, METH_VARARGS
},
3940 {"txn_begin", (PyCFunction
)DBEnv_txn_begin
, METH_VARARGS
|METH_KEYWORDS
},
3941 {"txn_checkpoint", (PyCFunction
)DBEnv_txn_checkpoint
, METH_VARARGS
},
3942 {"txn_stat", (PyCFunction
)DBEnv_txn_stat
, METH_VARARGS
},
3943 {"set_tx_max", (PyCFunction
)DBEnv_set_tx_max
, METH_VARARGS
},
3944 {"lock_detect", (PyCFunction
)DBEnv_lock_detect
, METH_VARARGS
},
3945 {"lock_get", (PyCFunction
)DBEnv_lock_get
, METH_VARARGS
},
3946 {"lock_id", (PyCFunction
)DBEnv_lock_id
, METH_VARARGS
},
3947 {"lock_put", (PyCFunction
)DBEnv_lock_put
, METH_VARARGS
},
3948 {"lock_stat", (PyCFunction
)DBEnv_lock_stat
, METH_VARARGS
},
3949 {"log_archive", (PyCFunction
)DBEnv_log_archive
, METH_VARARGS
},
3950 {"set_get_returns_none",(PyCFunction
)DBEnv_set_get_returns_none
, METH_VARARGS
},
3951 {NULL
, NULL
} /* sentinel */
3955 static PyMethodDef DBTxn_methods
[] = {
3956 {"commit", (PyCFunction
)DBTxn_commit
, METH_VARARGS
},
3957 {"prepare", (PyCFunction
)DBTxn_prepare
, METH_VARARGS
},
3958 {"abort", (PyCFunction
)DBTxn_abort
, METH_VARARGS
},
3959 {"id", (PyCFunction
)DBTxn_id
, METH_VARARGS
},
3960 {NULL
, NULL
} /* sentinel */
3965 DB_getattr(DBObject
* self
, char *name
)
3967 return Py_FindMethod(DB_methods
, (PyObject
* )self
, name
);
3972 DBEnv_getattr(DBEnvObject
* self
, char *name
)
3974 if (!strcmp(name
, "db_home")) {
3975 CHECK_ENV_NOT_CLOSED(self
);
3976 if (self
->db_env
->db_home
== NULL
) {
3979 return PyString_FromString(self
->db_env
->db_home
);
3982 return Py_FindMethod(DBEnv_methods
, (PyObject
* )self
, name
);
3987 DBCursor_getattr(DBCursorObject
* self
, char *name
)
3989 return Py_FindMethod(DBCursor_methods
, (PyObject
* )self
, name
);
3993 DBTxn_getattr(DBTxnObject
* self
, char *name
)
3995 return Py_FindMethod(DBTxn_methods
, (PyObject
* )self
, name
);
3999 DBLock_getattr(DBLockObject
* self
, char *name
)
4004 statichere PyTypeObject DB_Type
= {
4005 PyObject_HEAD_INIT(NULL
)
4008 sizeof(DBObject
), /*tp_basicsize*/
4011 (destructor
)DB_dealloc
, /*tp_dealloc*/
4013 (getattrfunc
)DB_getattr
, /*tp_getattr*/
4018 0, /*tp_as_sequence*/
4019 &DB_mapping
,/*tp_as_mapping*/
4024 statichere PyTypeObject DBCursor_Type
= {
4025 PyObject_HEAD_INIT(NULL
)
4027 "DBCursor", /*tp_name*/
4028 sizeof(DBCursorObject
), /*tp_basicsize*/
4031 (destructor
)DBCursor_dealloc
,/*tp_dealloc*/
4033 (getattrfunc
)DBCursor_getattr
, /*tp_getattr*/
4038 0, /*tp_as_sequence*/
4039 0, /*tp_as_mapping*/
4044 statichere PyTypeObject DBEnv_Type
= {
4045 PyObject_HEAD_INIT(NULL
)
4047 "DBEnv", /*tp_name*/
4048 sizeof(DBEnvObject
), /*tp_basicsize*/
4051 (destructor
)DBEnv_dealloc
, /*tp_dealloc*/
4053 (getattrfunc
)DBEnv_getattr
, /*tp_getattr*/
4058 0, /*tp_as_sequence*/
4059 0, /*tp_as_mapping*/
4063 statichere PyTypeObject DBTxn_Type
= {
4064 PyObject_HEAD_INIT(NULL
)
4066 "DBTxn", /*tp_name*/
4067 sizeof(DBTxnObject
), /*tp_basicsize*/
4070 (destructor
)DBTxn_dealloc
, /*tp_dealloc*/
4072 (getattrfunc
)DBTxn_getattr
, /*tp_getattr*/
4077 0, /*tp_as_sequence*/
4078 0, /*tp_as_mapping*/
4083 statichere PyTypeObject DBLock_Type
= {
4084 PyObject_HEAD_INIT(NULL
)
4086 "DBLock", /*tp_name*/
4087 sizeof(DBLockObject
), /*tp_basicsize*/
4090 (destructor
)DBLock_dealloc
, /*tp_dealloc*/
4092 (getattrfunc
)DBLock_getattr
, /*tp_getattr*/
4097 0, /*tp_as_sequence*/
4098 0, /*tp_as_mapping*/
4103 /* --------------------------------------------------------------------- */
4104 /* Module-level functions */
4107 DB_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4109 PyObject
* dbenvobj
= NULL
;
4111 char* kwnames
[] = { "dbEnv", "flags", NULL
};
4113 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:DB", kwnames
,
4116 if (dbenvobj
== Py_None
)
4118 else if (dbenvobj
&& !DBEnvObject_Check(dbenvobj
)) {
4119 makeTypeError("DBEnv", dbenvobj
);
4123 return (PyObject
* )newDBObject((DBEnvObject
*)dbenvobj
, flags
);
4128 DBEnv_construct(PyObject
* self
, PyObject
* args
)
4131 if (!PyArg_ParseTuple(args
, "|i:DbEnv", &flags
)) return NULL
;
4132 return (PyObject
* )newDBEnvObject(flags
);
4136 static char bsddb_version_doc
[] =
4137 "Returns a tuple of major, minor, and patch release numbers of the\n\
4138 underlying DB library.";
4141 bsddb_version(PyObject
* self
, PyObject
* args
)
4143 int major
, minor
, patch
;
4145 if (!PyArg_ParseTuple(args
, ":version"))
4147 db_version(&major
, &minor
, &patch
);
4148 return Py_BuildValue("(iii)", major
, minor
, patch
);
4152 /* List of functions defined in the module */
4154 static PyMethodDef bsddb_methods
[] = {
4155 {"DB", (PyCFunction
)DB_construct
, METH_VARARGS
| METH_KEYWORDS
},
4156 {"DBEnv", (PyCFunction
)DBEnv_construct
, METH_VARARGS
},
4157 {"version", (PyCFunction
)bsddb_version
, METH_VARARGS
, bsddb_version_doc
},
4158 {NULL
, NULL
} /* sentinel */
4162 /* --------------------------------------------------------------------- */
4163 /* Module initialization */
4166 /* Convenience routine to export an integer value.
4167 * Errors are silently ignored, for better or for worse...
4169 #define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
4173 DL_EXPORT(void) init_bsddb(void)
4177 PyObject
* pybsddb_version_s
= PyString_FromString( PY_BSDDB_VERSION
);
4178 PyObject
* db_version_s
= PyString_FromString( DB_VERSION_STRING
);
4179 PyObject
* cvsid_s
= PyString_FromString( rcs_id
);
4181 /* Initialize the type of the new type objects here; doing it here
4182 is required for portability to Windows without requiring C++. */
4183 DB_Type
.ob_type
= &PyType_Type
;
4184 DBCursor_Type
.ob_type
= &PyType_Type
;
4185 DBEnv_Type
.ob_type
= &PyType_Type
;
4186 DBTxn_Type
.ob_type
= &PyType_Type
;
4187 DBLock_Type
.ob_type
= &PyType_Type
;
4191 /* Save the current interpreter, so callbacks can do the right thing. */
4192 _db_interpreterState
= PyThreadState_Get()->interp
;
4195 /* Create the module and add the functions */
4196 m
= Py_InitModule("_bsddb", bsddb_methods
);
4198 /* Add some symbolic constants to the module */
4199 d
= PyModule_GetDict(m
);
4200 PyDict_SetItemString(d
, "__version__", pybsddb_version_s
);
4201 PyDict_SetItemString(d
, "cvsid", cvsid_s
);
4202 PyDict_SetItemString(d
, "DB_VERSION_STRING", db_version_s
);
4203 Py_DECREF(pybsddb_version_s
);
4204 pybsddb_version_s
= NULL
;
4207 Py_DECREF(db_version_s
);
4208 db_version_s
= NULL
;
4210 ADD_INT(d
, DB_VERSION_MAJOR
);
4211 ADD_INT(d
, DB_VERSION_MINOR
);
4212 ADD_INT(d
, DB_VERSION_PATCH
);
4214 ADD_INT(d
, DB_MAX_PAGES
);
4215 ADD_INT(d
, DB_MAX_RECORDS
);
4217 ADD_INT(d
, DB_CLIENT
);
4218 ADD_INT(d
, DB_XA_CREATE
);
4220 ADD_INT(d
, DB_CREATE
);
4221 ADD_INT(d
, DB_NOMMAP
);
4222 ADD_INT(d
, DB_THREAD
);
4224 ADD_INT(d
, DB_FORCE
);
4225 ADD_INT(d
, DB_INIT_CDB
);
4226 ADD_INT(d
, DB_INIT_LOCK
);
4227 ADD_INT(d
, DB_INIT_LOG
);
4228 ADD_INT(d
, DB_INIT_MPOOL
);
4229 ADD_INT(d
, DB_INIT_TXN
);
4231 ADD_INT(d
, DB_JOINENV
);
4234 ADD_INT(d
, DB_RECOVER
);
4235 ADD_INT(d
, DB_RECOVER_FATAL
);
4236 ADD_INT(d
, DB_TXN_NOSYNC
);
4237 ADD_INT(d
, DB_USE_ENVIRON
);
4238 ADD_INT(d
, DB_USE_ENVIRON_ROOT
);
4240 ADD_INT(d
, DB_LOCKDOWN
);
4241 ADD_INT(d
, DB_PRIVATE
);
4242 ADD_INT(d
, DB_SYSTEM_MEM
);
4244 ADD_INT(d
, DB_TXN_SYNC
);
4245 ADD_INT(d
, DB_TXN_NOWAIT
);
4247 ADD_INT(d
, DB_EXCL
);
4248 ADD_INT(d
, DB_FCNTL_LOCKING
);
4249 ADD_INT(d
, DB_ODDFILESIZE
);
4250 ADD_INT(d
, DB_RDWRMASTER
);
4251 ADD_INT(d
, DB_RDONLY
);
4252 ADD_INT(d
, DB_TRUNCATE
);
4254 ADD_INT(d
, DB_EXTENT
);
4255 ADD_INT(d
, DB_CDB_ALLDB
);
4256 ADD_INT(d
, DB_VERIFY
);
4258 ADD_INT(d
, DB_UPGRADE
);
4260 ADD_INT(d
, DB_AGGRESSIVE
);
4261 ADD_INT(d
, DB_NOORDERCHK
);
4262 ADD_INT(d
, DB_ORDERCHKONLY
);
4263 ADD_INT(d
, DB_PR_PAGE
);
4265 ADD_INT(d
, DB_VRFY_FLAGMASK
);
4266 ADD_INT(d
, DB_PR_HEADERS
);
4268 ADD_INT(d
, DB_PR_RECOVERYTEST
);
4269 ADD_INT(d
, DB_SALVAGE
);
4271 ADD_INT(d
, DB_LOCK_NORUN
);
4272 ADD_INT(d
, DB_LOCK_DEFAULT
);
4273 ADD_INT(d
, DB_LOCK_OLDEST
);
4274 ADD_INT(d
, DB_LOCK_RANDOM
);
4275 ADD_INT(d
, DB_LOCK_YOUNGEST
);
4277 ADD_INT(d
, DB_LOCK_MAXLOCKS
);
4278 ADD_INT(d
, DB_LOCK_MINLOCKS
);
4279 ADD_INT(d
, DB_LOCK_MINWRITE
);
4284 /* docs say to use zero instead */
4285 _addIntToDict(d
, "DB_LOCK_CONFLICT", 0);
4287 ADD_INT(d
, DB_LOCK_CONFLICT
);
4290 ADD_INT(d
, DB_LOCK_DUMP
);
4291 ADD_INT(d
, DB_LOCK_GET
);
4292 ADD_INT(d
, DB_LOCK_INHERIT
);
4293 ADD_INT(d
, DB_LOCK_PUT
);
4294 ADD_INT(d
, DB_LOCK_PUT_ALL
);
4295 ADD_INT(d
, DB_LOCK_PUT_OBJ
);
4297 ADD_INT(d
, DB_LOCK_NG
);
4298 ADD_INT(d
, DB_LOCK_READ
);
4299 ADD_INT(d
, DB_LOCK_WRITE
);
4300 ADD_INT(d
, DB_LOCK_NOWAIT
);
4302 ADD_INT(d
, DB_LOCK_WAIT
);
4304 ADD_INT(d
, DB_LOCK_IWRITE
);
4305 ADD_INT(d
, DB_LOCK_IREAD
);
4306 ADD_INT(d
, DB_LOCK_IWR
);
4308 ADD_INT(d
, DB_LOCK_DIRTY
);
4309 ADD_INT(d
, DB_LOCK_WWRITE
);
4312 ADD_INT(d
, DB_LOCK_RECORD
);
4313 ADD_INT(d
, DB_LOCK_UPGRADE
);
4315 ADD_INT(d
, DB_LOCK_SWITCH
);
4318 ADD_INT(d
, DB_LOCK_UPGRADE_WRITE
);
4321 ADD_INT(d
, DB_LOCK_NOWAIT
);
4322 ADD_INT(d
, DB_LOCK_RECORD
);
4323 ADD_INT(d
, DB_LOCK_UPGRADE
);
4326 ADD_INT(d
, DB_LSTAT_ABORTED
);
4327 ADD_INT(d
, DB_LSTAT_ERR
);
4328 ADD_INT(d
, DB_LSTAT_FREE
);
4329 ADD_INT(d
, DB_LSTAT_HELD
);
4331 ADD_INT(d
, DB_LSTAT_NOGRANT
);
4333 ADD_INT(d
, DB_LSTAT_PENDING
);
4334 ADD_INT(d
, DB_LSTAT_WAITING
);
4337 ADD_INT(d
, DB_ARCH_ABS
);
4338 ADD_INT(d
, DB_ARCH_DATA
);
4339 ADD_INT(d
, DB_ARCH_LOG
);
4341 ADD_INT(d
, DB_BTREE
);
4342 ADD_INT(d
, DB_HASH
);
4343 ADD_INT(d
, DB_RECNO
);
4344 ADD_INT(d
, DB_QUEUE
);
4345 ADD_INT(d
, DB_UNKNOWN
);
4348 ADD_INT(d
, DB_DUPSORT
);
4349 ADD_INT(d
, DB_RECNUM
);
4350 ADD_INT(d
, DB_RENUMBER
);
4351 ADD_INT(d
, DB_REVSPLITOFF
);
4352 ADD_INT(d
, DB_SNAPSHOT
);
4354 ADD_INT(d
, DB_JOIN_NOSORT
);
4356 ADD_INT(d
, DB_AFTER
);
4357 ADD_INT(d
, DB_APPEND
);
4358 ADD_INT(d
, DB_BEFORE
);
4359 ADD_INT(d
, DB_CACHED_COUNTS
);
4361 _addIntToDict(d
, "DB_CHECKPOINT", 0);
4363 ADD_INT(d
, DB_CHECKPOINT
);
4364 ADD_INT(d
, DB_CURLSN
);
4367 ADD_INT(d
, DB_COMMIT
);
4369 ADD_INT(d
, DB_CONSUME
);
4371 ADD_INT(d
, DB_CONSUME_WAIT
);
4373 ADD_INT(d
, DB_CURRENT
);
4375 ADD_INT(d
, DB_FAST_STAT
);
4377 ADD_INT(d
, DB_FIRST
);
4378 ADD_INT(d
, DB_FLUSH
);
4379 ADD_INT(d
, DB_GET_BOTH
);
4380 ADD_INT(d
, DB_GET_RECNO
);
4381 ADD_INT(d
, DB_JOIN_ITEM
);
4382 ADD_INT(d
, DB_KEYFIRST
);
4383 ADD_INT(d
, DB_KEYLAST
);
4384 ADD_INT(d
, DB_LAST
);
4385 ADD_INT(d
, DB_NEXT
);
4386 ADD_INT(d
, DB_NEXT_DUP
);
4387 ADD_INT(d
, DB_NEXT_NODUP
);
4388 ADD_INT(d
, DB_NODUPDATA
);
4389 ADD_INT(d
, DB_NOOVERWRITE
);
4390 ADD_INT(d
, DB_NOSYNC
);
4391 ADD_INT(d
, DB_POSITION
);
4392 ADD_INT(d
, DB_PREV
);
4393 ADD_INT(d
, DB_PREV_NODUP
);
4394 ADD_INT(d
, DB_RECORDCOUNT
);
4396 ADD_INT(d
, DB_SET_RANGE
);
4397 ADD_INT(d
, DB_SET_RECNO
);
4398 ADD_INT(d
, DB_WRITECURSOR
);
4400 ADD_INT(d
, DB_OPFLAGS_MASK
);
4403 ADD_INT(d
, DB_DIRTY_READ
);
4404 ADD_INT(d
, DB_MULTIPLE
);
4405 ADD_INT(d
, DB_MULTIPLE_KEY
);
4409 ADD_INT(d
, DB_DONOTINDEX
);
4413 _addIntToDict(d
, "DB_INCOMPLETE", 0);
4415 ADD_INT(d
, DB_INCOMPLETE
);
4417 ADD_INT(d
, DB_KEYEMPTY
);
4418 ADD_INT(d
, DB_KEYEXIST
);
4419 ADD_INT(d
, DB_LOCK_DEADLOCK
);
4420 ADD_INT(d
, DB_LOCK_NOTGRANTED
);
4421 ADD_INT(d
, DB_NOSERVER
);
4422 ADD_INT(d
, DB_NOSERVER_HOME
);
4423 ADD_INT(d
, DB_NOSERVER_ID
);
4424 ADD_INT(d
, DB_NOTFOUND
);
4425 ADD_INT(d
, DB_OLD_VERSION
);
4426 ADD_INT(d
, DB_RUNRECOVERY
);
4427 ADD_INT(d
, DB_VERIFY_BAD
);
4429 ADD_INT(d
, DB_PAGE_NOTFOUND
);
4430 ADD_INT(d
, DB_SECONDARY_BAD
);
4433 ADD_INT(d
, DB_STAT_CLEAR
);
4434 ADD_INT(d
, DB_REGION_INIT
);
4435 ADD_INT(d
, DB_NOLOCKING
);
4436 ADD_INT(d
, DB_YIELDCPU
);
4437 ADD_INT(d
, DB_PANIC_ENVIRONMENT
);
4438 ADD_INT(d
, DB_NOPANIC
);
4442 ADD_INT(d
, DB_ENCRYPT_AES
);
4443 ADD_INT(d
, DB_AUTO_COMMIT
);
4445 /* allow berkeleydb 4.1 aware apps to run on older versions */
4446 _addIntToDict(d
, "DB_AUTO_COMMIT", 0);
4461 /* The base exception class is DBError */
4462 DBError
= PyErr_NewException("bsddb._db.DBError", NULL
, NULL
);
4463 PyDict_SetItemString(d
, "DBError", DBError
);
4465 /* Some magic to make DBNotFoundError derive from both DBError and
4466 KeyError, since the API only supports using one base class. */
4467 PyDict_SetItemString(d
, "KeyError", PyExc_KeyError
);
4468 PyRun_String("class DBNotFoundError(DBError, KeyError): pass",
4469 Py_file_input
, d
, d
);
4470 DBNotFoundError
= PyDict_GetItemString(d
, "DBNotFoundError");
4471 PyDict_DelItemString(d
, "KeyError");
4474 /* All the rest of the exceptions derive only from DBError */
4475 #define MAKE_EX(name) name = PyErr_NewException("bsddb._db." #name, DBError, NULL); \
4476 PyDict_SetItemString(d, #name, name)
4478 #if !INCOMPLETE_IS_WARNING
4479 MAKE_EX(DBIncompleteError
);
4481 MAKE_EX(DBKeyEmptyError
);
4482 MAKE_EX(DBKeyExistError
);
4483 MAKE_EX(DBLockDeadlockError
);
4484 MAKE_EX(DBLockNotGrantedError
);
4485 MAKE_EX(DBOldVersionError
);
4486 MAKE_EX(DBRunRecoveryError
);
4487 MAKE_EX(DBVerifyBadError
);
4488 MAKE_EX(DBNoServerError
);
4489 MAKE_EX(DBNoServerHomeError
);
4490 MAKE_EX(DBNoServerIDError
);
4492 MAKE_EX(DBPageNotFoundError
);
4493 MAKE_EX(DBSecondaryBadError
);
4496 MAKE_EX(DBInvalidArgError
);
4497 MAKE_EX(DBAccessError
);
4498 MAKE_EX(DBNoSpaceError
);
4499 MAKE_EX(DBNoMemoryError
);
4500 MAKE_EX(DBAgainError
);
4501 MAKE_EX(DBBusyError
);
4502 MAKE_EX(DBFileExistsError
);
4503 MAKE_EX(DBNoSuchFileError
);
4504 MAKE_EX(DBPermissionsError
);
4508 /* Check for errors */
4509 if (PyErr_Occurred()) {
4511 Py_FatalError("can't initialize module _bsddb");