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 typedef int Py_ssize_t
;
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(PyObject
* _self
)
2687 Py_ssize_t size
= 0;
2690 DBObject
* self
= (DBObject
*)_self
;
2692 if (self
->db
== NULL
) {
2693 PyObject
*t
= Py_BuildValue("(is)", 0, "DB object has been closed");
2694 PyErr_SetObject(DBError
, t
);
2699 if (self
->haveStat
) { /* Has the stat function been called recently? If
2700 so, we can use the cached value. */
2701 flags
= DB_FAST_STAT
;
2704 MYDB_BEGIN_ALLOW_THREADS
;
2705 redo_stat_for_length
:
2707 err
= self
->db
->stat(self
->db
, /*txnid*/ NULL
, &sp
, flags
);
2709 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2711 err
= self
->db
->stat(self
->db
, &sp
, NULL
, flags
);
2714 /* All the stat structures have matching fields upto the ndata field,
2715 so we can use any of them for the type cast */
2716 size
= ((DB_BTREE_STAT
*)sp
)->bt_ndata
;
2718 /* A size of 0 could mean that BerkeleyDB no longer had the stat values cached.
2719 * redo a full stat to make sure.
2720 * Fixes SF python bug 1493322, pybsddb bug 1184012
2722 if (size
== 0 && (flags
& DB_FAST_STAT
)) {
2726 goto redo_stat_for_length
;
2729 MYDB_END_ALLOW_THREADS
;
2741 PyObject
* DB_subscript(DBObject
* self
, PyObject
* keyobj
)
2748 CHECK_DB_NOT_CLOSED(self
);
2749 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2753 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2754 /* Tell BerkeleyDB to malloc the return value (thread safe) */
2755 data
.flags
= DB_DBT_MALLOC
;
2757 MYDB_BEGIN_ALLOW_THREADS
;
2758 err
= self
->db
->get(self
->db
, NULL
, &key
, &data
, 0);
2759 MYDB_END_ALLOW_THREADS
;
2760 if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
2761 PyErr_SetObject(PyExc_KeyError
, keyobj
);
2764 else if (makeDBError(err
)) {
2768 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
2778 DB_ass_sub(DBObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
)
2784 if (self
->db
== NULL
) {
2785 PyObject
*t
= Py_BuildValue("(is)", 0, "DB object has been closed");
2786 PyErr_SetObject(DBError
, t
);
2791 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2794 if (dataobj
!= NULL
) {
2795 if (!make_dbt(dataobj
, &data
))
2798 if (self
->setflags
& (DB_DUP
|DB_DUPSORT
))
2799 /* dictionaries shouldn't have duplicate keys */
2800 flags
= DB_NOOVERWRITE
;
2801 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2803 if ((retval
== -1) && (self
->setflags
& (DB_DUP
|DB_DUPSORT
))) {
2804 /* try deleting any old record that matches and then PUT it
2806 _DB_delete(self
, NULL
, &key
, 0);
2808 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2813 /* dataobj == NULL, so delete the key */
2814 retval
= _DB_delete(self
, NULL
, &key
, 0);
2822 DB_has_key(DBObject
* self
, PyObject
* args
)
2827 PyObject
* txnobj
= NULL
;
2830 if (!PyArg_ParseTuple(args
,"O|O:has_key", &keyobj
, &txnobj
))
2832 CHECK_DB_NOT_CLOSED(self
);
2833 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2835 if (!checkTxnObj(txnobj
, &txn
)) {
2840 /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
2841 it has a record but can't allocate a buffer for the data. This saves
2842 having to deal with data we won't be using.
2845 data
.flags
= DB_DBT_USERMEM
;
2847 MYDB_BEGIN_ALLOW_THREADS
;
2848 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, 0);
2849 MYDB_END_ALLOW_THREADS
;
2852 if (err
== DB_BUFFER_SMALL
|| err
== 0) {
2853 return PyInt_FromLong(1);
2854 } else if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
2855 return PyInt_FromLong(0);
2863 #define _KEYS_LIST 1
2864 #define _VALUES_LIST 2
2865 #define _ITEMS_LIST 3
2868 _DB_make_list(DBObject
* self
, DB_TXN
* txn
, int type
)
2875 PyObject
* item
= NULL
;
2877 CHECK_DB_NOT_CLOSED(self
);
2881 dbtype
= _DB_get_type(self
);
2885 list
= PyList_New(0);
2890 MYDB_BEGIN_ALLOW_THREADS
;
2891 err
= self
->db
->cursor(self
->db
, txn
, &cursor
, 0);
2892 MYDB_END_ALLOW_THREADS
;
2893 if (makeDBError(err
)) {
2898 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2899 key
.flags
= DB_DBT_REALLOC
;
2900 data
.flags
= DB_DBT_REALLOC
;
2903 while (1) { /* use the cursor to traverse the DB, collecting items */
2904 MYDB_BEGIN_ALLOW_THREADS
;
2905 err
= cursor
->c_get(cursor
, &key
, &data
, DB_NEXT
);
2906 MYDB_END_ALLOW_THREADS
;
2909 /* for any error, break out of the loop */
2919 item
= PyString_FromStringAndSize((char*)key
.data
, key
.size
);
2923 item
= PyInt_FromLong(*((db_recno_t
*)key
.data
));
2929 item
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
2937 item
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
2942 item
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
2943 data
.data
, data
.size
);
2948 PyErr_Format(PyExc_ValueError
, "Unknown key type 0x%x", type
);
2957 PyList_Append(list
, item
);
2961 /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
2962 if (err
!= DB_NOTFOUND
&& err
!= DB_KEYEMPTY
&& makeDBError(err
)) {
2970 MYDB_BEGIN_ALLOW_THREADS
;
2971 cursor
->c_close(cursor
);
2972 MYDB_END_ALLOW_THREADS
;
2978 DB_keys(DBObject
* self
, PyObject
* args
)
2980 PyObject
* txnobj
= NULL
;
2983 if (!PyArg_UnpackTuple(args
, "keys", 0, 1, &txnobj
))
2985 if (!checkTxnObj(txnobj
, &txn
))
2987 return _DB_make_list(self
, txn
, _KEYS_LIST
);
2992 DB_items(DBObject
* self
, PyObject
* args
)
2994 PyObject
* txnobj
= NULL
;
2997 if (!PyArg_UnpackTuple(args
, "items", 0, 1, &txnobj
))
2999 if (!checkTxnObj(txnobj
, &txn
))
3001 return _DB_make_list(self
, txn
, _ITEMS_LIST
);
3006 DB_values(DBObject
* self
, PyObject
* args
)
3008 PyObject
* txnobj
= NULL
;
3011 if (!PyArg_UnpackTuple(args
, "values", 0, 1, &txnobj
))
3013 if (!checkTxnObj(txnobj
, &txn
))
3015 return _DB_make_list(self
, txn
, _VALUES_LIST
);
3018 /* --------------------------------------------------------------------- */
3019 /* DBCursor methods */
3023 DBC_close(DBCursorObject
* self
, PyObject
* args
)
3027 if (!PyArg_ParseTuple(args
, ":close"))
3030 if (self
->dbc
!= NULL
) {
3031 MYDB_BEGIN_ALLOW_THREADS
;
3032 err
= self
->dbc
->c_close(self
->dbc
);
3034 MYDB_END_ALLOW_THREADS
;
3042 DBC_count(DBCursorObject
* self
, PyObject
* args
)
3048 if (!PyArg_ParseTuple(args
, "|i:count", &flags
))
3051 CHECK_CURSOR_NOT_CLOSED(self
);
3053 MYDB_BEGIN_ALLOW_THREADS
;
3054 err
= self
->dbc
->c_count(self
->dbc
, &count
, flags
);
3055 MYDB_END_ALLOW_THREADS
;
3058 return PyInt_FromLong(count
);
3063 DBC_current(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3065 return _DBCursor_get(self
,DB_CURRENT
,args
,kwargs
,"|iii:current");
3070 DBC_delete(DBCursorObject
* self
, PyObject
* args
)
3074 if (!PyArg_ParseTuple(args
, "|i:delete", &flags
))
3077 CHECK_CURSOR_NOT_CLOSED(self
);
3079 MYDB_BEGIN_ALLOW_THREADS
;
3080 err
= self
->dbc
->c_del(self
->dbc
, flags
);
3081 MYDB_END_ALLOW_THREADS
;
3084 self
->mydb
->haveStat
= 0;
3090 DBC_dup(DBCursorObject
* self
, PyObject
* args
)
3095 if (!PyArg_ParseTuple(args
, "|i:dup", &flags
))
3098 CHECK_CURSOR_NOT_CLOSED(self
);
3100 MYDB_BEGIN_ALLOW_THREADS
;
3101 err
= self
->dbc
->c_dup(self
->dbc
, &dbc
, flags
);
3102 MYDB_END_ALLOW_THREADS
;
3105 return (PyObject
*) newDBCursorObject(dbc
, self
->mydb
);
3109 DBC_first(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3111 return _DBCursor_get(self
,DB_FIRST
,args
,kwargs
,"|iii:first");
3116 DBC_get(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3119 PyObject
* keyobj
= NULL
;
3120 PyObject
* dataobj
= NULL
;
3121 PyObject
* retval
= NULL
;
3125 static char* kwnames
[] = { "key","data", "flags", "dlen", "doff",
3130 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:get", &kwnames
[2],
3131 &flags
, &dlen
, &doff
))
3134 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:get",
3136 &keyobj
, &flags
, &dlen
, &doff
))
3139 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:get",
3140 kwnames
, &keyobj
, &dataobj
,
3141 &flags
, &dlen
, &doff
))
3148 CHECK_CURSOR_NOT_CLOSED(self
);
3150 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3152 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
3153 (!add_partial_dbt(&data
, dlen
, doff
)) )
3159 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3160 data
.flags
= DB_DBT_MALLOC
;
3161 if (!(key
.flags
& DB_DBT_REALLOC
)) {
3162 key
.flags
|= DB_DBT_MALLOC
;
3166 MYDB_BEGIN_ALLOW_THREADS
;
3167 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
3168 MYDB_END_ALLOW_THREADS
;
3170 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3171 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3175 else if (makeDBError(err
)) {
3179 switch (_DB_get_type(self
->mydb
)) {
3186 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3187 data
.data
, data
.size
);
3191 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3192 data
.data
, data
.size
);
3203 DBC_pget(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3206 PyObject
* keyobj
= NULL
;
3207 PyObject
* dataobj
= NULL
;
3208 PyObject
* retval
= NULL
;
3211 DBT key
, pkey
, data
;
3212 static char* kwnames_keyOnly
[] = { "key", "flags", "dlen", "doff", NULL
};
3213 static char* kwnames
[] = { "key", "data", "flags", "dlen", "doff", NULL
};
3217 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:pget", &kwnames
[2],
3218 &flags
, &dlen
, &doff
))
3221 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:pget",
3223 &keyobj
, &flags
, &dlen
, &doff
))
3226 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:pget",
3227 kwnames
, &keyobj
, &dataobj
,
3228 &flags
, &dlen
, &doff
))
3235 CHECK_CURSOR_NOT_CLOSED(self
);
3237 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3239 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
3240 (!add_partial_dbt(&data
, dlen
, doff
)) ) {
3245 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3246 data
.flags
= DB_DBT_MALLOC
;
3247 if (!(key
.flags
& DB_DBT_REALLOC
)) {
3248 key
.flags
|= DB_DBT_MALLOC
;
3253 pkey
.flags
= DB_DBT_MALLOC
;
3255 MYDB_BEGIN_ALLOW_THREADS
;
3256 err
= self
->dbc
->c_pget(self
->dbc
, &key
, &pkey
, &data
, flags
);
3257 MYDB_END_ALLOW_THREADS
;
3259 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3260 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3264 else if (makeDBError(err
)) {
3270 dataObj
= PyString_FromStringAndSize(data
.data
, data
.size
);
3272 if (self
->mydb
->primaryDBType
== DB_RECNO
||
3273 self
->mydb
->primaryDBType
== DB_QUEUE
)
3274 pkeyObj
= PyInt_FromLong(*(int *)pkey
.data
);
3276 pkeyObj
= PyString_FromStringAndSize(pkey
.data
, pkey
.size
);
3278 if (key
.data
&& key
.size
) /* return key, pkey and data */
3281 int type
= _DB_get_type(self
->mydb
);
3282 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
3283 keyObj
= PyInt_FromLong(*(int *)key
.data
);
3285 keyObj
= PyString_FromStringAndSize(key
.data
, key
.size
);
3286 #if (PY_VERSION_HEX >= 0x02040000)
3287 retval
= PyTuple_Pack(3, keyObj
, pkeyObj
, dataObj
);
3289 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
3294 else /* return just the pkey and data */
3296 #if (PY_VERSION_HEX >= 0x02040000)
3297 retval
= PyTuple_Pack(2, pkeyObj
, dataObj
);
3299 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
3307 /* the only time REALLOC should be set is if we used an integer
3308 * key that make_key_dbt malloc'd for us. always free these. */
3309 if (key
.flags
& DB_DBT_REALLOC
) {
3318 DBC_get_recno(DBCursorObject
* self
, PyObject
* args
)
3325 if (!PyArg_ParseTuple(args
, ":get_recno"))
3328 CHECK_CURSOR_NOT_CLOSED(self
);
3332 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3333 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3334 data
.flags
= DB_DBT_MALLOC
;
3335 key
.flags
= DB_DBT_MALLOC
;
3338 MYDB_BEGIN_ALLOW_THREADS
;
3339 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, DB_GET_RECNO
);
3340 MYDB_END_ALLOW_THREADS
;
3343 recno
= *((db_recno_t
*)data
.data
);
3346 return PyInt_FromLong(recno
);
3351 DBC_last(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3353 return _DBCursor_get(self
,DB_LAST
,args
,kwargs
,"|iii:last");
3358 DBC_next(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3360 return _DBCursor_get(self
,DB_NEXT
,args
,kwargs
,"|iii:next");
3365 DBC_prev(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3367 return _DBCursor_get(self
,DB_PREV
,args
,kwargs
,"|iii:prev");
3372 DBC_put(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3375 PyObject
* keyobj
, *dataobj
;
3377 static char* kwnames
[] = { "key", "data", "flags", "dlen", "doff",
3382 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iii:put", kwnames
,
3383 &keyobj
, &dataobj
, &flags
, &dlen
, &doff
))
3386 CHECK_CURSOR_NOT_CLOSED(self
);
3388 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3390 if (!make_dbt(dataobj
, &data
) ||
3391 !add_partial_dbt(&data
, dlen
, doff
) )
3397 MYDB_BEGIN_ALLOW_THREADS
;
3398 err
= self
->dbc
->c_put(self
->dbc
, &key
, &data
, flags
);
3399 MYDB_END_ALLOW_THREADS
;
3402 self
->mydb
->haveStat
= 0;
3408 DBC_set(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3412 PyObject
* retval
, *keyobj
;
3413 static char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
3417 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set", kwnames
,
3418 &keyobj
, &flags
, &dlen
, &doff
))
3421 CHECK_CURSOR_NOT_CLOSED(self
);
3423 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3427 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3428 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3429 data
.flags
= DB_DBT_MALLOC
;
3431 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3436 MYDB_BEGIN_ALLOW_THREADS
;
3437 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET
);
3438 MYDB_END_ALLOW_THREADS
;
3439 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3440 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3444 else if (makeDBError(err
)) {
3448 switch (_DB_get_type(self
->mydb
)) {
3455 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3456 data
.data
, data
.size
);
3460 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3461 data
.data
, data
.size
);
3467 /* the only time REALLOC should be set is if we used an integer
3468 * key that make_key_dbt malloc'd for us. always free these. */
3469 if (key
.flags
& DB_DBT_REALLOC
) {
3478 DBC_set_range(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3482 PyObject
* retval
, *keyobj
;
3483 static char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
3487 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set_range", kwnames
,
3488 &keyobj
, &flags
, &dlen
, &doff
))
3491 CHECK_CURSOR_NOT_CLOSED(self
);
3493 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3497 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3501 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3502 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3503 data
.flags
|= DB_DBT_MALLOC
;
3504 /* only BTREE databases will return anything in the key */
3505 if (!(key
.flags
& DB_DBT_REALLOC
) && _DB_get_type(self
->mydb
) == DB_BTREE
) {
3506 key
.flags
|= DB_DBT_MALLOC
;
3509 MYDB_BEGIN_ALLOW_THREADS
;
3510 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RANGE
);
3511 MYDB_END_ALLOW_THREADS
;
3512 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3513 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3517 else if (makeDBError(err
)) {
3521 switch (_DB_get_type(self
->mydb
)) {
3528 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3529 data
.data
, data
.size
);
3533 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3534 data
.data
, data
.size
);
3540 /* the only time REALLOC should be set is if we used an integer
3541 * key that make_key_dbt malloc'd for us. always free these. */
3542 if (key
.flags
& DB_DBT_REALLOC
) {
3550 _DBC_get_set_both(DBCursorObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
,
3551 int flags
, unsigned int returnsNone
)
3557 /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
3558 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3560 if (!make_dbt(dataobj
, &data
)) {
3565 MYDB_BEGIN_ALLOW_THREADS
;
3566 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_GET_BOTH
);
3567 MYDB_END_ALLOW_THREADS
;
3568 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && returnsNone
) {
3572 else if (makeDBError(err
)) {
3576 switch (_DB_get_type(self
->mydb
)) {
3583 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3584 data
.data
, data
.size
);
3588 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3589 data
.data
, data
.size
);
3599 DBC_get_both(DBCursorObject
* self
, PyObject
* args
)
3602 PyObject
*keyobj
, *dataobj
;
3604 if (!PyArg_ParseTuple(args
, "OO|i:get_both", &keyobj
, &dataobj
, &flags
))
3607 /* if the cursor is closed, self->mydb may be invalid */
3608 CHECK_CURSOR_NOT_CLOSED(self
);
3610 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3611 self
->mydb
->moduleFlags
.getReturnsNone
);
3614 /* Return size of entry */
3616 DBC_get_current_size(DBCursorObject
* self
, PyObject
* args
)
3618 int err
, flags
=DB_CURRENT
;
3619 PyObject
* retval
= NULL
;
3622 if (!PyArg_ParseTuple(args
, ":get_current_size"))
3624 CHECK_CURSOR_NOT_CLOSED(self
);
3628 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
3629 getting the record size. */
3630 data
.flags
= DB_DBT_USERMEM
;
3632 MYDB_BEGIN_ALLOW_THREADS
;
3633 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
3634 MYDB_END_ALLOW_THREADS
;
3635 if (err
== DB_BUFFER_SMALL
|| !err
) {
3636 /* DB_BUFFER_SMALL means positive size, !err means zero length value */
3637 retval
= PyInt_FromLong((long)data
.size
);
3648 DBC_set_both(DBCursorObject
* self
, PyObject
* args
)
3651 PyObject
*keyobj
, *dataobj
;
3653 if (!PyArg_ParseTuple(args
, "OO|i:set_both", &keyobj
, &dataobj
, &flags
))
3656 /* if the cursor is closed, self->mydb may be invalid */
3657 CHECK_CURSOR_NOT_CLOSED(self
);
3659 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3660 self
->mydb
->moduleFlags
.cursorSetReturnsNone
);
3665 DBC_set_recno(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3667 int err
, irecno
, flags
=0;
3673 static char* kwnames
[] = { "recno","flags", "dlen", "doff", NULL
};
3675 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|iii:set_recno", kwnames
,
3676 &irecno
, &flags
, &dlen
, &doff
))
3679 CHECK_CURSOR_NOT_CLOSED(self
);
3682 recno
= (db_recno_t
) irecno
;
3683 /* use allocated space so DB will be able to realloc room for the real
3685 key
.data
= malloc(sizeof(db_recno_t
));
3686 if (key
.data
== NULL
) {
3687 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
3690 key
.size
= sizeof(db_recno_t
);
3691 key
.ulen
= key
.size
;
3692 memcpy(key
.data
, &recno
, sizeof(db_recno_t
));
3693 key
.flags
= DB_DBT_REALLOC
;
3696 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3697 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3698 data
.flags
= DB_DBT_MALLOC
;
3700 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3705 MYDB_BEGIN_ALLOW_THREADS
;
3706 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RECNO
);
3707 MYDB_END_ALLOW_THREADS
;
3708 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3709 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3713 else if (makeDBError(err
)) {
3716 else { /* Can only be used for BTrees, so no need to return int key */
3717 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3718 data
.data
, data
.size
);
3728 DBC_consume(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3730 return _DBCursor_get(self
,DB_CONSUME
,args
,kwargs
,"|iii:consume");
3735 DBC_next_dup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3737 return _DBCursor_get(self
,DB_NEXT_DUP
,args
,kwargs
,"|iii:next_dup");
3742 DBC_next_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3744 return _DBCursor_get(self
,DB_NEXT_NODUP
,args
,kwargs
,"|iii:next_nodup");
3749 DBC_prev_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3751 return _DBCursor_get(self
,DB_PREV_NODUP
,args
,kwargs
,"|iii:prev_nodup");
3756 DBC_join_item(DBCursorObject
* self
, PyObject
* args
)
3762 if (!PyArg_ParseTuple(args
, "|i:join_item", &flags
))
3765 CHECK_CURSOR_NOT_CLOSED(self
);
3769 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3770 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3771 key
.flags
= DB_DBT_MALLOC
;
3774 MYDB_BEGIN_ALLOW_THREADS
;
3775 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
| DB_JOIN_ITEM
);
3776 MYDB_END_ALLOW_THREADS
;
3777 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3778 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3782 else if (makeDBError(err
)) {
3786 retval
= Py_BuildValue("s#", key
.data
, key
.size
);
3795 /* --------------------------------------------------------------------- */
3800 DBEnv_close(DBEnvObject
* self
, PyObject
* args
)
3804 if (!PyArg_ParseTuple(args
, "|i:close", &flags
))
3806 if (!self
->closed
) { /* Don't close more than once */
3807 MYDB_BEGIN_ALLOW_THREADS
;
3808 err
= self
->db_env
->close(self
->db_env
, flags
);
3809 MYDB_END_ALLOW_THREADS
;
3810 /* after calling DBEnv->close, regardless of error, this DBEnv
3811 * may not be accessed again (BerkeleyDB docs). */
3813 self
->db_env
= NULL
;
3821 DBEnv_open(DBEnvObject
* self
, PyObject
* args
)
3823 int err
, flags
=0, mode
=0660;
3826 if (!PyArg_ParseTuple(args
, "z|ii:open", &db_home
, &flags
, &mode
))
3829 CHECK_ENV_NOT_CLOSED(self
);
3831 MYDB_BEGIN_ALLOW_THREADS
;
3832 err
= self
->db_env
->open(self
->db_env
, db_home
, flags
, mode
);
3833 MYDB_END_ALLOW_THREADS
;
3836 self
->flags
= flags
;
3842 DBEnv_remove(DBEnvObject
* self
, PyObject
* args
)
3847 if (!PyArg_ParseTuple(args
, "s|i:remove", &db_home
, &flags
))
3849 CHECK_ENV_NOT_CLOSED(self
);
3850 MYDB_BEGIN_ALLOW_THREADS
;
3851 err
= self
->db_env
->remove(self
->db_env
, db_home
, flags
);
3852 MYDB_END_ALLOW_THREADS
;
3859 DBEnv_dbremove(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3864 char *database
= NULL
;
3865 PyObject
*txnobj
= NULL
;
3867 static char* kwnames
[] = { "file", "database", "txn", "flags",
3870 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ss|Oi:dbremove", kwnames
,
3871 &file
, &database
, &txnobj
, &flags
)) {
3874 if (!checkTxnObj(txnobj
, &txn
)) {
3877 CHECK_ENV_NOT_CLOSED(self
);
3878 MYDB_BEGIN_ALLOW_THREADS
;
3879 err
= self
->db_env
->dbremove(self
->db_env
, txn
, file
, database
, flags
);
3880 MYDB_END_ALLOW_THREADS
;
3886 DBEnv_dbrename(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3891 char *database
= NULL
;
3892 char *newname
= NULL
;
3893 PyObject
*txnobj
= NULL
;
3895 static char* kwnames
[] = { "file", "database", "newname", "txn",
3898 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "sss|Oi:dbrename", kwnames
,
3899 &file
, &database
, &newname
, &txnobj
, &flags
)) {
3902 if (!checkTxnObj(txnobj
, &txn
)) {
3905 CHECK_ENV_NOT_CLOSED(self
);
3906 MYDB_BEGIN_ALLOW_THREADS
;
3907 err
= self
->db_env
->dbrename(self
->db_env
, txn
, file
, database
, newname
,
3909 MYDB_END_ALLOW_THREADS
;
3915 DBEnv_set_encrypt(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3919 char *passwd
= NULL
;
3920 static char* kwnames
[] = { "passwd", "flags", NULL
};
3922 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
3927 MYDB_BEGIN_ALLOW_THREADS
;
3928 err
= self
->db_env
->set_encrypt(self
->db_env
, passwd
, flags
);
3929 MYDB_END_ALLOW_THREADS
;
3934 #endif /* DBVER >= 41 */
3938 DBEnv_set_timeout(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3942 u_int32_t timeout
= 0;
3943 static char* kwnames
[] = { "timeout", "flags", NULL
};
3945 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ii:set_timeout", kwnames
,
3946 &timeout
, &flags
)) {
3950 MYDB_BEGIN_ALLOW_THREADS
;
3951 err
= self
->db_env
->set_timeout(self
->db_env
, (db_timeout_t
)timeout
, flags
);
3952 MYDB_END_ALLOW_THREADS
;
3957 #endif /* DBVER >= 40 */
3960 DBEnv_set_shm_key(DBEnvObject
* self
, PyObject
* args
)
3965 if (!PyArg_ParseTuple(args
, "l:set_shm_key", &shm_key
))
3967 CHECK_ENV_NOT_CLOSED(self
);
3969 err
= self
->db_env
->set_shm_key(self
->db_env
, shm_key
);
3975 DBEnv_set_cachesize(DBEnvObject
* self
, PyObject
* args
)
3977 int err
, gbytes
=0, bytes
=0, ncache
=0;
3979 if (!PyArg_ParseTuple(args
, "ii|i:set_cachesize",
3980 &gbytes
, &bytes
, &ncache
))
3982 CHECK_ENV_NOT_CLOSED(self
);
3984 MYDB_BEGIN_ALLOW_THREADS
;
3985 err
= self
->db_env
->set_cachesize(self
->db_env
, gbytes
, bytes
, ncache
);
3986 MYDB_END_ALLOW_THREADS
;
3994 DBEnv_set_flags(DBEnvObject
* self
, PyObject
* args
)
3996 int err
, flags
=0, onoff
=0;
3998 if (!PyArg_ParseTuple(args
, "ii:set_flags",
4001 CHECK_ENV_NOT_CLOSED(self
);
4003 MYDB_BEGIN_ALLOW_THREADS
;
4004 err
= self
->db_env
->set_flags(self
->db_env
, flags
, onoff
);
4005 MYDB_END_ALLOW_THREADS
;
4013 DBEnv_set_data_dir(DBEnvObject
* self
, PyObject
* args
)
4018 if (!PyArg_ParseTuple(args
, "s:set_data_dir", &dir
))
4020 CHECK_ENV_NOT_CLOSED(self
);
4022 MYDB_BEGIN_ALLOW_THREADS
;
4023 err
= self
->db_env
->set_data_dir(self
->db_env
, dir
);
4024 MYDB_END_ALLOW_THREADS
;
4031 DBEnv_set_lg_bsize(DBEnvObject
* self
, PyObject
* args
)
4035 if (!PyArg_ParseTuple(args
, "i:set_lg_bsize", &lg_bsize
))
4037 CHECK_ENV_NOT_CLOSED(self
);
4039 MYDB_BEGIN_ALLOW_THREADS
;
4040 err
= self
->db_env
->set_lg_bsize(self
->db_env
, lg_bsize
);
4041 MYDB_END_ALLOW_THREADS
;
4048 DBEnv_set_lg_dir(DBEnvObject
* self
, PyObject
* args
)
4053 if (!PyArg_ParseTuple(args
, "s:set_lg_dir", &dir
))
4055 CHECK_ENV_NOT_CLOSED(self
);
4057 MYDB_BEGIN_ALLOW_THREADS
;
4058 err
= self
->db_env
->set_lg_dir(self
->db_env
, dir
);
4059 MYDB_END_ALLOW_THREADS
;
4065 DBEnv_set_lg_max(DBEnvObject
* self
, PyObject
* args
)
4069 if (!PyArg_ParseTuple(args
, "i:set_lg_max", &lg_max
))
4071 CHECK_ENV_NOT_CLOSED(self
);
4073 MYDB_BEGIN_ALLOW_THREADS
;
4074 err
= self
->db_env
->set_lg_max(self
->db_env
, lg_max
);
4075 MYDB_END_ALLOW_THREADS
;
4083 DBEnv_set_lg_regionmax(DBEnvObject
* self
, PyObject
* args
)
4087 if (!PyArg_ParseTuple(args
, "i:set_lg_regionmax", &lg_max
))
4089 CHECK_ENV_NOT_CLOSED(self
);
4091 MYDB_BEGIN_ALLOW_THREADS
;
4092 err
= self
->db_env
->set_lg_regionmax(self
->db_env
, lg_max
);
4093 MYDB_END_ALLOW_THREADS
;
4101 DBEnv_set_lk_detect(DBEnvObject
* self
, PyObject
* args
)
4105 if (!PyArg_ParseTuple(args
, "i:set_lk_detect", &lk_detect
))
4107 CHECK_ENV_NOT_CLOSED(self
);
4109 MYDB_BEGIN_ALLOW_THREADS
;
4110 err
= self
->db_env
->set_lk_detect(self
->db_env
, lk_detect
);
4111 MYDB_END_ALLOW_THREADS
;
4118 DBEnv_set_lk_max(DBEnvObject
* self
, PyObject
* args
)
4122 if (!PyArg_ParseTuple(args
, "i:set_lk_max", &max
))
4124 CHECK_ENV_NOT_CLOSED(self
);
4126 MYDB_BEGIN_ALLOW_THREADS
;
4127 err
= self
->db_env
->set_lk_max(self
->db_env
, max
);
4128 MYDB_END_ALLOW_THREADS
;
4137 DBEnv_set_lk_max_locks(DBEnvObject
* self
, PyObject
* args
)
4141 if (!PyArg_ParseTuple(args
, "i:set_lk_max_locks", &max
))
4143 CHECK_ENV_NOT_CLOSED(self
);
4145 MYDB_BEGIN_ALLOW_THREADS
;
4146 err
= self
->db_env
->set_lk_max_locks(self
->db_env
, max
);
4147 MYDB_END_ALLOW_THREADS
;
4154 DBEnv_set_lk_max_lockers(DBEnvObject
* self
, PyObject
* args
)
4158 if (!PyArg_ParseTuple(args
, "i:set_lk_max_lockers", &max
))
4160 CHECK_ENV_NOT_CLOSED(self
);
4162 MYDB_BEGIN_ALLOW_THREADS
;
4163 err
= self
->db_env
->set_lk_max_lockers(self
->db_env
, max
);
4164 MYDB_END_ALLOW_THREADS
;
4171 DBEnv_set_lk_max_objects(DBEnvObject
* self
, PyObject
* args
)
4175 if (!PyArg_ParseTuple(args
, "i:set_lk_max_objects", &max
))
4177 CHECK_ENV_NOT_CLOSED(self
);
4179 MYDB_BEGIN_ALLOW_THREADS
;
4180 err
= self
->db_env
->set_lk_max_objects(self
->db_env
, max
);
4181 MYDB_END_ALLOW_THREADS
;
4190 DBEnv_set_mp_mmapsize(DBEnvObject
* self
, PyObject
* args
)
4192 int err
, mp_mmapsize
;
4194 if (!PyArg_ParseTuple(args
, "i:set_mp_mmapsize", &mp_mmapsize
))
4196 CHECK_ENV_NOT_CLOSED(self
);
4198 MYDB_BEGIN_ALLOW_THREADS
;
4199 err
= self
->db_env
->set_mp_mmapsize(self
->db_env
, mp_mmapsize
);
4200 MYDB_END_ALLOW_THREADS
;
4207 DBEnv_set_tmp_dir(DBEnvObject
* self
, PyObject
* args
)
4212 if (!PyArg_ParseTuple(args
, "s:set_tmp_dir", &dir
))
4214 CHECK_ENV_NOT_CLOSED(self
);
4216 MYDB_BEGIN_ALLOW_THREADS
;
4217 err
= self
->db_env
->set_tmp_dir(self
->db_env
, dir
);
4218 MYDB_END_ALLOW_THREADS
;
4225 DBEnv_txn_begin(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4228 PyObject
* txnobj
= NULL
;
4230 static char* kwnames
[] = { "parent", "flags", NULL
};
4232 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:txn_begin", kwnames
,
4236 if (!checkTxnObj(txnobj
, &txn
))
4238 CHECK_ENV_NOT_CLOSED(self
);
4240 return (PyObject
*)newDBTxnObject(self
, txn
, flags
);
4245 DBEnv_txn_checkpoint(DBEnvObject
* self
, PyObject
* args
)
4247 int err
, kbyte
=0, min
=0, flags
=0;
4249 if (!PyArg_ParseTuple(args
, "|iii:txn_checkpoint", &kbyte
, &min
, &flags
))
4251 CHECK_ENV_NOT_CLOSED(self
);
4253 MYDB_BEGIN_ALLOW_THREADS
;
4255 err
= self
->db_env
->txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
4257 err
= txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
4259 MYDB_END_ALLOW_THREADS
;
4266 DBEnv_set_tx_max(DBEnvObject
* self
, PyObject
* args
)
4270 if (!PyArg_ParseTuple(args
, "i:set_tx_max", &max
))
4272 CHECK_ENV_NOT_CLOSED(self
);
4274 err
= self
->db_env
->set_tx_max(self
->db_env
, max
);
4281 DBEnv_set_tx_timestamp(DBEnvObject
* self
, PyObject
* args
)
4287 if (!PyArg_ParseTuple(args
, "l:set_tx_timestamp", &stamp
))
4289 CHECK_ENV_NOT_CLOSED(self
);
4290 timestamp
= (time_t)stamp
;
4291 err
= self
->db_env
->set_tx_timestamp(self
->db_env
, ×tamp
);
4298 DBEnv_lock_detect(DBEnvObject
* self
, PyObject
* args
)
4300 int err
, atype
, flags
=0;
4303 if (!PyArg_ParseTuple(args
, "i|i:lock_detect", &atype
, &flags
))
4305 CHECK_ENV_NOT_CLOSED(self
);
4307 MYDB_BEGIN_ALLOW_THREADS
;
4309 err
= self
->db_env
->lock_detect(self
->db_env
, flags
, atype
, &aborted
);
4311 err
= lock_detect(self
->db_env
, flags
, atype
, &aborted
);
4313 MYDB_END_ALLOW_THREADS
;
4315 return PyInt_FromLong(aborted
);
4320 DBEnv_lock_get(DBEnvObject
* self
, PyObject
* args
)
4323 int locker
, lock_mode
;
4327 if (!PyArg_ParseTuple(args
, "iOi|i:lock_get", &locker
, &objobj
, &lock_mode
, &flags
))
4331 if (!make_dbt(objobj
, &obj
))
4334 return (PyObject
*)newDBLockObject(self
, locker
, &obj
, lock_mode
, flags
);
4339 DBEnv_lock_id(DBEnvObject
* self
, PyObject
* args
)
4344 if (!PyArg_ParseTuple(args
, ":lock_id"))
4347 CHECK_ENV_NOT_CLOSED(self
);
4348 MYDB_BEGIN_ALLOW_THREADS
;
4350 err
= self
->db_env
->lock_id(self
->db_env
, &theID
);
4352 err
= lock_id(self
->db_env
, &theID
);
4354 MYDB_END_ALLOW_THREADS
;
4357 return PyInt_FromLong((long)theID
);
4362 DBEnv_lock_put(DBEnvObject
* self
, PyObject
* args
)
4365 DBLockObject
* dblockobj
;
4367 if (!PyArg_ParseTuple(args
, "O!:lock_put", &DBLock_Type
, &dblockobj
))
4370 CHECK_ENV_NOT_CLOSED(self
);
4371 MYDB_BEGIN_ALLOW_THREADS
;
4373 err
= self
->db_env
->lock_put(self
->db_env
, &dblockobj
->lock
);
4375 err
= lock_put(self
->db_env
, &dblockobj
->lock
);
4377 MYDB_END_ALLOW_THREADS
;
4384 DBEnv_lsn_reset(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4388 u_int32_t flags
= 0;
4389 static char* kwnames
[] = { "file", "flags", NULL
};
4391 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|i:lsn_reset", kwnames
,
4394 CHECK_ENV_NOT_CLOSED(self
);
4396 MYDB_BEGIN_ALLOW_THREADS
;
4397 err
= self
->db_env
->lsn_reset(self
->db_env
, file
, flags
);
4398 MYDB_END_ALLOW_THREADS
;
4402 #endif /* DBVER >= 4.4 */
4406 DBEnv_log_stat(DBEnvObject
* self
, PyObject
* args
)
4409 DB_LOG_STAT
* statp
= NULL
;
4411 u_int32_t flags
= 0;
4413 if (!PyArg_ParseTuple(args
, "|i:log_stat", &flags
))
4415 CHECK_ENV_NOT_CLOSED(self
);
4417 MYDB_BEGIN_ALLOW_THREADS
;
4418 err
= self
->db_env
->log_stat(self
->db_env
, &statp
, flags
);
4419 MYDB_END_ALLOW_THREADS
;
4422 /* Turn the stat structure into a dictionary */
4430 #define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
4433 MAKE_ENTRY(version
);
4435 MAKE_ENTRY(lg_bsize
);
4437 MAKE_ENTRY(lg_size
);
4443 MAKE_ENTRY(w_mbytes
);
4444 MAKE_ENTRY(w_bytes
);
4445 MAKE_ENTRY(wc_mbytes
);
4446 MAKE_ENTRY(wc_bytes
);
4448 MAKE_ENTRY(wcount_fill
);
4453 MAKE_ENTRY(cur_file
);
4454 MAKE_ENTRY(cur_offset
);
4455 MAKE_ENTRY(disk_file
);
4456 MAKE_ENTRY(disk_offset
);
4457 MAKE_ENTRY(maxcommitperflush
);
4458 MAKE_ENTRY(mincommitperflush
);
4459 MAKE_ENTRY(regsize
);
4460 MAKE_ENTRY(region_wait
);
4461 MAKE_ENTRY(region_nowait
);
4466 } /* DBEnv_log_stat */
4467 #endif /* DBVER >= 4.0 for log_stat method */
4471 DBEnv_lock_stat(DBEnvObject
* self
, PyObject
* args
)
4476 u_int32_t flags
= 0;
4478 if (!PyArg_ParseTuple(args
, "|i:lock_stat", &flags
))
4480 CHECK_ENV_NOT_CLOSED(self
);
4482 MYDB_BEGIN_ALLOW_THREADS
;
4484 err
= self
->db_env
->lock_stat(self
->db_env
, &sp
, flags
);
4487 err
= lock_stat(self
->db_env
, &sp
);
4489 err
= lock_stat(self
->db_env
, &sp
, NULL
);
4492 MYDB_END_ALLOW_THREADS
;
4495 /* Turn the stat structure into a dictionary */
4502 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4509 MAKE_ENTRY(maxlocks
);
4510 MAKE_ENTRY(maxlockers
);
4511 MAKE_ENTRY(maxobjects
);
4513 MAKE_ENTRY(maxnlocks
);
4515 MAKE_ENTRY(nlockers
);
4516 MAKE_ENTRY(maxnlockers
);
4518 MAKE_ENTRY(nobjects
);
4519 MAKE_ENTRY(maxnobjects
);
4521 MAKE_ENTRY(nrequests
);
4522 MAKE_ENTRY(nreleases
);
4524 MAKE_ENTRY(nnowaits
); /* these were renamed in 4.4 */
4525 MAKE_ENTRY(nconflicts
);
4527 MAKE_ENTRY(lock_nowait
);
4528 MAKE_ENTRY(lock_wait
);
4530 MAKE_ENTRY(ndeadlocks
);
4531 MAKE_ENTRY(regsize
);
4532 MAKE_ENTRY(region_wait
);
4533 MAKE_ENTRY(region_nowait
);
4542 DBEnv_log_archive(DBEnvObject
* self
, PyObject
* args
)
4546 char **log_list
= NULL
;
4548 PyObject
* item
= NULL
;
4550 if (!PyArg_ParseTuple(args
, "|i:log_archive", &flags
))
4553 CHECK_ENV_NOT_CLOSED(self
);
4554 MYDB_BEGIN_ALLOW_THREADS
;
4556 err
= self
->db_env
->log_archive(self
->db_env
, &log_list
, flags
);
4558 err
= log_archive(self
->db_env
, &log_list
, flags
);
4560 err
= log_archive(self
->db_env
, &log_list
, flags
, NULL
);
4562 MYDB_END_ALLOW_THREADS
;
4565 list
= PyList_New(0);
4573 char **log_list_start
;
4574 for (log_list_start
= log_list
; *log_list
!= NULL
; ++log_list
) {
4575 item
= PyString_FromString (*log_list
);
4581 PyList_Append(list
, item
);
4584 free(log_list_start
);
4591 DBEnv_txn_stat(DBEnvObject
* self
, PyObject
* args
)
4598 if (!PyArg_ParseTuple(args
, "|i:txn_stat", &flags
))
4600 CHECK_ENV_NOT_CLOSED(self
);
4602 MYDB_BEGIN_ALLOW_THREADS
;
4604 err
= self
->db_env
->txn_stat(self
->db_env
, &sp
, flags
);
4606 err
= txn_stat(self
->db_env
, &sp
);
4608 err
= txn_stat(self
->db_env
, &sp
, NULL
);
4610 MYDB_END_ALLOW_THREADS
;
4613 /* Turn the stat structure into a dictionary */
4620 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4622 MAKE_ENTRY(time_ckp
);
4623 MAKE_ENTRY(last_txnid
);
4624 MAKE_ENTRY(maxtxns
);
4625 MAKE_ENTRY(nactive
);
4626 MAKE_ENTRY(maxnactive
);
4627 MAKE_ENTRY(nbegins
);
4628 MAKE_ENTRY(naborts
);
4629 MAKE_ENTRY(ncommits
);
4630 MAKE_ENTRY(regsize
);
4631 MAKE_ENTRY(region_wait
);
4632 MAKE_ENTRY(region_nowait
);
4641 DBEnv_set_get_returns_none(DBEnvObject
* self
, PyObject
* args
)
4646 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
4648 CHECK_ENV_NOT_CLOSED(self
);
4650 if (self
->moduleFlags
.getReturnsNone
)
4652 if (self
->moduleFlags
.cursorSetReturnsNone
)
4654 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
4655 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
4656 return PyInt_FromLong(oldValue
);
4660 /* --------------------------------------------------------------------- */
4665 DBTxn_commit(DBTxnObject
* self
, PyObject
* args
)
4670 if (!PyArg_ParseTuple(args
, "|i:commit", &flags
))
4674 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4675 "after txn_commit or txn_abort");
4676 PyErr_SetObject(DBError
, t
);
4681 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
4682 MYDB_BEGIN_ALLOW_THREADS
;
4684 err
= txn
->commit(txn
, flags
);
4686 err
= txn_commit(txn
, flags
);
4688 MYDB_END_ALLOW_THREADS
;
4694 DBTxn_prepare(DBTxnObject
* self
, PyObject
* args
)
4701 if (!PyArg_ParseTuple(args
, "s#:prepare", &gid
, &gid_size
))
4704 if (gid_size
!= DB_XIDDATASIZE
) {
4705 PyErr_SetString(PyExc_TypeError
,
4706 "gid must be DB_XIDDATASIZE bytes long");
4711 PyObject
*t
= Py_BuildValue("(is)", 0,"DBTxn must not be used "
4712 "after txn_commit or txn_abort");
4713 PyErr_SetObject(DBError
, t
);
4717 MYDB_BEGIN_ALLOW_THREADS
;
4719 err
= self
->txn
->prepare(self
->txn
, (u_int8_t
*)gid
);
4721 err
= txn_prepare(self
->txn
, (u_int8_t
*)gid
);
4723 MYDB_END_ALLOW_THREADS
;
4729 if (!PyArg_ParseTuple(args
, ":prepare"))
4733 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4734 "after txn_commit or txn_abort");
4735 PyErr_SetObject(DBError
, t
);
4739 MYDB_BEGIN_ALLOW_THREADS
;
4740 err
= txn_prepare(self
->txn
);
4741 MYDB_END_ALLOW_THREADS
;
4749 DBTxn_abort(DBTxnObject
* self
, PyObject
* args
)
4754 if (!PyArg_ParseTuple(args
, ":abort"))
4758 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4759 "after txn_commit or txn_abort");
4760 PyErr_SetObject(DBError
, t
);
4765 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
4766 MYDB_BEGIN_ALLOW_THREADS
;
4768 err
= txn
->abort(txn
);
4770 err
= txn_abort(txn
);
4772 MYDB_END_ALLOW_THREADS
;
4779 DBTxn_id(DBTxnObject
* self
, PyObject
* args
)
4783 if (!PyArg_ParseTuple(args
, ":id"))
4787 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4788 "after txn_commit or txn_abort");
4789 PyErr_SetObject(DBError
, t
);
4793 MYDB_BEGIN_ALLOW_THREADS
;
4795 id
= self
->txn
->id(self
->txn
);
4797 id
= txn_id(self
->txn
);
4799 MYDB_END_ALLOW_THREADS
;
4800 return PyInt_FromLong(id
);
4804 /* --------------------------------------------------------------------- */
4805 /* DBSequence methods */
4809 DBSequence_close(DBSequenceObject
* self
, PyObject
* args
)
4812 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
4814 CHECK_SEQUENCE_NOT_CLOSED(self
)
4816 MYDB_BEGIN_ALLOW_THREADS
4817 err
= self
->sequence
->close(self
->sequence
, flags
);
4818 self
->sequence
= NULL
;
4819 MYDB_END_ALLOW_THREADS
4827 DBSequence_get(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4832 PyObject
*txnobj
= NULL
;
4834 static char* kwnames
[] = {"delta", "txn", "flags", NULL
};
4835 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iOi:get", kwnames
, &delta
, &txnobj
, &flags
))
4837 CHECK_SEQUENCE_NOT_CLOSED(self
)
4839 if (!checkTxnObj(txnobj
, &txn
))
4842 MYDB_BEGIN_ALLOW_THREADS
4843 err
= self
->sequence
->get(self
->sequence
, txn
, delta
, &value
, flags
);
4844 MYDB_END_ALLOW_THREADS
4847 return PyLong_FromLongLong(value
);
4852 DBSequence_get_dbp(DBSequenceObject
* self
, PyObject
* args
)
4854 if (!PyArg_ParseTuple(args
,":get_dbp"))
4856 CHECK_SEQUENCE_NOT_CLOSED(self
)
4857 Py_INCREF(self
->mydb
);
4858 return (PyObject
* )self
->mydb
;
4862 DBSequence_get_key(DBSequenceObject
* self
, PyObject
* args
)
4866 CHECK_SEQUENCE_NOT_CLOSED(self
)
4867 MYDB_BEGIN_ALLOW_THREADS
4868 err
= self
->sequence
->get_key(self
->sequence
, &key
);
4869 MYDB_END_ALLOW_THREADS
4873 return PyString_FromStringAndSize(key
.data
, key
.size
);
4877 DBSequence_init_value(DBSequenceObject
* self
, PyObject
* args
)
4881 if (!PyArg_ParseTuple(args
,"L:init_value", &value
))
4883 CHECK_SEQUENCE_NOT_CLOSED(self
)
4885 MYDB_BEGIN_ALLOW_THREADS
4886 err
= self
->sequence
->initial_value(self
->sequence
, value
);
4887 MYDB_END_ALLOW_THREADS
4895 DBSequence_open(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4899 PyObject
*txnobj
= NULL
;
4903 static char* kwnames
[] = {"key", "txn", "flags", NULL
};
4904 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:open", kwnames
, &keyobj
, &txnobj
, &flags
))
4907 if (!checkTxnObj(txnobj
, &txn
))
4910 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
4913 MYDB_BEGIN_ALLOW_THREADS
4914 err
= self
->sequence
->open(self
->sequence
, txn
, &key
, flags
);
4915 MYDB_END_ALLOW_THREADS
4924 DBSequence_remove(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4927 PyObject
*txnobj
= NULL
;
4930 static char* kwnames
[] = {"txn", "flags", NULL
};
4931 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:remove", kwnames
, &txnobj
, &flags
))
4934 if (!checkTxnObj(txnobj
, &txn
))
4937 CHECK_SEQUENCE_NOT_CLOSED(self
)
4939 MYDB_BEGIN_ALLOW_THREADS
4940 err
= self
->sequence
->remove(self
->sequence
, txn
, flags
);
4941 MYDB_END_ALLOW_THREADS
4948 DBSequence_set_cachesize(DBSequenceObject
* self
, PyObject
* args
)
4951 if (!PyArg_ParseTuple(args
,"i:set_cachesize", &size
))
4953 CHECK_SEQUENCE_NOT_CLOSED(self
)
4955 MYDB_BEGIN_ALLOW_THREADS
4956 err
= self
->sequence
->set_cachesize(self
->sequence
, size
);
4957 MYDB_END_ALLOW_THREADS
4964 DBSequence_get_cachesize(DBSequenceObject
* self
, PyObject
* args
)
4967 if (!PyArg_ParseTuple(args
,":get_cachesize"))
4969 CHECK_SEQUENCE_NOT_CLOSED(self
)
4971 MYDB_BEGIN_ALLOW_THREADS
4972 err
= self
->sequence
->get_cachesize(self
->sequence
, &size
);
4973 MYDB_END_ALLOW_THREADS
4976 return PyInt_FromLong(size
);
4980 DBSequence_set_flags(DBSequenceObject
* self
, PyObject
* args
)
4983 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
4985 CHECK_SEQUENCE_NOT_CLOSED(self
)
4987 MYDB_BEGIN_ALLOW_THREADS
4988 err
= self
->sequence
->set_flags(self
->sequence
, flags
);
4989 MYDB_END_ALLOW_THREADS
4997 DBSequence_get_flags(DBSequenceObject
* self
, PyObject
* args
)
5001 if (!PyArg_ParseTuple(args
,":get_flags"))
5003 CHECK_SEQUENCE_NOT_CLOSED(self
)
5005 MYDB_BEGIN_ALLOW_THREADS
5006 err
= self
->sequence
->get_flags(self
->sequence
, &flags
);
5007 MYDB_END_ALLOW_THREADS
5010 return PyInt_FromLong((int)flags
);
5014 DBSequence_set_range(DBSequenceObject
* self
, PyObject
* args
)
5018 if (!PyArg_ParseTuple(args
,"(LL):set_range", &min
, &max
))
5020 CHECK_SEQUENCE_NOT_CLOSED(self
)
5022 MYDB_BEGIN_ALLOW_THREADS
5023 err
= self
->sequence
->set_range(self
->sequence
, min
, max
);
5024 MYDB_END_ALLOW_THREADS
5031 DBSequence_get_range(DBSequenceObject
* self
, PyObject
* args
)
5035 if (!PyArg_ParseTuple(args
,":get_range"))
5037 CHECK_SEQUENCE_NOT_CLOSED(self
)
5039 MYDB_BEGIN_ALLOW_THREADS
5040 err
= self
->sequence
->get_range(self
->sequence
, &min
, &max
);
5041 MYDB_END_ALLOW_THREADS
5044 return Py_BuildValue("(LL)", min
, max
);
5048 DBSequence_stat(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5051 DB_SEQUENCE_STAT
* sp
= NULL
;
5052 PyObject
* dict_stat
;
5053 static char* kwnames
[] = {"flags", NULL
};
5054 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat", kwnames
, &flags
))
5056 CHECK_SEQUENCE_NOT_CLOSED(self
);
5058 MYDB_BEGIN_ALLOW_THREADS
;
5059 err
= self
->sequence
->stat(self
->sequence
, &sp
, flags
);
5060 MYDB_END_ALLOW_THREADS
;
5063 if ((dict_stat
= PyDict_New()) == NULL
) {
5069 #define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name)
5070 #define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
5072 MAKE_INT_ENTRY(wait
);
5073 MAKE_INT_ENTRY(nowait
);
5074 MAKE_LONG_LONG_ENTRY(current
);
5075 MAKE_LONG_LONG_ENTRY(value
);
5076 MAKE_LONG_LONG_ENTRY(last_value
);
5077 MAKE_LONG_LONG_ENTRY(min
);
5078 MAKE_LONG_LONG_ENTRY(max
);
5079 MAKE_INT_ENTRY(cache_size
);
5080 MAKE_INT_ENTRY(flags
);
5082 #undef MAKE_INT_ENTRY
5083 #undef MAKE_LONG_LONG_ENTRY
5091 /* --------------------------------------------------------------------- */
5092 /* Method definition tables and type objects */
5094 static PyMethodDef DB_methods
[] = {
5095 {"append", (PyCFunction
)DB_append
, METH_VARARGS
},
5097 {"associate", (PyCFunction
)DB_associate
, METH_VARARGS
|METH_KEYWORDS
},
5099 {"close", (PyCFunction
)DB_close
, METH_VARARGS
},
5101 {"consume", (PyCFunction
)DB_consume
, METH_VARARGS
|METH_KEYWORDS
},
5102 {"consume_wait", (PyCFunction
)DB_consume_wait
, METH_VARARGS
|METH_KEYWORDS
},
5104 {"cursor", (PyCFunction
)DB_cursor
, METH_VARARGS
|METH_KEYWORDS
},
5105 {"delete", (PyCFunction
)DB_delete
, METH_VARARGS
|METH_KEYWORDS
},
5106 {"fd", (PyCFunction
)DB_fd
, METH_VARARGS
},
5107 {"get", (PyCFunction
)DB_get
, METH_VARARGS
|METH_KEYWORDS
},
5109 {"pget", (PyCFunction
)DB_pget
, METH_VARARGS
|METH_KEYWORDS
},
5111 {"get_both", (PyCFunction
)DB_get_both
, METH_VARARGS
|METH_KEYWORDS
},
5112 {"get_byteswapped", (PyCFunction
)DB_get_byteswapped
,METH_VARARGS
},
5113 {"get_size", (PyCFunction
)DB_get_size
, METH_VARARGS
|METH_KEYWORDS
},
5114 {"get_type", (PyCFunction
)DB_get_type
, METH_VARARGS
},
5115 {"join", (PyCFunction
)DB_join
, METH_VARARGS
},
5116 {"key_range", (PyCFunction
)DB_key_range
, METH_VARARGS
|METH_KEYWORDS
},
5117 {"has_key", (PyCFunction
)DB_has_key
, METH_VARARGS
},
5118 {"items", (PyCFunction
)DB_items
, METH_VARARGS
},
5119 {"keys", (PyCFunction
)DB_keys
, METH_VARARGS
},
5120 {"open", (PyCFunction
)DB_open
, METH_VARARGS
|METH_KEYWORDS
},
5121 {"put", (PyCFunction
)DB_put
, METH_VARARGS
|METH_KEYWORDS
},
5122 {"remove", (PyCFunction
)DB_remove
, METH_VARARGS
|METH_KEYWORDS
},
5123 {"rename", (PyCFunction
)DB_rename
, METH_VARARGS
},
5124 {"set_bt_minkey", (PyCFunction
)DB_set_bt_minkey
, METH_VARARGS
},
5126 {"set_bt_compare", (PyCFunction
)DB_set_bt_compare
, METH_VARARGS
},
5128 {"set_cachesize", (PyCFunction
)DB_set_cachesize
, METH_VARARGS
},
5130 {"set_encrypt", (PyCFunction
)DB_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
5132 {"set_flags", (PyCFunction
)DB_set_flags
, METH_VARARGS
},
5133 {"set_h_ffactor", (PyCFunction
)DB_set_h_ffactor
, METH_VARARGS
},
5134 {"set_h_nelem", (PyCFunction
)DB_set_h_nelem
, METH_VARARGS
},
5135 {"set_lorder", (PyCFunction
)DB_set_lorder
, METH_VARARGS
},
5136 {"set_pagesize", (PyCFunction
)DB_set_pagesize
, METH_VARARGS
},
5137 {"set_re_delim", (PyCFunction
)DB_set_re_delim
, METH_VARARGS
},
5138 {"set_re_len", (PyCFunction
)DB_set_re_len
, METH_VARARGS
},
5139 {"set_re_pad", (PyCFunction
)DB_set_re_pad
, METH_VARARGS
},
5140 {"set_re_source", (PyCFunction
)DB_set_re_source
, METH_VARARGS
},
5142 {"set_q_extentsize",(PyCFunction
)DB_set_q_extentsize
,METH_VARARGS
},
5144 {"stat", (PyCFunction
)DB_stat
, METH_VARARGS
|METH_KEYWORDS
},
5145 {"sync", (PyCFunction
)DB_sync
, METH_VARARGS
},
5147 {"truncate", (PyCFunction
)DB_truncate
, METH_VARARGS
|METH_KEYWORDS
},
5149 {"type", (PyCFunction
)DB_get_type
, METH_VARARGS
},
5150 {"upgrade", (PyCFunction
)DB_upgrade
, METH_VARARGS
},
5151 {"values", (PyCFunction
)DB_values
, METH_VARARGS
},
5152 {"verify", (PyCFunction
)DB_verify
, METH_VARARGS
|METH_KEYWORDS
},
5153 {"set_get_returns_none",(PyCFunction
)DB_set_get_returns_none
, METH_VARARGS
},
5154 {NULL
, NULL
} /* sentinel */
5158 static PyMappingMethods DB_mapping
= {
5159 DB_length
, /*mp_length*/
5160 (binaryfunc
)DB_subscript
, /*mp_subscript*/
5161 (objobjargproc
)DB_ass_sub
, /*mp_ass_subscript*/
5165 static PyMethodDef DBCursor_methods
[] = {
5166 {"close", (PyCFunction
)DBC_close
, METH_VARARGS
},
5167 {"count", (PyCFunction
)DBC_count
, METH_VARARGS
},
5168 {"current", (PyCFunction
)DBC_current
, METH_VARARGS
|METH_KEYWORDS
},
5169 {"delete", (PyCFunction
)DBC_delete
, METH_VARARGS
},
5170 {"dup", (PyCFunction
)DBC_dup
, METH_VARARGS
},
5171 {"first", (PyCFunction
)DBC_first
, METH_VARARGS
|METH_KEYWORDS
},
5172 {"get", (PyCFunction
)DBC_get
, METH_VARARGS
|METH_KEYWORDS
},
5174 {"pget", (PyCFunction
)DBC_pget
, METH_VARARGS
|METH_KEYWORDS
},
5176 {"get_recno", (PyCFunction
)DBC_get_recno
, METH_VARARGS
},
5177 {"last", (PyCFunction
)DBC_last
, METH_VARARGS
|METH_KEYWORDS
},
5178 {"next", (PyCFunction
)DBC_next
, METH_VARARGS
|METH_KEYWORDS
},
5179 {"prev", (PyCFunction
)DBC_prev
, METH_VARARGS
|METH_KEYWORDS
},
5180 {"put", (PyCFunction
)DBC_put
, METH_VARARGS
|METH_KEYWORDS
},
5181 {"set", (PyCFunction
)DBC_set
, METH_VARARGS
|METH_KEYWORDS
},
5182 {"set_range", (PyCFunction
)DBC_set_range
, METH_VARARGS
|METH_KEYWORDS
},
5183 {"get_both", (PyCFunction
)DBC_get_both
, METH_VARARGS
},
5184 {"get_current_size",(PyCFunction
)DBC_get_current_size
, METH_VARARGS
},
5185 {"set_both", (PyCFunction
)DBC_set_both
, METH_VARARGS
},
5186 {"set_recno", (PyCFunction
)DBC_set_recno
, METH_VARARGS
|METH_KEYWORDS
},
5187 {"consume", (PyCFunction
)DBC_consume
, METH_VARARGS
|METH_KEYWORDS
},
5188 {"next_dup", (PyCFunction
)DBC_next_dup
, METH_VARARGS
|METH_KEYWORDS
},
5189 {"next_nodup", (PyCFunction
)DBC_next_nodup
, METH_VARARGS
|METH_KEYWORDS
},
5190 {"prev_nodup", (PyCFunction
)DBC_prev_nodup
, METH_VARARGS
|METH_KEYWORDS
},
5191 {"join_item", (PyCFunction
)DBC_join_item
, METH_VARARGS
},
5192 {NULL
, NULL
} /* sentinel */
5196 static PyMethodDef DBEnv_methods
[] = {
5197 {"close", (PyCFunction
)DBEnv_close
, METH_VARARGS
},
5198 {"open", (PyCFunction
)DBEnv_open
, METH_VARARGS
},
5199 {"remove", (PyCFunction
)DBEnv_remove
, METH_VARARGS
},
5201 {"dbremove", (PyCFunction
)DBEnv_dbremove
, METH_VARARGS
|METH_KEYWORDS
},
5202 {"dbrename", (PyCFunction
)DBEnv_dbrename
, METH_VARARGS
|METH_KEYWORDS
},
5203 {"set_encrypt", (PyCFunction
)DBEnv_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
5206 {"set_timeout", (PyCFunction
)DBEnv_set_timeout
, METH_VARARGS
|METH_KEYWORDS
},
5208 {"set_shm_key", (PyCFunction
)DBEnv_set_shm_key
, METH_VARARGS
},
5209 {"set_cachesize", (PyCFunction
)DBEnv_set_cachesize
, METH_VARARGS
},
5210 {"set_data_dir", (PyCFunction
)DBEnv_set_data_dir
, METH_VARARGS
},
5212 {"set_flags", (PyCFunction
)DBEnv_set_flags
, METH_VARARGS
},
5214 {"set_lg_bsize", (PyCFunction
)DBEnv_set_lg_bsize
, METH_VARARGS
},
5215 {"set_lg_dir", (PyCFunction
)DBEnv_set_lg_dir
, METH_VARARGS
},
5216 {"set_lg_max", (PyCFunction
)DBEnv_set_lg_max
, METH_VARARGS
},
5218 {"set_lg_regionmax",(PyCFunction
)DBEnv_set_lg_regionmax
, METH_VARARGS
},
5220 {"set_lk_detect", (PyCFunction
)DBEnv_set_lk_detect
, METH_VARARGS
},
5221 {"set_lk_max", (PyCFunction
)DBEnv_set_lk_max
, METH_VARARGS
},
5223 {"set_lk_max_locks", (PyCFunction
)DBEnv_set_lk_max_locks
, METH_VARARGS
},
5224 {"set_lk_max_lockers", (PyCFunction
)DBEnv_set_lk_max_lockers
, METH_VARARGS
},
5225 {"set_lk_max_objects", (PyCFunction
)DBEnv_set_lk_max_objects
, METH_VARARGS
},
5227 {"set_mp_mmapsize", (PyCFunction
)DBEnv_set_mp_mmapsize
, METH_VARARGS
},
5228 {"set_tmp_dir", (PyCFunction
)DBEnv_set_tmp_dir
, METH_VARARGS
},
5229 {"txn_begin", (PyCFunction
)DBEnv_txn_begin
, METH_VARARGS
|METH_KEYWORDS
},
5230 {"txn_checkpoint", (PyCFunction
)DBEnv_txn_checkpoint
, METH_VARARGS
},
5231 {"txn_stat", (PyCFunction
)DBEnv_txn_stat
, METH_VARARGS
},
5232 {"set_tx_max", (PyCFunction
)DBEnv_set_tx_max
, METH_VARARGS
},
5233 {"set_tx_timestamp", (PyCFunction
)DBEnv_set_tx_timestamp
, METH_VARARGS
},
5234 {"lock_detect", (PyCFunction
)DBEnv_lock_detect
, METH_VARARGS
},
5235 {"lock_get", (PyCFunction
)DBEnv_lock_get
, METH_VARARGS
},
5236 {"lock_id", (PyCFunction
)DBEnv_lock_id
, METH_VARARGS
},
5237 {"lock_put", (PyCFunction
)DBEnv_lock_put
, METH_VARARGS
},
5238 {"lock_stat", (PyCFunction
)DBEnv_lock_stat
, METH_VARARGS
},
5239 {"log_archive", (PyCFunction
)DBEnv_log_archive
, METH_VARARGS
},
5241 {"log_stat", (PyCFunction
)DBEnv_log_stat
, METH_VARARGS
},
5244 {"lsn_reset", (PyCFunction
)DBEnv_lsn_reset
, METH_VARARGS
|METH_KEYWORDS
},
5246 {"set_get_returns_none",(PyCFunction
)DBEnv_set_get_returns_none
, METH_VARARGS
},
5247 {NULL
, NULL
} /* sentinel */
5251 static PyMethodDef DBTxn_methods
[] = {
5252 {"commit", (PyCFunction
)DBTxn_commit
, METH_VARARGS
},
5253 {"prepare", (PyCFunction
)DBTxn_prepare
, METH_VARARGS
},
5254 {"abort", (PyCFunction
)DBTxn_abort
, METH_VARARGS
},
5255 {"id", (PyCFunction
)DBTxn_id
, METH_VARARGS
},
5256 {NULL
, NULL
} /* sentinel */
5261 static PyMethodDef DBSequence_methods
[] = {
5262 {"close", (PyCFunction
)DBSequence_close
, METH_VARARGS
},
5263 {"get", (PyCFunction
)DBSequence_get
, METH_VARARGS
|METH_KEYWORDS
},
5264 {"get_dbp", (PyCFunction
)DBSequence_get_dbp
, METH_VARARGS
},
5265 {"get_key", (PyCFunction
)DBSequence_get_key
, METH_VARARGS
},
5266 {"init_value", (PyCFunction
)DBSequence_init_value
, METH_VARARGS
},
5267 {"open", (PyCFunction
)DBSequence_open
, METH_VARARGS
|METH_KEYWORDS
},
5268 {"remove", (PyCFunction
)DBSequence_remove
, METH_VARARGS
|METH_KEYWORDS
},
5269 {"set_cachesize", (PyCFunction
)DBSequence_set_cachesize
, METH_VARARGS
},
5270 {"get_cachesize", (PyCFunction
)DBSequence_get_cachesize
, METH_VARARGS
},
5271 {"set_flags", (PyCFunction
)DBSequence_set_flags
, METH_VARARGS
},
5272 {"get_flags", (PyCFunction
)DBSequence_get_flags
, METH_VARARGS
},
5273 {"set_range", (PyCFunction
)DBSequence_set_range
, METH_VARARGS
},
5274 {"get_range", (PyCFunction
)DBSequence_get_range
, METH_VARARGS
},
5275 {"stat", (PyCFunction
)DBSequence_stat
, METH_VARARGS
|METH_KEYWORDS
},
5276 {NULL
, NULL
} /* sentinel */
5282 DB_getattr(DBObject
* self
, char *name
)
5284 return Py_FindMethod(DB_methods
, (PyObject
* )self
, name
);
5289 DBEnv_getattr(DBEnvObject
* self
, char *name
)
5291 if (!strcmp(name
, "db_home")) {
5292 CHECK_ENV_NOT_CLOSED(self
);
5293 if (self
->db_env
->db_home
== NULL
) {
5296 return PyString_FromString(self
->db_env
->db_home
);
5299 return Py_FindMethod(DBEnv_methods
, (PyObject
* )self
, name
);
5304 DBCursor_getattr(DBCursorObject
* self
, char *name
)
5306 return Py_FindMethod(DBCursor_methods
, (PyObject
* )self
, name
);
5310 DBTxn_getattr(DBTxnObject
* self
, char *name
)
5312 return Py_FindMethod(DBTxn_methods
, (PyObject
* )self
, name
);
5316 DBLock_getattr(DBLockObject
* self
, char *name
)
5323 DBSequence_getattr(DBSequenceObject
* self
, char *name
)
5325 return Py_FindMethod(DBSequence_methods
, (PyObject
* )self
, name
);
5329 statichere PyTypeObject DB_Type
= {
5330 PyObject_HEAD_INIT(NULL
)
5333 sizeof(DBObject
), /*tp_basicsize*/
5336 (destructor
)DB_dealloc
, /*tp_dealloc*/
5338 (getattrfunc
)DB_getattr
, /*tp_getattr*/
5343 0, /*tp_as_sequence*/
5344 &DB_mapping
,/*tp_as_mapping*/
5349 0, /* tp_getattro */
5350 0, /* tp_setattro */
5351 0, /* tp_as_buffer */
5352 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5354 0, /* tp_traverse */
5356 0, /* tp_richcompare */
5357 offsetof(DBObject
, in_weakreflist
), /* tp_weaklistoffset */
5362 statichere PyTypeObject DBCursor_Type
= {
5363 PyObject_HEAD_INIT(NULL
)
5365 "DBCursor", /*tp_name*/
5366 sizeof(DBCursorObject
), /*tp_basicsize*/
5369 (destructor
)DBCursor_dealloc
,/*tp_dealloc*/
5371 (getattrfunc
)DBCursor_getattr
, /*tp_getattr*/
5376 0, /*tp_as_sequence*/
5377 0, /*tp_as_mapping*/
5382 0, /* tp_getattro */
5383 0, /* tp_setattro */
5384 0, /* tp_as_buffer */
5385 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5387 0, /* tp_traverse */
5389 0, /* tp_richcompare */
5390 offsetof(DBCursorObject
, in_weakreflist
), /* tp_weaklistoffset */
5395 statichere PyTypeObject DBEnv_Type
= {
5396 PyObject_HEAD_INIT(NULL
)
5398 "DBEnv", /*tp_name*/
5399 sizeof(DBEnvObject
), /*tp_basicsize*/
5402 (destructor
)DBEnv_dealloc
, /*tp_dealloc*/
5404 (getattrfunc
)DBEnv_getattr
, /*tp_getattr*/
5409 0, /*tp_as_sequence*/
5410 0, /*tp_as_mapping*/
5415 0, /* tp_getattro */
5416 0, /* tp_setattro */
5417 0, /* tp_as_buffer */
5418 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5420 0, /* tp_traverse */
5422 0, /* tp_richcompare */
5423 offsetof(DBEnvObject
, in_weakreflist
), /* tp_weaklistoffset */
5427 statichere PyTypeObject DBTxn_Type
= {
5428 PyObject_HEAD_INIT(NULL
)
5430 "DBTxn", /*tp_name*/
5431 sizeof(DBTxnObject
), /*tp_basicsize*/
5434 (destructor
)DBTxn_dealloc
, /*tp_dealloc*/
5436 (getattrfunc
)DBTxn_getattr
, /*tp_getattr*/
5441 0, /*tp_as_sequence*/
5442 0, /*tp_as_mapping*/
5447 0, /* tp_getattro */
5448 0, /* tp_setattro */
5449 0, /* tp_as_buffer */
5450 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5452 0, /* tp_traverse */
5454 0, /* tp_richcompare */
5455 offsetof(DBTxnObject
, in_weakreflist
), /* tp_weaklistoffset */
5460 statichere PyTypeObject DBLock_Type
= {
5461 PyObject_HEAD_INIT(NULL
)
5463 "DBLock", /*tp_name*/
5464 sizeof(DBLockObject
), /*tp_basicsize*/
5467 (destructor
)DBLock_dealloc
, /*tp_dealloc*/
5469 (getattrfunc
)DBLock_getattr
, /*tp_getattr*/
5474 0, /*tp_as_sequence*/
5475 0, /*tp_as_mapping*/
5480 0, /* tp_getattro */
5481 0, /* tp_setattro */
5482 0, /* tp_as_buffer */
5483 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5485 0, /* tp_traverse */
5487 0, /* tp_richcompare */
5488 offsetof(DBLockObject
, in_weakreflist
), /* tp_weaklistoffset */
5493 statichere PyTypeObject DBSequence_Type
= {
5494 PyObject_HEAD_INIT(NULL
)
5496 "DBSequence", /*tp_name*/
5497 sizeof(DBSequenceObject
), /*tp_basicsize*/
5500 (destructor
)DBSequence_dealloc
, /*tp_dealloc*/
5502 (getattrfunc
)DBSequence_getattr
,/*tp_getattr*/
5507 0, /*tp_as_sequence*/
5508 0, /*tp_as_mapping*/
5513 0, /* tp_getattro */
5514 0, /* tp_setattro */
5515 0, /* tp_as_buffer */
5516 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5518 0, /* tp_traverse */
5520 0, /* tp_richcompare */
5521 offsetof(DBSequenceObject
, in_weakreflist
), /* tp_weaklistoffset */
5526 /* --------------------------------------------------------------------- */
5527 /* Module-level functions */
5530 DB_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5532 PyObject
* dbenvobj
= NULL
;
5534 static char* kwnames
[] = { "dbEnv", "flags", NULL
};
5536 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:DB", kwnames
,
5539 if (dbenvobj
== Py_None
)
5541 else if (dbenvobj
&& !DBEnvObject_Check(dbenvobj
)) {
5542 makeTypeError("DBEnv", dbenvobj
);
5546 return (PyObject
* )newDBObject((DBEnvObject
*)dbenvobj
, flags
);
5551 DBEnv_construct(PyObject
* self
, PyObject
* args
)
5554 if (!PyArg_ParseTuple(args
, "|i:DbEnv", &flags
)) return NULL
;
5555 return (PyObject
* )newDBEnvObject(flags
);
5560 DBSequence_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5564 static char* kwnames
[] = { "db", "flags", NULL
};
5566 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|i:DBSequence", kwnames
, &dbobj
, &flags
))
5568 if (!DBObject_Check(dbobj
)) {
5569 makeTypeError("DB", dbobj
);
5572 return (PyObject
* )newDBSequenceObject((DBObject
*)dbobj
, flags
);
5576 static char bsddb_version_doc
[] =
5577 "Returns a tuple of major, minor, and patch release numbers of the\n\
5578 underlying DB library.";
5581 bsddb_version(PyObject
* self
, PyObject
* args
)
5583 int major
, minor
, patch
;
5585 if (!PyArg_ParseTuple(args
, ":version"))
5587 db_version(&major
, &minor
, &patch
);
5588 return Py_BuildValue("(iii)", major
, minor
, patch
);
5592 /* List of functions defined in the module */
5594 static PyMethodDef bsddb_methods
[] = {
5595 {"DB", (PyCFunction
)DB_construct
, METH_VARARGS
| METH_KEYWORDS
},
5596 {"DBEnv", (PyCFunction
)DBEnv_construct
, METH_VARARGS
},
5598 {"DBSequence", (PyCFunction
)DBSequence_construct
, METH_VARARGS
| METH_KEYWORDS
},
5600 {"version", (PyCFunction
)bsddb_version
, METH_VARARGS
, bsddb_version_doc
},
5601 {NULL
, NULL
} /* sentinel */
5605 /* --------------------------------------------------------------------- */
5606 /* Module initialization */
5609 /* Convenience routine to export an integer value.
5610 * Errors are silently ignored, for better or for worse...
5612 #define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
5614 #define MODULE_NAME_MAX_LEN 11
5615 static char _bsddbModuleName
[MODULE_NAME_MAX_LEN
+1] = "_bsddb";
5617 DL_EXPORT(void) init_bsddb(void)
5621 PyObject
* pybsddb_version_s
= PyString_FromString( PY_BSDDB_VERSION
);
5622 PyObject
* db_version_s
= PyString_FromString( DB_VERSION_STRING
);
5623 PyObject
* cvsid_s
= PyString_FromString( rcs_id
);
5625 /* Initialize the type of the new type objects here; doing it here
5626 is required for portability to Windows without requiring C++. */
5627 DB_Type
.ob_type
= &PyType_Type
;
5628 DBCursor_Type
.ob_type
= &PyType_Type
;
5629 DBEnv_Type
.ob_type
= &PyType_Type
;
5630 DBTxn_Type
.ob_type
= &PyType_Type
;
5631 DBLock_Type
.ob_type
= &PyType_Type
;
5633 DBSequence_Type
.ob_type
= &PyType_Type
;
5637 #if defined(WITH_THREAD) && !defined(MYDB_USE_GILSTATE)
5638 /* Save the current interpreter, so callbacks can do the right thing. */
5639 _db_interpreterState
= PyThreadState_GET()->interp
;
5642 /* Create the module and add the functions */
5643 m
= Py_InitModule(_bsddbModuleName
, bsddb_methods
);
5647 /* Add some symbolic constants to the module */
5648 d
= PyModule_GetDict(m
);
5649 PyDict_SetItemString(d
, "__version__", pybsddb_version_s
);
5650 PyDict_SetItemString(d
, "cvsid", cvsid_s
);
5651 PyDict_SetItemString(d
, "DB_VERSION_STRING", db_version_s
);
5652 Py_DECREF(pybsddb_version_s
);
5653 pybsddb_version_s
= NULL
;
5656 Py_DECREF(db_version_s
);
5657 db_version_s
= NULL
;
5659 ADD_INT(d
, DB_VERSION_MAJOR
);
5660 ADD_INT(d
, DB_VERSION_MINOR
);
5661 ADD_INT(d
, DB_VERSION_PATCH
);
5663 ADD_INT(d
, DB_MAX_PAGES
);
5664 ADD_INT(d
, DB_MAX_RECORDS
);
5667 ADD_INT(d
, DB_RPCCLIENT
);
5669 ADD_INT(d
, DB_CLIENT
);
5670 /* allow apps to be written using DB_RPCCLIENT on older BerkeleyDB */
5671 _addIntToDict(d
, "DB_RPCCLIENT", DB_CLIENT
);
5673 ADD_INT(d
, DB_XA_CREATE
);
5675 ADD_INT(d
, DB_CREATE
);
5676 ADD_INT(d
, DB_NOMMAP
);
5677 ADD_INT(d
, DB_THREAD
);
5679 ADD_INT(d
, DB_FORCE
);
5680 ADD_INT(d
, DB_INIT_CDB
);
5681 ADD_INT(d
, DB_INIT_LOCK
);
5682 ADD_INT(d
, DB_INIT_LOG
);
5683 ADD_INT(d
, DB_INIT_MPOOL
);
5684 ADD_INT(d
, DB_INIT_TXN
);
5686 ADD_INT(d
, DB_JOINENV
);
5689 ADD_INT(d
, DB_RECOVER
);
5690 ADD_INT(d
, DB_RECOVER_FATAL
);
5691 ADD_INT(d
, DB_TXN_NOSYNC
);
5692 ADD_INT(d
, DB_USE_ENVIRON
);
5693 ADD_INT(d
, DB_USE_ENVIRON_ROOT
);
5695 ADD_INT(d
, DB_LOCKDOWN
);
5696 ADD_INT(d
, DB_PRIVATE
);
5697 ADD_INT(d
, DB_SYSTEM_MEM
);
5699 ADD_INT(d
, DB_TXN_SYNC
);
5700 ADD_INT(d
, DB_TXN_NOWAIT
);
5702 ADD_INT(d
, DB_EXCL
);
5703 ADD_INT(d
, DB_FCNTL_LOCKING
);
5704 ADD_INT(d
, DB_ODDFILESIZE
);
5705 ADD_INT(d
, DB_RDWRMASTER
);
5706 ADD_INT(d
, DB_RDONLY
);
5707 ADD_INT(d
, DB_TRUNCATE
);
5709 ADD_INT(d
, DB_EXTENT
);
5710 ADD_INT(d
, DB_CDB_ALLDB
);
5711 ADD_INT(d
, DB_VERIFY
);
5713 ADD_INT(d
, DB_UPGRADE
);
5715 ADD_INT(d
, DB_AGGRESSIVE
);
5716 ADD_INT(d
, DB_NOORDERCHK
);
5717 ADD_INT(d
, DB_ORDERCHKONLY
);
5718 ADD_INT(d
, DB_PR_PAGE
);
5720 ADD_INT(d
, DB_VRFY_FLAGMASK
);
5721 ADD_INT(d
, DB_PR_HEADERS
);
5723 ADD_INT(d
, DB_PR_RECOVERYTEST
);
5724 ADD_INT(d
, DB_SALVAGE
);
5726 ADD_INT(d
, DB_LOCK_NORUN
);
5727 ADD_INT(d
, DB_LOCK_DEFAULT
);
5728 ADD_INT(d
, DB_LOCK_OLDEST
);
5729 ADD_INT(d
, DB_LOCK_RANDOM
);
5730 ADD_INT(d
, DB_LOCK_YOUNGEST
);
5732 ADD_INT(d
, DB_LOCK_MAXLOCKS
);
5733 ADD_INT(d
, DB_LOCK_MINLOCKS
);
5734 ADD_INT(d
, DB_LOCK_MINWRITE
);
5739 /* docs say to use zero instead */
5740 _addIntToDict(d
, "DB_LOCK_CONFLICT", 0);
5742 ADD_INT(d
, DB_LOCK_CONFLICT
);
5745 ADD_INT(d
, DB_LOCK_DUMP
);
5746 ADD_INT(d
, DB_LOCK_GET
);
5747 ADD_INT(d
, DB_LOCK_INHERIT
);
5748 ADD_INT(d
, DB_LOCK_PUT
);
5749 ADD_INT(d
, DB_LOCK_PUT_ALL
);
5750 ADD_INT(d
, DB_LOCK_PUT_OBJ
);
5752 ADD_INT(d
, DB_LOCK_NG
);
5753 ADD_INT(d
, DB_LOCK_READ
);
5754 ADD_INT(d
, DB_LOCK_WRITE
);
5755 ADD_INT(d
, DB_LOCK_NOWAIT
);
5757 ADD_INT(d
, DB_LOCK_WAIT
);
5759 ADD_INT(d
, DB_LOCK_IWRITE
);
5760 ADD_INT(d
, DB_LOCK_IREAD
);
5761 ADD_INT(d
, DB_LOCK_IWR
);
5764 ADD_INT(d
, DB_LOCK_DIRTY
);
5766 ADD_INT(d
, DB_LOCK_READ_UNCOMMITTED
); /* renamed in 4.4 */
5768 ADD_INT(d
, DB_LOCK_WWRITE
);
5771 ADD_INT(d
, DB_LOCK_RECORD
);
5772 ADD_INT(d
, DB_LOCK_UPGRADE
);
5774 ADD_INT(d
, DB_LOCK_SWITCH
);
5777 ADD_INT(d
, DB_LOCK_UPGRADE_WRITE
);
5780 ADD_INT(d
, DB_LOCK_NOWAIT
);
5781 ADD_INT(d
, DB_LOCK_RECORD
);
5782 ADD_INT(d
, DB_LOCK_UPGRADE
);
5785 ADD_INT(d
, DB_LSTAT_ABORTED
);
5787 ADD_INT(d
, DB_LSTAT_ERR
);
5789 ADD_INT(d
, DB_LSTAT_FREE
);
5790 ADD_INT(d
, DB_LSTAT_HELD
);
5792 ADD_INT(d
, DB_LSTAT_NOGRANT
);
5794 ADD_INT(d
, DB_LSTAT_PENDING
);
5795 ADD_INT(d
, DB_LSTAT_WAITING
);
5798 ADD_INT(d
, DB_ARCH_ABS
);
5799 ADD_INT(d
, DB_ARCH_DATA
);
5800 ADD_INT(d
, DB_ARCH_LOG
);
5802 ADD_INT(d
, DB_ARCH_REMOVE
);
5805 ADD_INT(d
, DB_BTREE
);
5806 ADD_INT(d
, DB_HASH
);
5807 ADD_INT(d
, DB_RECNO
);
5808 ADD_INT(d
, DB_QUEUE
);
5809 ADD_INT(d
, DB_UNKNOWN
);
5812 ADD_INT(d
, DB_DUPSORT
);
5813 ADD_INT(d
, DB_RECNUM
);
5814 ADD_INT(d
, DB_RENUMBER
);
5815 ADD_INT(d
, DB_REVSPLITOFF
);
5816 ADD_INT(d
, DB_SNAPSHOT
);
5818 ADD_INT(d
, DB_JOIN_NOSORT
);
5820 ADD_INT(d
, DB_AFTER
);
5821 ADD_INT(d
, DB_APPEND
);
5822 ADD_INT(d
, DB_BEFORE
);
5823 ADD_INT(d
, DB_CACHED_COUNTS
);
5825 _addIntToDict(d
, "DB_CHECKPOINT", 0);
5827 ADD_INT(d
, DB_CHECKPOINT
);
5828 ADD_INT(d
, DB_CURLSN
);
5830 #if ((DBVER >= 33) && (DBVER <= 41))
5831 ADD_INT(d
, DB_COMMIT
);
5833 ADD_INT(d
, DB_CONSUME
);
5835 ADD_INT(d
, DB_CONSUME_WAIT
);
5837 ADD_INT(d
, DB_CURRENT
);
5839 ADD_INT(d
, DB_FAST_STAT
);
5841 ADD_INT(d
, DB_FIRST
);
5842 ADD_INT(d
, DB_FLUSH
);
5843 ADD_INT(d
, DB_GET_BOTH
);
5844 ADD_INT(d
, DB_GET_RECNO
);
5845 ADD_INT(d
, DB_JOIN_ITEM
);
5846 ADD_INT(d
, DB_KEYFIRST
);
5847 ADD_INT(d
, DB_KEYLAST
);
5848 ADD_INT(d
, DB_LAST
);
5849 ADD_INT(d
, DB_NEXT
);
5850 ADD_INT(d
, DB_NEXT_DUP
);
5851 ADD_INT(d
, DB_NEXT_NODUP
);
5852 ADD_INT(d
, DB_NODUPDATA
);
5853 ADD_INT(d
, DB_NOOVERWRITE
);
5854 ADD_INT(d
, DB_NOSYNC
);
5855 ADD_INT(d
, DB_POSITION
);
5856 ADD_INT(d
, DB_PREV
);
5857 ADD_INT(d
, DB_PREV_NODUP
);
5858 ADD_INT(d
, DB_RECORDCOUNT
);
5860 ADD_INT(d
, DB_SET_RANGE
);
5861 ADD_INT(d
, DB_SET_RECNO
);
5862 ADD_INT(d
, DB_WRITECURSOR
);
5864 ADD_INT(d
, DB_OPFLAGS_MASK
);
5867 ADD_INT(d
, DB_DIRTY_READ
);
5868 ADD_INT(d
, DB_MULTIPLE
);
5869 ADD_INT(d
, DB_MULTIPLE_KEY
);
5873 ADD_INT(d
, DB_READ_UNCOMMITTED
); /* replaces DB_DIRTY_READ in 4.4 */
5874 ADD_INT(d
, DB_READ_COMMITTED
);
5878 ADD_INT(d
, DB_DONOTINDEX
);
5882 _addIntToDict(d
, "DB_INCOMPLETE", 0);
5884 ADD_INT(d
, DB_INCOMPLETE
);
5886 ADD_INT(d
, DB_KEYEMPTY
);
5887 ADD_INT(d
, DB_KEYEXIST
);
5888 ADD_INT(d
, DB_LOCK_DEADLOCK
);
5889 ADD_INT(d
, DB_LOCK_NOTGRANTED
);
5890 ADD_INT(d
, DB_NOSERVER
);
5891 ADD_INT(d
, DB_NOSERVER_HOME
);
5892 ADD_INT(d
, DB_NOSERVER_ID
);
5893 ADD_INT(d
, DB_NOTFOUND
);
5894 ADD_INT(d
, DB_OLD_VERSION
);
5895 ADD_INT(d
, DB_RUNRECOVERY
);
5896 ADD_INT(d
, DB_VERIFY_BAD
);
5898 ADD_INT(d
, DB_PAGE_NOTFOUND
);
5899 ADD_INT(d
, DB_SECONDARY_BAD
);
5902 ADD_INT(d
, DB_STAT_CLEAR
);
5903 ADD_INT(d
, DB_REGION_INIT
);
5904 ADD_INT(d
, DB_NOLOCKING
);
5905 ADD_INT(d
, DB_YIELDCPU
);
5906 ADD_INT(d
, DB_PANIC_ENVIRONMENT
);
5907 ADD_INT(d
, DB_NOPANIC
);
5911 ADD_INT(d
, DB_TIME_NOTGRANTED
);
5912 ADD_INT(d
, DB_TXN_NOT_DURABLE
);
5913 ADD_INT(d
, DB_TXN_WRITE_NOSYNC
);
5914 ADD_INT(d
, DB_LOG_AUTOREMOVE
);
5915 ADD_INT(d
, DB_DIRECT_LOG
);
5916 ADD_INT(d
, DB_DIRECT_DB
);
5917 ADD_INT(d
, DB_INIT_REP
);
5918 ADD_INT(d
, DB_ENCRYPT
);
5919 ADD_INT(d
, DB_CHKSUM
);
5923 ADD_INT(d
, DB_LOG_INMEMORY
);
5924 ADD_INT(d
, DB_BUFFER_SMALL
);
5925 ADD_INT(d
, DB_SEQ_DEC
);
5926 ADD_INT(d
, DB_SEQ_INC
);
5927 ADD_INT(d
, DB_SEQ_WRAP
);
5931 ADD_INT(d
, DB_ENCRYPT_AES
);
5932 ADD_INT(d
, DB_AUTO_COMMIT
);
5934 /* allow berkeleydb 4.1 aware apps to run on older versions */
5935 _addIntToDict(d
, "DB_AUTO_COMMIT", 0);
5949 ADD_INT(d
, DB_SET_LOCK_TIMEOUT
);
5950 ADD_INT(d
, DB_SET_TXN_TIMEOUT
);
5953 /* The exception name must be correct for pickled exception *
5954 * objects to unpickle properly. */
5955 #ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
5956 #define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
5958 #define PYBSDDB_EXCEPTION_BASE "bsddb.db."
5961 /* All the rest of the exceptions derive only from DBError */
5962 #define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
5963 PyDict_SetItemString(d, #name, name)
5965 /* The base exception class is DBError */
5966 DBError
= NULL
; /* used in MAKE_EX so that it derives from nothing */
5969 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
5970 * from both DBError and KeyError, since the API only supports
5971 * using one base class. */
5972 PyDict_SetItemString(d
, "KeyError", PyExc_KeyError
);
5973 PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
5974 "class DBKeyEmptyError(DBError, KeyError): pass",
5975 Py_file_input
, d
, d
);
5976 DBNotFoundError
= PyDict_GetItemString(d
, "DBNotFoundError");
5977 DBKeyEmptyError
= PyDict_GetItemString(d
, "DBKeyEmptyError");
5978 PyDict_DelItemString(d
, "KeyError");
5981 #if !INCOMPLETE_IS_WARNING
5982 MAKE_EX(DBIncompleteError
);
5984 MAKE_EX(DBCursorClosedError
);
5985 MAKE_EX(DBKeyEmptyError
);
5986 MAKE_EX(DBKeyExistError
);
5987 MAKE_EX(DBLockDeadlockError
);
5988 MAKE_EX(DBLockNotGrantedError
);
5989 MAKE_EX(DBOldVersionError
);
5990 MAKE_EX(DBRunRecoveryError
);
5991 MAKE_EX(DBVerifyBadError
);
5992 MAKE_EX(DBNoServerError
);
5993 MAKE_EX(DBNoServerHomeError
);
5994 MAKE_EX(DBNoServerIDError
);
5996 MAKE_EX(DBPageNotFoundError
);
5997 MAKE_EX(DBSecondaryBadError
);
6000 MAKE_EX(DBInvalidArgError
);
6001 MAKE_EX(DBAccessError
);
6002 MAKE_EX(DBNoSpaceError
);
6003 MAKE_EX(DBNoMemoryError
);
6004 MAKE_EX(DBAgainError
);
6005 MAKE_EX(DBBusyError
);
6006 MAKE_EX(DBFileExistsError
);
6007 MAKE_EX(DBNoSuchFileError
);
6008 MAKE_EX(DBPermissionsError
);
6012 /* Check for errors */
6013 if (PyErr_Occurred()) {
6015 Py_FatalError("can't initialize module _bsddb");
6019 /* allow this module to be named _pybsddb so that it can be installed
6020 * and imported on top of python >= 2.3 that includes its own older
6021 * copy of the library named _bsddb without importing the old version. */
6022 DL_EXPORT(void) init_pybsddb(void)
6024 strncpy(_bsddbModuleName
, "_pybsddb", MODULE_NAME_MAX_LEN
);