1 /*----------------------------------------------------------------------
2 Copyright (c) 1999-2001, Digital Creations, Fredericksburg, VA, USA
3 and Andrew Kuchling. All rights reserved.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
9 o Redistributions of source code must retain the above copyright
10 notice, this list of conditions, and the disclaimer that follows.
12 o Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions, and the following disclaimer in
14 the documentation and/or other materials provided with the
17 o Neither the name of Digital Creations nor the names of its
18 contributors may be used to endorse or promote products derived
19 from this software without specific prior written permission.
21 THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
22 IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
25 CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
33 ------------------------------------------------------------------------*/
37 * Handwritten code to wrap version 3.x of the Berkeley DB library,
38 * written to replace a SWIG-generated file. It has since been updated
39 * to compile with BerkeleyDB versions 3.2 through 4.2.
41 * This module was started by Andrew Kuchling to remove the dependency
42 * on SWIG in a package by Gregory P. Smith <greg@electricrain.com> who
43 * based his work on a similar package by Robin Dunn <robin@alldunn.com>
44 * which wrapped Berkeley DB 2.7.x.
46 * Development of this module then returned full circle back to Robin Dunn
47 * who worked on behalf of Digital Creations to complete the wrapping of
48 * the DB 3.x API and to build a solid unit test suite. Robin has
49 * since gone onto other projects (wxPython).
51 * Gregory P. Smith <greg@electricrain.com> is once again the maintainer.
53 * Use the pybsddb-users@lists.sf.net mailing list for all questions.
54 * Things can change faster than the header of this file is updated. This
55 * file is shared with the PyBSDDB project at SourceForge:
57 * http://pybsddb.sf.net
59 * This file should remain backward compatible with Python 2.1, but see PEP
60 * 291 for the most current backward compatibility requirements:
62 * http://www.python.org/peps/pep-0291.html
64 * This module contains 6 types:
67 * DBCursor (Database Cursor)
68 * DBEnv (database environment)
69 * DBTxn (An explicit database transaction)
70 * DBLock (A lock handle)
71 * DBSequence (Sequence)
75 /* --------------------------------------------------------------------- */
78 * Portions of this module, associated unit tests and build scripts are the
79 * result of a contract with The Written Word (http://thewrittenword.com/)
80 * Many thanks go out to them for causing me to raise the bar on quality and
81 * functionality, resulting in a better bsddb3 package for all of us to use.
86 /* --------------------------------------------------------------------- */
88 #include <stddef.h> /* for offsetof() */
92 /* --------------------------------------------------------------------- */
93 /* Various macro definitions */
95 /* 40 = 4.0, 33 = 3.3; this will break if the second number is > 9 */
96 #define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
97 #if DB_VERSION_MINOR > 9
98 #error "eek! DBVER can't handle minor versions > 9"
101 #define PY_BSDDB_VERSION "4.4.4"
102 static char *rcs_id
= "$Id$";
105 #if (PY_VERSION_HEX < 0x02050000)
106 #define Py_ssize_t int
111 /* These are for when calling Python --> C */
112 #define MYDB_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS;
113 #define MYDB_END_ALLOW_THREADS Py_END_ALLOW_THREADS;
115 /* For 2.3, use the PyGILState_ calls */
116 #if (PY_VERSION_HEX >= 0x02030000)
117 #define MYDB_USE_GILSTATE
120 /* and these are for calling C --> Python */
121 #if defined(MYDB_USE_GILSTATE)
122 #define MYDB_BEGIN_BLOCK_THREADS \
123 PyGILState_STATE __savestate = PyGILState_Ensure();
124 #define MYDB_END_BLOCK_THREADS \
125 PyGILState_Release(__savestate);
126 #else /* MYDB_USE_GILSTATE */
127 /* Pre GILState API - do it the long old way */
128 static PyInterpreterState
* _db_interpreterState
= NULL
;
129 #define MYDB_BEGIN_BLOCK_THREADS { \
130 PyThreadState* prevState; \
131 PyThreadState* newState; \
132 PyEval_AcquireLock(); \
133 newState = PyThreadState_New(_db_interpreterState); \
134 prevState = PyThreadState_Swap(newState);
136 #define MYDB_END_BLOCK_THREADS \
137 newState = PyThreadState_Swap(prevState); \
138 PyThreadState_Clear(newState); \
139 PyEval_ReleaseLock(); \
140 PyThreadState_Delete(newState); \
142 #endif /* MYDB_USE_GILSTATE */
145 /* Compiled without threads - avoid all this cruft */
146 #define MYDB_BEGIN_ALLOW_THREADS
147 #define MYDB_END_ALLOW_THREADS
148 #define MYDB_BEGIN_BLOCK_THREADS
149 #define MYDB_END_BLOCK_THREADS
153 /* Should DB_INCOMPLETE be turned into a warning or an exception? */
154 #define INCOMPLETE_IS_WARNING 1
156 /* --------------------------------------------------------------------- */
159 static PyObject
* DBError
; /* Base class, all others derive from this */
160 static PyObject
* DBCursorClosedError
; /* raised when trying to use a closed cursor object */
161 static PyObject
* DBKeyEmptyError
; /* DB_KEYEMPTY: also derives from KeyError */
162 static PyObject
* DBKeyExistError
; /* DB_KEYEXIST */
163 static PyObject
* DBLockDeadlockError
; /* DB_LOCK_DEADLOCK */
164 static PyObject
* DBLockNotGrantedError
; /* DB_LOCK_NOTGRANTED */
165 static PyObject
* DBNotFoundError
; /* DB_NOTFOUND: also derives from KeyError */
166 static PyObject
* DBOldVersionError
; /* DB_OLD_VERSION */
167 static PyObject
* DBRunRecoveryError
; /* DB_RUNRECOVERY */
168 static PyObject
* DBVerifyBadError
; /* DB_VERIFY_BAD */
169 static PyObject
* DBNoServerError
; /* DB_NOSERVER */
170 static PyObject
* DBNoServerHomeError
; /* DB_NOSERVER_HOME */
171 static PyObject
* DBNoServerIDError
; /* DB_NOSERVER_ID */
173 static PyObject
* DBPageNotFoundError
; /* DB_PAGE_NOTFOUND */
174 static PyObject
* DBSecondaryBadError
; /* DB_SECONDARY_BAD */
177 #if !INCOMPLETE_IS_WARNING
178 static PyObject
* DBIncompleteError
; /* DB_INCOMPLETE */
181 static PyObject
* DBInvalidArgError
; /* EINVAL */
182 static PyObject
* DBAccessError
; /* EACCES */
183 static PyObject
* DBNoSpaceError
; /* ENOSPC */
184 static PyObject
* DBNoMemoryError
; /* DB_BUFFER_SMALL (ENOMEM when < 4.3) */
185 static PyObject
* DBAgainError
; /* EAGAIN */
186 static PyObject
* DBBusyError
; /* EBUSY */
187 static PyObject
* DBFileExistsError
; /* EEXIST */
188 static PyObject
* DBNoSuchFileError
; /* ENOENT */
189 static PyObject
* DBPermissionsError
; /* EPERM */
192 #define DB_BUFFER_SMALL ENOMEM
196 /* --------------------------------------------------------------------- */
197 /* Structure definitions */
199 #if PYTHON_API_VERSION >= 1010 /* python >= 2.1 support weak references */
205 /* if Python >= 2.1 better support warnings */
206 #if PYTHON_API_VERSION >= 1010
207 #define HAVE_WARNINGS
212 #if PYTHON_API_VERSION <= 1007
213 /* 1.5 compatibility */
214 #define PyObject_New PyObject_NEW
215 #define PyObject_Del PyMem_DEL
218 struct behaviourFlags
{
219 /* What is the default behaviour when DB->get or DBCursor->get returns a
220 DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise an exception? */
221 unsigned int getReturnsNone
: 1;
222 /* What is the default behaviour for DBCursor.set* methods when DBCursor->get
223 * returns a DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise? */
224 unsigned int cursorSetReturnsNone
: 1;
227 #define DEFAULT_GET_RETURNS_NONE 1
228 #define DEFAULT_CURSOR_SET_RETURNS_NONE 1 /* 0 in pybsddb < 4.2, python < 2.4 */
233 u_int32_t flags
; /* saved flags from open() */
235 struct behaviourFlags moduleFlags
;
237 PyObject
*in_weakreflist
; /* List of weak references */
245 DBEnvObject
* myenvobj
; /* PyObject containing the DB_ENV */
246 u_int32_t flags
; /* saved flags from open() */
247 u_int32_t setflags
; /* saved flags from set_flags() */
249 struct behaviourFlags moduleFlags
;
251 PyObject
* associateCallback
;
252 PyObject
* btCompareCallback
;
256 PyObject
*in_weakreflist
; /* List of weak references */
266 PyObject
*in_weakreflist
; /* List of weak references */
276 PyObject
*in_weakreflist
; /* List of weak references */
285 PyObject
*in_weakreflist
; /* List of weak references */
292 DB_SEQUENCE
* sequence
;
295 PyObject
*in_weakreflist
; /* List of weak references */
298 staticforward PyTypeObject DBSequence_Type
;
301 staticforward PyTypeObject DB_Type
, DBCursor_Type
, DBEnv_Type
, DBTxn_Type
, DBLock_Type
;
303 #define DBObject_Check(v) ((v)->ob_type == &DB_Type)
304 #define DBCursorObject_Check(v) ((v)->ob_type == &DBCursor_Type)
305 #define DBEnvObject_Check(v) ((v)->ob_type == &DBEnv_Type)
306 #define DBTxnObject_Check(v) ((v)->ob_type == &DBTxn_Type)
307 #define DBLockObject_Check(v) ((v)->ob_type == &DBLock_Type)
309 #define DBSequenceObject_Check(v) ((v)->ob_type == &DBSequence_Type)
313 /* --------------------------------------------------------------------- */
314 /* Utility macros and functions */
316 #define RETURN_IF_ERR() \
317 if (makeDBError(err)) { \
321 #define RETURN_NONE() Py_INCREF(Py_None); return Py_None;
323 #define _CHECK_OBJECT_NOT_CLOSED(nonNull, pyErrObj, name) \
324 if ((nonNull) == NULL) { \
325 PyObject *errTuple = NULL; \
326 errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
327 PyErr_SetObject((pyErrObj), errTuple); \
328 Py_DECREF(errTuple); \
332 #define CHECK_DB_NOT_CLOSED(dbobj) \
333 _CHECK_OBJECT_NOT_CLOSED(dbobj->db, DBError, DB)
335 #define CHECK_ENV_NOT_CLOSED(env) \
336 _CHECK_OBJECT_NOT_CLOSED(env->db_env, DBError, DBEnv)
338 #define CHECK_CURSOR_NOT_CLOSED(curs) \
339 _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)
342 #define CHECK_SEQUENCE_NOT_CLOSED(curs) \
343 _CHECK_OBJECT_NOT_CLOSED(curs->sequence, DBError, DBSequence)
346 #define CHECK_DBFLAG(mydb, flag) (((mydb)->flags & (flag)) || \
347 (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))
349 #define CLEAR_DBT(dbt) (memset(&(dbt), 0, sizeof(dbt)))
351 #define FREE_DBT(dbt) if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
352 dbt.data != NULL) { free(dbt.data); dbt.data = NULL; }
355 static int makeDBError(int err
);
358 /* Return the access method type of the DBObject */
359 static int _DB_get_type(DBObject
* self
)
364 err
= self
->db
->get_type(self
->db
, &type
);
365 if (makeDBError(err
)) {
370 return self
->db
->get_type(self
->db
);
375 /* Create a DBT structure (containing key and data values) from Python
376 strings. Returns 1 on success, 0 on an error. */
377 static int make_dbt(PyObject
* obj
, DBT
* dbt
)
380 if (obj
== Py_None
) {
381 /* no need to do anything, the structure has already been zeroed */
383 else if (!PyArg_Parse(obj
, "s#", &dbt
->data
, &dbt
->size
)) {
384 PyErr_SetString(PyExc_TypeError
,
385 "Data values must be of type string or None.");
392 /* Recno and Queue DBs can have integer keys. This function figures out
393 what's been given, verifies that it's allowed, and then makes the DBT.
395 Caller MUST call FREE_DBT(key) when done. */
397 make_key_dbt(DBObject
* self
, PyObject
* keyobj
, DBT
* key
, int* pflags
)
403 if (keyobj
== Py_None
) {
404 type
= _DB_get_type(self
);
407 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
410 "None keys not allowed for Recno and Queue DB's");
413 /* no need to do anything, the structure has already been zeroed */
416 else if (PyString_Check(keyobj
)) {
417 /* verify access method type */
418 type
= _DB_get_type(self
);
421 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
424 "String keys not allowed for Recno and Queue DB's");
428 key
->data
= PyString_AS_STRING(keyobj
);
429 key
->size
= PyString_GET_SIZE(keyobj
);
432 else if (PyInt_Check(keyobj
)) {
433 /* verify access method type */
434 type
= _DB_get_type(self
);
437 if (type
== DB_BTREE
&& pflags
!= NULL
) {
438 /* if BTREE then an Integer key is allowed with the
439 * DB_SET_RECNO flag */
440 *pflags
|= DB_SET_RECNO
;
442 else if (type
!= DB_RECNO
&& type
!= DB_QUEUE
) {
445 "Integer keys only allowed for Recno and Queue DB's");
449 /* Make a key out of the requested recno, use allocated space so DB
450 * will be able to realloc room for the real key if needed. */
451 recno
= PyInt_AS_LONG(keyobj
);
452 key
->data
= malloc(sizeof(db_recno_t
));
453 if (key
->data
== NULL
) {
454 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
457 key
->ulen
= key
->size
= sizeof(db_recno_t
);
458 memcpy(key
->data
, &recno
, sizeof(db_recno_t
));
459 key
->flags
= DB_DBT_REALLOC
;
462 PyErr_Format(PyExc_TypeError
,
463 "String or Integer object expected for key, %s found",
464 keyobj
->ob_type
->tp_name
);
472 /* Add partial record access to an existing DBT data struct.
473 If dlen and doff are set, then the DB_DBT_PARTIAL flag will be set
474 and the data storage/retrieval will be done using dlen and doff. */
475 static int add_partial_dbt(DBT
* d
, int dlen
, int doff
) {
476 /* if neither were set we do nothing (-1 is the default value) */
477 if ((dlen
== -1) && (doff
== -1)) {
481 if ((dlen
< 0) || (doff
< 0)) {
482 PyErr_SetString(PyExc_TypeError
, "dlen and doff must both be >= 0");
486 d
->flags
= d
->flags
| DB_DBT_PARTIAL
;
487 d
->dlen
= (unsigned int) dlen
;
488 d
->doff
= (unsigned int) doff
;
492 /* a safe strcpy() without the zeroing behaviour and semantics of strncpy. */
493 /* TODO: make this use the native libc strlcpy() when available (BSD) */
494 unsigned int our_strlcpy(char* dest
, const char* src
, unsigned int n
)
496 unsigned int srclen
, copylen
;
498 srclen
= strlen(src
);
501 copylen
= (srclen
> n
-1) ? n
-1 : srclen
;
502 /* populate dest[0] thru dest[copylen-1] */
503 memcpy(dest
, src
, copylen
);
504 /* guarantee null termination */
510 /* Callback used to save away more information about errors from the DB
512 static char _db_errmsg
[1024];
514 static void _db_errorCallback(const char* prefix
, char* msg
)
516 static void _db_errorCallback(const DB_ENV
*db_env
,
517 const char* prefix
, const char* msg
)
520 our_strlcpy(_db_errmsg
, msg
, sizeof(_db_errmsg
));
524 /* make a nice exception object to raise for errors. */
525 static int makeDBError(int err
)
527 char errTxt
[2048]; /* really big, just in case... */
528 PyObject
*errObj
= NULL
;
529 PyObject
*errTuple
= NULL
;
530 int exceptionRaised
= 0;
533 case 0: /* successful, no error */ break;
537 #if INCOMPLETE_IS_WARNING
538 our_strlcpy(errTxt
, db_strerror(err
), sizeof(errTxt
));
540 strcat(errTxt
, " -- ");
541 strcat(errTxt
, _db_errmsg
);
545 exceptionRaised
= PyErr_Warn(PyExc_RuntimeWarning
, errTxt
);
547 fprintf(stderr
, errTxt
);
548 fprintf(stderr
, "\n");
551 #else /* do an exception instead */
552 errObj
= DBIncompleteError
;
555 #endif /* DBVER < 41 */
557 case DB_KEYEMPTY
: errObj
= DBKeyEmptyError
; break;
558 case DB_KEYEXIST
: errObj
= DBKeyExistError
; break;
559 case DB_LOCK_DEADLOCK
: errObj
= DBLockDeadlockError
; break;
560 case DB_LOCK_NOTGRANTED
: errObj
= DBLockNotGrantedError
; break;
561 case DB_NOTFOUND
: errObj
= DBNotFoundError
; break;
562 case DB_OLD_VERSION
: errObj
= DBOldVersionError
; break;
563 case DB_RUNRECOVERY
: errObj
= DBRunRecoveryError
; break;
564 case DB_VERIFY_BAD
: errObj
= DBVerifyBadError
; break;
565 case DB_NOSERVER
: errObj
= DBNoServerError
; break;
566 case DB_NOSERVER_HOME
: errObj
= DBNoServerHomeError
; break;
567 case DB_NOSERVER_ID
: errObj
= DBNoServerIDError
; break;
569 case DB_PAGE_NOTFOUND
: errObj
= DBPageNotFoundError
; break;
570 case DB_SECONDARY_BAD
: errObj
= DBSecondaryBadError
; break;
572 case DB_BUFFER_SMALL
: errObj
= DBNoMemoryError
; break;
575 /* ENOMEM and DB_BUFFER_SMALL were one and the same until 4.3 */
576 case ENOMEM
: errObj
= PyExc_MemoryError
; break;
578 case EINVAL
: errObj
= DBInvalidArgError
; break;
579 case EACCES
: errObj
= DBAccessError
; break;
580 case ENOSPC
: errObj
= DBNoSpaceError
; break;
581 case EAGAIN
: errObj
= DBAgainError
; break;
582 case EBUSY
: errObj
= DBBusyError
; break;
583 case EEXIST
: errObj
= DBFileExistsError
; break;
584 case ENOENT
: errObj
= DBNoSuchFileError
; break;
585 case EPERM
: errObj
= DBPermissionsError
; break;
587 default: errObj
= DBError
; break;
590 if (errObj
!= NULL
) {
591 our_strlcpy(errTxt
, db_strerror(err
), sizeof(errTxt
));
593 strcat(errTxt
, " -- ");
594 strcat(errTxt
, _db_errmsg
);
598 errTuple
= Py_BuildValue("(is)", err
, errTxt
);
599 PyErr_SetObject(errObj
, errTuple
);
603 return ((errObj
!= NULL
) || exceptionRaised
);
608 /* set a type exception */
609 static void makeTypeError(char* expected
, PyObject
* found
)
611 PyErr_Format(PyExc_TypeError
, "Expected %s argument, %s found.",
612 expected
, found
->ob_type
->tp_name
);
616 /* verify that an obj is either None or a DBTxn, and set the txn pointer */
617 static int checkTxnObj(PyObject
* txnobj
, DB_TXN
** txn
)
619 if (txnobj
== Py_None
|| txnobj
== NULL
) {
623 if (DBTxnObject_Check(txnobj
)) {
624 *txn
= ((DBTxnObject
*)txnobj
)->txn
;
628 makeTypeError("DBTxn", txnobj
);
633 /* Delete a key from a database
634 Returns 0 on success, -1 on an error. */
635 static int _DB_delete(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, int flags
)
639 MYDB_BEGIN_ALLOW_THREADS
;
640 err
= self
->db
->del(self
->db
, txn
, key
, 0);
641 MYDB_END_ALLOW_THREADS
;
642 if (makeDBError(err
)) {
650 /* Store a key into a database
651 Returns 0 on success, -1 on an error. */
652 static int _DB_put(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, DBT
*data
, int flags
)
656 MYDB_BEGIN_ALLOW_THREADS
;
657 err
= self
->db
->put(self
->db
, txn
, key
, data
, flags
);
658 MYDB_END_ALLOW_THREADS
;
659 if (makeDBError(err
)) {
666 /* Get a key/data pair from a cursor */
667 static PyObject
* _DBCursor_get(DBCursorObject
* self
, int extra_flags
,
668 PyObject
*args
, PyObject
*kwargs
, char *format
)
671 PyObject
* retval
= NULL
;
676 static char* kwnames
[] = { "flags", "dlen", "doff", NULL
};
678 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, format
, kwnames
,
679 &flags
, &dlen
, &doff
))
682 CHECK_CURSOR_NOT_CLOSED(self
);
684 flags
|= extra_flags
;
687 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
688 /* Tell BerkeleyDB to malloc the return value (thread safe) */
689 data
.flags
= DB_DBT_MALLOC
;
690 key
.flags
= DB_DBT_MALLOC
;
692 if (!add_partial_dbt(&data
, dlen
, doff
))
695 MYDB_BEGIN_ALLOW_THREADS
;
696 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
697 MYDB_END_ALLOW_THREADS
;
699 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
700 && self
->mydb
->moduleFlags
.getReturnsNone
) {
704 else if (makeDBError(err
)) {
707 else { /* otherwise, success! */
709 /* if Recno or Queue, return the key as an Int */
710 switch (_DB_get_type(self
->mydb
)) {
717 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
718 data
.data
, data
.size
);
723 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
724 data
.data
, data
.size
);
736 /* add an integer to a dictionary using the given name as a key */
737 static void _addIntToDict(PyObject
* dict
, char *name
, int value
)
739 PyObject
* v
= PyInt_FromLong((long) value
);
740 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
746 /* add an db_seq_t to a dictionary using the given name as a key */
747 static void _addDb_seq_tToDict(PyObject
* dict
, char *name
, db_seq_t value
)
749 PyObject
* v
= PyLong_FromLongLong(value
);
750 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
759 /* --------------------------------------------------------------------- */
760 /* Allocators and deallocators */
763 newDBObject(DBEnvObject
* arg
, int flags
)
766 DB_ENV
* db_env
= NULL
;
769 self
= PyObject_New(DBObject
, &DB_Type
);
776 self
->myenvobj
= NULL
;
778 self
->associateCallback
= NULL
;
779 self
->btCompareCallback
= NULL
;
780 self
->primaryDBType
= 0;
783 self
->in_weakreflist
= NULL
;
786 /* keep a reference to our python DBEnv object */
789 self
->myenvobj
= arg
;
790 db_env
= arg
->db_env
;
794 self
->moduleFlags
= self
->myenvobj
->moduleFlags
;
796 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
797 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
799 MYDB_BEGIN_ALLOW_THREADS
;
800 err
= db_create(&self
->db
, db_env
, flags
);
801 self
->db
->set_errcall(self
->db
, _db_errorCallback
);
803 self
->db
->app_private
= (void*)self
;
805 MYDB_END_ALLOW_THREADS
;
806 /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
807 * list so that a DBEnv can refuse to close without aborting any open
808 * DBTxns and closing any open DBs first. */
809 if (makeDBError(err
)) {
810 if (self
->myenvobj
) {
811 Py_DECREF(self
->myenvobj
);
812 self
->myenvobj
= NULL
;
822 DB_dealloc(DBObject
* self
)
824 if (self
->db
!= NULL
) {
825 /* avoid closing a DB when its DBEnv has been closed out from under
827 if (!self
->myenvobj
||
828 (self
->myenvobj
&& self
->myenvobj
->db_env
))
830 MYDB_BEGIN_ALLOW_THREADS
;
831 self
->db
->close(self
->db
, 0);
832 MYDB_END_ALLOW_THREADS
;
835 PyErr_Warn(PyExc_RuntimeWarning
,
836 "DB could not be closed in destructor: DBEnv already closed");
842 if (self
->in_weakreflist
!= NULL
) {
843 PyObject_ClearWeakRefs((PyObject
*) self
);
846 if (self
->myenvobj
) {
847 Py_DECREF(self
->myenvobj
);
848 self
->myenvobj
= NULL
;
851 if (self
->associateCallback
!= NULL
) {
852 Py_DECREF(self
->associateCallback
);
853 self
->associateCallback
= NULL
;
855 if (self
->btCompareCallback
!= NULL
) {
856 Py_DECREF(self
->btCompareCallback
);
857 self
->btCompareCallback
= NULL
;
864 static DBCursorObject
*
865 newDBCursorObject(DBC
* dbc
, DBObject
* db
)
867 DBCursorObject
* self
= PyObject_New(DBCursorObject
, &DBCursor_Type
);
874 self
->in_weakreflist
= NULL
;
876 Py_INCREF(self
->mydb
);
882 DBCursor_dealloc(DBCursorObject
* self
)
887 if (self
->in_weakreflist
!= NULL
) {
888 PyObject_ClearWeakRefs((PyObject
*) self
);
892 if (self
->dbc
!= NULL
) {
893 MYDB_BEGIN_ALLOW_THREADS
;
894 /* If the underlying database has been closed, we don't
895 need to do anything. If the environment has been closed
896 we need to leak, as BerkeleyDB will crash trying to access
897 the environment. There was an exception when the
898 user closed the environment even though there still was
900 if (self
->mydb
->db
&& self
->mydb
->myenvobj
&&
901 !self
->mydb
->myenvobj
->closed
)
902 err
= self
->dbc
->c_close(self
->dbc
);
904 MYDB_END_ALLOW_THREADS
;
906 Py_XDECREF( self
->mydb
);
912 newDBEnvObject(int flags
)
915 DBEnvObject
* self
= PyObject_New(DBEnvObject
, &DBEnv_Type
);
921 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
922 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
924 self
->in_weakreflist
= NULL
;
927 MYDB_BEGIN_ALLOW_THREADS
;
928 err
= db_env_create(&self
->db_env
, flags
);
929 MYDB_END_ALLOW_THREADS
;
930 if (makeDBError(err
)) {
935 self
->db_env
->set_errcall(self
->db_env
, _db_errorCallback
);
942 DBEnv_dealloc(DBEnvObject
* self
)
945 if (self
->in_weakreflist
!= NULL
) {
946 PyObject_ClearWeakRefs((PyObject
*) self
);
950 if (self
->db_env
&& !self
->closed
) {
951 MYDB_BEGIN_ALLOW_THREADS
;
952 self
->db_env
->close(self
->db_env
, 0);
953 MYDB_END_ALLOW_THREADS
;
960 newDBTxnObject(DBEnvObject
* myenv
, DB_TXN
*parent
, int flags
)
963 DBTxnObject
* self
= PyObject_New(DBTxnObject
, &DBTxn_Type
);
967 self
->env
= (PyObject
*)myenv
;
969 self
->in_weakreflist
= NULL
;
972 MYDB_BEGIN_ALLOW_THREADS
;
974 err
= myenv
->db_env
->txn_begin(myenv
->db_env
, parent
, &(self
->txn
), flags
);
976 err
= txn_begin(myenv
->db_env
, parent
, &(self
->txn
), flags
);
978 MYDB_END_ALLOW_THREADS
;
979 if (makeDBError(err
)) {
980 Py_DECREF(self
->env
);
989 DBTxn_dealloc(DBTxnObject
* self
)
992 if (self
->in_weakreflist
!= NULL
) {
993 PyObject_ClearWeakRefs((PyObject
*) self
);
999 /* it hasn't been finalized, abort it! */
1000 MYDB_BEGIN_ALLOW_THREADS
;
1002 self
->txn
->abort(self
->txn
);
1004 txn_abort(self
->txn
);
1006 MYDB_END_ALLOW_THREADS
;
1007 PyErr_Warn(PyExc_RuntimeWarning
,
1008 "DBTxn aborted in destructor. No prior commit() or abort().");
1012 Py_DECREF(self
->env
);
1017 static DBLockObject
*
1018 newDBLockObject(DBEnvObject
* myenv
, u_int32_t locker
, DBT
* obj
,
1019 db_lockmode_t lock_mode
, int flags
)
1022 DBLockObject
* self
= PyObject_New(DBLockObject
, &DBLock_Type
);
1026 self
->in_weakreflist
= NULL
;
1029 MYDB_BEGIN_ALLOW_THREADS
;
1031 err
= myenv
->db_env
->lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
,
1034 err
= lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
, &self
->lock
);
1036 MYDB_END_ALLOW_THREADS
;
1037 if (makeDBError(err
)) {
1047 DBLock_dealloc(DBLockObject
* self
)
1050 if (self
->in_weakreflist
!= NULL
) {
1051 PyObject_ClearWeakRefs((PyObject
*) self
);
1054 /* TODO: is this lock held? should we release it? */
1061 static DBSequenceObject
*
1062 newDBSequenceObject(DBObject
* mydb
, int flags
)
1065 DBSequenceObject
* self
= PyObject_New(DBSequenceObject
, &DBSequence_Type
);
1071 self
->in_weakreflist
= NULL
;
1075 MYDB_BEGIN_ALLOW_THREADS
;
1076 err
= db_sequence_create(&self
->sequence
, self
->mydb
->db
, flags
);
1077 MYDB_END_ALLOW_THREADS
;
1078 if (makeDBError(err
)) {
1079 Py_DECREF(self
->mydb
);
1089 DBSequence_dealloc(DBSequenceObject
* self
)
1092 if (self
->in_weakreflist
!= NULL
) {
1093 PyObject_ClearWeakRefs((PyObject
*) self
);
1097 Py_DECREF(self
->mydb
);
1102 /* --------------------------------------------------------------------- */
1106 DB_append(DBObject
* self
, PyObject
* args
)
1108 PyObject
* txnobj
= NULL
;
1114 if (!PyArg_UnpackTuple(args
, "append", 1, 2, &dataobj
, &txnobj
))
1117 CHECK_DB_NOT_CLOSED(self
);
1119 /* make a dummy key out of a recno */
1123 key
.size
= sizeof(recno
);
1124 key
.ulen
= key
.size
;
1125 key
.flags
= DB_DBT_USERMEM
;
1127 if (!make_dbt(dataobj
, &data
)) return NULL
;
1128 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1130 if (-1 == _DB_put(self
, txn
, &key
, &data
, DB_APPEND
))
1133 return PyInt_FromLong(recno
);
1140 _db_associateCallback(DB
* db
, const DBT
* priKey
, const DBT
* priData
,
1143 int retval
= DB_DONOTINDEX
;
1144 DBObject
* secondaryDB
= (DBObject
*)db
->app_private
;
1145 PyObject
* callback
= secondaryDB
->associateCallback
;
1146 int type
= secondaryDB
->primaryDBType
;
1148 PyObject
* result
= NULL
;
1151 if (callback
!= NULL
) {
1152 MYDB_BEGIN_BLOCK_THREADS
;
1154 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
1155 args
= Py_BuildValue("(ls#)", *((db_recno_t
*)priKey
->data
),
1156 priData
->data
, priData
->size
);
1158 args
= Py_BuildValue("(s#s#)", priKey
->data
, priKey
->size
,
1159 priData
->data
, priData
->size
);
1161 result
= PyEval_CallObject(callback
, args
);
1163 if (args
== NULL
|| result
== NULL
) {
1166 else if (result
== Py_None
) {
1167 retval
= DB_DONOTINDEX
;
1169 else if (PyInt_Check(result
)) {
1170 retval
= PyInt_AsLong(result
);
1172 else if (PyString_Check(result
)) {
1177 #if PYTHON_API_VERSION <= 1007
1178 /* 1.5 compatibility */
1179 size
= PyString_Size(result
);
1180 data
= PyString_AsString(result
);
1182 PyString_AsStringAndSize(result
, &data
, &size
);
1184 secKey
->flags
= DB_DBT_APPMALLOC
; /* DB will free */
1185 secKey
->data
= malloc(size
); /* TODO, check this */
1187 memcpy(secKey
->data
, data
, size
);
1188 secKey
->size
= size
;
1192 PyErr_SetString(PyExc_MemoryError
,
1193 "malloc failed in _db_associateCallback");
1200 "DB associate callback should return DB_DONOTINDEX or string.");
1207 MYDB_END_BLOCK_THREADS
;
1214 DB_associate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1217 DBObject
* secondaryDB
;
1220 PyObject
*txnobj
= NULL
;
1222 static char* kwnames
[] = {"secondaryDB", "callback", "flags", "txn",
1225 static char* kwnames
[] = {"secondaryDB", "callback", "flags", NULL
};
1229 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iO:associate", kwnames
,
1230 &secondaryDB
, &callback
, &flags
,
1233 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|i:associate", kwnames
,
1234 &secondaryDB
, &callback
, &flags
)) {
1240 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1243 CHECK_DB_NOT_CLOSED(self
);
1244 if (!DBObject_Check(secondaryDB
)) {
1245 makeTypeError("DB", (PyObject
*)secondaryDB
);
1248 CHECK_DB_NOT_CLOSED(secondaryDB
);
1249 if (callback
== Py_None
) {
1252 else if (!PyCallable_Check(callback
)) {
1253 makeTypeError("Callable", callback
);
1257 /* Save a reference to the callback in the secondary DB. */
1258 Py_XDECREF(secondaryDB
->associateCallback
);
1259 Py_XINCREF(callback
);
1260 secondaryDB
->associateCallback
= callback
;
1261 secondaryDB
->primaryDBType
= _DB_get_type(self
);
1263 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1264 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1265 * The global interepreter lock is not initialized until the first
1266 * thread is created using thread.start_new_thread() or fork() is
1267 * called. that would cause the ALLOW_THREADS here to segfault due
1268 * to a null pointer reference if no threads or child processes
1269 * have been created. This works around that and is a no-op if
1270 * threads have already been initialized.
1271 * (see pybsddb-users mailing list post on 2002-08-07)
1274 PyEval_InitThreads();
1276 MYDB_BEGIN_ALLOW_THREADS
;
1278 err
= self
->db
->associate(self
->db
,
1281 _db_associateCallback
,
1284 err
= self
->db
->associate(self
->db
,
1286 _db_associateCallback
,
1289 MYDB_END_ALLOW_THREADS
;
1292 Py_XDECREF(secondaryDB
->associateCallback
);
1293 secondaryDB
->associateCallback
= NULL
;
1294 secondaryDB
->primaryDBType
= 0;
1306 DB_close(DBObject
* self
, PyObject
* args
)
1309 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
1311 if (self
->db
!= NULL
) {
1313 CHECK_ENV_NOT_CLOSED(self
->myenvobj
);
1314 err
= self
->db
->close(self
->db
, flags
);
1324 _DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1326 int err
, flags
=0, type
;
1327 PyObject
* txnobj
= NULL
;
1328 PyObject
* retval
= NULL
;
1331 static char* kwnames
[] = { "txn", "flags", NULL
};
1333 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:consume", kwnames
,
1337 CHECK_DB_NOT_CLOSED(self
);
1338 type
= _DB_get_type(self
);
1341 if (type
!= DB_QUEUE
) {
1342 PyErr_SetString(PyExc_TypeError
,
1343 "Consume methods only allowed for Queue DB's");
1346 if (!checkTxnObj(txnobj
, &txn
))
1351 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1352 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1353 data
.flags
= DB_DBT_MALLOC
;
1354 key
.flags
= DB_DBT_MALLOC
;
1357 MYDB_BEGIN_ALLOW_THREADS
;
1358 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
|consume_flag
);
1359 MYDB_END_ALLOW_THREADS
;
1361 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1362 && self
->moduleFlags
.getReturnsNone
) {
1368 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
1379 DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1381 return _DB_consume(self
, args
, kwargs
, DB_CONSUME
);
1385 DB_consume_wait(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
,
1388 return _DB_consume(self
, args
, kwargs
, DB_CONSUME_WAIT
);
1395 DB_cursor(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1399 PyObject
* txnobj
= NULL
;
1401 static char* kwnames
[] = { "txn", "flags", NULL
};
1403 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
1406 CHECK_DB_NOT_CLOSED(self
);
1407 if (!checkTxnObj(txnobj
, &txn
))
1410 MYDB_BEGIN_ALLOW_THREADS
;
1411 err
= self
->db
->cursor(self
->db
, txn
, &dbc
, flags
);
1412 MYDB_END_ALLOW_THREADS
;
1414 return (PyObject
*) newDBCursorObject(dbc
, self
);
1419 DB_delete(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1421 PyObject
* txnobj
= NULL
;
1426 static char* kwnames
[] = { "key", "txn", "flags", NULL
};
1428 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:delete", kwnames
,
1429 &keyobj
, &txnobj
, &flags
))
1431 CHECK_DB_NOT_CLOSED(self
);
1432 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1434 if (!checkTxnObj(txnobj
, &txn
)) {
1439 if (-1 == _DB_delete(self
, txn
, &key
, 0)) {
1450 DB_fd(DBObject
* self
, PyObject
* args
)
1454 if (!PyArg_ParseTuple(args
,":fd"))
1456 CHECK_DB_NOT_CLOSED(self
);
1458 MYDB_BEGIN_ALLOW_THREADS
;
1459 err
= self
->db
->fd(self
->db
, &the_fd
);
1460 MYDB_END_ALLOW_THREADS
;
1462 return PyInt_FromLong(the_fd
);
1467 DB_get(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1470 PyObject
* txnobj
= NULL
;
1472 PyObject
* dfltobj
= NULL
;
1473 PyObject
* retval
= NULL
;
1478 static char* kwnames
[] = {"key", "default", "txn", "flags", "dlen",
1481 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:get", kwnames
,
1482 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1486 CHECK_DB_NOT_CLOSED(self
);
1487 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1489 if (!checkTxnObj(txnobj
, &txn
)) {
1495 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1496 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1497 data
.flags
= DB_DBT_MALLOC
;
1499 if (!add_partial_dbt(&data
, dlen
, doff
)) {
1504 MYDB_BEGIN_ALLOW_THREADS
;
1505 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1506 MYDB_END_ALLOW_THREADS
;
1508 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && (dfltobj
!= NULL
)) {
1513 else if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1514 && self
->moduleFlags
.getReturnsNone
) {
1520 if (flags
& DB_SET_RECNO
) /* return both key and data */
1521 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
1523 else /* return just the data */
1524 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
1535 DB_pget(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1538 PyObject
* txnobj
= NULL
;
1540 PyObject
* dfltobj
= NULL
;
1541 PyObject
* retval
= NULL
;
1544 DBT key
, pkey
, data
;
1546 static char* kwnames
[] = {"key", "default", "txn", "flags", "dlen",
1549 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:pget", kwnames
,
1550 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1554 CHECK_DB_NOT_CLOSED(self
);
1555 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1557 if (!checkTxnObj(txnobj
, &txn
)) {
1563 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1564 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1565 data
.flags
= DB_DBT_MALLOC
;
1567 if (!add_partial_dbt(&data
, dlen
, doff
)) {
1573 pkey
.flags
= DB_DBT_MALLOC
;
1575 MYDB_BEGIN_ALLOW_THREADS
;
1576 err
= self
->db
->pget(self
->db
, txn
, &key
, &pkey
, &data
, flags
);
1577 MYDB_END_ALLOW_THREADS
;
1579 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && (dfltobj
!= NULL
)) {
1584 else if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1585 && self
->moduleFlags
.getReturnsNone
) {
1593 dataObj
= PyString_FromStringAndSize(data
.data
, data
.size
);
1595 if (self
->primaryDBType
== DB_RECNO
||
1596 self
->primaryDBType
== DB_QUEUE
)
1597 pkeyObj
= PyInt_FromLong(*(int *)pkey
.data
);
1599 pkeyObj
= PyString_FromStringAndSize(pkey
.data
, pkey
.size
);
1601 if (flags
& DB_SET_RECNO
) /* return key , pkey and data */
1604 int type
= _DB_get_type(self
);
1605 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
1606 keyObj
= PyInt_FromLong(*(int *)key
.data
);
1608 keyObj
= PyString_FromStringAndSize(key
.data
, key
.size
);
1609 #if (PY_VERSION_HEX >= 0x02040000)
1610 retval
= PyTuple_Pack(3, keyObj
, pkeyObj
, dataObj
);
1612 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
1616 else /* return just the pkey and data */
1618 #if (PY_VERSION_HEX >= 0x02040000)
1619 retval
= PyTuple_Pack(2, pkeyObj
, dataObj
);
1621 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
1637 /* Return size of entry */
1639 DB_get_size(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1642 PyObject
* txnobj
= NULL
;
1644 PyObject
* retval
= NULL
;
1647 static char* kwnames
[] = { "key", "txn", NULL
};
1649 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O:get_size", kwnames
,
1652 CHECK_DB_NOT_CLOSED(self
);
1653 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1655 if (!checkTxnObj(txnobj
, &txn
)) {
1661 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
1662 thus getting the record size. */
1663 data
.flags
= DB_DBT_USERMEM
;
1665 MYDB_BEGIN_ALLOW_THREADS
;
1666 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1667 MYDB_END_ALLOW_THREADS
;
1668 if (err
== DB_BUFFER_SMALL
) {
1669 retval
= PyInt_FromLong((long)data
.size
);
1681 DB_get_both(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1684 PyObject
* txnobj
= NULL
;
1687 PyObject
* retval
= NULL
;
1690 static char* kwnames
[] = { "key", "data", "txn", "flags", NULL
};
1693 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oi:get_both", kwnames
,
1694 &keyobj
, &dataobj
, &txnobj
, &flags
))
1697 CHECK_DB_NOT_CLOSED(self
);
1698 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1700 if ( !make_dbt(dataobj
, &data
) ||
1701 !checkTxnObj(txnobj
, &txn
) )
1707 flags
|= DB_GET_BOTH
;
1709 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1710 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1711 data
.flags
= DB_DBT_MALLOC
;
1712 /* TODO: Is this flag needed? We're passing a data object that should
1713 match what's in the DB, so there should be no need to malloc.
1714 We run the risk of freeing something twice! Check this. */
1717 MYDB_BEGIN_ALLOW_THREADS
;
1718 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1719 MYDB_END_ALLOW_THREADS
;
1721 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1722 && self
->moduleFlags
.getReturnsNone
) {
1728 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
1729 FREE_DBT(data
); /* Only if retrieval was successful */
1739 DB_get_byteswapped(DBObject
* self
, PyObject
* args
)
1746 if (!PyArg_ParseTuple(args
,":get_byteswapped"))
1748 CHECK_DB_NOT_CLOSED(self
);
1751 MYDB_BEGIN_ALLOW_THREADS
;
1752 err
= self
->db
->get_byteswapped(self
->db
, &retval
);
1753 MYDB_END_ALLOW_THREADS
;
1756 MYDB_BEGIN_ALLOW_THREADS
;
1757 retval
= self
->db
->get_byteswapped(self
->db
);
1758 MYDB_END_ALLOW_THREADS
;
1760 return PyInt_FromLong(retval
);
1765 DB_get_type(DBObject
* self
, PyObject
* args
)
1769 if (!PyArg_ParseTuple(args
,":get_type"))
1771 CHECK_DB_NOT_CLOSED(self
);
1773 MYDB_BEGIN_ALLOW_THREADS
;
1774 type
= _DB_get_type(self
);
1775 MYDB_END_ALLOW_THREADS
;
1778 return PyInt_FromLong(type
);
1783 DB_join(DBObject
* self
, PyObject
* args
)
1787 PyObject
* cursorsObj
;
1792 if (!PyArg_ParseTuple(args
,"O|i:join", &cursorsObj
, &flags
))
1795 CHECK_DB_NOT_CLOSED(self
);
1797 if (!PySequence_Check(cursorsObj
)) {
1798 PyErr_SetString(PyExc_TypeError
,
1799 "Sequence of DBCursor objects expected");
1803 length
= PyObject_Length(cursorsObj
);
1804 cursors
= malloc((length
+1) * sizeof(DBC
*));
1805 cursors
[length
] = NULL
;
1806 for (x
=0; x
<length
; x
++) {
1807 PyObject
* item
= PySequence_GetItem(cursorsObj
, x
);
1812 if (!DBCursorObject_Check(item
)) {
1813 PyErr_SetString(PyExc_TypeError
,
1814 "Sequence of DBCursor objects expected");
1818 cursors
[x
] = ((DBCursorObject
*)item
)->dbc
;
1822 MYDB_BEGIN_ALLOW_THREADS
;
1823 err
= self
->db
->join(self
->db
, cursors
, &dbc
, flags
);
1824 MYDB_END_ALLOW_THREADS
;
1828 /* FIXME: this is a buggy interface. The returned cursor
1829 contains internal references to the passed in cursors
1830 but does not hold python references to them or prevent
1831 them from being closed prematurely. This can cause
1832 python to crash when things are done in the wrong order. */
1833 return (PyObject
*) newDBCursorObject(dbc
, self
);
1838 DB_key_range(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1841 PyObject
* txnobj
= NULL
;
1846 static char* kwnames
[] = { "key", "txn", "flags", NULL
};
1848 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:key_range", kwnames
,
1849 &keyobj
, &txnobj
, &flags
))
1851 CHECK_DB_NOT_CLOSED(self
);
1852 if (!make_dbt(keyobj
, &key
))
1853 /* BTree only, don't need to allow for an int key */
1855 if (!checkTxnObj(txnobj
, &txn
))
1858 MYDB_BEGIN_ALLOW_THREADS
;
1859 err
= self
->db
->key_range(self
->db
, txn
, &key
, &range
, flags
);
1860 MYDB_END_ALLOW_THREADS
;
1863 return Py_BuildValue("ddd", range
.less
, range
.equal
, range
.greater
);
1868 DB_open(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1870 int err
, type
= DB_UNKNOWN
, flags
=0, mode
=0660;
1871 char* filename
= NULL
;
1872 char* dbname
= NULL
;
1874 PyObject
*txnobj
= NULL
;
1877 static char* kwnames
[] = {
1878 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL
};
1879 /* without dbname */
1880 static char* kwnames_basic
[] = {
1881 "filename", "dbtype", "flags", "mode", "txn", NULL
};
1884 static char* kwnames
[] = {
1885 "filename", "dbname", "dbtype", "flags", "mode", NULL
};
1886 /* without dbname */
1887 static char* kwnames_basic
[] = {
1888 "filename", "dbtype", "flags", "mode", NULL
};
1892 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziiiO:open", kwnames
,
1893 &filename
, &dbname
, &type
, &flags
, &mode
,
1896 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziii:open", kwnames
,
1897 &filename
, &dbname
, &type
, &flags
,
1902 type
= DB_UNKNOWN
; flags
= 0; mode
= 0660;
1903 filename
= NULL
; dbname
= NULL
;
1905 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iiiO:open",
1907 &filename
, &type
, &flags
, &mode
,
1911 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iii:open",
1913 &filename
, &type
, &flags
, &mode
))
1919 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1922 if (NULL
== self
->db
) {
1923 PyObject
*t
= Py_BuildValue("(is)", 0,
1924 "Cannot call open() twice for DB object");
1925 PyErr_SetObject(DBError
, t
);
1930 #if 0 && (DBVER >= 41)
1931 if ((!txn
) && (txnobj
!= Py_None
) && self
->myenvobj
1932 && (self
->myenvobj
->flags
& DB_INIT_TXN
))
1934 /* If no 'txn' parameter was supplied (no DbTxn object and None was not
1935 * explicitly passed) but we are in a transaction ready environment:
1936 * add DB_AUTO_COMMIT to allow for older pybsddb apps using transactions
1937 * to work on BerkeleyDB 4.1 without needing to modify their
1938 * DBEnv or DB open calls.
1939 * TODO make this behaviour of the library configurable.
1941 flags
|= DB_AUTO_COMMIT
;
1945 MYDB_BEGIN_ALLOW_THREADS
;
1947 err
= self
->db
->open(self
->db
, txn
, filename
, dbname
, type
, flags
, mode
);
1949 err
= self
->db
->open(self
->db
, filename
, dbname
, type
, flags
, mode
);
1951 MYDB_END_ALLOW_THREADS
;
1952 if (makeDBError(err
)) {
1953 self
->db
->close(self
->db
, 0);
1958 self
->flags
= flags
;
1964 DB_put(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1967 PyObject
* txnobj
= NULL
;
1970 PyObject
* keyobj
, *dataobj
, *retval
;
1973 static char* kwnames
[] = { "key", "data", "txn", "flags", "dlen",
1976 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oiii:put", kwnames
,
1977 &keyobj
, &dataobj
, &txnobj
, &flags
, &dlen
, &doff
))
1980 CHECK_DB_NOT_CLOSED(self
);
1981 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1983 if ( !make_dbt(dataobj
, &data
) ||
1984 !add_partial_dbt(&data
, dlen
, doff
) ||
1985 !checkTxnObj(txnobj
, &txn
) )
1991 if (-1 == _DB_put(self
, txn
, &key
, &data
, flags
)) {
1996 if (flags
& DB_APPEND
)
1997 retval
= PyInt_FromLong(*((db_recno_t
*)key
.data
));
2009 DB_remove(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2012 char* database
= NULL
;
2014 static char* kwnames
[] = { "filename", "dbname", "flags", NULL
};
2016 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zi:remove", kwnames
,
2017 &filename
, &database
, &flags
))
2019 CHECK_DB_NOT_CLOSED(self
);
2021 err
= self
->db
->remove(self
->db
, filename
, database
, flags
);
2030 DB_rename(DBObject
* self
, PyObject
* args
)
2037 if (!PyArg_ParseTuple(args
, "sss|i:rename", &filename
, &database
, &newname
,
2040 CHECK_DB_NOT_CLOSED(self
);
2042 MYDB_BEGIN_ALLOW_THREADS
;
2043 err
= self
->db
->rename(self
->db
, filename
, database
, newname
, flags
);
2044 MYDB_END_ALLOW_THREADS
;
2051 DB_set_bt_minkey(DBObject
* self
, PyObject
* args
)
2055 if (!PyArg_ParseTuple(args
,"i:set_bt_minkey", &minkey
))
2057 CHECK_DB_NOT_CLOSED(self
);
2059 MYDB_BEGIN_ALLOW_THREADS
;
2060 err
= self
->db
->set_bt_minkey(self
->db
, minkey
);
2061 MYDB_END_ALLOW_THREADS
;
2068 _default_cmp(const DBT
*leftKey
,
2069 const DBT
*rightKey
)
2072 int lsize
= leftKey
->size
, rsize
= rightKey
->size
;
2074 res
= memcmp(leftKey
->data
, rightKey
->data
,
2075 lsize
< rsize
? lsize
: rsize
);
2078 if (lsize
< rsize
) {
2081 else if (lsize
> rsize
) {
2089 _db_compareCallback(DB
* db
,
2091 const DBT
*rightKey
)
2095 PyObject
*result
= NULL
;
2096 DBObject
*self
= (DBObject
*)db
->app_private
;
2098 if (self
== NULL
|| self
->btCompareCallback
== NULL
) {
2099 MYDB_BEGIN_BLOCK_THREADS
;
2100 PyErr_SetString(PyExc_TypeError
,
2102 ? "DB_bt_compare db is NULL."
2103 : "DB_bt_compare callback is NULL."));
2104 /* we're in a callback within the DB code, we can't raise */
2106 res
= _default_cmp(leftKey
, rightKey
);
2107 MYDB_END_BLOCK_THREADS
;
2109 MYDB_BEGIN_BLOCK_THREADS
;
2111 args
= Py_BuildValue("s#s#", leftKey
->data
, leftKey
->size
,
2112 rightKey
->data
, rightKey
->size
);
2114 /* XXX(twouters) I highly doubt this INCREF is correct */
2116 result
= PyEval_CallObject(self
->btCompareCallback
, args
);
2118 if (args
== NULL
|| result
== NULL
) {
2119 /* we're in a callback within the DB code, we can't raise */
2121 res
= _default_cmp(leftKey
, rightKey
);
2122 } else if (PyInt_Check(result
)) {
2123 res
= PyInt_AsLong(result
);
2125 PyErr_SetString(PyExc_TypeError
,
2126 "DB_bt_compare callback MUST return an int.");
2127 /* we're in a callback within the DB code, we can't raise */
2129 res
= _default_cmp(leftKey
, rightKey
);
2135 MYDB_END_BLOCK_THREADS
;
2141 DB_set_bt_compare(DBObject
* self
, PyObject
* args
)
2144 PyObject
*comparator
;
2145 PyObject
*tuple
, *result
;
2147 if (!PyArg_ParseTuple(args
, "O:set_bt_compare", &comparator
))
2150 CHECK_DB_NOT_CLOSED(self
);
2152 if (!PyCallable_Check(comparator
)) {
2153 makeTypeError("Callable", comparator
);
2158 * Perform a test call of the comparator function with two empty
2159 * string objects here. verify that it returns an int (0).
2162 tuple
= Py_BuildValue("(ss)", "", "");
2163 result
= PyEval_CallObject(comparator
, tuple
);
2167 if (!PyInt_Check(result
)) {
2168 PyErr_SetString(PyExc_TypeError
,
2169 "callback MUST return an int");
2171 } else if (PyInt_AsLong(result
) != 0) {
2172 PyErr_SetString(PyExc_TypeError
,
2173 "callback failed to return 0 on two empty strings");
2178 /* We don't accept multiple set_bt_compare operations, in order to
2179 * simplify the code. This would have no real use, as one cannot
2180 * change the function once the db is opened anyway */
2181 if (self
->btCompareCallback
!= NULL
) {
2182 PyErr_SetString(PyExc_RuntimeError
, "set_bt_compare() cannot be called more than once");
2186 Py_INCREF(comparator
);
2187 self
->btCompareCallback
= comparator
;
2189 /* This is to workaround a problem with un-initialized threads (see
2190 comment in DB_associate) */
2192 PyEval_InitThreads();
2195 err
= self
->db
->set_bt_compare(self
->db
, _db_compareCallback
);
2198 /* restore the old state in case of error */
2199 Py_DECREF(comparator
);
2200 self
->btCompareCallback
= NULL
;
2206 #endif /* DBVER >= 33 */
2210 DB_set_cachesize(DBObject
* self
, PyObject
* args
)
2213 int gbytes
= 0, bytes
= 0, ncache
= 0;
2215 if (!PyArg_ParseTuple(args
,"ii|i:set_cachesize",
2216 &gbytes
,&bytes
,&ncache
))
2218 CHECK_DB_NOT_CLOSED(self
);
2220 MYDB_BEGIN_ALLOW_THREADS
;
2221 err
= self
->db
->set_cachesize(self
->db
, gbytes
, bytes
, ncache
);
2222 MYDB_END_ALLOW_THREADS
;
2229 DB_set_flags(DBObject
* self
, PyObject
* args
)
2233 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
2235 CHECK_DB_NOT_CLOSED(self
);
2237 MYDB_BEGIN_ALLOW_THREADS
;
2238 err
= self
->db
->set_flags(self
->db
, flags
);
2239 MYDB_END_ALLOW_THREADS
;
2242 self
->setflags
|= flags
;
2248 DB_set_h_ffactor(DBObject
* self
, PyObject
* args
)
2252 if (!PyArg_ParseTuple(args
,"i:set_h_ffactor", &ffactor
))
2254 CHECK_DB_NOT_CLOSED(self
);
2256 MYDB_BEGIN_ALLOW_THREADS
;
2257 err
= self
->db
->set_h_ffactor(self
->db
, ffactor
);
2258 MYDB_END_ALLOW_THREADS
;
2265 DB_set_h_nelem(DBObject
* self
, PyObject
* args
)
2269 if (!PyArg_ParseTuple(args
,"i:set_h_nelem", &nelem
))
2271 CHECK_DB_NOT_CLOSED(self
);
2273 MYDB_BEGIN_ALLOW_THREADS
;
2274 err
= self
->db
->set_h_nelem(self
->db
, nelem
);
2275 MYDB_END_ALLOW_THREADS
;
2282 DB_set_lorder(DBObject
* self
, PyObject
* args
)
2286 if (!PyArg_ParseTuple(args
,"i:set_lorder", &lorder
))
2288 CHECK_DB_NOT_CLOSED(self
);
2290 MYDB_BEGIN_ALLOW_THREADS
;
2291 err
= self
->db
->set_lorder(self
->db
, lorder
);
2292 MYDB_END_ALLOW_THREADS
;
2299 DB_set_pagesize(DBObject
* self
, PyObject
* args
)
2303 if (!PyArg_ParseTuple(args
,"i:set_pagesize", &pagesize
))
2305 CHECK_DB_NOT_CLOSED(self
);
2307 MYDB_BEGIN_ALLOW_THREADS
;
2308 err
= self
->db
->set_pagesize(self
->db
, pagesize
);
2309 MYDB_END_ALLOW_THREADS
;
2316 DB_set_re_delim(DBObject
* self
, PyObject
* args
)
2321 if (!PyArg_ParseTuple(args
,"b:set_re_delim", &delim
)) {
2323 if (!PyArg_ParseTuple(args
,"c:set_re_delim", &delim
))
2327 CHECK_DB_NOT_CLOSED(self
);
2329 MYDB_BEGIN_ALLOW_THREADS
;
2330 err
= self
->db
->set_re_delim(self
->db
, delim
);
2331 MYDB_END_ALLOW_THREADS
;
2337 DB_set_re_len(DBObject
* self
, PyObject
* args
)
2341 if (!PyArg_ParseTuple(args
,"i:set_re_len", &len
))
2343 CHECK_DB_NOT_CLOSED(self
);
2345 MYDB_BEGIN_ALLOW_THREADS
;
2346 err
= self
->db
->set_re_len(self
->db
, len
);
2347 MYDB_END_ALLOW_THREADS
;
2354 DB_set_re_pad(DBObject
* self
, PyObject
* args
)
2359 if (!PyArg_ParseTuple(args
,"b:set_re_pad", &pad
)) {
2361 if (!PyArg_ParseTuple(args
,"c:set_re_pad", &pad
))
2364 CHECK_DB_NOT_CLOSED(self
);
2366 MYDB_BEGIN_ALLOW_THREADS
;
2367 err
= self
->db
->set_re_pad(self
->db
, pad
);
2368 MYDB_END_ALLOW_THREADS
;
2375 DB_set_re_source(DBObject
* self
, PyObject
* args
)
2380 if (!PyArg_ParseTuple(args
,"s:set_re_source", &re_source
))
2382 CHECK_DB_NOT_CLOSED(self
);
2384 MYDB_BEGIN_ALLOW_THREADS
;
2385 err
= self
->db
->set_re_source(self
->db
, re_source
);
2386 MYDB_END_ALLOW_THREADS
;
2394 DB_set_q_extentsize(DBObject
* self
, PyObject
* args
)
2399 if (!PyArg_ParseTuple(args
,"i:set_q_extentsize", &extentsize
))
2401 CHECK_DB_NOT_CLOSED(self
);
2403 MYDB_BEGIN_ALLOW_THREADS
;
2404 err
= self
->db
->set_q_extentsize(self
->db
, extentsize
);
2405 MYDB_END_ALLOW_THREADS
;
2412 DB_stat(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2414 int err
, flags
= 0, type
;
2418 PyObject
* txnobj
= NULL
;
2420 static char* kwnames
[] = { "txn", "flags", NULL
};
2422 static char* kwnames
[] = { "flags", NULL
};
2426 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iO:stat", kwnames
,
2429 if (!checkTxnObj(txnobj
, &txn
))
2432 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat", kwnames
, &flags
))
2435 CHECK_DB_NOT_CLOSED(self
);
2437 MYDB_BEGIN_ALLOW_THREADS
;
2439 err
= self
->db
->stat(self
->db
, txn
, &sp
, flags
);
2441 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2443 err
= self
->db
->stat(self
->db
, &sp
, NULL
, flags
);
2445 MYDB_END_ALLOW_THREADS
;
2450 /* Turn the stat structure into a dictionary */
2451 type
= _DB_get_type(self
);
2452 if ((type
== -1) || ((d
= PyDict_New()) == NULL
)) {
2457 #define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
2458 #define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
2459 #define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
2463 MAKE_HASH_ENTRY(magic
);
2464 MAKE_HASH_ENTRY(version
);
2465 MAKE_HASH_ENTRY(nkeys
);
2466 MAKE_HASH_ENTRY(ndata
);
2467 MAKE_HASH_ENTRY(pagesize
);
2469 MAKE_HASH_ENTRY(nelem
);
2471 MAKE_HASH_ENTRY(ffactor
);
2472 MAKE_HASH_ENTRY(buckets
);
2473 MAKE_HASH_ENTRY(free
);
2474 MAKE_HASH_ENTRY(bfree
);
2475 MAKE_HASH_ENTRY(bigpages
);
2476 MAKE_HASH_ENTRY(big_bfree
);
2477 MAKE_HASH_ENTRY(overflows
);
2478 MAKE_HASH_ENTRY(ovfl_free
);
2479 MAKE_HASH_ENTRY(dup
);
2480 MAKE_HASH_ENTRY(dup_free
);
2485 MAKE_BT_ENTRY(magic
);
2486 MAKE_BT_ENTRY(version
);
2487 MAKE_BT_ENTRY(nkeys
);
2488 MAKE_BT_ENTRY(ndata
);
2489 MAKE_BT_ENTRY(pagesize
);
2490 MAKE_BT_ENTRY(minkey
);
2491 MAKE_BT_ENTRY(re_len
);
2492 MAKE_BT_ENTRY(re_pad
);
2493 MAKE_BT_ENTRY(levels
);
2494 MAKE_BT_ENTRY(int_pg
);
2495 MAKE_BT_ENTRY(leaf_pg
);
2496 MAKE_BT_ENTRY(dup_pg
);
2497 MAKE_BT_ENTRY(over_pg
);
2498 MAKE_BT_ENTRY(free
);
2499 MAKE_BT_ENTRY(int_pgfree
);
2500 MAKE_BT_ENTRY(leaf_pgfree
);
2501 MAKE_BT_ENTRY(dup_pgfree
);
2502 MAKE_BT_ENTRY(over_pgfree
);
2506 MAKE_QUEUE_ENTRY(magic
);
2507 MAKE_QUEUE_ENTRY(version
);
2508 MAKE_QUEUE_ENTRY(nkeys
);
2509 MAKE_QUEUE_ENTRY(ndata
);
2510 MAKE_QUEUE_ENTRY(pagesize
);
2511 MAKE_QUEUE_ENTRY(pages
);
2512 MAKE_QUEUE_ENTRY(re_len
);
2513 MAKE_QUEUE_ENTRY(re_pad
);
2514 MAKE_QUEUE_ENTRY(pgfree
);
2516 MAKE_QUEUE_ENTRY(start
);
2518 MAKE_QUEUE_ENTRY(first_recno
);
2519 MAKE_QUEUE_ENTRY(cur_recno
);
2523 PyErr_SetString(PyExc_TypeError
, "Unknown DB type, unable to stat");
2528 #undef MAKE_HASH_ENTRY
2529 #undef MAKE_BT_ENTRY
2530 #undef MAKE_QUEUE_ENTRY
2537 DB_sync(DBObject
* self
, PyObject
* args
)
2542 if (!PyArg_ParseTuple(args
,"|i:sync", &flags
))
2544 CHECK_DB_NOT_CLOSED(self
);
2546 MYDB_BEGIN_ALLOW_THREADS
;
2547 err
= self
->db
->sync(self
->db
, flags
);
2548 MYDB_END_ALLOW_THREADS
;
2556 DB_truncate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2560 PyObject
* txnobj
= NULL
;
2562 static char* kwnames
[] = { "txn", "flags", NULL
};
2564 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
2567 CHECK_DB_NOT_CLOSED(self
);
2568 if (!checkTxnObj(txnobj
, &txn
))
2571 MYDB_BEGIN_ALLOW_THREADS
;
2572 err
= self
->db
->truncate(self
->db
, txn
, &count
, flags
);
2573 MYDB_END_ALLOW_THREADS
;
2575 return PyInt_FromLong(count
);
2581 DB_upgrade(DBObject
* self
, PyObject
* args
)
2586 if (!PyArg_ParseTuple(args
,"s|i:upgrade", &filename
, &flags
))
2588 CHECK_DB_NOT_CLOSED(self
);
2590 MYDB_BEGIN_ALLOW_THREADS
;
2591 err
= self
->db
->upgrade(self
->db
, filename
, flags
);
2592 MYDB_END_ALLOW_THREADS
;
2599 DB_verify(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2604 char* outFileName
=NULL
;
2606 static char* kwnames
[] = { "filename", "dbname", "outfile", "flags",
2609 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zzi:verify", kwnames
,
2610 &fileName
, &dbName
, &outFileName
, &flags
))
2613 CHECK_DB_NOT_CLOSED(self
);
2615 outFile
= fopen(outFileName
, "w");
2617 MYDB_BEGIN_ALLOW_THREADS
;
2618 err
= self
->db
->verify(self
->db
, fileName
, dbName
, outFile
, flags
);
2619 MYDB_END_ALLOW_THREADS
;
2623 /* DB.verify acts as a DB handle destructor (like close); this was
2624 * documented in BerkeleyDB 4.2 but had the undocumented effect
2625 * of not being safe in prior versions while still requiring an explicit
2626 * DB.close call afterwards. Lets call close for the user to emulate
2627 * the safe 4.2 behaviour. */
2629 self
->db
->close(self
->db
, 0);
2639 DB_set_get_returns_none(DBObject
* self
, PyObject
* args
)
2644 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
2646 CHECK_DB_NOT_CLOSED(self
);
2648 if (self
->moduleFlags
.getReturnsNone
)
2650 if (self
->moduleFlags
.cursorSetReturnsNone
)
2652 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
2653 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
2654 return PyInt_FromLong(oldValue
);
2659 DB_set_encrypt(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2663 char *passwd
= NULL
;
2664 static char* kwnames
[] = { "passwd", "flags", NULL
};
2666 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
2671 MYDB_BEGIN_ALLOW_THREADS
;
2672 err
= self
->db
->set_encrypt(self
->db
, passwd
, flags
);
2673 MYDB_END_ALLOW_THREADS
;
2678 #endif /* DBVER >= 41 */
2681 /*-------------------------------------------------------------- */
2682 /* Mapping and Dictionary-like access routines */
2684 Py_ssize_t
DB_length(DBObject
* self
)
2687 Py_ssize_t size
= 0;
2691 if (self
->db
== NULL
) {
2692 PyObject
*t
= Py_BuildValue("(is)", 0, "DB object has been closed");
2693 PyErr_SetObject(DBError
, t
);
2698 if (self
->haveStat
) { /* Has the stat function been called recently? If
2699 so, we can use the cached value. */
2700 flags
= DB_FAST_STAT
;
2703 MYDB_BEGIN_ALLOW_THREADS
;
2704 redo_stat_for_length
:
2706 err
= self
->db
->stat(self
->db
, /*txnid*/ NULL
, &sp
, flags
);
2708 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2710 err
= self
->db
->stat(self
->db
, &sp
, NULL
, flags
);
2713 /* All the stat structures have matching fields upto the ndata field,
2714 so we can use any of them for the type cast */
2715 size
= ((DB_BTREE_STAT
*)sp
)->bt_ndata
;
2717 /* A size of 0 could mean that BerkeleyDB no longer had the stat values cached.
2718 * redo a full stat to make sure.
2719 * Fixes SF python bug 1493322, pybsddb bug 1184012
2721 if (size
== 0 && (flags
& DB_FAST_STAT
)) {
2723 goto redo_stat_for_length
;
2726 MYDB_END_ALLOW_THREADS
;
2738 PyObject
* DB_subscript(DBObject
* self
, PyObject
* keyobj
)
2745 CHECK_DB_NOT_CLOSED(self
);
2746 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2750 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2751 /* Tell BerkeleyDB to malloc the return value (thread safe) */
2752 data
.flags
= DB_DBT_MALLOC
;
2754 MYDB_BEGIN_ALLOW_THREADS
;
2755 err
= self
->db
->get(self
->db
, NULL
, &key
, &data
, 0);
2756 MYDB_END_ALLOW_THREADS
;
2757 if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
2758 PyErr_SetObject(PyExc_KeyError
, keyobj
);
2761 else if (makeDBError(err
)) {
2765 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
2775 DB_ass_sub(DBObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
)
2781 if (self
->db
== NULL
) {
2782 PyObject
*t
= Py_BuildValue("(is)", 0, "DB object has been closed");
2783 PyErr_SetObject(DBError
, t
);
2788 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2791 if (dataobj
!= NULL
) {
2792 if (!make_dbt(dataobj
, &data
))
2795 if (self
->setflags
& (DB_DUP
|DB_DUPSORT
))
2796 /* dictionaries shouldn't have duplicate keys */
2797 flags
= DB_NOOVERWRITE
;
2798 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2800 if ((retval
== -1) && (self
->setflags
& (DB_DUP
|DB_DUPSORT
))) {
2801 /* try deleting any old record that matches and then PUT it
2803 _DB_delete(self
, NULL
, &key
, 0);
2805 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2810 /* dataobj == NULL, so delete the key */
2811 retval
= _DB_delete(self
, NULL
, &key
, 0);
2819 DB_has_key(DBObject
* self
, PyObject
* args
)
2824 PyObject
* txnobj
= NULL
;
2827 if (!PyArg_ParseTuple(args
,"O|O:has_key", &keyobj
, &txnobj
))
2829 CHECK_DB_NOT_CLOSED(self
);
2830 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2832 if (!checkTxnObj(txnobj
, &txn
)) {
2837 /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
2838 it has a record but can't allocate a buffer for the data. This saves
2839 having to deal with data we won't be using.
2842 data
.flags
= DB_DBT_USERMEM
;
2844 MYDB_BEGIN_ALLOW_THREADS
;
2845 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, 0);
2846 MYDB_END_ALLOW_THREADS
;
2849 if (err
== DB_BUFFER_SMALL
|| err
== 0) {
2850 return PyInt_FromLong(1);
2851 } else if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
2852 return PyInt_FromLong(0);
2860 #define _KEYS_LIST 1
2861 #define _VALUES_LIST 2
2862 #define _ITEMS_LIST 3
2865 _DB_make_list(DBObject
* self
, DB_TXN
* txn
, int type
)
2872 PyObject
* item
= NULL
;
2874 CHECK_DB_NOT_CLOSED(self
);
2878 dbtype
= _DB_get_type(self
);
2882 list
= PyList_New(0);
2887 MYDB_BEGIN_ALLOW_THREADS
;
2888 err
= self
->db
->cursor(self
->db
, txn
, &cursor
, 0);
2889 MYDB_END_ALLOW_THREADS
;
2890 if (makeDBError(err
)) {
2895 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2896 key
.flags
= DB_DBT_REALLOC
;
2897 data
.flags
= DB_DBT_REALLOC
;
2900 while (1) { /* use the cursor to traverse the DB, collecting items */
2901 MYDB_BEGIN_ALLOW_THREADS
;
2902 err
= cursor
->c_get(cursor
, &key
, &data
, DB_NEXT
);
2903 MYDB_END_ALLOW_THREADS
;
2906 /* for any error, break out of the loop */
2916 item
= PyString_FromStringAndSize((char*)key
.data
, key
.size
);
2920 item
= PyInt_FromLong(*((db_recno_t
*)key
.data
));
2926 item
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
2934 item
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
2939 item
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
2940 data
.data
, data
.size
);
2945 PyErr_Format(PyExc_ValueError
, "Unknown key type 0x%x", type
);
2954 PyList_Append(list
, item
);
2958 /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
2959 if (err
!= DB_NOTFOUND
&& err
!= DB_KEYEMPTY
&& makeDBError(err
)) {
2967 MYDB_BEGIN_ALLOW_THREADS
;
2968 cursor
->c_close(cursor
);
2969 MYDB_END_ALLOW_THREADS
;
2975 DB_keys(DBObject
* self
, PyObject
* args
)
2977 PyObject
* txnobj
= NULL
;
2980 if (!PyArg_UnpackTuple(args
, "keys", 0, 1, &txnobj
))
2982 if (!checkTxnObj(txnobj
, &txn
))
2984 return _DB_make_list(self
, txn
, _KEYS_LIST
);
2989 DB_items(DBObject
* self
, PyObject
* args
)
2991 PyObject
* txnobj
= NULL
;
2994 if (!PyArg_UnpackTuple(args
, "items", 0, 1, &txnobj
))
2996 if (!checkTxnObj(txnobj
, &txn
))
2998 return _DB_make_list(self
, txn
, _ITEMS_LIST
);
3003 DB_values(DBObject
* self
, PyObject
* args
)
3005 PyObject
* txnobj
= NULL
;
3008 if (!PyArg_UnpackTuple(args
, "values", 0, 1, &txnobj
))
3010 if (!checkTxnObj(txnobj
, &txn
))
3012 return _DB_make_list(self
, txn
, _VALUES_LIST
);
3015 /* --------------------------------------------------------------------- */
3016 /* DBCursor methods */
3020 DBC_close(DBCursorObject
* self
, PyObject
* args
)
3024 if (!PyArg_ParseTuple(args
, ":close"))
3027 if (self
->dbc
!= NULL
) {
3028 MYDB_BEGIN_ALLOW_THREADS
;
3029 err
= self
->dbc
->c_close(self
->dbc
);
3031 MYDB_END_ALLOW_THREADS
;
3039 DBC_count(DBCursorObject
* self
, PyObject
* args
)
3045 if (!PyArg_ParseTuple(args
, "|i:count", &flags
))
3048 CHECK_CURSOR_NOT_CLOSED(self
);
3050 MYDB_BEGIN_ALLOW_THREADS
;
3051 err
= self
->dbc
->c_count(self
->dbc
, &count
, flags
);
3052 MYDB_END_ALLOW_THREADS
;
3055 return PyInt_FromLong(count
);
3060 DBC_current(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3062 return _DBCursor_get(self
,DB_CURRENT
,args
,kwargs
,"|iii:current");
3067 DBC_delete(DBCursorObject
* self
, PyObject
* args
)
3071 if (!PyArg_ParseTuple(args
, "|i:delete", &flags
))
3074 CHECK_CURSOR_NOT_CLOSED(self
);
3076 MYDB_BEGIN_ALLOW_THREADS
;
3077 err
= self
->dbc
->c_del(self
->dbc
, flags
);
3078 MYDB_END_ALLOW_THREADS
;
3081 self
->mydb
->haveStat
= 0;
3087 DBC_dup(DBCursorObject
* self
, PyObject
* args
)
3092 if (!PyArg_ParseTuple(args
, "|i:dup", &flags
))
3095 CHECK_CURSOR_NOT_CLOSED(self
);
3097 MYDB_BEGIN_ALLOW_THREADS
;
3098 err
= self
->dbc
->c_dup(self
->dbc
, &dbc
, flags
);
3099 MYDB_END_ALLOW_THREADS
;
3102 return (PyObject
*) newDBCursorObject(dbc
, self
->mydb
);
3106 DBC_first(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3108 return _DBCursor_get(self
,DB_FIRST
,args
,kwargs
,"|iii:first");
3113 DBC_get(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3116 PyObject
* keyobj
= NULL
;
3117 PyObject
* dataobj
= NULL
;
3118 PyObject
* retval
= NULL
;
3122 static char* kwnames
[] = { "key","data", "flags", "dlen", "doff",
3127 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:get", &kwnames
[2],
3128 &flags
, &dlen
, &doff
))
3131 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:get",
3133 &keyobj
, &flags
, &dlen
, &doff
))
3136 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:get",
3137 kwnames
, &keyobj
, &dataobj
,
3138 &flags
, &dlen
, &doff
))
3145 CHECK_CURSOR_NOT_CLOSED(self
);
3147 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3149 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
3150 (!add_partial_dbt(&data
, dlen
, doff
)) )
3156 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3157 data
.flags
= DB_DBT_MALLOC
;
3158 if (!(key
.flags
& DB_DBT_REALLOC
)) {
3159 key
.flags
|= DB_DBT_MALLOC
;
3163 MYDB_BEGIN_ALLOW_THREADS
;
3164 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
3165 MYDB_END_ALLOW_THREADS
;
3167 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3168 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3172 else if (makeDBError(err
)) {
3176 switch (_DB_get_type(self
->mydb
)) {
3183 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3184 data
.data
, data
.size
);
3188 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3189 data
.data
, data
.size
);
3200 DBC_pget(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3203 PyObject
* keyobj
= NULL
;
3204 PyObject
* dataobj
= NULL
;
3205 PyObject
* retval
= NULL
;
3208 DBT key
, pkey
, data
;
3209 static char* kwnames_keyOnly
[] = { "key", "flags", "dlen", "doff", NULL
};
3210 static char* kwnames
[] = { "key", "data", "flags", "dlen", "doff", NULL
};
3214 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:pget", &kwnames
[2],
3215 &flags
, &dlen
, &doff
))
3218 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:pget",
3220 &keyobj
, &flags
, &dlen
, &doff
))
3223 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:pget",
3224 kwnames
, &keyobj
, &dataobj
,
3225 &flags
, &dlen
, &doff
))
3232 CHECK_CURSOR_NOT_CLOSED(self
);
3234 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3236 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
3237 (!add_partial_dbt(&data
, dlen
, doff
)) ) {
3242 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3243 data
.flags
= DB_DBT_MALLOC
;
3244 if (!(key
.flags
& DB_DBT_REALLOC
)) {
3245 key
.flags
|= DB_DBT_MALLOC
;
3250 pkey
.flags
= DB_DBT_MALLOC
;
3252 MYDB_BEGIN_ALLOW_THREADS
;
3253 err
= self
->dbc
->c_pget(self
->dbc
, &key
, &pkey
, &data
, flags
);
3254 MYDB_END_ALLOW_THREADS
;
3256 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3257 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3261 else if (makeDBError(err
)) {
3267 dataObj
= PyString_FromStringAndSize(data
.data
, data
.size
);
3269 if (self
->mydb
->primaryDBType
== DB_RECNO
||
3270 self
->mydb
->primaryDBType
== DB_QUEUE
)
3271 pkeyObj
= PyInt_FromLong(*(int *)pkey
.data
);
3273 pkeyObj
= PyString_FromStringAndSize(pkey
.data
, pkey
.size
);
3275 if (key
.data
&& key
.size
) /* return key, pkey and data */
3278 int type
= _DB_get_type(self
->mydb
);
3279 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
3280 keyObj
= PyInt_FromLong(*(int *)key
.data
);
3282 keyObj
= PyString_FromStringAndSize(key
.data
, key
.size
);
3283 #if (PY_VERSION_HEX >= 0x02040000)
3284 retval
= PyTuple_Pack(3, keyObj
, pkeyObj
, dataObj
);
3286 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
3291 else /* return just the pkey and data */
3293 #if (PY_VERSION_HEX >= 0x02040000)
3294 retval
= PyTuple_Pack(2, pkeyObj
, dataObj
);
3296 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
3304 /* the only time REALLOC should be set is if we used an integer
3305 * key that make_key_dbt malloc'd for us. always free these. */
3306 if (key
.flags
& DB_DBT_REALLOC
) {
3315 DBC_get_recno(DBCursorObject
* self
, PyObject
* args
)
3322 if (!PyArg_ParseTuple(args
, ":get_recno"))
3325 CHECK_CURSOR_NOT_CLOSED(self
);
3329 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3330 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3331 data
.flags
= DB_DBT_MALLOC
;
3332 key
.flags
= DB_DBT_MALLOC
;
3335 MYDB_BEGIN_ALLOW_THREADS
;
3336 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, DB_GET_RECNO
);
3337 MYDB_END_ALLOW_THREADS
;
3340 recno
= *((db_recno_t
*)data
.data
);
3343 return PyInt_FromLong(recno
);
3348 DBC_last(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3350 return _DBCursor_get(self
,DB_LAST
,args
,kwargs
,"|iii:last");
3355 DBC_next(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3357 return _DBCursor_get(self
,DB_NEXT
,args
,kwargs
,"|iii:next");
3362 DBC_prev(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3364 return _DBCursor_get(self
,DB_PREV
,args
,kwargs
,"|iii:prev");
3369 DBC_put(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3372 PyObject
* keyobj
, *dataobj
;
3374 static char* kwnames
[] = { "key", "data", "flags", "dlen", "doff",
3379 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iii:put", kwnames
,
3380 &keyobj
, &dataobj
, &flags
, &dlen
, &doff
))
3383 CHECK_CURSOR_NOT_CLOSED(self
);
3385 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3387 if (!make_dbt(dataobj
, &data
) ||
3388 !add_partial_dbt(&data
, dlen
, doff
) )
3394 MYDB_BEGIN_ALLOW_THREADS
;
3395 err
= self
->dbc
->c_put(self
->dbc
, &key
, &data
, flags
);
3396 MYDB_END_ALLOW_THREADS
;
3399 self
->mydb
->haveStat
= 0;
3405 DBC_set(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3409 PyObject
* retval
, *keyobj
;
3410 static char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
3414 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set", kwnames
,
3415 &keyobj
, &flags
, &dlen
, &doff
))
3418 CHECK_CURSOR_NOT_CLOSED(self
);
3420 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3424 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3425 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3426 data
.flags
= DB_DBT_MALLOC
;
3428 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3433 MYDB_BEGIN_ALLOW_THREADS
;
3434 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET
);
3435 MYDB_END_ALLOW_THREADS
;
3436 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3437 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3441 else if (makeDBError(err
)) {
3445 switch (_DB_get_type(self
->mydb
)) {
3452 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3453 data
.data
, data
.size
);
3457 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3458 data
.data
, data
.size
);
3464 /* the only time REALLOC should be set is if we used an integer
3465 * key that make_key_dbt malloc'd for us. always free these. */
3466 if (key
.flags
& DB_DBT_REALLOC
) {
3475 DBC_set_range(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3479 PyObject
* retval
, *keyobj
;
3480 static char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
3484 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set_range", kwnames
,
3485 &keyobj
, &flags
, &dlen
, &doff
))
3488 CHECK_CURSOR_NOT_CLOSED(self
);
3490 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3494 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3498 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3499 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3500 data
.flags
|= DB_DBT_MALLOC
;
3501 /* only BTREE databases will return anything in the key */
3502 if (!(key
.flags
& DB_DBT_REALLOC
) && _DB_get_type(self
->mydb
) == DB_BTREE
) {
3503 key
.flags
|= DB_DBT_MALLOC
;
3506 MYDB_BEGIN_ALLOW_THREADS
;
3507 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RANGE
);
3508 MYDB_END_ALLOW_THREADS
;
3509 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3510 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3514 else if (makeDBError(err
)) {
3518 switch (_DB_get_type(self
->mydb
)) {
3525 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3526 data
.data
, data
.size
);
3530 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3531 data
.data
, data
.size
);
3537 /* the only time REALLOC should be set is if we used an integer
3538 * key that make_key_dbt malloc'd for us. always free these. */
3539 if (key
.flags
& DB_DBT_REALLOC
) {
3547 _DBC_get_set_both(DBCursorObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
,
3548 int flags
, unsigned int returnsNone
)
3554 /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
3555 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3557 if (!make_dbt(dataobj
, &data
)) {
3562 MYDB_BEGIN_ALLOW_THREADS
;
3563 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_GET_BOTH
);
3564 MYDB_END_ALLOW_THREADS
;
3565 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && returnsNone
) {
3569 else if (makeDBError(err
)) {
3573 switch (_DB_get_type(self
->mydb
)) {
3580 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3581 data
.data
, data
.size
);
3585 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3586 data
.data
, data
.size
);
3596 DBC_get_both(DBCursorObject
* self
, PyObject
* args
)
3599 PyObject
*keyobj
, *dataobj
;
3601 if (!PyArg_ParseTuple(args
, "OO|i:get_both", &keyobj
, &dataobj
, &flags
))
3604 /* if the cursor is closed, self->mydb may be invalid */
3605 CHECK_CURSOR_NOT_CLOSED(self
);
3607 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3608 self
->mydb
->moduleFlags
.getReturnsNone
);
3611 /* Return size of entry */
3613 DBC_get_current_size(DBCursorObject
* self
, PyObject
* args
)
3615 int err
, flags
=DB_CURRENT
;
3616 PyObject
* retval
= NULL
;
3619 if (!PyArg_ParseTuple(args
, ":get_current_size"))
3621 CHECK_CURSOR_NOT_CLOSED(self
);
3625 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
3626 getting the record size. */
3627 data
.flags
= DB_DBT_USERMEM
;
3629 MYDB_BEGIN_ALLOW_THREADS
;
3630 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
3631 MYDB_END_ALLOW_THREADS
;
3632 if (err
== DB_BUFFER_SMALL
|| !err
) {
3633 /* DB_BUFFER_SMALL means positive size, !err means zero length value */
3634 retval
= PyInt_FromLong((long)data
.size
);
3645 DBC_set_both(DBCursorObject
* self
, PyObject
* args
)
3648 PyObject
*keyobj
, *dataobj
;
3650 if (!PyArg_ParseTuple(args
, "OO|i:set_both", &keyobj
, &dataobj
, &flags
))
3653 /* if the cursor is closed, self->mydb may be invalid */
3654 CHECK_CURSOR_NOT_CLOSED(self
);
3656 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3657 self
->mydb
->moduleFlags
.cursorSetReturnsNone
);
3662 DBC_set_recno(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3664 int err
, irecno
, flags
=0;
3670 static char* kwnames
[] = { "recno","flags", "dlen", "doff", NULL
};
3672 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|iii:set_recno", kwnames
,
3673 &irecno
, &flags
, &dlen
, &doff
))
3676 CHECK_CURSOR_NOT_CLOSED(self
);
3679 recno
= (db_recno_t
) irecno
;
3680 /* use allocated space so DB will be able to realloc room for the real
3682 key
.data
= malloc(sizeof(db_recno_t
));
3683 if (key
.data
== NULL
) {
3684 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
3687 key
.size
= sizeof(db_recno_t
);
3688 key
.ulen
= key
.size
;
3689 memcpy(key
.data
, &recno
, sizeof(db_recno_t
));
3690 key
.flags
= DB_DBT_REALLOC
;
3693 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3694 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3695 data
.flags
= DB_DBT_MALLOC
;
3697 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3702 MYDB_BEGIN_ALLOW_THREADS
;
3703 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RECNO
);
3704 MYDB_END_ALLOW_THREADS
;
3705 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3706 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3710 else if (makeDBError(err
)) {
3713 else { /* Can only be used for BTrees, so no need to return int key */
3714 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3715 data
.data
, data
.size
);
3725 DBC_consume(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3727 return _DBCursor_get(self
,DB_CONSUME
,args
,kwargs
,"|iii:consume");
3732 DBC_next_dup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3734 return _DBCursor_get(self
,DB_NEXT_DUP
,args
,kwargs
,"|iii:next_dup");
3739 DBC_next_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3741 return _DBCursor_get(self
,DB_NEXT_NODUP
,args
,kwargs
,"|iii:next_nodup");
3746 DBC_prev_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3748 return _DBCursor_get(self
,DB_PREV_NODUP
,args
,kwargs
,"|iii:prev_nodup");
3753 DBC_join_item(DBCursorObject
* self
, PyObject
* args
)
3759 if (!PyArg_ParseTuple(args
, "|i:join_item", &flags
))
3762 CHECK_CURSOR_NOT_CLOSED(self
);
3766 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3767 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3768 key
.flags
= DB_DBT_MALLOC
;
3771 MYDB_BEGIN_ALLOW_THREADS
;
3772 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
| DB_JOIN_ITEM
);
3773 MYDB_END_ALLOW_THREADS
;
3774 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3775 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3779 else if (makeDBError(err
)) {
3783 retval
= Py_BuildValue("s#", key
.data
, key
.size
);
3792 /* --------------------------------------------------------------------- */
3797 DBEnv_close(DBEnvObject
* self
, PyObject
* args
)
3801 if (!PyArg_ParseTuple(args
, "|i:close", &flags
))
3803 if (!self
->closed
) { /* Don't close more than once */
3804 MYDB_BEGIN_ALLOW_THREADS
;
3805 err
= self
->db_env
->close(self
->db_env
, flags
);
3806 MYDB_END_ALLOW_THREADS
;
3807 /* after calling DBEnv->close, regardless of error, this DBEnv
3808 * may not be accessed again (BerkeleyDB docs). */
3810 self
->db_env
= NULL
;
3818 DBEnv_open(DBEnvObject
* self
, PyObject
* args
)
3820 int err
, flags
=0, mode
=0660;
3823 if (!PyArg_ParseTuple(args
, "z|ii:open", &db_home
, &flags
, &mode
))
3826 CHECK_ENV_NOT_CLOSED(self
);
3828 MYDB_BEGIN_ALLOW_THREADS
;
3829 err
= self
->db_env
->open(self
->db_env
, db_home
, flags
, mode
);
3830 MYDB_END_ALLOW_THREADS
;
3833 self
->flags
= flags
;
3839 DBEnv_remove(DBEnvObject
* self
, PyObject
* args
)
3844 if (!PyArg_ParseTuple(args
, "s|i:remove", &db_home
, &flags
))
3846 CHECK_ENV_NOT_CLOSED(self
);
3847 MYDB_BEGIN_ALLOW_THREADS
;
3848 err
= self
->db_env
->remove(self
->db_env
, db_home
, flags
);
3849 MYDB_END_ALLOW_THREADS
;
3856 DBEnv_dbremove(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3861 char *database
= NULL
;
3862 PyObject
*txnobj
= NULL
;
3864 static char* kwnames
[] = { "file", "database", "txn", "flags",
3867 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ss|Oi:dbremove", kwnames
,
3868 &file
, &database
, &txnobj
, &flags
)) {
3871 if (!checkTxnObj(txnobj
, &txn
)) {
3874 CHECK_ENV_NOT_CLOSED(self
);
3875 MYDB_BEGIN_ALLOW_THREADS
;
3876 err
= self
->db_env
->dbremove(self
->db_env
, txn
, file
, database
, flags
);
3877 MYDB_END_ALLOW_THREADS
;
3883 DBEnv_dbrename(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3888 char *database
= NULL
;
3889 char *newname
= NULL
;
3890 PyObject
*txnobj
= NULL
;
3892 static char* kwnames
[] = { "file", "database", "newname", "txn",
3895 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "sss|Oi:dbrename", kwnames
,
3896 &file
, &database
, &newname
, &txnobj
, &flags
)) {
3899 if (!checkTxnObj(txnobj
, &txn
)) {
3902 CHECK_ENV_NOT_CLOSED(self
);
3903 MYDB_BEGIN_ALLOW_THREADS
;
3904 err
= self
->db_env
->dbrename(self
->db_env
, txn
, file
, database
, newname
,
3906 MYDB_END_ALLOW_THREADS
;
3912 DBEnv_set_encrypt(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3916 char *passwd
= NULL
;
3917 static char* kwnames
[] = { "passwd", "flags", NULL
};
3919 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
3924 MYDB_BEGIN_ALLOW_THREADS
;
3925 err
= self
->db_env
->set_encrypt(self
->db_env
, passwd
, flags
);
3926 MYDB_END_ALLOW_THREADS
;
3931 #endif /* DBVER >= 41 */
3935 DBEnv_set_timeout(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3939 u_int32_t timeout
= 0;
3940 static char* kwnames
[] = { "timeout", "flags", NULL
};
3942 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ii:set_timeout", kwnames
,
3943 &timeout
, &flags
)) {
3947 MYDB_BEGIN_ALLOW_THREADS
;
3948 err
= self
->db_env
->set_timeout(self
->db_env
, (db_timeout_t
)timeout
, flags
);
3949 MYDB_END_ALLOW_THREADS
;
3954 #endif /* DBVER >= 40 */
3957 DBEnv_set_shm_key(DBEnvObject
* self
, PyObject
* args
)
3962 if (!PyArg_ParseTuple(args
, "l:set_shm_key", &shm_key
))
3964 CHECK_ENV_NOT_CLOSED(self
);
3966 err
= self
->db_env
->set_shm_key(self
->db_env
, shm_key
);
3972 DBEnv_set_cachesize(DBEnvObject
* self
, PyObject
* args
)
3974 int err
, gbytes
=0, bytes
=0, ncache
=0;
3976 if (!PyArg_ParseTuple(args
, "ii|i:set_cachesize",
3977 &gbytes
, &bytes
, &ncache
))
3979 CHECK_ENV_NOT_CLOSED(self
);
3981 MYDB_BEGIN_ALLOW_THREADS
;
3982 err
= self
->db_env
->set_cachesize(self
->db_env
, gbytes
, bytes
, ncache
);
3983 MYDB_END_ALLOW_THREADS
;
3991 DBEnv_set_flags(DBEnvObject
* self
, PyObject
* args
)
3993 int err
, flags
=0, onoff
=0;
3995 if (!PyArg_ParseTuple(args
, "ii:set_flags",
3998 CHECK_ENV_NOT_CLOSED(self
);
4000 MYDB_BEGIN_ALLOW_THREADS
;
4001 err
= self
->db_env
->set_flags(self
->db_env
, flags
, onoff
);
4002 MYDB_END_ALLOW_THREADS
;
4010 DBEnv_set_data_dir(DBEnvObject
* self
, PyObject
* args
)
4015 if (!PyArg_ParseTuple(args
, "s:set_data_dir", &dir
))
4017 CHECK_ENV_NOT_CLOSED(self
);
4019 MYDB_BEGIN_ALLOW_THREADS
;
4020 err
= self
->db_env
->set_data_dir(self
->db_env
, dir
);
4021 MYDB_END_ALLOW_THREADS
;
4028 DBEnv_set_lg_bsize(DBEnvObject
* self
, PyObject
* args
)
4032 if (!PyArg_ParseTuple(args
, "i:set_lg_bsize", &lg_bsize
))
4034 CHECK_ENV_NOT_CLOSED(self
);
4036 MYDB_BEGIN_ALLOW_THREADS
;
4037 err
= self
->db_env
->set_lg_bsize(self
->db_env
, lg_bsize
);
4038 MYDB_END_ALLOW_THREADS
;
4045 DBEnv_set_lg_dir(DBEnvObject
* self
, PyObject
* args
)
4050 if (!PyArg_ParseTuple(args
, "s:set_lg_dir", &dir
))
4052 CHECK_ENV_NOT_CLOSED(self
);
4054 MYDB_BEGIN_ALLOW_THREADS
;
4055 err
= self
->db_env
->set_lg_dir(self
->db_env
, dir
);
4056 MYDB_END_ALLOW_THREADS
;
4062 DBEnv_set_lg_max(DBEnvObject
* self
, PyObject
* args
)
4066 if (!PyArg_ParseTuple(args
, "i:set_lg_max", &lg_max
))
4068 CHECK_ENV_NOT_CLOSED(self
);
4070 MYDB_BEGIN_ALLOW_THREADS
;
4071 err
= self
->db_env
->set_lg_max(self
->db_env
, lg_max
);
4072 MYDB_END_ALLOW_THREADS
;
4080 DBEnv_set_lg_regionmax(DBEnvObject
* self
, PyObject
* args
)
4084 if (!PyArg_ParseTuple(args
, "i:set_lg_regionmax", &lg_max
))
4086 CHECK_ENV_NOT_CLOSED(self
);
4088 MYDB_BEGIN_ALLOW_THREADS
;
4089 err
= self
->db_env
->set_lg_regionmax(self
->db_env
, lg_max
);
4090 MYDB_END_ALLOW_THREADS
;
4098 DBEnv_set_lk_detect(DBEnvObject
* self
, PyObject
* args
)
4102 if (!PyArg_ParseTuple(args
, "i:set_lk_detect", &lk_detect
))
4104 CHECK_ENV_NOT_CLOSED(self
);
4106 MYDB_BEGIN_ALLOW_THREADS
;
4107 err
= self
->db_env
->set_lk_detect(self
->db_env
, lk_detect
);
4108 MYDB_END_ALLOW_THREADS
;
4115 DBEnv_set_lk_max(DBEnvObject
* self
, PyObject
* args
)
4119 if (!PyArg_ParseTuple(args
, "i:set_lk_max", &max
))
4121 CHECK_ENV_NOT_CLOSED(self
);
4123 MYDB_BEGIN_ALLOW_THREADS
;
4124 err
= self
->db_env
->set_lk_max(self
->db_env
, max
);
4125 MYDB_END_ALLOW_THREADS
;
4134 DBEnv_set_lk_max_locks(DBEnvObject
* self
, PyObject
* args
)
4138 if (!PyArg_ParseTuple(args
, "i:set_lk_max_locks", &max
))
4140 CHECK_ENV_NOT_CLOSED(self
);
4142 MYDB_BEGIN_ALLOW_THREADS
;
4143 err
= self
->db_env
->set_lk_max_locks(self
->db_env
, max
);
4144 MYDB_END_ALLOW_THREADS
;
4151 DBEnv_set_lk_max_lockers(DBEnvObject
* self
, PyObject
* args
)
4155 if (!PyArg_ParseTuple(args
, "i:set_lk_max_lockers", &max
))
4157 CHECK_ENV_NOT_CLOSED(self
);
4159 MYDB_BEGIN_ALLOW_THREADS
;
4160 err
= self
->db_env
->set_lk_max_lockers(self
->db_env
, max
);
4161 MYDB_END_ALLOW_THREADS
;
4168 DBEnv_set_lk_max_objects(DBEnvObject
* self
, PyObject
* args
)
4172 if (!PyArg_ParseTuple(args
, "i:set_lk_max_objects", &max
))
4174 CHECK_ENV_NOT_CLOSED(self
);
4176 MYDB_BEGIN_ALLOW_THREADS
;
4177 err
= self
->db_env
->set_lk_max_objects(self
->db_env
, max
);
4178 MYDB_END_ALLOW_THREADS
;
4187 DBEnv_set_mp_mmapsize(DBEnvObject
* self
, PyObject
* args
)
4189 int err
, mp_mmapsize
;
4191 if (!PyArg_ParseTuple(args
, "i:set_mp_mmapsize", &mp_mmapsize
))
4193 CHECK_ENV_NOT_CLOSED(self
);
4195 MYDB_BEGIN_ALLOW_THREADS
;
4196 err
= self
->db_env
->set_mp_mmapsize(self
->db_env
, mp_mmapsize
);
4197 MYDB_END_ALLOW_THREADS
;
4204 DBEnv_set_tmp_dir(DBEnvObject
* self
, PyObject
* args
)
4209 if (!PyArg_ParseTuple(args
, "s:set_tmp_dir", &dir
))
4211 CHECK_ENV_NOT_CLOSED(self
);
4213 MYDB_BEGIN_ALLOW_THREADS
;
4214 err
= self
->db_env
->set_tmp_dir(self
->db_env
, dir
);
4215 MYDB_END_ALLOW_THREADS
;
4222 DBEnv_txn_begin(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4225 PyObject
* txnobj
= NULL
;
4227 static char* kwnames
[] = { "parent", "flags", NULL
};
4229 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:txn_begin", kwnames
,
4233 if (!checkTxnObj(txnobj
, &txn
))
4235 CHECK_ENV_NOT_CLOSED(self
);
4237 return (PyObject
*)newDBTxnObject(self
, txn
, flags
);
4242 DBEnv_txn_checkpoint(DBEnvObject
* self
, PyObject
* args
)
4244 int err
, kbyte
=0, min
=0, flags
=0;
4246 if (!PyArg_ParseTuple(args
, "|iii:txn_checkpoint", &kbyte
, &min
, &flags
))
4248 CHECK_ENV_NOT_CLOSED(self
);
4250 MYDB_BEGIN_ALLOW_THREADS
;
4252 err
= self
->db_env
->txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
4254 err
= txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
4256 MYDB_END_ALLOW_THREADS
;
4263 DBEnv_set_tx_max(DBEnvObject
* self
, PyObject
* args
)
4267 if (!PyArg_ParseTuple(args
, "i:set_tx_max", &max
))
4269 CHECK_ENV_NOT_CLOSED(self
);
4271 err
= self
->db_env
->set_tx_max(self
->db_env
, max
);
4278 DBEnv_set_tx_timestamp(DBEnvObject
* self
, PyObject
* args
)
4284 if (!PyArg_ParseTuple(args
, "l:set_tx_timestamp", &stamp
))
4286 CHECK_ENV_NOT_CLOSED(self
);
4287 timestamp
= (time_t)stamp
;
4288 err
= self
->db_env
->set_tx_timestamp(self
->db_env
, ×tamp
);
4295 DBEnv_lock_detect(DBEnvObject
* self
, PyObject
* args
)
4297 int err
, atype
, flags
=0;
4300 if (!PyArg_ParseTuple(args
, "i|i:lock_detect", &atype
, &flags
))
4302 CHECK_ENV_NOT_CLOSED(self
);
4304 MYDB_BEGIN_ALLOW_THREADS
;
4306 err
= self
->db_env
->lock_detect(self
->db_env
, flags
, atype
, &aborted
);
4308 err
= lock_detect(self
->db_env
, flags
, atype
, &aborted
);
4310 MYDB_END_ALLOW_THREADS
;
4312 return PyInt_FromLong(aborted
);
4317 DBEnv_lock_get(DBEnvObject
* self
, PyObject
* args
)
4320 int locker
, lock_mode
;
4324 if (!PyArg_ParseTuple(args
, "iOi|i:lock_get", &locker
, &objobj
, &lock_mode
, &flags
))
4328 if (!make_dbt(objobj
, &obj
))
4331 return (PyObject
*)newDBLockObject(self
, locker
, &obj
, lock_mode
, flags
);
4336 DBEnv_lock_id(DBEnvObject
* self
, PyObject
* args
)
4341 if (!PyArg_ParseTuple(args
, ":lock_id"))
4344 CHECK_ENV_NOT_CLOSED(self
);
4345 MYDB_BEGIN_ALLOW_THREADS
;
4347 err
= self
->db_env
->lock_id(self
->db_env
, &theID
);
4349 err
= lock_id(self
->db_env
, &theID
);
4351 MYDB_END_ALLOW_THREADS
;
4354 return PyInt_FromLong((long)theID
);
4359 DBEnv_lock_put(DBEnvObject
* self
, PyObject
* args
)
4362 DBLockObject
* dblockobj
;
4364 if (!PyArg_ParseTuple(args
, "O!:lock_put", &DBLock_Type
, &dblockobj
))
4367 CHECK_ENV_NOT_CLOSED(self
);
4368 MYDB_BEGIN_ALLOW_THREADS
;
4370 err
= self
->db_env
->lock_put(self
->db_env
, &dblockobj
->lock
);
4372 err
= lock_put(self
->db_env
, &dblockobj
->lock
);
4374 MYDB_END_ALLOW_THREADS
;
4381 DBEnv_lsn_reset(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4385 u_int32_t flags
= 0;
4386 static char* kwnames
[] = { "file", "flags", NULL
};
4388 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|i:lsn_reset", kwnames
,
4391 CHECK_ENV_NOT_CLOSED(self
);
4393 MYDB_BEGIN_ALLOW_THREADS
;
4394 err
= self
->db_env
->lsn_reset(self
->db_env
, file
, flags
);
4395 MYDB_END_ALLOW_THREADS
;
4399 #endif /* DBVER >= 4.4 */
4403 DBEnv_log_stat(DBEnvObject
* self
, PyObject
* args
)
4406 DB_LOG_STAT
* statp
= NULL
;
4408 u_int32_t flags
= 0;
4410 if (!PyArg_ParseTuple(args
, "|i:log_stat", &flags
))
4412 CHECK_ENV_NOT_CLOSED(self
);
4414 MYDB_BEGIN_ALLOW_THREADS
;
4415 err
= self
->db_env
->log_stat(self
->db_env
, &statp
, flags
);
4416 MYDB_END_ALLOW_THREADS
;
4419 /* Turn the stat structure into a dictionary */
4427 #define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
4430 MAKE_ENTRY(version
);
4432 MAKE_ENTRY(lg_bsize
);
4434 MAKE_ENTRY(lg_size
);
4440 MAKE_ENTRY(w_mbytes
);
4441 MAKE_ENTRY(w_bytes
);
4442 MAKE_ENTRY(wc_mbytes
);
4443 MAKE_ENTRY(wc_bytes
);
4445 MAKE_ENTRY(wcount_fill
);
4450 MAKE_ENTRY(cur_file
);
4451 MAKE_ENTRY(cur_offset
);
4452 MAKE_ENTRY(disk_file
);
4453 MAKE_ENTRY(disk_offset
);
4454 MAKE_ENTRY(maxcommitperflush
);
4455 MAKE_ENTRY(mincommitperflush
);
4456 MAKE_ENTRY(regsize
);
4457 MAKE_ENTRY(region_wait
);
4458 MAKE_ENTRY(region_nowait
);
4463 } /* DBEnv_log_stat */
4464 #endif /* DBVER >= 4.0 for log_stat method */
4468 DBEnv_lock_stat(DBEnvObject
* self
, PyObject
* args
)
4473 u_int32_t flags
= 0;
4475 if (!PyArg_ParseTuple(args
, "|i:lock_stat", &flags
))
4477 CHECK_ENV_NOT_CLOSED(self
);
4479 MYDB_BEGIN_ALLOW_THREADS
;
4481 err
= self
->db_env
->lock_stat(self
->db_env
, &sp
, flags
);
4484 err
= lock_stat(self
->db_env
, &sp
);
4486 err
= lock_stat(self
->db_env
, &sp
, NULL
);
4489 MYDB_END_ALLOW_THREADS
;
4492 /* Turn the stat structure into a dictionary */
4499 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4506 MAKE_ENTRY(maxlocks
);
4507 MAKE_ENTRY(maxlockers
);
4508 MAKE_ENTRY(maxobjects
);
4510 MAKE_ENTRY(maxnlocks
);
4512 MAKE_ENTRY(nlockers
);
4513 MAKE_ENTRY(maxnlockers
);
4515 MAKE_ENTRY(nobjects
);
4516 MAKE_ENTRY(maxnobjects
);
4518 MAKE_ENTRY(nrequests
);
4519 MAKE_ENTRY(nreleases
);
4521 MAKE_ENTRY(nnowaits
); /* these were renamed in 4.4 */
4522 MAKE_ENTRY(nconflicts
);
4524 MAKE_ENTRY(lock_nowait
);
4525 MAKE_ENTRY(lock_wait
);
4527 MAKE_ENTRY(ndeadlocks
);
4528 MAKE_ENTRY(regsize
);
4529 MAKE_ENTRY(region_wait
);
4530 MAKE_ENTRY(region_nowait
);
4539 DBEnv_log_archive(DBEnvObject
* self
, PyObject
* args
)
4543 char **log_list
= NULL
;
4545 PyObject
* item
= NULL
;
4547 if (!PyArg_ParseTuple(args
, "|i:log_archive", &flags
))
4550 CHECK_ENV_NOT_CLOSED(self
);
4551 MYDB_BEGIN_ALLOW_THREADS
;
4553 err
= self
->db_env
->log_archive(self
->db_env
, &log_list
, flags
);
4555 err
= log_archive(self
->db_env
, &log_list
, flags
);
4557 err
= log_archive(self
->db_env
, &log_list
, flags
, NULL
);
4559 MYDB_END_ALLOW_THREADS
;
4562 list
= PyList_New(0);
4570 char **log_list_start
;
4571 for (log_list_start
= log_list
; *log_list
!= NULL
; ++log_list
) {
4572 item
= PyString_FromString (*log_list
);
4578 PyList_Append(list
, item
);
4581 free(log_list_start
);
4588 DBEnv_txn_stat(DBEnvObject
* self
, PyObject
* args
)
4595 if (!PyArg_ParseTuple(args
, "|i:txn_stat", &flags
))
4597 CHECK_ENV_NOT_CLOSED(self
);
4599 MYDB_BEGIN_ALLOW_THREADS
;
4601 err
= self
->db_env
->txn_stat(self
->db_env
, &sp
, flags
);
4603 err
= txn_stat(self
->db_env
, &sp
);
4605 err
= txn_stat(self
->db_env
, &sp
, NULL
);
4607 MYDB_END_ALLOW_THREADS
;
4610 /* Turn the stat structure into a dictionary */
4617 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4619 MAKE_ENTRY(time_ckp
);
4620 MAKE_ENTRY(last_txnid
);
4621 MAKE_ENTRY(maxtxns
);
4622 MAKE_ENTRY(nactive
);
4623 MAKE_ENTRY(maxnactive
);
4624 MAKE_ENTRY(nbegins
);
4625 MAKE_ENTRY(naborts
);
4626 MAKE_ENTRY(ncommits
);
4627 MAKE_ENTRY(regsize
);
4628 MAKE_ENTRY(region_wait
);
4629 MAKE_ENTRY(region_nowait
);
4638 DBEnv_set_get_returns_none(DBEnvObject
* self
, PyObject
* args
)
4643 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
4645 CHECK_ENV_NOT_CLOSED(self
);
4647 if (self
->moduleFlags
.getReturnsNone
)
4649 if (self
->moduleFlags
.cursorSetReturnsNone
)
4651 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
4652 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
4653 return PyInt_FromLong(oldValue
);
4657 /* --------------------------------------------------------------------- */
4662 DBTxn_commit(DBTxnObject
* self
, PyObject
* args
)
4667 if (!PyArg_ParseTuple(args
, "|i:commit", &flags
))
4671 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4672 "after txn_commit or txn_abort");
4673 PyErr_SetObject(DBError
, t
);
4678 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
4679 MYDB_BEGIN_ALLOW_THREADS
;
4681 err
= txn
->commit(txn
, flags
);
4683 err
= txn_commit(txn
, flags
);
4685 MYDB_END_ALLOW_THREADS
;
4691 DBTxn_prepare(DBTxnObject
* self
, PyObject
* args
)
4698 if (!PyArg_ParseTuple(args
, "s#:prepare", &gid
, &gid_size
))
4701 if (gid_size
!= DB_XIDDATASIZE
) {
4702 PyErr_SetString(PyExc_TypeError
,
4703 "gid must be DB_XIDDATASIZE bytes long");
4708 PyObject
*t
= Py_BuildValue("(is)", 0,"DBTxn must not be used "
4709 "after txn_commit or txn_abort");
4710 PyErr_SetObject(DBError
, t
);
4714 MYDB_BEGIN_ALLOW_THREADS
;
4716 err
= self
->txn
->prepare(self
->txn
, (u_int8_t
*)gid
);
4718 err
= txn_prepare(self
->txn
, (u_int8_t
*)gid
);
4720 MYDB_END_ALLOW_THREADS
;
4726 if (!PyArg_ParseTuple(args
, ":prepare"))
4730 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4731 "after txn_commit or txn_abort");
4732 PyErr_SetObject(DBError
, t
);
4736 MYDB_BEGIN_ALLOW_THREADS
;
4737 err
= txn_prepare(self
->txn
);
4738 MYDB_END_ALLOW_THREADS
;
4746 DBTxn_abort(DBTxnObject
* self
, PyObject
* args
)
4751 if (!PyArg_ParseTuple(args
, ":abort"))
4755 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4756 "after txn_commit or txn_abort");
4757 PyErr_SetObject(DBError
, t
);
4762 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
4763 MYDB_BEGIN_ALLOW_THREADS
;
4765 err
= txn
->abort(txn
);
4767 err
= txn_abort(txn
);
4769 MYDB_END_ALLOW_THREADS
;
4776 DBTxn_id(DBTxnObject
* self
, PyObject
* args
)
4780 if (!PyArg_ParseTuple(args
, ":id"))
4784 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4785 "after txn_commit or txn_abort");
4786 PyErr_SetObject(DBError
, t
);
4790 MYDB_BEGIN_ALLOW_THREADS
;
4792 id
= self
->txn
->id(self
->txn
);
4794 id
= txn_id(self
->txn
);
4796 MYDB_END_ALLOW_THREADS
;
4797 return PyInt_FromLong(id
);
4801 /* --------------------------------------------------------------------- */
4802 /* DBSequence methods */
4806 DBSequence_close(DBSequenceObject
* self
, PyObject
* args
)
4809 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
4811 CHECK_SEQUENCE_NOT_CLOSED(self
)
4813 MYDB_BEGIN_ALLOW_THREADS
4814 err
= self
->sequence
->close(self
->sequence
, flags
);
4815 self
->sequence
= NULL
;
4816 MYDB_END_ALLOW_THREADS
4824 DBSequence_get(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4829 PyObject
*txnobj
= NULL
;
4831 static char* kwnames
[] = {"delta", "txn", "flags", NULL
};
4832 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iOi:get", kwnames
, &delta
, &txnobj
, &flags
))
4834 CHECK_SEQUENCE_NOT_CLOSED(self
)
4836 if (!checkTxnObj(txnobj
, &txn
))
4839 MYDB_BEGIN_ALLOW_THREADS
4840 err
= self
->sequence
->get(self
->sequence
, txn
, delta
, &value
, flags
);
4841 MYDB_END_ALLOW_THREADS
4844 return PyLong_FromLongLong(value
);
4849 DBSequence_get_dbp(DBSequenceObject
* self
, PyObject
* args
)
4851 if (!PyArg_ParseTuple(args
,":get_dbp"))
4853 CHECK_SEQUENCE_NOT_CLOSED(self
)
4854 Py_INCREF(self
->mydb
);
4855 return (PyObject
* )self
->mydb
;
4859 DBSequence_get_key(DBSequenceObject
* self
, PyObject
* args
)
4863 CHECK_SEQUENCE_NOT_CLOSED(self
)
4864 MYDB_BEGIN_ALLOW_THREADS
4865 err
= self
->sequence
->get_key(self
->sequence
, &key
);
4866 MYDB_END_ALLOW_THREADS
4870 return PyString_FromStringAndSize(key
.data
, key
.size
);
4874 DBSequence_init_value(DBSequenceObject
* self
, PyObject
* args
)
4878 if (!PyArg_ParseTuple(args
,"L:init_value", &value
))
4880 CHECK_SEQUENCE_NOT_CLOSED(self
)
4882 MYDB_BEGIN_ALLOW_THREADS
4883 err
= self
->sequence
->initial_value(self
->sequence
, value
);
4884 MYDB_END_ALLOW_THREADS
4892 DBSequence_open(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4896 PyObject
*txnobj
= NULL
;
4900 static char* kwnames
[] = {"key", "txn", "flags", NULL
};
4901 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:open", kwnames
, &keyobj
, &txnobj
, &flags
))
4904 if (!checkTxnObj(txnobj
, &txn
))
4907 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
4910 MYDB_BEGIN_ALLOW_THREADS
4911 err
= self
->sequence
->open(self
->sequence
, txn
, &key
, flags
);
4912 MYDB_END_ALLOW_THREADS
4921 DBSequence_remove(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4924 PyObject
*txnobj
= NULL
;
4927 static char* kwnames
[] = {"txn", "flags", NULL
};
4928 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:remove", kwnames
, &txnobj
, &flags
))
4931 if (!checkTxnObj(txnobj
, &txn
))
4934 CHECK_SEQUENCE_NOT_CLOSED(self
)
4936 MYDB_BEGIN_ALLOW_THREADS
4937 err
= self
->sequence
->remove(self
->sequence
, txn
, flags
);
4938 MYDB_END_ALLOW_THREADS
4945 DBSequence_set_cachesize(DBSequenceObject
* self
, PyObject
* args
)
4948 if (!PyArg_ParseTuple(args
,"i:set_cachesize", &size
))
4950 CHECK_SEQUENCE_NOT_CLOSED(self
)
4952 MYDB_BEGIN_ALLOW_THREADS
4953 err
= self
->sequence
->set_cachesize(self
->sequence
, size
);
4954 MYDB_END_ALLOW_THREADS
4961 DBSequence_get_cachesize(DBSequenceObject
* self
, PyObject
* args
)
4964 if (!PyArg_ParseTuple(args
,":get_cachesize"))
4966 CHECK_SEQUENCE_NOT_CLOSED(self
)
4968 MYDB_BEGIN_ALLOW_THREADS
4969 err
= self
->sequence
->get_cachesize(self
->sequence
, &size
);
4970 MYDB_END_ALLOW_THREADS
4973 return PyInt_FromLong(size
);
4977 DBSequence_set_flags(DBSequenceObject
* self
, PyObject
* args
)
4980 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
4982 CHECK_SEQUENCE_NOT_CLOSED(self
)
4984 MYDB_BEGIN_ALLOW_THREADS
4985 err
= self
->sequence
->set_flags(self
->sequence
, flags
);
4986 MYDB_END_ALLOW_THREADS
4994 DBSequence_get_flags(DBSequenceObject
* self
, PyObject
* args
)
4998 if (!PyArg_ParseTuple(args
,":get_flags"))
5000 CHECK_SEQUENCE_NOT_CLOSED(self
)
5002 MYDB_BEGIN_ALLOW_THREADS
5003 err
= self
->sequence
->get_flags(self
->sequence
, &flags
);
5004 MYDB_END_ALLOW_THREADS
5007 return PyInt_FromLong((int)flags
);
5011 DBSequence_set_range(DBSequenceObject
* self
, PyObject
* args
)
5015 if (!PyArg_ParseTuple(args
,"LL:set_range", &min
, &max
))
5017 CHECK_SEQUENCE_NOT_CLOSED(self
)
5019 MYDB_BEGIN_ALLOW_THREADS
5020 err
= self
->sequence
->set_range(self
->sequence
, min
, max
);
5021 MYDB_END_ALLOW_THREADS
5028 DBSequence_get_range(DBSequenceObject
* self
, PyObject
* args
)
5032 if (!PyArg_ParseTuple(args
,":get_range"))
5034 CHECK_SEQUENCE_NOT_CLOSED(self
)
5036 MYDB_BEGIN_ALLOW_THREADS
5037 err
= self
->sequence
->get_range(self
->sequence
, &min
, &max
);
5038 MYDB_END_ALLOW_THREADS
5041 return Py_BuildValue("(LL)", min
, max
);
5045 DBSequence_stat(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5048 DB_SEQUENCE_STAT
* sp
= NULL
;
5049 PyObject
* dict_stat
;
5050 static char* kwnames
[] = {"flags", NULL
};
5051 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat", kwnames
, &flags
))
5053 CHECK_SEQUENCE_NOT_CLOSED(self
);
5055 MYDB_BEGIN_ALLOW_THREADS
;
5056 err
= self
->sequence
->stat(self
->sequence
, &sp
, flags
);
5057 MYDB_END_ALLOW_THREADS
;
5060 if ((dict_stat
= PyDict_New()) == NULL
) {
5066 #define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name)
5067 #define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
5069 MAKE_INT_ENTRY(wait
);
5070 MAKE_INT_ENTRY(nowait
);
5071 MAKE_LONG_LONG_ENTRY(current
);
5072 MAKE_LONG_LONG_ENTRY(value
);
5073 MAKE_LONG_LONG_ENTRY(last_value
);
5074 MAKE_LONG_LONG_ENTRY(min
);
5075 MAKE_LONG_LONG_ENTRY(max
);
5076 MAKE_INT_ENTRY(cache_size
);
5077 MAKE_INT_ENTRY(flags
);
5079 #undef MAKE_INT_ENTRY
5080 #undef MAKE_LONG_LONG_ENTRY
5088 /* --------------------------------------------------------------------- */
5089 /* Method definition tables and type objects */
5091 static PyMethodDef DB_methods
[] = {
5092 {"append", (PyCFunction
)DB_append
, METH_VARARGS
},
5094 {"associate", (PyCFunction
)DB_associate
, METH_VARARGS
|METH_KEYWORDS
},
5096 {"close", (PyCFunction
)DB_close
, METH_VARARGS
},
5098 {"consume", (PyCFunction
)DB_consume
, METH_VARARGS
|METH_KEYWORDS
},
5099 {"consume_wait", (PyCFunction
)DB_consume_wait
, METH_VARARGS
|METH_KEYWORDS
},
5101 {"cursor", (PyCFunction
)DB_cursor
, METH_VARARGS
|METH_KEYWORDS
},
5102 {"delete", (PyCFunction
)DB_delete
, METH_VARARGS
|METH_KEYWORDS
},
5103 {"fd", (PyCFunction
)DB_fd
, METH_VARARGS
},
5104 {"get", (PyCFunction
)DB_get
, METH_VARARGS
|METH_KEYWORDS
},
5106 {"pget", (PyCFunction
)DB_pget
, METH_VARARGS
|METH_KEYWORDS
},
5108 {"get_both", (PyCFunction
)DB_get_both
, METH_VARARGS
|METH_KEYWORDS
},
5109 {"get_byteswapped", (PyCFunction
)DB_get_byteswapped
,METH_VARARGS
},
5110 {"get_size", (PyCFunction
)DB_get_size
, METH_VARARGS
|METH_KEYWORDS
},
5111 {"get_type", (PyCFunction
)DB_get_type
, METH_VARARGS
},
5112 {"join", (PyCFunction
)DB_join
, METH_VARARGS
},
5113 {"key_range", (PyCFunction
)DB_key_range
, METH_VARARGS
|METH_KEYWORDS
},
5114 {"has_key", (PyCFunction
)DB_has_key
, METH_VARARGS
},
5115 {"items", (PyCFunction
)DB_items
, METH_VARARGS
},
5116 {"keys", (PyCFunction
)DB_keys
, METH_VARARGS
},
5117 {"open", (PyCFunction
)DB_open
, METH_VARARGS
|METH_KEYWORDS
},
5118 {"put", (PyCFunction
)DB_put
, METH_VARARGS
|METH_KEYWORDS
},
5119 {"remove", (PyCFunction
)DB_remove
, METH_VARARGS
|METH_KEYWORDS
},
5120 {"rename", (PyCFunction
)DB_rename
, METH_VARARGS
},
5121 {"set_bt_minkey", (PyCFunction
)DB_set_bt_minkey
, METH_VARARGS
},
5123 {"set_bt_compare", (PyCFunction
)DB_set_bt_compare
, METH_VARARGS
},
5125 {"set_cachesize", (PyCFunction
)DB_set_cachesize
, METH_VARARGS
},
5127 {"set_encrypt", (PyCFunction
)DB_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
5129 {"set_flags", (PyCFunction
)DB_set_flags
, METH_VARARGS
},
5130 {"set_h_ffactor", (PyCFunction
)DB_set_h_ffactor
, METH_VARARGS
},
5131 {"set_h_nelem", (PyCFunction
)DB_set_h_nelem
, METH_VARARGS
},
5132 {"set_lorder", (PyCFunction
)DB_set_lorder
, METH_VARARGS
},
5133 {"set_pagesize", (PyCFunction
)DB_set_pagesize
, METH_VARARGS
},
5134 {"set_re_delim", (PyCFunction
)DB_set_re_delim
, METH_VARARGS
},
5135 {"set_re_len", (PyCFunction
)DB_set_re_len
, METH_VARARGS
},
5136 {"set_re_pad", (PyCFunction
)DB_set_re_pad
, METH_VARARGS
},
5137 {"set_re_source", (PyCFunction
)DB_set_re_source
, METH_VARARGS
},
5139 {"set_q_extentsize",(PyCFunction
)DB_set_q_extentsize
,METH_VARARGS
},
5141 {"stat", (PyCFunction
)DB_stat
, METH_VARARGS
|METH_KEYWORDS
},
5142 {"sync", (PyCFunction
)DB_sync
, METH_VARARGS
},
5144 {"truncate", (PyCFunction
)DB_truncate
, METH_VARARGS
|METH_KEYWORDS
},
5146 {"type", (PyCFunction
)DB_get_type
, METH_VARARGS
},
5147 {"upgrade", (PyCFunction
)DB_upgrade
, METH_VARARGS
},
5148 {"values", (PyCFunction
)DB_values
, METH_VARARGS
},
5149 {"verify", (PyCFunction
)DB_verify
, METH_VARARGS
|METH_KEYWORDS
},
5150 {"set_get_returns_none",(PyCFunction
)DB_set_get_returns_none
, METH_VARARGS
},
5151 {NULL
, NULL
} /* sentinel */
5155 static PyMappingMethods DB_mapping
= {
5156 #if (PY_VERSION_HEX < 0x02050000)
5157 (inquiry
)DB_length
, /*mp_length*/
5159 (lenfunc
)DB_length
, /*mp_length*/
5161 (binaryfunc
)DB_subscript
, /*mp_subscript*/
5162 (objobjargproc
)DB_ass_sub
, /*mp_ass_subscript*/
5166 static PyMethodDef DBCursor_methods
[] = {
5167 {"close", (PyCFunction
)DBC_close
, METH_VARARGS
},
5168 {"count", (PyCFunction
)DBC_count
, METH_VARARGS
},
5169 {"current", (PyCFunction
)DBC_current
, METH_VARARGS
|METH_KEYWORDS
},
5170 {"delete", (PyCFunction
)DBC_delete
, METH_VARARGS
},
5171 {"dup", (PyCFunction
)DBC_dup
, METH_VARARGS
},
5172 {"first", (PyCFunction
)DBC_first
, METH_VARARGS
|METH_KEYWORDS
},
5173 {"get", (PyCFunction
)DBC_get
, METH_VARARGS
|METH_KEYWORDS
},
5175 {"pget", (PyCFunction
)DBC_pget
, METH_VARARGS
|METH_KEYWORDS
},
5177 {"get_recno", (PyCFunction
)DBC_get_recno
, METH_VARARGS
},
5178 {"last", (PyCFunction
)DBC_last
, METH_VARARGS
|METH_KEYWORDS
},
5179 {"next", (PyCFunction
)DBC_next
, METH_VARARGS
|METH_KEYWORDS
},
5180 {"prev", (PyCFunction
)DBC_prev
, METH_VARARGS
|METH_KEYWORDS
},
5181 {"put", (PyCFunction
)DBC_put
, METH_VARARGS
|METH_KEYWORDS
},
5182 {"set", (PyCFunction
)DBC_set
, METH_VARARGS
|METH_KEYWORDS
},
5183 {"set_range", (PyCFunction
)DBC_set_range
, METH_VARARGS
|METH_KEYWORDS
},
5184 {"get_both", (PyCFunction
)DBC_get_both
, METH_VARARGS
},
5185 {"get_current_size",(PyCFunction
)DBC_get_current_size
, METH_VARARGS
},
5186 {"set_both", (PyCFunction
)DBC_set_both
, METH_VARARGS
},
5187 {"set_recno", (PyCFunction
)DBC_set_recno
, METH_VARARGS
|METH_KEYWORDS
},
5188 {"consume", (PyCFunction
)DBC_consume
, METH_VARARGS
|METH_KEYWORDS
},
5189 {"next_dup", (PyCFunction
)DBC_next_dup
, METH_VARARGS
|METH_KEYWORDS
},
5190 {"next_nodup", (PyCFunction
)DBC_next_nodup
, METH_VARARGS
|METH_KEYWORDS
},
5191 {"prev_nodup", (PyCFunction
)DBC_prev_nodup
, METH_VARARGS
|METH_KEYWORDS
},
5192 {"join_item", (PyCFunction
)DBC_join_item
, METH_VARARGS
},
5193 {NULL
, NULL
} /* sentinel */
5197 static PyMethodDef DBEnv_methods
[] = {
5198 {"close", (PyCFunction
)DBEnv_close
, METH_VARARGS
},
5199 {"open", (PyCFunction
)DBEnv_open
, METH_VARARGS
},
5200 {"remove", (PyCFunction
)DBEnv_remove
, METH_VARARGS
},
5202 {"dbremove", (PyCFunction
)DBEnv_dbremove
, METH_VARARGS
|METH_KEYWORDS
},
5203 {"dbrename", (PyCFunction
)DBEnv_dbrename
, METH_VARARGS
|METH_KEYWORDS
},
5204 {"set_encrypt", (PyCFunction
)DBEnv_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
5207 {"set_timeout", (PyCFunction
)DBEnv_set_timeout
, METH_VARARGS
|METH_KEYWORDS
},
5209 {"set_shm_key", (PyCFunction
)DBEnv_set_shm_key
, METH_VARARGS
},
5210 {"set_cachesize", (PyCFunction
)DBEnv_set_cachesize
, METH_VARARGS
},
5211 {"set_data_dir", (PyCFunction
)DBEnv_set_data_dir
, METH_VARARGS
},
5213 {"set_flags", (PyCFunction
)DBEnv_set_flags
, METH_VARARGS
},
5215 {"set_lg_bsize", (PyCFunction
)DBEnv_set_lg_bsize
, METH_VARARGS
},
5216 {"set_lg_dir", (PyCFunction
)DBEnv_set_lg_dir
, METH_VARARGS
},
5217 {"set_lg_max", (PyCFunction
)DBEnv_set_lg_max
, METH_VARARGS
},
5219 {"set_lg_regionmax",(PyCFunction
)DBEnv_set_lg_regionmax
, METH_VARARGS
},
5221 {"set_lk_detect", (PyCFunction
)DBEnv_set_lk_detect
, METH_VARARGS
},
5222 {"set_lk_max", (PyCFunction
)DBEnv_set_lk_max
, METH_VARARGS
},
5224 {"set_lk_max_locks", (PyCFunction
)DBEnv_set_lk_max_locks
, METH_VARARGS
},
5225 {"set_lk_max_lockers", (PyCFunction
)DBEnv_set_lk_max_lockers
, METH_VARARGS
},
5226 {"set_lk_max_objects", (PyCFunction
)DBEnv_set_lk_max_objects
, METH_VARARGS
},
5228 {"set_mp_mmapsize", (PyCFunction
)DBEnv_set_mp_mmapsize
, METH_VARARGS
},
5229 {"set_tmp_dir", (PyCFunction
)DBEnv_set_tmp_dir
, METH_VARARGS
},
5230 {"txn_begin", (PyCFunction
)DBEnv_txn_begin
, METH_VARARGS
|METH_KEYWORDS
},
5231 {"txn_checkpoint", (PyCFunction
)DBEnv_txn_checkpoint
, METH_VARARGS
},
5232 {"txn_stat", (PyCFunction
)DBEnv_txn_stat
, METH_VARARGS
},
5233 {"set_tx_max", (PyCFunction
)DBEnv_set_tx_max
, METH_VARARGS
},
5234 {"set_tx_timestamp", (PyCFunction
)DBEnv_set_tx_timestamp
, METH_VARARGS
},
5235 {"lock_detect", (PyCFunction
)DBEnv_lock_detect
, METH_VARARGS
},
5236 {"lock_get", (PyCFunction
)DBEnv_lock_get
, METH_VARARGS
},
5237 {"lock_id", (PyCFunction
)DBEnv_lock_id
, METH_VARARGS
},
5238 {"lock_put", (PyCFunction
)DBEnv_lock_put
, METH_VARARGS
},
5239 {"lock_stat", (PyCFunction
)DBEnv_lock_stat
, METH_VARARGS
},
5240 {"log_archive", (PyCFunction
)DBEnv_log_archive
, METH_VARARGS
},
5242 {"log_stat", (PyCFunction
)DBEnv_log_stat
, METH_VARARGS
},
5245 {"lsn_reset", (PyCFunction
)DBEnv_lsn_reset
, METH_VARARGS
|METH_KEYWORDS
},
5247 {"set_get_returns_none",(PyCFunction
)DBEnv_set_get_returns_none
, METH_VARARGS
},
5248 {NULL
, NULL
} /* sentinel */
5252 static PyMethodDef DBTxn_methods
[] = {
5253 {"commit", (PyCFunction
)DBTxn_commit
, METH_VARARGS
},
5254 {"prepare", (PyCFunction
)DBTxn_prepare
, METH_VARARGS
},
5255 {"abort", (PyCFunction
)DBTxn_abort
, METH_VARARGS
},
5256 {"id", (PyCFunction
)DBTxn_id
, METH_VARARGS
},
5257 {NULL
, NULL
} /* sentinel */
5262 static PyMethodDef DBSequence_methods
[] = {
5263 {"close", (PyCFunction
)DBSequence_close
, METH_VARARGS
},
5264 {"get", (PyCFunction
)DBSequence_get
, METH_VARARGS
|METH_KEYWORDS
},
5265 {"get_dbp", (PyCFunction
)DBSequence_get_dbp
, METH_VARARGS
},
5266 {"get_key", (PyCFunction
)DBSequence_get_key
, METH_VARARGS
},
5267 {"init_value", (PyCFunction
)DBSequence_init_value
, METH_VARARGS
},
5268 {"open", (PyCFunction
)DBSequence_open
, METH_VARARGS
|METH_KEYWORDS
},
5269 {"remove", (PyCFunction
)DBSequence_remove
, METH_VARARGS
|METH_KEYWORDS
},
5270 {"set_cachesize", (PyCFunction
)DBSequence_set_cachesize
, METH_VARARGS
},
5271 {"get_cachesize", (PyCFunction
)DBSequence_get_cachesize
, METH_VARARGS
},
5272 {"set_flags", (PyCFunction
)DBSequence_set_flags
, METH_VARARGS
},
5273 {"get_flags", (PyCFunction
)DBSequence_get_flags
, METH_VARARGS
},
5274 {"set_range", (PyCFunction
)DBSequence_set_range
, METH_VARARGS
},
5275 {"get_range", (PyCFunction
)DBSequence_get_range
, METH_VARARGS
},
5276 {"stat", (PyCFunction
)DBSequence_stat
, METH_VARARGS
|METH_KEYWORDS
},
5277 {NULL
, NULL
} /* sentinel */
5283 DB_getattr(DBObject
* self
, char *name
)
5285 return Py_FindMethod(DB_methods
, (PyObject
* )self
, name
);
5290 DBEnv_getattr(DBEnvObject
* self
, char *name
)
5292 if (!strcmp(name
, "db_home")) {
5293 CHECK_ENV_NOT_CLOSED(self
);
5294 if (self
->db_env
->db_home
== NULL
) {
5297 return PyString_FromString(self
->db_env
->db_home
);
5300 return Py_FindMethod(DBEnv_methods
, (PyObject
* )self
, name
);
5305 DBCursor_getattr(DBCursorObject
* self
, char *name
)
5307 return Py_FindMethod(DBCursor_methods
, (PyObject
* )self
, name
);
5311 DBTxn_getattr(DBTxnObject
* self
, char *name
)
5313 return Py_FindMethod(DBTxn_methods
, (PyObject
* )self
, name
);
5317 DBLock_getattr(DBLockObject
* self
, char *name
)
5324 DBSequence_getattr(DBSequenceObject
* self
, char *name
)
5326 return Py_FindMethod(DBSequence_methods
, (PyObject
* )self
, name
);
5330 statichere PyTypeObject DB_Type
= {
5331 PyObject_HEAD_INIT(NULL
)
5334 sizeof(DBObject
), /*tp_basicsize*/
5337 (destructor
)DB_dealloc
, /*tp_dealloc*/
5339 (getattrfunc
)DB_getattr
, /*tp_getattr*/
5344 0, /*tp_as_sequence*/
5345 &DB_mapping
,/*tp_as_mapping*/
5350 0, /* tp_getattro */
5351 0, /* tp_setattro */
5352 0, /* tp_as_buffer */
5353 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5355 0, /* tp_traverse */
5357 0, /* tp_richcompare */
5358 offsetof(DBObject
, in_weakreflist
), /* tp_weaklistoffset */
5363 statichere PyTypeObject DBCursor_Type
= {
5364 PyObject_HEAD_INIT(NULL
)
5366 "DBCursor", /*tp_name*/
5367 sizeof(DBCursorObject
), /*tp_basicsize*/
5370 (destructor
)DBCursor_dealloc
,/*tp_dealloc*/
5372 (getattrfunc
)DBCursor_getattr
, /*tp_getattr*/
5377 0, /*tp_as_sequence*/
5378 0, /*tp_as_mapping*/
5383 0, /* tp_getattro */
5384 0, /* tp_setattro */
5385 0, /* tp_as_buffer */
5386 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5388 0, /* tp_traverse */
5390 0, /* tp_richcompare */
5391 offsetof(DBCursorObject
, in_weakreflist
), /* tp_weaklistoffset */
5396 statichere PyTypeObject DBEnv_Type
= {
5397 PyObject_HEAD_INIT(NULL
)
5399 "DBEnv", /*tp_name*/
5400 sizeof(DBEnvObject
), /*tp_basicsize*/
5403 (destructor
)DBEnv_dealloc
, /*tp_dealloc*/
5405 (getattrfunc
)DBEnv_getattr
, /*tp_getattr*/
5410 0, /*tp_as_sequence*/
5411 0, /*tp_as_mapping*/
5416 0, /* tp_getattro */
5417 0, /* tp_setattro */
5418 0, /* tp_as_buffer */
5419 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5421 0, /* tp_traverse */
5423 0, /* tp_richcompare */
5424 offsetof(DBEnvObject
, in_weakreflist
), /* tp_weaklistoffset */
5428 statichere PyTypeObject DBTxn_Type
= {
5429 PyObject_HEAD_INIT(NULL
)
5431 "DBTxn", /*tp_name*/
5432 sizeof(DBTxnObject
), /*tp_basicsize*/
5435 (destructor
)DBTxn_dealloc
, /*tp_dealloc*/
5437 (getattrfunc
)DBTxn_getattr
, /*tp_getattr*/
5442 0, /*tp_as_sequence*/
5443 0, /*tp_as_mapping*/
5448 0, /* tp_getattro */
5449 0, /* tp_setattro */
5450 0, /* tp_as_buffer */
5451 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5453 0, /* tp_traverse */
5455 0, /* tp_richcompare */
5456 offsetof(DBTxnObject
, in_weakreflist
), /* tp_weaklistoffset */
5461 statichere PyTypeObject DBLock_Type
= {
5462 PyObject_HEAD_INIT(NULL
)
5464 "DBLock", /*tp_name*/
5465 sizeof(DBLockObject
), /*tp_basicsize*/
5468 (destructor
)DBLock_dealloc
, /*tp_dealloc*/
5470 (getattrfunc
)DBLock_getattr
, /*tp_getattr*/
5475 0, /*tp_as_sequence*/
5476 0, /*tp_as_mapping*/
5481 0, /* tp_getattro */
5482 0, /* tp_setattro */
5483 0, /* tp_as_buffer */
5484 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5486 0, /* tp_traverse */
5488 0, /* tp_richcompare */
5489 offsetof(DBLockObject
, in_weakreflist
), /* tp_weaklistoffset */
5494 statichere PyTypeObject DBSequence_Type
= {
5495 PyObject_HEAD_INIT(NULL
)
5497 "DBSequence", /*tp_name*/
5498 sizeof(DBSequenceObject
), /*tp_basicsize*/
5501 (destructor
)DBSequence_dealloc
, /*tp_dealloc*/
5503 (getattrfunc
)DBSequence_getattr
,/*tp_getattr*/
5508 0, /*tp_as_sequence*/
5509 0, /*tp_as_mapping*/
5514 0, /* tp_getattro */
5515 0, /* tp_setattro */
5516 0, /* tp_as_buffer */
5517 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5519 0, /* tp_traverse */
5521 0, /* tp_richcompare */
5522 offsetof(DBSequenceObject
, in_weakreflist
), /* tp_weaklistoffset */
5527 /* --------------------------------------------------------------------- */
5528 /* Module-level functions */
5531 DB_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5533 PyObject
* dbenvobj
= NULL
;
5535 static char* kwnames
[] = { "dbEnv", "flags", NULL
};
5537 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:DB", kwnames
,
5540 if (dbenvobj
== Py_None
)
5542 else if (dbenvobj
&& !DBEnvObject_Check(dbenvobj
)) {
5543 makeTypeError("DBEnv", dbenvobj
);
5547 return (PyObject
* )newDBObject((DBEnvObject
*)dbenvobj
, flags
);
5552 DBEnv_construct(PyObject
* self
, PyObject
* args
)
5555 if (!PyArg_ParseTuple(args
, "|i:DbEnv", &flags
)) return NULL
;
5556 return (PyObject
* )newDBEnvObject(flags
);
5561 DBSequence_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5563 PyObject
* dbobj
= NULL
;
5565 static char* kwnames
[] = { "db", "flags", NULL
};
5567 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|i:DBSequence", kwnames
, &dbobj
, &flags
))
5569 if (dbobj
== Py_None
)
5571 else if (dbobj
&& !DBObject_Check(dbobj
)) {
5572 makeTypeError("DB", dbobj
);
5575 return (PyObject
* )newDBSequenceObject((DBObject
*)dbobj
, flags
);
5579 static char bsddb_version_doc
[] =
5580 "Returns a tuple of major, minor, and patch release numbers of the\n\
5581 underlying DB library.";
5584 bsddb_version(PyObject
* self
, PyObject
* args
)
5586 int major
, minor
, patch
;
5588 if (!PyArg_ParseTuple(args
, ":version"))
5590 db_version(&major
, &minor
, &patch
);
5591 return Py_BuildValue("(iii)", major
, minor
, patch
);
5595 /* List of functions defined in the module */
5597 static PyMethodDef bsddb_methods
[] = {
5598 {"DB", (PyCFunction
)DB_construct
, METH_VARARGS
| METH_KEYWORDS
},
5599 {"DBEnv", (PyCFunction
)DBEnv_construct
, METH_VARARGS
},
5601 {"DBSequence", (PyCFunction
)DBSequence_construct
, METH_VARARGS
| METH_KEYWORDS
},
5603 {"version", (PyCFunction
)bsddb_version
, METH_VARARGS
, bsddb_version_doc
},
5604 {NULL
, NULL
} /* sentinel */
5608 /* --------------------------------------------------------------------- */
5609 /* Module initialization */
5612 /* Convenience routine to export an integer value.
5613 * Errors are silently ignored, for better or for worse...
5615 #define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
5617 #define MODULE_NAME_MAX_LEN 11
5618 static char _bsddbModuleName
[MODULE_NAME_MAX_LEN
+1] = "_bsddb";
5620 DL_EXPORT(void) init_bsddb(void)
5624 PyObject
* pybsddb_version_s
= PyString_FromString( PY_BSDDB_VERSION
);
5625 PyObject
* db_version_s
= PyString_FromString( DB_VERSION_STRING
);
5626 PyObject
* cvsid_s
= PyString_FromString( rcs_id
);
5628 /* Initialize the type of the new type objects here; doing it here
5629 is required for portability to Windows without requiring C++. */
5630 DB_Type
.ob_type
= &PyType_Type
;
5631 DBCursor_Type
.ob_type
= &PyType_Type
;
5632 DBEnv_Type
.ob_type
= &PyType_Type
;
5633 DBTxn_Type
.ob_type
= &PyType_Type
;
5634 DBLock_Type
.ob_type
= &PyType_Type
;
5636 DBSequence_Type
.ob_type
= &PyType_Type
;
5640 #if defined(WITH_THREAD) && !defined(MYDB_USE_GILSTATE)
5641 /* Save the current interpreter, so callbacks can do the right thing. */
5642 _db_interpreterState
= PyThreadState_GET()->interp
;
5645 /* Create the module and add the functions */
5646 m
= Py_InitModule(_bsddbModuleName
, bsddb_methods
);
5650 /* Add some symbolic constants to the module */
5651 d
= PyModule_GetDict(m
);
5652 PyDict_SetItemString(d
, "__version__", pybsddb_version_s
);
5653 PyDict_SetItemString(d
, "cvsid", cvsid_s
);
5654 PyDict_SetItemString(d
, "DB_VERSION_STRING", db_version_s
);
5655 Py_DECREF(pybsddb_version_s
);
5656 pybsddb_version_s
= NULL
;
5659 Py_DECREF(db_version_s
);
5660 db_version_s
= NULL
;
5662 ADD_INT(d
, DB_VERSION_MAJOR
);
5663 ADD_INT(d
, DB_VERSION_MINOR
);
5664 ADD_INT(d
, DB_VERSION_PATCH
);
5666 ADD_INT(d
, DB_MAX_PAGES
);
5667 ADD_INT(d
, DB_MAX_RECORDS
);
5670 ADD_INT(d
, DB_RPCCLIENT
);
5672 ADD_INT(d
, DB_CLIENT
);
5673 /* allow apps to be written using DB_RPCCLIENT on older BerkeleyDB */
5674 _addIntToDict(d
, "DB_RPCCLIENT", DB_CLIENT
);
5676 ADD_INT(d
, DB_XA_CREATE
);
5678 ADD_INT(d
, DB_CREATE
);
5679 ADD_INT(d
, DB_NOMMAP
);
5680 ADD_INT(d
, DB_THREAD
);
5682 ADD_INT(d
, DB_FORCE
);
5683 ADD_INT(d
, DB_INIT_CDB
);
5684 ADD_INT(d
, DB_INIT_LOCK
);
5685 ADD_INT(d
, DB_INIT_LOG
);
5686 ADD_INT(d
, DB_INIT_MPOOL
);
5687 ADD_INT(d
, DB_INIT_TXN
);
5689 ADD_INT(d
, DB_JOINENV
);
5692 ADD_INT(d
, DB_RECOVER
);
5693 ADD_INT(d
, DB_RECOVER_FATAL
);
5694 ADD_INT(d
, DB_TXN_NOSYNC
);
5695 ADD_INT(d
, DB_USE_ENVIRON
);
5696 ADD_INT(d
, DB_USE_ENVIRON_ROOT
);
5698 ADD_INT(d
, DB_LOCKDOWN
);
5699 ADD_INT(d
, DB_PRIVATE
);
5700 ADD_INT(d
, DB_SYSTEM_MEM
);
5702 ADD_INT(d
, DB_TXN_SYNC
);
5703 ADD_INT(d
, DB_TXN_NOWAIT
);
5705 ADD_INT(d
, DB_EXCL
);
5706 ADD_INT(d
, DB_FCNTL_LOCKING
);
5707 ADD_INT(d
, DB_ODDFILESIZE
);
5708 ADD_INT(d
, DB_RDWRMASTER
);
5709 ADD_INT(d
, DB_RDONLY
);
5710 ADD_INT(d
, DB_TRUNCATE
);
5712 ADD_INT(d
, DB_EXTENT
);
5713 ADD_INT(d
, DB_CDB_ALLDB
);
5714 ADD_INT(d
, DB_VERIFY
);
5716 ADD_INT(d
, DB_UPGRADE
);
5718 ADD_INT(d
, DB_AGGRESSIVE
);
5719 ADD_INT(d
, DB_NOORDERCHK
);
5720 ADD_INT(d
, DB_ORDERCHKONLY
);
5721 ADD_INT(d
, DB_PR_PAGE
);
5723 ADD_INT(d
, DB_VRFY_FLAGMASK
);
5724 ADD_INT(d
, DB_PR_HEADERS
);
5726 ADD_INT(d
, DB_PR_RECOVERYTEST
);
5727 ADD_INT(d
, DB_SALVAGE
);
5729 ADD_INT(d
, DB_LOCK_NORUN
);
5730 ADD_INT(d
, DB_LOCK_DEFAULT
);
5731 ADD_INT(d
, DB_LOCK_OLDEST
);
5732 ADD_INT(d
, DB_LOCK_RANDOM
);
5733 ADD_INT(d
, DB_LOCK_YOUNGEST
);
5735 ADD_INT(d
, DB_LOCK_MAXLOCKS
);
5736 ADD_INT(d
, DB_LOCK_MINLOCKS
);
5737 ADD_INT(d
, DB_LOCK_MINWRITE
);
5742 /* docs say to use zero instead */
5743 _addIntToDict(d
, "DB_LOCK_CONFLICT", 0);
5745 ADD_INT(d
, DB_LOCK_CONFLICT
);
5748 ADD_INT(d
, DB_LOCK_DUMP
);
5749 ADD_INT(d
, DB_LOCK_GET
);
5750 ADD_INT(d
, DB_LOCK_INHERIT
);
5751 ADD_INT(d
, DB_LOCK_PUT
);
5752 ADD_INT(d
, DB_LOCK_PUT_ALL
);
5753 ADD_INT(d
, DB_LOCK_PUT_OBJ
);
5755 ADD_INT(d
, DB_LOCK_NG
);
5756 ADD_INT(d
, DB_LOCK_READ
);
5757 ADD_INT(d
, DB_LOCK_WRITE
);
5758 ADD_INT(d
, DB_LOCK_NOWAIT
);
5760 ADD_INT(d
, DB_LOCK_WAIT
);
5762 ADD_INT(d
, DB_LOCK_IWRITE
);
5763 ADD_INT(d
, DB_LOCK_IREAD
);
5764 ADD_INT(d
, DB_LOCK_IWR
);
5767 ADD_INT(d
, DB_LOCK_DIRTY
);
5769 ADD_INT(d
, DB_LOCK_READ_UNCOMMITTED
); /* renamed in 4.4 */
5771 ADD_INT(d
, DB_LOCK_WWRITE
);
5774 ADD_INT(d
, DB_LOCK_RECORD
);
5775 ADD_INT(d
, DB_LOCK_UPGRADE
);
5777 ADD_INT(d
, DB_LOCK_SWITCH
);
5780 ADD_INT(d
, DB_LOCK_UPGRADE_WRITE
);
5783 ADD_INT(d
, DB_LOCK_NOWAIT
);
5784 ADD_INT(d
, DB_LOCK_RECORD
);
5785 ADD_INT(d
, DB_LOCK_UPGRADE
);
5788 ADD_INT(d
, DB_LSTAT_ABORTED
);
5790 ADD_INT(d
, DB_LSTAT_ERR
);
5792 ADD_INT(d
, DB_LSTAT_FREE
);
5793 ADD_INT(d
, DB_LSTAT_HELD
);
5795 ADD_INT(d
, DB_LSTAT_NOGRANT
);
5797 ADD_INT(d
, DB_LSTAT_PENDING
);
5798 ADD_INT(d
, DB_LSTAT_WAITING
);
5801 ADD_INT(d
, DB_ARCH_ABS
);
5802 ADD_INT(d
, DB_ARCH_DATA
);
5803 ADD_INT(d
, DB_ARCH_LOG
);
5805 ADD_INT(d
, DB_ARCH_REMOVE
);
5808 ADD_INT(d
, DB_BTREE
);
5809 ADD_INT(d
, DB_HASH
);
5810 ADD_INT(d
, DB_RECNO
);
5811 ADD_INT(d
, DB_QUEUE
);
5812 ADD_INT(d
, DB_UNKNOWN
);
5815 ADD_INT(d
, DB_DUPSORT
);
5816 ADD_INT(d
, DB_RECNUM
);
5817 ADD_INT(d
, DB_RENUMBER
);
5818 ADD_INT(d
, DB_REVSPLITOFF
);
5819 ADD_INT(d
, DB_SNAPSHOT
);
5821 ADD_INT(d
, DB_JOIN_NOSORT
);
5823 ADD_INT(d
, DB_AFTER
);
5824 ADD_INT(d
, DB_APPEND
);
5825 ADD_INT(d
, DB_BEFORE
);
5826 ADD_INT(d
, DB_CACHED_COUNTS
);
5828 _addIntToDict(d
, "DB_CHECKPOINT", 0);
5830 ADD_INT(d
, DB_CHECKPOINT
);
5831 ADD_INT(d
, DB_CURLSN
);
5833 #if ((DBVER >= 33) && (DBVER <= 41))
5834 ADD_INT(d
, DB_COMMIT
);
5836 ADD_INT(d
, DB_CONSUME
);
5838 ADD_INT(d
, DB_CONSUME_WAIT
);
5840 ADD_INT(d
, DB_CURRENT
);
5842 ADD_INT(d
, DB_FAST_STAT
);
5844 ADD_INT(d
, DB_FIRST
);
5845 ADD_INT(d
, DB_FLUSH
);
5846 ADD_INT(d
, DB_GET_BOTH
);
5847 ADD_INT(d
, DB_GET_RECNO
);
5848 ADD_INT(d
, DB_JOIN_ITEM
);
5849 ADD_INT(d
, DB_KEYFIRST
);
5850 ADD_INT(d
, DB_KEYLAST
);
5851 ADD_INT(d
, DB_LAST
);
5852 ADD_INT(d
, DB_NEXT
);
5853 ADD_INT(d
, DB_NEXT_DUP
);
5854 ADD_INT(d
, DB_NEXT_NODUP
);
5855 ADD_INT(d
, DB_NODUPDATA
);
5856 ADD_INT(d
, DB_NOOVERWRITE
);
5857 ADD_INT(d
, DB_NOSYNC
);
5858 ADD_INT(d
, DB_POSITION
);
5859 ADD_INT(d
, DB_PREV
);
5860 ADD_INT(d
, DB_PREV_NODUP
);
5861 ADD_INT(d
, DB_RECORDCOUNT
);
5863 ADD_INT(d
, DB_SET_RANGE
);
5864 ADD_INT(d
, DB_SET_RECNO
);
5865 ADD_INT(d
, DB_WRITECURSOR
);
5867 ADD_INT(d
, DB_OPFLAGS_MASK
);
5870 ADD_INT(d
, DB_DIRTY_READ
);
5871 ADD_INT(d
, DB_MULTIPLE
);
5872 ADD_INT(d
, DB_MULTIPLE_KEY
);
5876 ADD_INT(d
, DB_READ_UNCOMMITTED
); /* replaces DB_DIRTY_READ in 4.4 */
5877 ADD_INT(d
, DB_READ_COMMITTED
);
5881 ADD_INT(d
, DB_DONOTINDEX
);
5885 _addIntToDict(d
, "DB_INCOMPLETE", 0);
5887 ADD_INT(d
, DB_INCOMPLETE
);
5889 ADD_INT(d
, DB_KEYEMPTY
);
5890 ADD_INT(d
, DB_KEYEXIST
);
5891 ADD_INT(d
, DB_LOCK_DEADLOCK
);
5892 ADD_INT(d
, DB_LOCK_NOTGRANTED
);
5893 ADD_INT(d
, DB_NOSERVER
);
5894 ADD_INT(d
, DB_NOSERVER_HOME
);
5895 ADD_INT(d
, DB_NOSERVER_ID
);
5896 ADD_INT(d
, DB_NOTFOUND
);
5897 ADD_INT(d
, DB_OLD_VERSION
);
5898 ADD_INT(d
, DB_RUNRECOVERY
);
5899 ADD_INT(d
, DB_VERIFY_BAD
);
5901 ADD_INT(d
, DB_PAGE_NOTFOUND
);
5902 ADD_INT(d
, DB_SECONDARY_BAD
);
5905 ADD_INT(d
, DB_STAT_CLEAR
);
5906 ADD_INT(d
, DB_REGION_INIT
);
5907 ADD_INT(d
, DB_NOLOCKING
);
5908 ADD_INT(d
, DB_YIELDCPU
);
5909 ADD_INT(d
, DB_PANIC_ENVIRONMENT
);
5910 ADD_INT(d
, DB_NOPANIC
);
5914 ADD_INT(d
, DB_TIME_NOTGRANTED
);
5915 ADD_INT(d
, DB_TXN_NOT_DURABLE
);
5916 ADD_INT(d
, DB_TXN_WRITE_NOSYNC
);
5917 ADD_INT(d
, DB_LOG_AUTOREMOVE
);
5918 ADD_INT(d
, DB_DIRECT_LOG
);
5919 ADD_INT(d
, DB_DIRECT_DB
);
5920 ADD_INT(d
, DB_INIT_REP
);
5921 ADD_INT(d
, DB_ENCRYPT
);
5922 ADD_INT(d
, DB_CHKSUM
);
5926 ADD_INT(d
, DB_LOG_INMEMORY
);
5927 ADD_INT(d
, DB_BUFFER_SMALL
);
5928 ADD_INT(d
, DB_SEQ_DEC
);
5929 ADD_INT(d
, DB_SEQ_INC
);
5930 ADD_INT(d
, DB_SEQ_WRAP
);
5934 ADD_INT(d
, DB_ENCRYPT_AES
);
5935 ADD_INT(d
, DB_AUTO_COMMIT
);
5937 /* allow berkeleydb 4.1 aware apps to run on older versions */
5938 _addIntToDict(d
, "DB_AUTO_COMMIT", 0);
5952 ADD_INT(d
, DB_SET_LOCK_TIMEOUT
);
5953 ADD_INT(d
, DB_SET_TXN_TIMEOUT
);
5956 /* The exception name must be correct for pickled exception *
5957 * objects to unpickle properly. */
5958 #ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
5959 #define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
5961 #define PYBSDDB_EXCEPTION_BASE "bsddb.db."
5964 /* All the rest of the exceptions derive only from DBError */
5965 #define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
5966 PyDict_SetItemString(d, #name, name)
5968 /* The base exception class is DBError */
5969 DBError
= NULL
; /* used in MAKE_EX so that it derives from nothing */
5972 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
5973 * from both DBError and KeyError, since the API only supports
5974 * using one base class. */
5975 PyDict_SetItemString(d
, "KeyError", PyExc_KeyError
);
5976 PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
5977 "class DBKeyEmptyError(DBError, KeyError): pass",
5978 Py_file_input
, d
, d
);
5979 DBNotFoundError
= PyDict_GetItemString(d
, "DBNotFoundError");
5980 DBKeyEmptyError
= PyDict_GetItemString(d
, "DBKeyEmptyError");
5981 PyDict_DelItemString(d
, "KeyError");
5984 #if !INCOMPLETE_IS_WARNING
5985 MAKE_EX(DBIncompleteError
);
5987 MAKE_EX(DBCursorClosedError
);
5988 MAKE_EX(DBKeyEmptyError
);
5989 MAKE_EX(DBKeyExistError
);
5990 MAKE_EX(DBLockDeadlockError
);
5991 MAKE_EX(DBLockNotGrantedError
);
5992 MAKE_EX(DBOldVersionError
);
5993 MAKE_EX(DBRunRecoveryError
);
5994 MAKE_EX(DBVerifyBadError
);
5995 MAKE_EX(DBNoServerError
);
5996 MAKE_EX(DBNoServerHomeError
);
5997 MAKE_EX(DBNoServerIDError
);
5999 MAKE_EX(DBPageNotFoundError
);
6000 MAKE_EX(DBSecondaryBadError
);
6003 MAKE_EX(DBInvalidArgError
);
6004 MAKE_EX(DBAccessError
);
6005 MAKE_EX(DBNoSpaceError
);
6006 MAKE_EX(DBNoMemoryError
);
6007 MAKE_EX(DBAgainError
);
6008 MAKE_EX(DBBusyError
);
6009 MAKE_EX(DBFileExistsError
);
6010 MAKE_EX(DBNoSuchFileError
);
6011 MAKE_EX(DBPermissionsError
);
6015 /* Check for errors */
6016 if (PyErr_Occurred()) {
6018 Py_FatalError("can't initialize module _bsddb");
6022 /* allow this module to be named _pybsddb so that it can be installed
6023 * and imported on top of python >= 2.3 that includes its own older
6024 * copy of the library named _bsddb without importing the old version. */
6025 DL_EXPORT(void) init_pybsddb(void)
6027 strncpy(_bsddbModuleName
, "_pybsddb", MODULE_NAME_MAX_LEN
);