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.6"
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;
531 unsigned int bytes_left
;
534 case 0: /* successful, no error */ break;
538 #if INCOMPLETE_IS_WARNING
539 bytes_left
= our_strlcpy(errTxt
, db_strerror(err
), sizeof(errTxt
));
540 /* Ensure that bytes_left never goes negative */
541 if (_db_errmsg
[0] && bytes_left
< (sizeof(errTxt
) - 4)) {
542 bytes_left
= sizeof(errTxt
) - bytes_left
- 4 - 1;
543 assert(bytes_left
>= 0);
544 strcat(errTxt
, " -- ");
545 strncat(errTxt
, _db_errmsg
, bytes_left
);
549 exceptionRaised
= PyErr_Warn(PyExc_RuntimeWarning
, errTxt
);
551 fprintf(stderr
, errTxt
);
552 fprintf(stderr
, "\n");
555 #else /* do an exception instead */
556 errObj
= DBIncompleteError
;
559 #endif /* DBVER < 41 */
561 case DB_KEYEMPTY
: errObj
= DBKeyEmptyError
; break;
562 case DB_KEYEXIST
: errObj
= DBKeyExistError
; break;
563 case DB_LOCK_DEADLOCK
: errObj
= DBLockDeadlockError
; break;
564 case DB_LOCK_NOTGRANTED
: errObj
= DBLockNotGrantedError
; break;
565 case DB_NOTFOUND
: errObj
= DBNotFoundError
; break;
566 case DB_OLD_VERSION
: errObj
= DBOldVersionError
; break;
567 case DB_RUNRECOVERY
: errObj
= DBRunRecoveryError
; break;
568 case DB_VERIFY_BAD
: errObj
= DBVerifyBadError
; break;
569 case DB_NOSERVER
: errObj
= DBNoServerError
; break;
570 case DB_NOSERVER_HOME
: errObj
= DBNoServerHomeError
; break;
571 case DB_NOSERVER_ID
: errObj
= DBNoServerIDError
; break;
573 case DB_PAGE_NOTFOUND
: errObj
= DBPageNotFoundError
; break;
574 case DB_SECONDARY_BAD
: errObj
= DBSecondaryBadError
; break;
576 case DB_BUFFER_SMALL
: errObj
= DBNoMemoryError
; break;
579 /* ENOMEM and DB_BUFFER_SMALL were one and the same until 4.3 */
580 case ENOMEM
: errObj
= PyExc_MemoryError
; break;
582 case EINVAL
: errObj
= DBInvalidArgError
; break;
583 case EACCES
: errObj
= DBAccessError
; break;
584 case ENOSPC
: errObj
= DBNoSpaceError
; break;
585 case EAGAIN
: errObj
= DBAgainError
; break;
586 case EBUSY
: errObj
= DBBusyError
; break;
587 case EEXIST
: errObj
= DBFileExistsError
; break;
588 case ENOENT
: errObj
= DBNoSuchFileError
; break;
589 case EPERM
: errObj
= DBPermissionsError
; break;
591 default: errObj
= DBError
; break;
594 if (errObj
!= NULL
) {
595 bytes_left
= our_strlcpy(errTxt
, db_strerror(err
), sizeof(errTxt
));
596 /* Ensure that bytes_left never goes negative */
597 if (_db_errmsg
[0] && bytes_left
< (sizeof(errTxt
) - 4)) {
598 bytes_left
= sizeof(errTxt
) - bytes_left
- 4 - 1;
599 assert(bytes_left
>= 0);
600 strcat(errTxt
, " -- ");
601 strncat(errTxt
, _db_errmsg
, bytes_left
);
605 errTuple
= Py_BuildValue("(is)", err
, errTxt
);
606 PyErr_SetObject(errObj
, errTuple
);
610 return ((errObj
!= NULL
) || exceptionRaised
);
615 /* set a type exception */
616 static void makeTypeError(char* expected
, PyObject
* found
)
618 PyErr_Format(PyExc_TypeError
, "Expected %s argument, %s found.",
619 expected
, found
->ob_type
->tp_name
);
623 /* verify that an obj is either None or a DBTxn, and set the txn pointer */
624 static int checkTxnObj(PyObject
* txnobj
, DB_TXN
** txn
)
626 if (txnobj
== Py_None
|| txnobj
== NULL
) {
630 if (DBTxnObject_Check(txnobj
)) {
631 *txn
= ((DBTxnObject
*)txnobj
)->txn
;
635 makeTypeError("DBTxn", txnobj
);
640 /* Delete a key from a database
641 Returns 0 on success, -1 on an error. */
642 static int _DB_delete(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, int flags
)
646 MYDB_BEGIN_ALLOW_THREADS
;
647 err
= self
->db
->del(self
->db
, txn
, key
, 0);
648 MYDB_END_ALLOW_THREADS
;
649 if (makeDBError(err
)) {
657 /* Store a key into a database
658 Returns 0 on success, -1 on an error. */
659 static int _DB_put(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, DBT
*data
, int flags
)
663 MYDB_BEGIN_ALLOW_THREADS
;
664 err
= self
->db
->put(self
->db
, txn
, key
, data
, flags
);
665 MYDB_END_ALLOW_THREADS
;
666 if (makeDBError(err
)) {
673 /* Get a key/data pair from a cursor */
674 static PyObject
* _DBCursor_get(DBCursorObject
* self
, int extra_flags
,
675 PyObject
*args
, PyObject
*kwargs
, char *format
)
678 PyObject
* retval
= NULL
;
683 static char* kwnames
[] = { "flags", "dlen", "doff", NULL
};
685 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, format
, kwnames
,
686 &flags
, &dlen
, &doff
))
689 CHECK_CURSOR_NOT_CLOSED(self
);
691 flags
|= extra_flags
;
694 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
695 /* Tell BerkeleyDB to malloc the return value (thread safe) */
696 data
.flags
= DB_DBT_MALLOC
;
697 key
.flags
= DB_DBT_MALLOC
;
699 if (!add_partial_dbt(&data
, dlen
, doff
))
702 MYDB_BEGIN_ALLOW_THREADS
;
703 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
704 MYDB_END_ALLOW_THREADS
;
706 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
707 && self
->mydb
->moduleFlags
.getReturnsNone
) {
711 else if (makeDBError(err
)) {
714 else { /* otherwise, success! */
716 /* if Recno or Queue, return the key as an Int */
717 switch (_DB_get_type(self
->mydb
)) {
724 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
725 data
.data
, data
.size
);
730 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
731 data
.data
, data
.size
);
743 /* add an integer to a dictionary using the given name as a key */
744 static void _addIntToDict(PyObject
* dict
, char *name
, int value
)
746 PyObject
* v
= PyInt_FromLong((long) value
);
747 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
753 /* add an db_seq_t to a dictionary using the given name as a key */
754 static void _addDb_seq_tToDict(PyObject
* dict
, char *name
, db_seq_t value
)
756 PyObject
* v
= PyLong_FromLongLong(value
);
757 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
766 /* --------------------------------------------------------------------- */
767 /* Allocators and deallocators */
770 newDBObject(DBEnvObject
* arg
, int flags
)
773 DB_ENV
* db_env
= NULL
;
776 self
= PyObject_New(DBObject
, &DB_Type
);
783 self
->myenvobj
= NULL
;
785 self
->associateCallback
= NULL
;
786 self
->btCompareCallback
= NULL
;
787 self
->primaryDBType
= 0;
790 self
->in_weakreflist
= NULL
;
793 /* keep a reference to our python DBEnv object */
796 self
->myenvobj
= arg
;
797 db_env
= arg
->db_env
;
801 self
->moduleFlags
= self
->myenvobj
->moduleFlags
;
803 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
804 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
806 MYDB_BEGIN_ALLOW_THREADS
;
807 err
= db_create(&self
->db
, db_env
, flags
);
808 if (self
->db
!= NULL
) {
809 self
->db
->set_errcall(self
->db
, _db_errorCallback
);
811 self
->db
->app_private
= (void*)self
;
814 MYDB_END_ALLOW_THREADS
;
815 /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
816 * list so that a DBEnv can refuse to close without aborting any open
817 * DBTxns and closing any open DBs first. */
818 if (makeDBError(err
)) {
819 if (self
->myenvobj
) {
820 Py_DECREF(self
->myenvobj
);
821 self
->myenvobj
= NULL
;
831 DB_dealloc(DBObject
* self
)
833 if (self
->db
!= NULL
) {
834 /* avoid closing a DB when its DBEnv has been closed out from under
836 if (!self
->myenvobj
||
837 (self
->myenvobj
&& self
->myenvobj
->db_env
))
839 MYDB_BEGIN_ALLOW_THREADS
;
840 self
->db
->close(self
->db
, 0);
841 MYDB_END_ALLOW_THREADS
;
844 PyErr_Warn(PyExc_RuntimeWarning
,
845 "DB could not be closed in destructor: DBEnv already closed");
851 if (self
->in_weakreflist
!= NULL
) {
852 PyObject_ClearWeakRefs((PyObject
*) self
);
855 if (self
->myenvobj
) {
856 Py_DECREF(self
->myenvobj
);
857 self
->myenvobj
= NULL
;
860 if (self
->associateCallback
!= NULL
) {
861 Py_DECREF(self
->associateCallback
);
862 self
->associateCallback
= NULL
;
864 if (self
->btCompareCallback
!= NULL
) {
865 Py_DECREF(self
->btCompareCallback
);
866 self
->btCompareCallback
= NULL
;
873 static DBCursorObject
*
874 newDBCursorObject(DBC
* dbc
, DBObject
* db
)
876 DBCursorObject
* self
= PyObject_New(DBCursorObject
, &DBCursor_Type
);
883 self
->in_weakreflist
= NULL
;
885 Py_INCREF(self
->mydb
);
891 DBCursor_dealloc(DBCursorObject
* self
)
896 if (self
->in_weakreflist
!= NULL
) {
897 PyObject_ClearWeakRefs((PyObject
*) self
);
901 if (self
->dbc
!= NULL
) {
902 MYDB_BEGIN_ALLOW_THREADS
;
903 /* If the underlying database has been closed, we don't
904 need to do anything. If the environment has been closed
905 we need to leak, as BerkeleyDB will crash trying to access
906 the environment. There was an exception when the
907 user closed the environment even though there still was
909 if (self
->mydb
->db
&& self
->mydb
->myenvobj
&&
910 !self
->mydb
->myenvobj
->closed
)
911 err
= self
->dbc
->c_close(self
->dbc
);
913 MYDB_END_ALLOW_THREADS
;
915 Py_XDECREF( self
->mydb
);
921 newDBEnvObject(int flags
)
924 DBEnvObject
* self
= PyObject_New(DBEnvObject
, &DBEnv_Type
);
930 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
931 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
933 self
->in_weakreflist
= NULL
;
936 MYDB_BEGIN_ALLOW_THREADS
;
937 err
= db_env_create(&self
->db_env
, flags
);
938 MYDB_END_ALLOW_THREADS
;
939 if (makeDBError(err
)) {
944 self
->db_env
->set_errcall(self
->db_env
, _db_errorCallback
);
951 DBEnv_dealloc(DBEnvObject
* self
)
954 if (self
->in_weakreflist
!= NULL
) {
955 PyObject_ClearWeakRefs((PyObject
*) self
);
959 if (self
->db_env
&& !self
->closed
) {
960 MYDB_BEGIN_ALLOW_THREADS
;
961 self
->db_env
->close(self
->db_env
, 0);
962 MYDB_END_ALLOW_THREADS
;
969 newDBTxnObject(DBEnvObject
* myenv
, DB_TXN
*parent
, int flags
)
972 DBTxnObject
* self
= PyObject_New(DBTxnObject
, &DBTxn_Type
);
976 self
->env
= (PyObject
*)myenv
;
978 self
->in_weakreflist
= NULL
;
981 MYDB_BEGIN_ALLOW_THREADS
;
983 err
= myenv
->db_env
->txn_begin(myenv
->db_env
, parent
, &(self
->txn
), flags
);
985 err
= txn_begin(myenv
->db_env
, parent
, &(self
->txn
), flags
);
987 MYDB_END_ALLOW_THREADS
;
988 if (makeDBError(err
)) {
989 Py_DECREF(self
->env
);
998 DBTxn_dealloc(DBTxnObject
* self
)
1001 if (self
->in_weakreflist
!= NULL
) {
1002 PyObject_ClearWeakRefs((PyObject
*) self
);
1006 #ifdef HAVE_WARNINGS
1008 /* it hasn't been finalized, abort it! */
1009 MYDB_BEGIN_ALLOW_THREADS
;
1011 self
->txn
->abort(self
->txn
);
1013 txn_abort(self
->txn
);
1015 MYDB_END_ALLOW_THREADS
;
1016 PyErr_Warn(PyExc_RuntimeWarning
,
1017 "DBTxn aborted in destructor. No prior commit() or abort().");
1021 Py_DECREF(self
->env
);
1026 static DBLockObject
*
1027 newDBLockObject(DBEnvObject
* myenv
, u_int32_t locker
, DBT
* obj
,
1028 db_lockmode_t lock_mode
, int flags
)
1031 DBLockObject
* self
= PyObject_New(DBLockObject
, &DBLock_Type
);
1035 self
->in_weakreflist
= NULL
;
1038 MYDB_BEGIN_ALLOW_THREADS
;
1040 err
= myenv
->db_env
->lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
,
1043 err
= lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
, &self
->lock
);
1045 MYDB_END_ALLOW_THREADS
;
1046 if (makeDBError(err
)) {
1056 DBLock_dealloc(DBLockObject
* self
)
1059 if (self
->in_weakreflist
!= NULL
) {
1060 PyObject_ClearWeakRefs((PyObject
*) self
);
1063 /* TODO: is this lock held? should we release it? */
1070 static DBSequenceObject
*
1071 newDBSequenceObject(DBObject
* mydb
, int flags
)
1074 DBSequenceObject
* self
= PyObject_New(DBSequenceObject
, &DBSequence_Type
);
1080 self
->in_weakreflist
= NULL
;
1084 MYDB_BEGIN_ALLOW_THREADS
;
1085 err
= db_sequence_create(&self
->sequence
, self
->mydb
->db
, flags
);
1086 MYDB_END_ALLOW_THREADS
;
1087 if (makeDBError(err
)) {
1088 Py_DECREF(self
->mydb
);
1098 DBSequence_dealloc(DBSequenceObject
* self
)
1101 if (self
->in_weakreflist
!= NULL
) {
1102 PyObject_ClearWeakRefs((PyObject
*) self
);
1106 Py_DECREF(self
->mydb
);
1111 /* --------------------------------------------------------------------- */
1115 DB_append(DBObject
* self
, PyObject
* args
)
1117 PyObject
* txnobj
= NULL
;
1123 if (!PyArg_UnpackTuple(args
, "append", 1, 2, &dataobj
, &txnobj
))
1126 CHECK_DB_NOT_CLOSED(self
);
1128 /* make a dummy key out of a recno */
1132 key
.size
= sizeof(recno
);
1133 key
.ulen
= key
.size
;
1134 key
.flags
= DB_DBT_USERMEM
;
1136 if (!make_dbt(dataobj
, &data
)) return NULL
;
1137 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1139 if (-1 == _DB_put(self
, txn
, &key
, &data
, DB_APPEND
))
1142 return PyInt_FromLong(recno
);
1149 _db_associateCallback(DB
* db
, const DBT
* priKey
, const DBT
* priData
,
1152 int retval
= DB_DONOTINDEX
;
1153 DBObject
* secondaryDB
= (DBObject
*)db
->app_private
;
1154 PyObject
* callback
= secondaryDB
->associateCallback
;
1155 int type
= secondaryDB
->primaryDBType
;
1157 PyObject
* result
= NULL
;
1160 if (callback
!= NULL
) {
1161 MYDB_BEGIN_BLOCK_THREADS
;
1163 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
1164 args
= Py_BuildValue("(ls#)", *((db_recno_t
*)priKey
->data
),
1165 priData
->data
, priData
->size
);
1167 args
= Py_BuildValue("(s#s#)", priKey
->data
, priKey
->size
,
1168 priData
->data
, priData
->size
);
1170 result
= PyEval_CallObject(callback
, args
);
1172 if (args
== NULL
|| result
== NULL
) {
1175 else if (result
== Py_None
) {
1176 retval
= DB_DONOTINDEX
;
1178 else if (PyInt_Check(result
)) {
1179 retval
= PyInt_AsLong(result
);
1181 else if (PyString_Check(result
)) {
1186 #if PYTHON_API_VERSION <= 1007
1187 /* 1.5 compatibility */
1188 size
= PyString_Size(result
);
1189 data
= PyString_AsString(result
);
1191 PyString_AsStringAndSize(result
, &data
, &size
);
1193 secKey
->flags
= DB_DBT_APPMALLOC
; /* DB will free */
1194 secKey
->data
= malloc(size
); /* TODO, check this */
1196 memcpy(secKey
->data
, data
, size
);
1197 secKey
->size
= size
;
1201 PyErr_SetString(PyExc_MemoryError
,
1202 "malloc failed in _db_associateCallback");
1209 "DB associate callback should return DB_DONOTINDEX or string.");
1216 MYDB_END_BLOCK_THREADS
;
1223 DB_associate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1226 DBObject
* secondaryDB
;
1229 PyObject
*txnobj
= NULL
;
1231 static char* kwnames
[] = {"secondaryDB", "callback", "flags", "txn",
1234 static char* kwnames
[] = {"secondaryDB", "callback", "flags", NULL
};
1238 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iO:associate", kwnames
,
1239 &secondaryDB
, &callback
, &flags
,
1242 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|i:associate", kwnames
,
1243 &secondaryDB
, &callback
, &flags
)) {
1249 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1252 CHECK_DB_NOT_CLOSED(self
);
1253 if (!DBObject_Check(secondaryDB
)) {
1254 makeTypeError("DB", (PyObject
*)secondaryDB
);
1257 CHECK_DB_NOT_CLOSED(secondaryDB
);
1258 if (callback
== Py_None
) {
1261 else if (!PyCallable_Check(callback
)) {
1262 makeTypeError("Callable", callback
);
1266 /* Save a reference to the callback in the secondary DB. */
1267 Py_XDECREF(secondaryDB
->associateCallback
);
1268 Py_XINCREF(callback
);
1269 secondaryDB
->associateCallback
= callback
;
1270 secondaryDB
->primaryDBType
= _DB_get_type(self
);
1272 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1273 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1274 * The global interepreter lock is not initialized until the first
1275 * thread is created using thread.start_new_thread() or fork() is
1276 * called. that would cause the ALLOW_THREADS here to segfault due
1277 * to a null pointer reference if no threads or child processes
1278 * have been created. This works around that and is a no-op if
1279 * threads have already been initialized.
1280 * (see pybsddb-users mailing list post on 2002-08-07)
1283 PyEval_InitThreads();
1285 MYDB_BEGIN_ALLOW_THREADS
;
1287 err
= self
->db
->associate(self
->db
,
1290 _db_associateCallback
,
1293 err
= self
->db
->associate(self
->db
,
1295 _db_associateCallback
,
1298 MYDB_END_ALLOW_THREADS
;
1301 Py_XDECREF(secondaryDB
->associateCallback
);
1302 secondaryDB
->associateCallback
= NULL
;
1303 secondaryDB
->primaryDBType
= 0;
1315 DB_close(DBObject
* self
, PyObject
* args
)
1318 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
1320 if (self
->db
!= NULL
) {
1322 CHECK_ENV_NOT_CLOSED(self
->myenvobj
);
1323 err
= self
->db
->close(self
->db
, flags
);
1333 _DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1335 int err
, flags
=0, type
;
1336 PyObject
* txnobj
= NULL
;
1337 PyObject
* retval
= NULL
;
1340 static char* kwnames
[] = { "txn", "flags", NULL
};
1342 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:consume", kwnames
,
1346 CHECK_DB_NOT_CLOSED(self
);
1347 type
= _DB_get_type(self
);
1350 if (type
!= DB_QUEUE
) {
1351 PyErr_SetString(PyExc_TypeError
,
1352 "Consume methods only allowed for Queue DB's");
1355 if (!checkTxnObj(txnobj
, &txn
))
1360 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1361 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1362 data
.flags
= DB_DBT_MALLOC
;
1363 key
.flags
= DB_DBT_MALLOC
;
1366 MYDB_BEGIN_ALLOW_THREADS
;
1367 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
|consume_flag
);
1368 MYDB_END_ALLOW_THREADS
;
1370 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1371 && self
->moduleFlags
.getReturnsNone
) {
1377 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
1388 DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1390 return _DB_consume(self
, args
, kwargs
, DB_CONSUME
);
1394 DB_consume_wait(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
,
1397 return _DB_consume(self
, args
, kwargs
, DB_CONSUME_WAIT
);
1404 DB_cursor(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1408 PyObject
* txnobj
= NULL
;
1410 static char* kwnames
[] = { "txn", "flags", NULL
};
1412 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
1415 CHECK_DB_NOT_CLOSED(self
);
1416 if (!checkTxnObj(txnobj
, &txn
))
1419 MYDB_BEGIN_ALLOW_THREADS
;
1420 err
= self
->db
->cursor(self
->db
, txn
, &dbc
, flags
);
1421 MYDB_END_ALLOW_THREADS
;
1423 return (PyObject
*) newDBCursorObject(dbc
, self
);
1428 DB_delete(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1430 PyObject
* txnobj
= NULL
;
1435 static char* kwnames
[] = { "key", "txn", "flags", NULL
};
1437 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:delete", kwnames
,
1438 &keyobj
, &txnobj
, &flags
))
1440 CHECK_DB_NOT_CLOSED(self
);
1441 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1443 if (!checkTxnObj(txnobj
, &txn
)) {
1448 if (-1 == _DB_delete(self
, txn
, &key
, 0)) {
1459 DB_fd(DBObject
* self
, PyObject
* args
)
1463 if (!PyArg_ParseTuple(args
,":fd"))
1465 CHECK_DB_NOT_CLOSED(self
);
1467 MYDB_BEGIN_ALLOW_THREADS
;
1468 err
= self
->db
->fd(self
->db
, &the_fd
);
1469 MYDB_END_ALLOW_THREADS
;
1471 return PyInt_FromLong(the_fd
);
1476 DB_get(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1479 PyObject
* txnobj
= NULL
;
1481 PyObject
* dfltobj
= NULL
;
1482 PyObject
* retval
= NULL
;
1487 static char* kwnames
[] = {"key", "default", "txn", "flags", "dlen",
1490 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:get", kwnames
,
1491 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1495 CHECK_DB_NOT_CLOSED(self
);
1496 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1498 if (!checkTxnObj(txnobj
, &txn
)) {
1504 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1505 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1506 data
.flags
= DB_DBT_MALLOC
;
1508 if (!add_partial_dbt(&data
, dlen
, doff
)) {
1513 MYDB_BEGIN_ALLOW_THREADS
;
1514 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1515 MYDB_END_ALLOW_THREADS
;
1517 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && (dfltobj
!= NULL
)) {
1522 else if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1523 && self
->moduleFlags
.getReturnsNone
) {
1529 if (flags
& DB_SET_RECNO
) /* return both key and data */
1530 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
1532 else /* return just the data */
1533 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
1544 DB_pget(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1547 PyObject
* txnobj
= NULL
;
1549 PyObject
* dfltobj
= NULL
;
1550 PyObject
* retval
= NULL
;
1553 DBT key
, pkey
, data
;
1555 static char* kwnames
[] = {"key", "default", "txn", "flags", "dlen",
1558 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:pget", kwnames
,
1559 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1563 CHECK_DB_NOT_CLOSED(self
);
1564 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1566 if (!checkTxnObj(txnobj
, &txn
)) {
1572 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1573 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1574 data
.flags
= DB_DBT_MALLOC
;
1576 if (!add_partial_dbt(&data
, dlen
, doff
)) {
1582 pkey
.flags
= DB_DBT_MALLOC
;
1584 MYDB_BEGIN_ALLOW_THREADS
;
1585 err
= self
->db
->pget(self
->db
, txn
, &key
, &pkey
, &data
, flags
);
1586 MYDB_END_ALLOW_THREADS
;
1588 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && (dfltobj
!= NULL
)) {
1593 else if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1594 && self
->moduleFlags
.getReturnsNone
) {
1602 dataObj
= PyString_FromStringAndSize(data
.data
, data
.size
);
1604 if (self
->primaryDBType
== DB_RECNO
||
1605 self
->primaryDBType
== DB_QUEUE
)
1606 pkeyObj
= PyInt_FromLong(*(int *)pkey
.data
);
1608 pkeyObj
= PyString_FromStringAndSize(pkey
.data
, pkey
.size
);
1610 if (flags
& DB_SET_RECNO
) /* return key , pkey and data */
1613 int type
= _DB_get_type(self
);
1614 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
1615 keyObj
= PyInt_FromLong(*(int *)key
.data
);
1617 keyObj
= PyString_FromStringAndSize(key
.data
, key
.size
);
1618 #if (PY_VERSION_HEX >= 0x02040000)
1619 retval
= PyTuple_Pack(3, keyObj
, pkeyObj
, dataObj
);
1621 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
1625 else /* return just the pkey and data */
1627 #if (PY_VERSION_HEX >= 0x02040000)
1628 retval
= PyTuple_Pack(2, pkeyObj
, dataObj
);
1630 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
1646 /* Return size of entry */
1648 DB_get_size(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1651 PyObject
* txnobj
= NULL
;
1653 PyObject
* retval
= NULL
;
1656 static char* kwnames
[] = { "key", "txn", NULL
};
1658 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O:get_size", kwnames
,
1661 CHECK_DB_NOT_CLOSED(self
);
1662 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1664 if (!checkTxnObj(txnobj
, &txn
)) {
1670 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
1671 thus getting the record size. */
1672 data
.flags
= DB_DBT_USERMEM
;
1674 MYDB_BEGIN_ALLOW_THREADS
;
1675 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1676 MYDB_END_ALLOW_THREADS
;
1677 if (err
== DB_BUFFER_SMALL
) {
1678 retval
= PyInt_FromLong((long)data
.size
);
1690 DB_get_both(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1693 PyObject
* txnobj
= NULL
;
1696 PyObject
* retval
= NULL
;
1699 static char* kwnames
[] = { "key", "data", "txn", "flags", NULL
};
1702 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oi:get_both", kwnames
,
1703 &keyobj
, &dataobj
, &txnobj
, &flags
))
1706 CHECK_DB_NOT_CLOSED(self
);
1707 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1709 if ( !make_dbt(dataobj
, &data
) ||
1710 !checkTxnObj(txnobj
, &txn
) )
1716 flags
|= DB_GET_BOTH
;
1718 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1719 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1720 data
.flags
= DB_DBT_MALLOC
;
1721 /* TODO: Is this flag needed? We're passing a data object that should
1722 match what's in the DB, so there should be no need to malloc.
1723 We run the risk of freeing something twice! Check this. */
1726 MYDB_BEGIN_ALLOW_THREADS
;
1727 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1728 MYDB_END_ALLOW_THREADS
;
1730 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1731 && self
->moduleFlags
.getReturnsNone
) {
1737 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
1738 FREE_DBT(data
); /* Only if retrieval was successful */
1748 DB_get_byteswapped(DBObject
* self
, PyObject
* args
)
1755 if (!PyArg_ParseTuple(args
,":get_byteswapped"))
1757 CHECK_DB_NOT_CLOSED(self
);
1760 MYDB_BEGIN_ALLOW_THREADS
;
1761 err
= self
->db
->get_byteswapped(self
->db
, &retval
);
1762 MYDB_END_ALLOW_THREADS
;
1765 MYDB_BEGIN_ALLOW_THREADS
;
1766 retval
= self
->db
->get_byteswapped(self
->db
);
1767 MYDB_END_ALLOW_THREADS
;
1769 return PyInt_FromLong(retval
);
1774 DB_get_type(DBObject
* self
, PyObject
* args
)
1778 if (!PyArg_ParseTuple(args
,":get_type"))
1780 CHECK_DB_NOT_CLOSED(self
);
1782 type
= _DB_get_type(self
);
1785 return PyInt_FromLong(type
);
1790 DB_join(DBObject
* self
, PyObject
* args
)
1794 PyObject
* cursorsObj
;
1798 if (!PyArg_ParseTuple(args
,"O|i:join", &cursorsObj
, &flags
))
1801 CHECK_DB_NOT_CLOSED(self
);
1803 if (!PySequence_Check(cursorsObj
)) {
1804 PyErr_SetString(PyExc_TypeError
,
1805 "Sequence of DBCursor objects expected");
1809 length
= PyObject_Length(cursorsObj
);
1810 cursors
= malloc((length
+1) * sizeof(DBC
*));
1816 cursors
[length
] = NULL
;
1817 for (x
=0; x
<length
; x
++) {
1818 PyObject
* item
= PySequence_GetItem(cursorsObj
, x
);
1823 if (!DBCursorObject_Check(item
)) {
1824 PyErr_SetString(PyExc_TypeError
,
1825 "Sequence of DBCursor objects expected");
1829 cursors
[x
] = ((DBCursorObject
*)item
)->dbc
;
1833 MYDB_BEGIN_ALLOW_THREADS
;
1834 err
= self
->db
->join(self
->db
, cursors
, &dbc
, flags
);
1835 MYDB_END_ALLOW_THREADS
;
1839 /* FIXME: this is a buggy interface. The returned cursor
1840 contains internal references to the passed in cursors
1841 but does not hold python references to them or prevent
1842 them from being closed prematurely. This can cause
1843 python to crash when things are done in the wrong order. */
1844 return (PyObject
*) newDBCursorObject(dbc
, self
);
1849 DB_key_range(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1852 PyObject
* txnobj
= NULL
;
1857 static char* kwnames
[] = { "key", "txn", "flags", NULL
};
1859 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:key_range", kwnames
,
1860 &keyobj
, &txnobj
, &flags
))
1862 CHECK_DB_NOT_CLOSED(self
);
1863 if (!make_dbt(keyobj
, &key
))
1864 /* BTree only, don't need to allow for an int key */
1866 if (!checkTxnObj(txnobj
, &txn
))
1869 MYDB_BEGIN_ALLOW_THREADS
;
1870 err
= self
->db
->key_range(self
->db
, txn
, &key
, &range
, flags
);
1871 MYDB_END_ALLOW_THREADS
;
1874 return Py_BuildValue("ddd", range
.less
, range
.equal
, range
.greater
);
1879 DB_open(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1881 int err
, type
= DB_UNKNOWN
, flags
=0, mode
=0660;
1882 char* filename
= NULL
;
1883 char* dbname
= NULL
;
1885 PyObject
*txnobj
= NULL
;
1888 static char* kwnames
[] = {
1889 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL
};
1890 /* without dbname */
1891 static char* kwnames_basic
[] = {
1892 "filename", "dbtype", "flags", "mode", "txn", NULL
};
1895 static char* kwnames
[] = {
1896 "filename", "dbname", "dbtype", "flags", "mode", NULL
};
1897 /* without dbname */
1898 static char* kwnames_basic
[] = {
1899 "filename", "dbtype", "flags", "mode", NULL
};
1903 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziiiO:open", kwnames
,
1904 &filename
, &dbname
, &type
, &flags
, &mode
,
1907 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziii:open", kwnames
,
1908 &filename
, &dbname
, &type
, &flags
,
1913 type
= DB_UNKNOWN
; flags
= 0; mode
= 0660;
1914 filename
= NULL
; dbname
= NULL
;
1916 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iiiO:open",
1918 &filename
, &type
, &flags
, &mode
,
1922 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iii:open",
1924 &filename
, &type
, &flags
, &mode
))
1930 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1933 if (NULL
== self
->db
) {
1934 PyObject
*t
= Py_BuildValue("(is)", 0,
1935 "Cannot call open() twice for DB object");
1936 PyErr_SetObject(DBError
, t
);
1941 #if 0 && (DBVER >= 41)
1942 if ((!txn
) && (txnobj
!= Py_None
) && self
->myenvobj
1943 && (self
->myenvobj
->flags
& DB_INIT_TXN
))
1945 /* If no 'txn' parameter was supplied (no DbTxn object and None was not
1946 * explicitly passed) but we are in a transaction ready environment:
1947 * add DB_AUTO_COMMIT to allow for older pybsddb apps using transactions
1948 * to work on BerkeleyDB 4.1 without needing to modify their
1949 * DBEnv or DB open calls.
1950 * TODO make this behaviour of the library configurable.
1952 flags
|= DB_AUTO_COMMIT
;
1956 MYDB_BEGIN_ALLOW_THREADS
;
1958 err
= self
->db
->open(self
->db
, txn
, filename
, dbname
, type
, flags
, mode
);
1960 err
= self
->db
->open(self
->db
, filename
, dbname
, type
, flags
, mode
);
1962 MYDB_END_ALLOW_THREADS
;
1963 if (makeDBError(err
)) {
1964 self
->db
->close(self
->db
, 0);
1969 self
->flags
= flags
;
1975 DB_put(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1978 PyObject
* txnobj
= NULL
;
1981 PyObject
* keyobj
, *dataobj
, *retval
;
1984 static char* kwnames
[] = { "key", "data", "txn", "flags", "dlen",
1987 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oiii:put", kwnames
,
1988 &keyobj
, &dataobj
, &txnobj
, &flags
, &dlen
, &doff
))
1991 CHECK_DB_NOT_CLOSED(self
);
1992 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1994 if ( !make_dbt(dataobj
, &data
) ||
1995 !add_partial_dbt(&data
, dlen
, doff
) ||
1996 !checkTxnObj(txnobj
, &txn
) )
2002 if (-1 == _DB_put(self
, txn
, &key
, &data
, flags
)) {
2007 if (flags
& DB_APPEND
)
2008 retval
= PyInt_FromLong(*((db_recno_t
*)key
.data
));
2020 DB_remove(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2023 char* database
= NULL
;
2025 static char* kwnames
[] = { "filename", "dbname", "flags", NULL
};
2027 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zi:remove", kwnames
,
2028 &filename
, &database
, &flags
))
2030 CHECK_DB_NOT_CLOSED(self
);
2032 err
= self
->db
->remove(self
->db
, filename
, database
, flags
);
2041 DB_rename(DBObject
* self
, PyObject
* args
)
2048 if (!PyArg_ParseTuple(args
, "sss|i:rename", &filename
, &database
, &newname
,
2051 CHECK_DB_NOT_CLOSED(self
);
2053 MYDB_BEGIN_ALLOW_THREADS
;
2054 err
= self
->db
->rename(self
->db
, filename
, database
, newname
, flags
);
2055 MYDB_END_ALLOW_THREADS
;
2062 DB_set_bt_minkey(DBObject
* self
, PyObject
* args
)
2066 if (!PyArg_ParseTuple(args
,"i:set_bt_minkey", &minkey
))
2068 CHECK_DB_NOT_CLOSED(self
);
2070 MYDB_BEGIN_ALLOW_THREADS
;
2071 err
= self
->db
->set_bt_minkey(self
->db
, minkey
);
2072 MYDB_END_ALLOW_THREADS
;
2079 _default_cmp(const DBT
*leftKey
,
2080 const DBT
*rightKey
)
2083 int lsize
= leftKey
->size
, rsize
= rightKey
->size
;
2085 res
= memcmp(leftKey
->data
, rightKey
->data
,
2086 lsize
< rsize
? lsize
: rsize
);
2089 if (lsize
< rsize
) {
2092 else if (lsize
> rsize
) {
2100 _db_compareCallback(DB
* db
,
2102 const DBT
*rightKey
)
2106 PyObject
*result
= NULL
;
2107 DBObject
*self
= (DBObject
*)db
->app_private
;
2109 if (self
== NULL
|| self
->btCompareCallback
== NULL
) {
2110 MYDB_BEGIN_BLOCK_THREADS
;
2111 PyErr_SetString(PyExc_TypeError
,
2113 ? "DB_bt_compare db is NULL."
2114 : "DB_bt_compare callback is NULL."));
2115 /* we're in a callback within the DB code, we can't raise */
2117 res
= _default_cmp(leftKey
, rightKey
);
2118 MYDB_END_BLOCK_THREADS
;
2120 MYDB_BEGIN_BLOCK_THREADS
;
2122 args
= Py_BuildValue("s#s#", leftKey
->data
, leftKey
->size
,
2123 rightKey
->data
, rightKey
->size
);
2125 /* XXX(twouters) I highly doubt this INCREF is correct */
2127 result
= PyEval_CallObject(self
->btCompareCallback
, args
);
2129 if (args
== NULL
|| result
== NULL
) {
2130 /* we're in a callback within the DB code, we can't raise */
2132 res
= _default_cmp(leftKey
, rightKey
);
2133 } else if (PyInt_Check(result
)) {
2134 res
= PyInt_AsLong(result
);
2136 PyErr_SetString(PyExc_TypeError
,
2137 "DB_bt_compare callback MUST return an int.");
2138 /* we're in a callback within the DB code, we can't raise */
2140 res
= _default_cmp(leftKey
, rightKey
);
2146 MYDB_END_BLOCK_THREADS
;
2152 DB_set_bt_compare(DBObject
* self
, PyObject
* args
)
2155 PyObject
*comparator
;
2156 PyObject
*tuple
, *result
;
2158 if (!PyArg_ParseTuple(args
, "O:set_bt_compare", &comparator
))
2161 CHECK_DB_NOT_CLOSED(self
);
2163 if (!PyCallable_Check(comparator
)) {
2164 makeTypeError("Callable", comparator
);
2169 * Perform a test call of the comparator function with two empty
2170 * string objects here. verify that it returns an int (0).
2173 tuple
= Py_BuildValue("(ss)", "", "");
2174 result
= PyEval_CallObject(comparator
, tuple
);
2178 if (!PyInt_Check(result
)) {
2179 PyErr_SetString(PyExc_TypeError
,
2180 "callback MUST return an int");
2182 } else if (PyInt_AsLong(result
) != 0) {
2183 PyErr_SetString(PyExc_TypeError
,
2184 "callback failed to return 0 on two empty strings");
2189 /* We don't accept multiple set_bt_compare operations, in order to
2190 * simplify the code. This would have no real use, as one cannot
2191 * change the function once the db is opened anyway */
2192 if (self
->btCompareCallback
!= NULL
) {
2193 PyErr_SetString(PyExc_RuntimeError
, "set_bt_compare() cannot be called more than once");
2197 Py_INCREF(comparator
);
2198 self
->btCompareCallback
= comparator
;
2200 /* This is to workaround a problem with un-initialized threads (see
2201 comment in DB_associate) */
2203 PyEval_InitThreads();
2206 err
= self
->db
->set_bt_compare(self
->db
, _db_compareCallback
);
2209 /* restore the old state in case of error */
2210 Py_DECREF(comparator
);
2211 self
->btCompareCallback
= NULL
;
2217 #endif /* DBVER >= 33 */
2221 DB_set_cachesize(DBObject
* self
, PyObject
* args
)
2224 int gbytes
= 0, bytes
= 0, ncache
= 0;
2226 if (!PyArg_ParseTuple(args
,"ii|i:set_cachesize",
2227 &gbytes
,&bytes
,&ncache
))
2229 CHECK_DB_NOT_CLOSED(self
);
2231 MYDB_BEGIN_ALLOW_THREADS
;
2232 err
= self
->db
->set_cachesize(self
->db
, gbytes
, bytes
, ncache
);
2233 MYDB_END_ALLOW_THREADS
;
2240 DB_set_flags(DBObject
* self
, PyObject
* args
)
2244 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
2246 CHECK_DB_NOT_CLOSED(self
);
2248 MYDB_BEGIN_ALLOW_THREADS
;
2249 err
= self
->db
->set_flags(self
->db
, flags
);
2250 MYDB_END_ALLOW_THREADS
;
2253 self
->setflags
|= flags
;
2259 DB_set_h_ffactor(DBObject
* self
, PyObject
* args
)
2263 if (!PyArg_ParseTuple(args
,"i:set_h_ffactor", &ffactor
))
2265 CHECK_DB_NOT_CLOSED(self
);
2267 MYDB_BEGIN_ALLOW_THREADS
;
2268 err
= self
->db
->set_h_ffactor(self
->db
, ffactor
);
2269 MYDB_END_ALLOW_THREADS
;
2276 DB_set_h_nelem(DBObject
* self
, PyObject
* args
)
2280 if (!PyArg_ParseTuple(args
,"i:set_h_nelem", &nelem
))
2282 CHECK_DB_NOT_CLOSED(self
);
2284 MYDB_BEGIN_ALLOW_THREADS
;
2285 err
= self
->db
->set_h_nelem(self
->db
, nelem
);
2286 MYDB_END_ALLOW_THREADS
;
2293 DB_set_lorder(DBObject
* self
, PyObject
* args
)
2297 if (!PyArg_ParseTuple(args
,"i:set_lorder", &lorder
))
2299 CHECK_DB_NOT_CLOSED(self
);
2301 MYDB_BEGIN_ALLOW_THREADS
;
2302 err
= self
->db
->set_lorder(self
->db
, lorder
);
2303 MYDB_END_ALLOW_THREADS
;
2310 DB_set_pagesize(DBObject
* self
, PyObject
* args
)
2314 if (!PyArg_ParseTuple(args
,"i:set_pagesize", &pagesize
))
2316 CHECK_DB_NOT_CLOSED(self
);
2318 MYDB_BEGIN_ALLOW_THREADS
;
2319 err
= self
->db
->set_pagesize(self
->db
, pagesize
);
2320 MYDB_END_ALLOW_THREADS
;
2327 DB_set_re_delim(DBObject
* self
, PyObject
* args
)
2332 if (!PyArg_ParseTuple(args
,"b:set_re_delim", &delim
)) {
2334 if (!PyArg_ParseTuple(args
,"c:set_re_delim", &delim
))
2338 CHECK_DB_NOT_CLOSED(self
);
2340 MYDB_BEGIN_ALLOW_THREADS
;
2341 err
= self
->db
->set_re_delim(self
->db
, delim
);
2342 MYDB_END_ALLOW_THREADS
;
2348 DB_set_re_len(DBObject
* self
, PyObject
* args
)
2352 if (!PyArg_ParseTuple(args
,"i:set_re_len", &len
))
2354 CHECK_DB_NOT_CLOSED(self
);
2356 MYDB_BEGIN_ALLOW_THREADS
;
2357 err
= self
->db
->set_re_len(self
->db
, len
);
2358 MYDB_END_ALLOW_THREADS
;
2365 DB_set_re_pad(DBObject
* self
, PyObject
* args
)
2370 if (!PyArg_ParseTuple(args
,"b:set_re_pad", &pad
)) {
2372 if (!PyArg_ParseTuple(args
,"c:set_re_pad", &pad
))
2375 CHECK_DB_NOT_CLOSED(self
);
2377 MYDB_BEGIN_ALLOW_THREADS
;
2378 err
= self
->db
->set_re_pad(self
->db
, pad
);
2379 MYDB_END_ALLOW_THREADS
;
2386 DB_set_re_source(DBObject
* self
, PyObject
* args
)
2391 if (!PyArg_ParseTuple(args
,"s:set_re_source", &re_source
))
2393 CHECK_DB_NOT_CLOSED(self
);
2395 MYDB_BEGIN_ALLOW_THREADS
;
2396 err
= self
->db
->set_re_source(self
->db
, re_source
);
2397 MYDB_END_ALLOW_THREADS
;
2405 DB_set_q_extentsize(DBObject
* self
, PyObject
* args
)
2410 if (!PyArg_ParseTuple(args
,"i:set_q_extentsize", &extentsize
))
2412 CHECK_DB_NOT_CLOSED(self
);
2414 MYDB_BEGIN_ALLOW_THREADS
;
2415 err
= self
->db
->set_q_extentsize(self
->db
, extentsize
);
2416 MYDB_END_ALLOW_THREADS
;
2423 DB_stat(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2425 int err
, flags
= 0, type
;
2429 PyObject
* txnobj
= NULL
;
2431 static char* kwnames
[] = { "flags", "txn", NULL
};
2433 static char* kwnames
[] = { "flags", NULL
};
2437 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iO:stat", kwnames
,
2440 if (!checkTxnObj(txnobj
, &txn
))
2443 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat", kwnames
, &flags
))
2446 CHECK_DB_NOT_CLOSED(self
);
2448 MYDB_BEGIN_ALLOW_THREADS
;
2450 err
= self
->db
->stat(self
->db
, txn
, &sp
, flags
);
2452 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2454 err
= self
->db
->stat(self
->db
, &sp
, NULL
, flags
);
2456 MYDB_END_ALLOW_THREADS
;
2461 /* Turn the stat structure into a dictionary */
2462 type
= _DB_get_type(self
);
2463 if ((type
== -1) || ((d
= PyDict_New()) == NULL
)) {
2468 #define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
2469 #define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
2470 #define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
2474 MAKE_HASH_ENTRY(magic
);
2475 MAKE_HASH_ENTRY(version
);
2476 MAKE_HASH_ENTRY(nkeys
);
2477 MAKE_HASH_ENTRY(ndata
);
2478 MAKE_HASH_ENTRY(pagesize
);
2480 MAKE_HASH_ENTRY(nelem
);
2482 MAKE_HASH_ENTRY(ffactor
);
2483 MAKE_HASH_ENTRY(buckets
);
2484 MAKE_HASH_ENTRY(free
);
2485 MAKE_HASH_ENTRY(bfree
);
2486 MAKE_HASH_ENTRY(bigpages
);
2487 MAKE_HASH_ENTRY(big_bfree
);
2488 MAKE_HASH_ENTRY(overflows
);
2489 MAKE_HASH_ENTRY(ovfl_free
);
2490 MAKE_HASH_ENTRY(dup
);
2491 MAKE_HASH_ENTRY(dup_free
);
2496 MAKE_BT_ENTRY(magic
);
2497 MAKE_BT_ENTRY(version
);
2498 MAKE_BT_ENTRY(nkeys
);
2499 MAKE_BT_ENTRY(ndata
);
2500 MAKE_BT_ENTRY(pagesize
);
2501 MAKE_BT_ENTRY(minkey
);
2502 MAKE_BT_ENTRY(re_len
);
2503 MAKE_BT_ENTRY(re_pad
);
2504 MAKE_BT_ENTRY(levels
);
2505 MAKE_BT_ENTRY(int_pg
);
2506 MAKE_BT_ENTRY(leaf_pg
);
2507 MAKE_BT_ENTRY(dup_pg
);
2508 MAKE_BT_ENTRY(over_pg
);
2509 MAKE_BT_ENTRY(free
);
2510 MAKE_BT_ENTRY(int_pgfree
);
2511 MAKE_BT_ENTRY(leaf_pgfree
);
2512 MAKE_BT_ENTRY(dup_pgfree
);
2513 MAKE_BT_ENTRY(over_pgfree
);
2517 MAKE_QUEUE_ENTRY(magic
);
2518 MAKE_QUEUE_ENTRY(version
);
2519 MAKE_QUEUE_ENTRY(nkeys
);
2520 MAKE_QUEUE_ENTRY(ndata
);
2521 MAKE_QUEUE_ENTRY(pagesize
);
2522 MAKE_QUEUE_ENTRY(pages
);
2523 MAKE_QUEUE_ENTRY(re_len
);
2524 MAKE_QUEUE_ENTRY(re_pad
);
2525 MAKE_QUEUE_ENTRY(pgfree
);
2527 MAKE_QUEUE_ENTRY(start
);
2529 MAKE_QUEUE_ENTRY(first_recno
);
2530 MAKE_QUEUE_ENTRY(cur_recno
);
2534 PyErr_SetString(PyExc_TypeError
, "Unknown DB type, unable to stat");
2539 #undef MAKE_HASH_ENTRY
2540 #undef MAKE_BT_ENTRY
2541 #undef MAKE_QUEUE_ENTRY
2548 DB_sync(DBObject
* self
, PyObject
* args
)
2553 if (!PyArg_ParseTuple(args
,"|i:sync", &flags
))
2555 CHECK_DB_NOT_CLOSED(self
);
2557 MYDB_BEGIN_ALLOW_THREADS
;
2558 err
= self
->db
->sync(self
->db
, flags
);
2559 MYDB_END_ALLOW_THREADS
;
2567 DB_truncate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2571 PyObject
* txnobj
= NULL
;
2573 static char* kwnames
[] = { "txn", "flags", NULL
};
2575 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
2578 CHECK_DB_NOT_CLOSED(self
);
2579 if (!checkTxnObj(txnobj
, &txn
))
2582 MYDB_BEGIN_ALLOW_THREADS
;
2583 err
= self
->db
->truncate(self
->db
, txn
, &count
, flags
);
2584 MYDB_END_ALLOW_THREADS
;
2586 return PyInt_FromLong(count
);
2592 DB_upgrade(DBObject
* self
, PyObject
* args
)
2597 if (!PyArg_ParseTuple(args
,"s|i:upgrade", &filename
, &flags
))
2599 CHECK_DB_NOT_CLOSED(self
);
2601 MYDB_BEGIN_ALLOW_THREADS
;
2602 err
= self
->db
->upgrade(self
->db
, filename
, flags
);
2603 MYDB_END_ALLOW_THREADS
;
2610 DB_verify(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2615 char* outFileName
=NULL
;
2617 static char* kwnames
[] = { "filename", "dbname", "outfile", "flags",
2620 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zzi:verify", kwnames
,
2621 &fileName
, &dbName
, &outFileName
, &flags
))
2624 CHECK_DB_NOT_CLOSED(self
);
2626 outFile
= fopen(outFileName
, "w");
2627 /* XXX(nnorwitz): it should probably be an exception if outFile
2630 MYDB_BEGIN_ALLOW_THREADS
;
2631 err
= self
->db
->verify(self
->db
, fileName
, dbName
, outFile
, flags
);
2632 MYDB_END_ALLOW_THREADS
;
2636 /* DB.verify acts as a DB handle destructor (like close); this was
2637 * documented in BerkeleyDB 4.2 but had the undocumented effect
2638 * of not being safe in prior versions while still requiring an explicit
2639 * DB.close call afterwards. Lets call close for the user to emulate
2640 * the safe 4.2 behaviour. */
2642 self
->db
->close(self
->db
, 0);
2652 DB_set_get_returns_none(DBObject
* self
, PyObject
* args
)
2657 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
2659 CHECK_DB_NOT_CLOSED(self
);
2661 if (self
->moduleFlags
.getReturnsNone
)
2663 if (self
->moduleFlags
.cursorSetReturnsNone
)
2665 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
2666 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
2667 return PyInt_FromLong(oldValue
);
2672 DB_set_encrypt(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2676 char *passwd
= NULL
;
2677 static char* kwnames
[] = { "passwd", "flags", NULL
};
2679 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
2684 MYDB_BEGIN_ALLOW_THREADS
;
2685 err
= self
->db
->set_encrypt(self
->db
, passwd
, flags
);
2686 MYDB_END_ALLOW_THREADS
;
2691 #endif /* DBVER >= 41 */
2694 /*-------------------------------------------------------------- */
2695 /* Mapping and Dictionary-like access routines */
2697 Py_ssize_t
DB_length(PyObject
* _self
)
2700 Py_ssize_t size
= 0;
2703 DBObject
* self
= (DBObject
*)_self
;
2705 if (self
->db
== NULL
) {
2706 PyObject
*t
= Py_BuildValue("(is)", 0, "DB object has been closed");
2707 PyErr_SetObject(DBError
, t
);
2712 if (self
->haveStat
) { /* Has the stat function been called recently? If
2713 so, we can use the cached value. */
2714 flags
= DB_FAST_STAT
;
2717 MYDB_BEGIN_ALLOW_THREADS
;
2718 redo_stat_for_length
:
2720 err
= self
->db
->stat(self
->db
, /*txnid*/ NULL
, &sp
, flags
);
2722 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2724 err
= self
->db
->stat(self
->db
, &sp
, NULL
, flags
);
2727 /* All the stat structures have matching fields upto the ndata field,
2728 so we can use any of them for the type cast */
2729 size
= ((DB_BTREE_STAT
*)sp
)->bt_ndata
;
2731 /* A size of 0 could mean that BerkeleyDB no longer had the stat values cached.
2732 * redo a full stat to make sure.
2733 * Fixes SF python bug 1493322, pybsddb bug 1184012
2735 if (size
== 0 && (flags
& DB_FAST_STAT
)) {
2739 goto redo_stat_for_length
;
2742 MYDB_END_ALLOW_THREADS
;
2754 PyObject
* DB_subscript(DBObject
* self
, PyObject
* keyobj
)
2761 CHECK_DB_NOT_CLOSED(self
);
2762 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2766 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2767 /* Tell BerkeleyDB to malloc the return value (thread safe) */
2768 data
.flags
= DB_DBT_MALLOC
;
2770 MYDB_BEGIN_ALLOW_THREADS
;
2771 err
= self
->db
->get(self
->db
, NULL
, &key
, &data
, 0);
2772 MYDB_END_ALLOW_THREADS
;
2773 if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
2774 PyErr_SetObject(PyExc_KeyError
, keyobj
);
2777 else if (makeDBError(err
)) {
2781 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
2791 DB_ass_sub(DBObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
)
2797 if (self
->db
== NULL
) {
2798 PyObject
*t
= Py_BuildValue("(is)", 0, "DB object has been closed");
2799 PyErr_SetObject(DBError
, t
);
2804 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2807 if (dataobj
!= NULL
) {
2808 if (!make_dbt(dataobj
, &data
))
2811 if (self
->setflags
& (DB_DUP
|DB_DUPSORT
))
2812 /* dictionaries shouldn't have duplicate keys */
2813 flags
= DB_NOOVERWRITE
;
2814 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2816 if ((retval
== -1) && (self
->setflags
& (DB_DUP
|DB_DUPSORT
))) {
2817 /* try deleting any old record that matches and then PUT it
2819 _DB_delete(self
, NULL
, &key
, 0);
2821 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2826 /* dataobj == NULL, so delete the key */
2827 retval
= _DB_delete(self
, NULL
, &key
, 0);
2835 DB_has_key(DBObject
* self
, PyObject
* args
)
2840 PyObject
* txnobj
= NULL
;
2843 if (!PyArg_ParseTuple(args
,"O|O:has_key", &keyobj
, &txnobj
))
2845 CHECK_DB_NOT_CLOSED(self
);
2846 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2848 if (!checkTxnObj(txnobj
, &txn
)) {
2853 /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
2854 it has a record but can't allocate a buffer for the data. This saves
2855 having to deal with data we won't be using.
2858 data
.flags
= DB_DBT_USERMEM
;
2860 MYDB_BEGIN_ALLOW_THREADS
;
2861 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, 0);
2862 MYDB_END_ALLOW_THREADS
;
2865 if (err
== DB_BUFFER_SMALL
|| err
== 0) {
2866 return PyInt_FromLong(1);
2867 } else if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
2868 return PyInt_FromLong(0);
2876 #define _KEYS_LIST 1
2877 #define _VALUES_LIST 2
2878 #define _ITEMS_LIST 3
2881 _DB_make_list(DBObject
* self
, DB_TXN
* txn
, int type
)
2888 PyObject
* item
= NULL
;
2890 CHECK_DB_NOT_CLOSED(self
);
2894 dbtype
= _DB_get_type(self
);
2898 list
= PyList_New(0);
2903 MYDB_BEGIN_ALLOW_THREADS
;
2904 err
= self
->db
->cursor(self
->db
, txn
, &cursor
, 0);
2905 MYDB_END_ALLOW_THREADS
;
2906 if (makeDBError(err
)) {
2911 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2912 key
.flags
= DB_DBT_REALLOC
;
2913 data
.flags
= DB_DBT_REALLOC
;
2916 while (1) { /* use the cursor to traverse the DB, collecting items */
2917 MYDB_BEGIN_ALLOW_THREADS
;
2918 err
= cursor
->c_get(cursor
, &key
, &data
, DB_NEXT
);
2919 MYDB_END_ALLOW_THREADS
;
2922 /* for any error, break out of the loop */
2932 item
= PyString_FromStringAndSize((char*)key
.data
, key
.size
);
2936 item
= PyInt_FromLong(*((db_recno_t
*)key
.data
));
2942 item
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
2950 item
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
2955 item
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
2956 data
.data
, data
.size
);
2961 PyErr_Format(PyExc_ValueError
, "Unknown key type 0x%x", type
);
2970 PyList_Append(list
, item
);
2974 /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
2975 if (err
!= DB_NOTFOUND
&& err
!= DB_KEYEMPTY
&& makeDBError(err
)) {
2983 MYDB_BEGIN_ALLOW_THREADS
;
2984 cursor
->c_close(cursor
);
2985 MYDB_END_ALLOW_THREADS
;
2991 DB_keys(DBObject
* self
, PyObject
* args
)
2993 PyObject
* txnobj
= NULL
;
2996 if (!PyArg_UnpackTuple(args
, "keys", 0, 1, &txnobj
))
2998 if (!checkTxnObj(txnobj
, &txn
))
3000 return _DB_make_list(self
, txn
, _KEYS_LIST
);
3005 DB_items(DBObject
* self
, PyObject
* args
)
3007 PyObject
* txnobj
= NULL
;
3010 if (!PyArg_UnpackTuple(args
, "items", 0, 1, &txnobj
))
3012 if (!checkTxnObj(txnobj
, &txn
))
3014 return _DB_make_list(self
, txn
, _ITEMS_LIST
);
3019 DB_values(DBObject
* self
, PyObject
* args
)
3021 PyObject
* txnobj
= NULL
;
3024 if (!PyArg_UnpackTuple(args
, "values", 0, 1, &txnobj
))
3026 if (!checkTxnObj(txnobj
, &txn
))
3028 return _DB_make_list(self
, txn
, _VALUES_LIST
);
3031 /* --------------------------------------------------------------------- */
3032 /* DBCursor methods */
3036 DBC_close(DBCursorObject
* self
, PyObject
* args
)
3040 if (!PyArg_ParseTuple(args
, ":close"))
3043 if (self
->dbc
!= NULL
) {
3044 MYDB_BEGIN_ALLOW_THREADS
;
3045 err
= self
->dbc
->c_close(self
->dbc
);
3047 MYDB_END_ALLOW_THREADS
;
3055 DBC_count(DBCursorObject
* self
, PyObject
* args
)
3061 if (!PyArg_ParseTuple(args
, "|i:count", &flags
))
3064 CHECK_CURSOR_NOT_CLOSED(self
);
3066 MYDB_BEGIN_ALLOW_THREADS
;
3067 err
= self
->dbc
->c_count(self
->dbc
, &count
, flags
);
3068 MYDB_END_ALLOW_THREADS
;
3071 return PyInt_FromLong(count
);
3076 DBC_current(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3078 return _DBCursor_get(self
,DB_CURRENT
,args
,kwargs
,"|iii:current");
3083 DBC_delete(DBCursorObject
* self
, PyObject
* args
)
3087 if (!PyArg_ParseTuple(args
, "|i:delete", &flags
))
3090 CHECK_CURSOR_NOT_CLOSED(self
);
3092 MYDB_BEGIN_ALLOW_THREADS
;
3093 err
= self
->dbc
->c_del(self
->dbc
, flags
);
3094 MYDB_END_ALLOW_THREADS
;
3097 self
->mydb
->haveStat
= 0;
3103 DBC_dup(DBCursorObject
* self
, PyObject
* args
)
3108 if (!PyArg_ParseTuple(args
, "|i:dup", &flags
))
3111 CHECK_CURSOR_NOT_CLOSED(self
);
3113 MYDB_BEGIN_ALLOW_THREADS
;
3114 err
= self
->dbc
->c_dup(self
->dbc
, &dbc
, flags
);
3115 MYDB_END_ALLOW_THREADS
;
3118 return (PyObject
*) newDBCursorObject(dbc
, self
->mydb
);
3122 DBC_first(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3124 return _DBCursor_get(self
,DB_FIRST
,args
,kwargs
,"|iii:first");
3129 DBC_get(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3132 PyObject
* keyobj
= NULL
;
3133 PyObject
* dataobj
= NULL
;
3134 PyObject
* retval
= NULL
;
3138 static char* kwnames
[] = { "key","data", "flags", "dlen", "doff",
3143 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:get", &kwnames
[2],
3144 &flags
, &dlen
, &doff
))
3147 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:get",
3149 &keyobj
, &flags
, &dlen
, &doff
))
3152 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:get",
3153 kwnames
, &keyobj
, &dataobj
,
3154 &flags
, &dlen
, &doff
))
3161 CHECK_CURSOR_NOT_CLOSED(self
);
3163 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3165 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
3166 (!add_partial_dbt(&data
, dlen
, doff
)) )
3172 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3173 data
.flags
= DB_DBT_MALLOC
;
3174 if (!(key
.flags
& DB_DBT_REALLOC
)) {
3175 key
.flags
|= DB_DBT_MALLOC
;
3179 MYDB_BEGIN_ALLOW_THREADS
;
3180 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
3181 MYDB_END_ALLOW_THREADS
;
3183 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3184 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3188 else if (makeDBError(err
)) {
3192 switch (_DB_get_type(self
->mydb
)) {
3199 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3200 data
.data
, data
.size
);
3204 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3205 data
.data
, data
.size
);
3216 DBC_pget(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3219 PyObject
* keyobj
= NULL
;
3220 PyObject
* dataobj
= NULL
;
3221 PyObject
* retval
= NULL
;
3224 DBT key
, pkey
, data
;
3225 static char* kwnames_keyOnly
[] = { "key", "flags", "dlen", "doff", NULL
};
3226 static char* kwnames
[] = { "key", "data", "flags", "dlen", "doff", NULL
};
3230 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:pget", &kwnames
[2],
3231 &flags
, &dlen
, &doff
))
3234 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:pget",
3236 &keyobj
, &flags
, &dlen
, &doff
))
3239 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:pget",
3240 kwnames
, &keyobj
, &dataobj
,
3241 &flags
, &dlen
, &doff
))
3248 CHECK_CURSOR_NOT_CLOSED(self
);
3250 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3252 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
3253 (!add_partial_dbt(&data
, dlen
, doff
)) ) {
3258 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3259 data
.flags
= DB_DBT_MALLOC
;
3260 if (!(key
.flags
& DB_DBT_REALLOC
)) {
3261 key
.flags
|= DB_DBT_MALLOC
;
3266 pkey
.flags
= DB_DBT_MALLOC
;
3268 MYDB_BEGIN_ALLOW_THREADS
;
3269 err
= self
->dbc
->c_pget(self
->dbc
, &key
, &pkey
, &data
, flags
);
3270 MYDB_END_ALLOW_THREADS
;
3272 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3273 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3277 else if (makeDBError(err
)) {
3283 dataObj
= PyString_FromStringAndSize(data
.data
, data
.size
);
3285 if (self
->mydb
->primaryDBType
== DB_RECNO
||
3286 self
->mydb
->primaryDBType
== DB_QUEUE
)
3287 pkeyObj
= PyInt_FromLong(*(int *)pkey
.data
);
3289 pkeyObj
= PyString_FromStringAndSize(pkey
.data
, pkey
.size
);
3291 if (key
.data
&& key
.size
) /* return key, pkey and data */
3294 int type
= _DB_get_type(self
->mydb
);
3295 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
3296 keyObj
= PyInt_FromLong(*(int *)key
.data
);
3298 keyObj
= PyString_FromStringAndSize(key
.data
, key
.size
);
3299 #if (PY_VERSION_HEX >= 0x02040000)
3300 retval
= PyTuple_Pack(3, keyObj
, pkeyObj
, dataObj
);
3302 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
3307 else /* return just the pkey and data */
3309 #if (PY_VERSION_HEX >= 0x02040000)
3310 retval
= PyTuple_Pack(2, pkeyObj
, dataObj
);
3312 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
3320 /* the only time REALLOC should be set is if we used an integer
3321 * key that make_key_dbt malloc'd for us. always free these. */
3322 if (key
.flags
& DB_DBT_REALLOC
) {
3331 DBC_get_recno(DBCursorObject
* self
, PyObject
* args
)
3338 if (!PyArg_ParseTuple(args
, ":get_recno"))
3341 CHECK_CURSOR_NOT_CLOSED(self
);
3345 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3346 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3347 data
.flags
= DB_DBT_MALLOC
;
3348 key
.flags
= DB_DBT_MALLOC
;
3351 MYDB_BEGIN_ALLOW_THREADS
;
3352 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, DB_GET_RECNO
);
3353 MYDB_END_ALLOW_THREADS
;
3356 recno
= *((db_recno_t
*)data
.data
);
3359 return PyInt_FromLong(recno
);
3364 DBC_last(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3366 return _DBCursor_get(self
,DB_LAST
,args
,kwargs
,"|iii:last");
3371 DBC_next(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3373 return _DBCursor_get(self
,DB_NEXT
,args
,kwargs
,"|iii:next");
3378 DBC_prev(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3380 return _DBCursor_get(self
,DB_PREV
,args
,kwargs
,"|iii:prev");
3385 DBC_put(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3388 PyObject
* keyobj
, *dataobj
;
3390 static char* kwnames
[] = { "key", "data", "flags", "dlen", "doff",
3395 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iii:put", kwnames
,
3396 &keyobj
, &dataobj
, &flags
, &dlen
, &doff
))
3399 CHECK_CURSOR_NOT_CLOSED(self
);
3401 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3403 if (!make_dbt(dataobj
, &data
) ||
3404 !add_partial_dbt(&data
, dlen
, doff
) )
3410 MYDB_BEGIN_ALLOW_THREADS
;
3411 err
= self
->dbc
->c_put(self
->dbc
, &key
, &data
, flags
);
3412 MYDB_END_ALLOW_THREADS
;
3415 self
->mydb
->haveStat
= 0;
3421 DBC_set(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3425 PyObject
* retval
, *keyobj
;
3426 static char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
3430 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set", kwnames
,
3431 &keyobj
, &flags
, &dlen
, &doff
))
3434 CHECK_CURSOR_NOT_CLOSED(self
);
3436 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3440 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3441 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3442 data
.flags
= DB_DBT_MALLOC
;
3444 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3449 MYDB_BEGIN_ALLOW_THREADS
;
3450 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET
);
3451 MYDB_END_ALLOW_THREADS
;
3452 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3453 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3457 else if (makeDBError(err
)) {
3461 switch (_DB_get_type(self
->mydb
)) {
3468 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3469 data
.data
, data
.size
);
3473 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3474 data
.data
, data
.size
);
3480 /* the only time REALLOC should be set is if we used an integer
3481 * key that make_key_dbt malloc'd for us. always free these. */
3482 if (key
.flags
& DB_DBT_REALLOC
) {
3491 DBC_set_range(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3495 PyObject
* retval
, *keyobj
;
3496 static char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
3500 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set_range", kwnames
,
3501 &keyobj
, &flags
, &dlen
, &doff
))
3504 CHECK_CURSOR_NOT_CLOSED(self
);
3506 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3510 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3514 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3515 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3516 data
.flags
|= DB_DBT_MALLOC
;
3517 /* only BTREE databases will return anything in the key */
3518 if (!(key
.flags
& DB_DBT_REALLOC
) && _DB_get_type(self
->mydb
) == DB_BTREE
) {
3519 key
.flags
|= DB_DBT_MALLOC
;
3522 MYDB_BEGIN_ALLOW_THREADS
;
3523 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RANGE
);
3524 MYDB_END_ALLOW_THREADS
;
3525 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3526 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3530 else if (makeDBError(err
)) {
3534 switch (_DB_get_type(self
->mydb
)) {
3541 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3542 data
.data
, data
.size
);
3546 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3547 data
.data
, data
.size
);
3553 /* the only time REALLOC should be set is if we used an integer
3554 * key that make_key_dbt malloc'd for us. always free these. */
3555 if (key
.flags
& DB_DBT_REALLOC
) {
3563 _DBC_get_set_both(DBCursorObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
,
3564 int flags
, unsigned int returnsNone
)
3570 /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
3571 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3573 if (!make_dbt(dataobj
, &data
)) {
3578 MYDB_BEGIN_ALLOW_THREADS
;
3579 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_GET_BOTH
);
3580 MYDB_END_ALLOW_THREADS
;
3581 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && returnsNone
) {
3585 else if (makeDBError(err
)) {
3589 switch (_DB_get_type(self
->mydb
)) {
3596 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3597 data
.data
, data
.size
);
3601 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3602 data
.data
, data
.size
);
3612 DBC_get_both(DBCursorObject
* self
, PyObject
* args
)
3615 PyObject
*keyobj
, *dataobj
;
3617 if (!PyArg_ParseTuple(args
, "OO|i:get_both", &keyobj
, &dataobj
, &flags
))
3620 /* if the cursor is closed, self->mydb may be invalid */
3621 CHECK_CURSOR_NOT_CLOSED(self
);
3623 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3624 self
->mydb
->moduleFlags
.getReturnsNone
);
3627 /* Return size of entry */
3629 DBC_get_current_size(DBCursorObject
* self
, PyObject
* args
)
3631 int err
, flags
=DB_CURRENT
;
3632 PyObject
* retval
= NULL
;
3635 if (!PyArg_ParseTuple(args
, ":get_current_size"))
3637 CHECK_CURSOR_NOT_CLOSED(self
);
3641 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
3642 getting the record size. */
3643 data
.flags
= DB_DBT_USERMEM
;
3645 MYDB_BEGIN_ALLOW_THREADS
;
3646 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
3647 MYDB_END_ALLOW_THREADS
;
3648 if (err
== DB_BUFFER_SMALL
|| !err
) {
3649 /* DB_BUFFER_SMALL means positive size, !err means zero length value */
3650 retval
= PyInt_FromLong((long)data
.size
);
3661 DBC_set_both(DBCursorObject
* self
, PyObject
* args
)
3664 PyObject
*keyobj
, *dataobj
;
3666 if (!PyArg_ParseTuple(args
, "OO|i:set_both", &keyobj
, &dataobj
, &flags
))
3669 /* if the cursor is closed, self->mydb may be invalid */
3670 CHECK_CURSOR_NOT_CLOSED(self
);
3672 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3673 self
->mydb
->moduleFlags
.cursorSetReturnsNone
);
3678 DBC_set_recno(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3680 int err
, irecno
, flags
=0;
3686 static char* kwnames
[] = { "recno","flags", "dlen", "doff", NULL
};
3688 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|iii:set_recno", kwnames
,
3689 &irecno
, &flags
, &dlen
, &doff
))
3692 CHECK_CURSOR_NOT_CLOSED(self
);
3695 recno
= (db_recno_t
) irecno
;
3696 /* use allocated space so DB will be able to realloc room for the real
3698 key
.data
= malloc(sizeof(db_recno_t
));
3699 if (key
.data
== NULL
) {
3700 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
3703 key
.size
= sizeof(db_recno_t
);
3704 key
.ulen
= key
.size
;
3705 memcpy(key
.data
, &recno
, sizeof(db_recno_t
));
3706 key
.flags
= DB_DBT_REALLOC
;
3709 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3710 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3711 data
.flags
= DB_DBT_MALLOC
;
3713 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3718 MYDB_BEGIN_ALLOW_THREADS
;
3719 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RECNO
);
3720 MYDB_END_ALLOW_THREADS
;
3721 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3722 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3726 else if (makeDBError(err
)) {
3729 else { /* Can only be used for BTrees, so no need to return int key */
3730 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3731 data
.data
, data
.size
);
3741 DBC_consume(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3743 return _DBCursor_get(self
,DB_CONSUME
,args
,kwargs
,"|iii:consume");
3748 DBC_next_dup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3750 return _DBCursor_get(self
,DB_NEXT_DUP
,args
,kwargs
,"|iii:next_dup");
3755 DBC_next_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3757 return _DBCursor_get(self
,DB_NEXT_NODUP
,args
,kwargs
,"|iii:next_nodup");
3762 DBC_prev_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3764 return _DBCursor_get(self
,DB_PREV_NODUP
,args
,kwargs
,"|iii:prev_nodup");
3769 DBC_join_item(DBCursorObject
* self
, PyObject
* args
)
3775 if (!PyArg_ParseTuple(args
, "|i:join_item", &flags
))
3778 CHECK_CURSOR_NOT_CLOSED(self
);
3782 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3783 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3784 key
.flags
= DB_DBT_MALLOC
;
3787 MYDB_BEGIN_ALLOW_THREADS
;
3788 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
| DB_JOIN_ITEM
);
3789 MYDB_END_ALLOW_THREADS
;
3790 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3791 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3795 else if (makeDBError(err
)) {
3799 retval
= Py_BuildValue("s#", key
.data
, key
.size
);
3808 /* --------------------------------------------------------------------- */
3813 DBEnv_close(DBEnvObject
* self
, PyObject
* args
)
3817 if (!PyArg_ParseTuple(args
, "|i:close", &flags
))
3819 if (!self
->closed
) { /* Don't close more than once */
3820 MYDB_BEGIN_ALLOW_THREADS
;
3821 err
= self
->db_env
->close(self
->db_env
, flags
);
3822 MYDB_END_ALLOW_THREADS
;
3823 /* after calling DBEnv->close, regardless of error, this DBEnv
3824 * may not be accessed again (BerkeleyDB docs). */
3826 self
->db_env
= NULL
;
3834 DBEnv_open(DBEnvObject
* self
, PyObject
* args
)
3836 int err
, flags
=0, mode
=0660;
3839 if (!PyArg_ParseTuple(args
, "z|ii:open", &db_home
, &flags
, &mode
))
3842 CHECK_ENV_NOT_CLOSED(self
);
3844 MYDB_BEGIN_ALLOW_THREADS
;
3845 err
= self
->db_env
->open(self
->db_env
, db_home
, flags
, mode
);
3846 MYDB_END_ALLOW_THREADS
;
3849 self
->flags
= flags
;
3855 DBEnv_remove(DBEnvObject
* self
, PyObject
* args
)
3860 if (!PyArg_ParseTuple(args
, "s|i:remove", &db_home
, &flags
))
3862 CHECK_ENV_NOT_CLOSED(self
);
3863 MYDB_BEGIN_ALLOW_THREADS
;
3864 err
= self
->db_env
->remove(self
->db_env
, db_home
, flags
);
3865 MYDB_END_ALLOW_THREADS
;
3872 DBEnv_dbremove(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3877 char *database
= NULL
;
3878 PyObject
*txnobj
= NULL
;
3880 static char* kwnames
[] = { "file", "database", "txn", "flags",
3883 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zOi:dbremove", kwnames
,
3884 &file
, &database
, &txnobj
, &flags
)) {
3887 if (!checkTxnObj(txnobj
, &txn
)) {
3890 CHECK_ENV_NOT_CLOSED(self
);
3891 MYDB_BEGIN_ALLOW_THREADS
;
3892 err
= self
->db_env
->dbremove(self
->db_env
, txn
, file
, database
, flags
);
3893 MYDB_END_ALLOW_THREADS
;
3899 DBEnv_dbrename(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3904 char *database
= NULL
;
3905 char *newname
= NULL
;
3906 PyObject
*txnobj
= NULL
;
3908 static char* kwnames
[] = { "file", "database", "newname", "txn",
3911 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "szs|Oi:dbrename", kwnames
,
3912 &file
, &database
, &newname
, &txnobj
, &flags
)) {
3915 if (!checkTxnObj(txnobj
, &txn
)) {
3918 CHECK_ENV_NOT_CLOSED(self
);
3919 MYDB_BEGIN_ALLOW_THREADS
;
3920 err
= self
->db_env
->dbrename(self
->db_env
, txn
, file
, database
, newname
,
3922 MYDB_END_ALLOW_THREADS
;
3928 DBEnv_set_encrypt(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3932 char *passwd
= NULL
;
3933 static char* kwnames
[] = { "passwd", "flags", NULL
};
3935 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
3940 MYDB_BEGIN_ALLOW_THREADS
;
3941 err
= self
->db_env
->set_encrypt(self
->db_env
, passwd
, flags
);
3942 MYDB_END_ALLOW_THREADS
;
3947 #endif /* DBVER >= 41 */
3951 DBEnv_set_timeout(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3955 u_int32_t timeout
= 0;
3956 static char* kwnames
[] = { "timeout", "flags", NULL
};
3958 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ii:set_timeout", kwnames
,
3959 &timeout
, &flags
)) {
3963 MYDB_BEGIN_ALLOW_THREADS
;
3964 err
= self
->db_env
->set_timeout(self
->db_env
, (db_timeout_t
)timeout
, flags
);
3965 MYDB_END_ALLOW_THREADS
;
3970 #endif /* DBVER >= 40 */
3973 DBEnv_set_shm_key(DBEnvObject
* self
, PyObject
* args
)
3978 if (!PyArg_ParseTuple(args
, "l:set_shm_key", &shm_key
))
3980 CHECK_ENV_NOT_CLOSED(self
);
3982 err
= self
->db_env
->set_shm_key(self
->db_env
, shm_key
);
3988 DBEnv_set_cachesize(DBEnvObject
* self
, PyObject
* args
)
3990 int err
, gbytes
=0, bytes
=0, ncache
=0;
3992 if (!PyArg_ParseTuple(args
, "ii|i:set_cachesize",
3993 &gbytes
, &bytes
, &ncache
))
3995 CHECK_ENV_NOT_CLOSED(self
);
3997 MYDB_BEGIN_ALLOW_THREADS
;
3998 err
= self
->db_env
->set_cachesize(self
->db_env
, gbytes
, bytes
, ncache
);
3999 MYDB_END_ALLOW_THREADS
;
4007 DBEnv_set_flags(DBEnvObject
* self
, PyObject
* args
)
4009 int err
, flags
=0, onoff
=0;
4011 if (!PyArg_ParseTuple(args
, "ii:set_flags",
4014 CHECK_ENV_NOT_CLOSED(self
);
4016 MYDB_BEGIN_ALLOW_THREADS
;
4017 err
= self
->db_env
->set_flags(self
->db_env
, flags
, onoff
);
4018 MYDB_END_ALLOW_THREADS
;
4026 DBEnv_set_data_dir(DBEnvObject
* self
, PyObject
* args
)
4031 if (!PyArg_ParseTuple(args
, "s:set_data_dir", &dir
))
4033 CHECK_ENV_NOT_CLOSED(self
);
4035 MYDB_BEGIN_ALLOW_THREADS
;
4036 err
= self
->db_env
->set_data_dir(self
->db_env
, dir
);
4037 MYDB_END_ALLOW_THREADS
;
4044 DBEnv_set_lg_bsize(DBEnvObject
* self
, PyObject
* args
)
4048 if (!PyArg_ParseTuple(args
, "i:set_lg_bsize", &lg_bsize
))
4050 CHECK_ENV_NOT_CLOSED(self
);
4052 MYDB_BEGIN_ALLOW_THREADS
;
4053 err
= self
->db_env
->set_lg_bsize(self
->db_env
, lg_bsize
);
4054 MYDB_END_ALLOW_THREADS
;
4061 DBEnv_set_lg_dir(DBEnvObject
* self
, PyObject
* args
)
4066 if (!PyArg_ParseTuple(args
, "s:set_lg_dir", &dir
))
4068 CHECK_ENV_NOT_CLOSED(self
);
4070 MYDB_BEGIN_ALLOW_THREADS
;
4071 err
= self
->db_env
->set_lg_dir(self
->db_env
, dir
);
4072 MYDB_END_ALLOW_THREADS
;
4078 DBEnv_set_lg_max(DBEnvObject
* self
, PyObject
* args
)
4082 if (!PyArg_ParseTuple(args
, "i:set_lg_max", &lg_max
))
4084 CHECK_ENV_NOT_CLOSED(self
);
4086 MYDB_BEGIN_ALLOW_THREADS
;
4087 err
= self
->db_env
->set_lg_max(self
->db_env
, lg_max
);
4088 MYDB_END_ALLOW_THREADS
;
4096 DBEnv_set_lg_regionmax(DBEnvObject
* self
, PyObject
* args
)
4100 if (!PyArg_ParseTuple(args
, "i:set_lg_regionmax", &lg_max
))
4102 CHECK_ENV_NOT_CLOSED(self
);
4104 MYDB_BEGIN_ALLOW_THREADS
;
4105 err
= self
->db_env
->set_lg_regionmax(self
->db_env
, lg_max
);
4106 MYDB_END_ALLOW_THREADS
;
4114 DBEnv_set_lk_detect(DBEnvObject
* self
, PyObject
* args
)
4118 if (!PyArg_ParseTuple(args
, "i:set_lk_detect", &lk_detect
))
4120 CHECK_ENV_NOT_CLOSED(self
);
4122 MYDB_BEGIN_ALLOW_THREADS
;
4123 err
= self
->db_env
->set_lk_detect(self
->db_env
, lk_detect
);
4124 MYDB_END_ALLOW_THREADS
;
4132 DBEnv_set_lk_max(DBEnvObject
* self
, PyObject
* args
)
4136 if (!PyArg_ParseTuple(args
, "i:set_lk_max", &max
))
4138 CHECK_ENV_NOT_CLOSED(self
);
4140 MYDB_BEGIN_ALLOW_THREADS
;
4141 err
= self
->db_env
->set_lk_max(self
->db_env
, max
);
4142 MYDB_END_ALLOW_THREADS
;
4152 DBEnv_set_lk_max_locks(DBEnvObject
* self
, PyObject
* args
)
4156 if (!PyArg_ParseTuple(args
, "i:set_lk_max_locks", &max
))
4158 CHECK_ENV_NOT_CLOSED(self
);
4160 MYDB_BEGIN_ALLOW_THREADS
;
4161 err
= self
->db_env
->set_lk_max_locks(self
->db_env
, max
);
4162 MYDB_END_ALLOW_THREADS
;
4169 DBEnv_set_lk_max_lockers(DBEnvObject
* self
, PyObject
* args
)
4173 if (!PyArg_ParseTuple(args
, "i:set_lk_max_lockers", &max
))
4175 CHECK_ENV_NOT_CLOSED(self
);
4177 MYDB_BEGIN_ALLOW_THREADS
;
4178 err
= self
->db_env
->set_lk_max_lockers(self
->db_env
, max
);
4179 MYDB_END_ALLOW_THREADS
;
4186 DBEnv_set_lk_max_objects(DBEnvObject
* self
, PyObject
* args
)
4190 if (!PyArg_ParseTuple(args
, "i:set_lk_max_objects", &max
))
4192 CHECK_ENV_NOT_CLOSED(self
);
4194 MYDB_BEGIN_ALLOW_THREADS
;
4195 err
= self
->db_env
->set_lk_max_objects(self
->db_env
, max
);
4196 MYDB_END_ALLOW_THREADS
;
4205 DBEnv_set_mp_mmapsize(DBEnvObject
* self
, PyObject
* args
)
4207 int err
, mp_mmapsize
;
4209 if (!PyArg_ParseTuple(args
, "i:set_mp_mmapsize", &mp_mmapsize
))
4211 CHECK_ENV_NOT_CLOSED(self
);
4213 MYDB_BEGIN_ALLOW_THREADS
;
4214 err
= self
->db_env
->set_mp_mmapsize(self
->db_env
, mp_mmapsize
);
4215 MYDB_END_ALLOW_THREADS
;
4222 DBEnv_set_tmp_dir(DBEnvObject
* self
, PyObject
* args
)
4227 if (!PyArg_ParseTuple(args
, "s:set_tmp_dir", &dir
))
4229 CHECK_ENV_NOT_CLOSED(self
);
4231 MYDB_BEGIN_ALLOW_THREADS
;
4232 err
= self
->db_env
->set_tmp_dir(self
->db_env
, dir
);
4233 MYDB_END_ALLOW_THREADS
;
4240 DBEnv_txn_begin(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4243 PyObject
* txnobj
= NULL
;
4245 static char* kwnames
[] = { "parent", "flags", NULL
};
4247 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:txn_begin", kwnames
,
4251 if (!checkTxnObj(txnobj
, &txn
))
4253 CHECK_ENV_NOT_CLOSED(self
);
4255 return (PyObject
*)newDBTxnObject(self
, txn
, flags
);
4260 DBEnv_txn_checkpoint(DBEnvObject
* self
, PyObject
* args
)
4262 int err
, kbyte
=0, min
=0, flags
=0;
4264 if (!PyArg_ParseTuple(args
, "|iii:txn_checkpoint", &kbyte
, &min
, &flags
))
4266 CHECK_ENV_NOT_CLOSED(self
);
4268 MYDB_BEGIN_ALLOW_THREADS
;
4270 err
= self
->db_env
->txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
4272 err
= txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
4274 MYDB_END_ALLOW_THREADS
;
4281 DBEnv_set_tx_max(DBEnvObject
* self
, PyObject
* args
)
4285 if (!PyArg_ParseTuple(args
, "i:set_tx_max", &max
))
4287 CHECK_ENV_NOT_CLOSED(self
);
4289 err
= self
->db_env
->set_tx_max(self
->db_env
, max
);
4296 DBEnv_set_tx_timestamp(DBEnvObject
* self
, PyObject
* args
)
4302 if (!PyArg_ParseTuple(args
, "l:set_tx_timestamp", &stamp
))
4304 CHECK_ENV_NOT_CLOSED(self
);
4305 timestamp
= (time_t)stamp
;
4306 err
= self
->db_env
->set_tx_timestamp(self
->db_env
, ×tamp
);
4313 DBEnv_lock_detect(DBEnvObject
* self
, PyObject
* args
)
4315 int err
, atype
, flags
=0;
4318 if (!PyArg_ParseTuple(args
, "i|i:lock_detect", &atype
, &flags
))
4320 CHECK_ENV_NOT_CLOSED(self
);
4322 MYDB_BEGIN_ALLOW_THREADS
;
4324 err
= self
->db_env
->lock_detect(self
->db_env
, flags
, atype
, &aborted
);
4326 err
= lock_detect(self
->db_env
, flags
, atype
, &aborted
);
4328 MYDB_END_ALLOW_THREADS
;
4330 return PyInt_FromLong(aborted
);
4335 DBEnv_lock_get(DBEnvObject
* self
, PyObject
* args
)
4338 int locker
, lock_mode
;
4342 if (!PyArg_ParseTuple(args
, "iOi|i:lock_get", &locker
, &objobj
, &lock_mode
, &flags
))
4346 if (!make_dbt(objobj
, &obj
))
4349 return (PyObject
*)newDBLockObject(self
, locker
, &obj
, lock_mode
, flags
);
4354 DBEnv_lock_id(DBEnvObject
* self
, PyObject
* args
)
4359 if (!PyArg_ParseTuple(args
, ":lock_id"))
4362 CHECK_ENV_NOT_CLOSED(self
);
4363 MYDB_BEGIN_ALLOW_THREADS
;
4365 err
= self
->db_env
->lock_id(self
->db_env
, &theID
);
4367 err
= lock_id(self
->db_env
, &theID
);
4369 MYDB_END_ALLOW_THREADS
;
4372 return PyInt_FromLong((long)theID
);
4377 DBEnv_lock_put(DBEnvObject
* self
, PyObject
* args
)
4380 DBLockObject
* dblockobj
;
4382 if (!PyArg_ParseTuple(args
, "O!:lock_put", &DBLock_Type
, &dblockobj
))
4385 CHECK_ENV_NOT_CLOSED(self
);
4386 MYDB_BEGIN_ALLOW_THREADS
;
4388 err
= self
->db_env
->lock_put(self
->db_env
, &dblockobj
->lock
);
4390 err
= lock_put(self
->db_env
, &dblockobj
->lock
);
4392 MYDB_END_ALLOW_THREADS
;
4399 DBEnv_lsn_reset(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4403 u_int32_t flags
= 0;
4404 static char* kwnames
[] = { "file", "flags", NULL
};
4406 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|i:lsn_reset", kwnames
,
4409 CHECK_ENV_NOT_CLOSED(self
);
4411 MYDB_BEGIN_ALLOW_THREADS
;
4412 err
= self
->db_env
->lsn_reset(self
->db_env
, file
, flags
);
4413 MYDB_END_ALLOW_THREADS
;
4417 #endif /* DBVER >= 4.4 */
4421 DBEnv_log_stat(DBEnvObject
* self
, PyObject
* args
)
4424 DB_LOG_STAT
* statp
= NULL
;
4426 u_int32_t flags
= 0;
4428 if (!PyArg_ParseTuple(args
, "|i:log_stat", &flags
))
4430 CHECK_ENV_NOT_CLOSED(self
);
4432 MYDB_BEGIN_ALLOW_THREADS
;
4433 err
= self
->db_env
->log_stat(self
->db_env
, &statp
, flags
);
4434 MYDB_END_ALLOW_THREADS
;
4437 /* Turn the stat structure into a dictionary */
4445 #define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
4448 MAKE_ENTRY(version
);
4450 MAKE_ENTRY(lg_bsize
);
4452 MAKE_ENTRY(lg_size
);
4458 MAKE_ENTRY(w_mbytes
);
4459 MAKE_ENTRY(w_bytes
);
4460 MAKE_ENTRY(wc_mbytes
);
4461 MAKE_ENTRY(wc_bytes
);
4463 MAKE_ENTRY(wcount_fill
);
4468 MAKE_ENTRY(cur_file
);
4469 MAKE_ENTRY(cur_offset
);
4470 MAKE_ENTRY(disk_file
);
4471 MAKE_ENTRY(disk_offset
);
4472 MAKE_ENTRY(maxcommitperflush
);
4473 MAKE_ENTRY(mincommitperflush
);
4474 MAKE_ENTRY(regsize
);
4475 MAKE_ENTRY(region_wait
);
4476 MAKE_ENTRY(region_nowait
);
4481 } /* DBEnv_log_stat */
4482 #endif /* DBVER >= 4.0 for log_stat method */
4486 DBEnv_lock_stat(DBEnvObject
* self
, PyObject
* args
)
4491 u_int32_t flags
= 0;
4493 if (!PyArg_ParseTuple(args
, "|i:lock_stat", &flags
))
4495 CHECK_ENV_NOT_CLOSED(self
);
4497 MYDB_BEGIN_ALLOW_THREADS
;
4499 err
= self
->db_env
->lock_stat(self
->db_env
, &sp
, flags
);
4502 err
= lock_stat(self
->db_env
, &sp
);
4504 err
= lock_stat(self
->db_env
, &sp
, NULL
);
4507 MYDB_END_ALLOW_THREADS
;
4510 /* Turn the stat structure into a dictionary */
4517 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4524 MAKE_ENTRY(maxlocks
);
4525 MAKE_ENTRY(maxlockers
);
4526 MAKE_ENTRY(maxobjects
);
4528 MAKE_ENTRY(maxnlocks
);
4530 MAKE_ENTRY(nlockers
);
4531 MAKE_ENTRY(maxnlockers
);
4533 MAKE_ENTRY(nobjects
);
4534 MAKE_ENTRY(maxnobjects
);
4536 MAKE_ENTRY(nrequests
);
4537 MAKE_ENTRY(nreleases
);
4539 MAKE_ENTRY(nnowaits
); /* these were renamed in 4.4 */
4540 MAKE_ENTRY(nconflicts
);
4542 MAKE_ENTRY(lock_nowait
);
4543 MAKE_ENTRY(lock_wait
);
4545 MAKE_ENTRY(ndeadlocks
);
4546 MAKE_ENTRY(regsize
);
4547 MAKE_ENTRY(region_wait
);
4548 MAKE_ENTRY(region_nowait
);
4557 DBEnv_log_archive(DBEnvObject
* self
, PyObject
* args
)
4561 char **log_list
= NULL
;
4563 PyObject
* item
= NULL
;
4565 if (!PyArg_ParseTuple(args
, "|i:log_archive", &flags
))
4568 CHECK_ENV_NOT_CLOSED(self
);
4569 MYDB_BEGIN_ALLOW_THREADS
;
4571 err
= self
->db_env
->log_archive(self
->db_env
, &log_list
, flags
);
4573 err
= log_archive(self
->db_env
, &log_list
, flags
);
4575 err
= log_archive(self
->db_env
, &log_list
, flags
, NULL
);
4577 MYDB_END_ALLOW_THREADS
;
4580 list
= PyList_New(0);
4588 char **log_list_start
;
4589 for (log_list_start
= log_list
; *log_list
!= NULL
; ++log_list
) {
4590 item
= PyString_FromString (*log_list
);
4596 PyList_Append(list
, item
);
4599 free(log_list_start
);
4606 DBEnv_txn_stat(DBEnvObject
* self
, PyObject
* args
)
4613 if (!PyArg_ParseTuple(args
, "|i:txn_stat", &flags
))
4615 CHECK_ENV_NOT_CLOSED(self
);
4617 MYDB_BEGIN_ALLOW_THREADS
;
4619 err
= self
->db_env
->txn_stat(self
->db_env
, &sp
, flags
);
4621 err
= txn_stat(self
->db_env
, &sp
);
4623 err
= txn_stat(self
->db_env
, &sp
, NULL
);
4625 MYDB_END_ALLOW_THREADS
;
4628 /* Turn the stat structure into a dictionary */
4635 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4637 MAKE_ENTRY(time_ckp
);
4638 MAKE_ENTRY(last_txnid
);
4639 MAKE_ENTRY(maxtxns
);
4640 MAKE_ENTRY(nactive
);
4641 MAKE_ENTRY(maxnactive
);
4642 MAKE_ENTRY(nbegins
);
4643 MAKE_ENTRY(naborts
);
4644 MAKE_ENTRY(ncommits
);
4645 MAKE_ENTRY(regsize
);
4646 MAKE_ENTRY(region_wait
);
4647 MAKE_ENTRY(region_nowait
);
4656 DBEnv_set_get_returns_none(DBEnvObject
* self
, PyObject
* args
)
4661 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
4663 CHECK_ENV_NOT_CLOSED(self
);
4665 if (self
->moduleFlags
.getReturnsNone
)
4667 if (self
->moduleFlags
.cursorSetReturnsNone
)
4669 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
4670 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
4671 return PyInt_FromLong(oldValue
);
4675 /* --------------------------------------------------------------------- */
4680 DBTxn_commit(DBTxnObject
* self
, PyObject
* args
)
4685 if (!PyArg_ParseTuple(args
, "|i:commit", &flags
))
4689 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4690 "after txn_commit or txn_abort");
4691 PyErr_SetObject(DBError
, t
);
4696 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
4697 MYDB_BEGIN_ALLOW_THREADS
;
4699 err
= txn
->commit(txn
, flags
);
4701 err
= txn_commit(txn
, flags
);
4703 MYDB_END_ALLOW_THREADS
;
4709 DBTxn_prepare(DBTxnObject
* self
, PyObject
* args
)
4716 if (!PyArg_ParseTuple(args
, "s#:prepare", &gid
, &gid_size
))
4719 if (gid_size
!= DB_XIDDATASIZE
) {
4720 PyErr_SetString(PyExc_TypeError
,
4721 "gid must be DB_XIDDATASIZE bytes long");
4726 PyObject
*t
= Py_BuildValue("(is)", 0,"DBTxn must not be used "
4727 "after txn_commit or txn_abort");
4728 PyErr_SetObject(DBError
, t
);
4732 MYDB_BEGIN_ALLOW_THREADS
;
4734 err
= self
->txn
->prepare(self
->txn
, (u_int8_t
*)gid
);
4736 err
= txn_prepare(self
->txn
, (u_int8_t
*)gid
);
4738 MYDB_END_ALLOW_THREADS
;
4744 if (!PyArg_ParseTuple(args
, ":prepare"))
4748 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4749 "after txn_commit or txn_abort");
4750 PyErr_SetObject(DBError
, t
);
4754 MYDB_BEGIN_ALLOW_THREADS
;
4755 err
= txn_prepare(self
->txn
);
4756 MYDB_END_ALLOW_THREADS
;
4764 DBTxn_abort(DBTxnObject
* self
, PyObject
* args
)
4769 if (!PyArg_ParseTuple(args
, ":abort"))
4773 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4774 "after txn_commit or txn_abort");
4775 PyErr_SetObject(DBError
, t
);
4780 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
4781 MYDB_BEGIN_ALLOW_THREADS
;
4783 err
= txn
->abort(txn
);
4785 err
= txn_abort(txn
);
4787 MYDB_END_ALLOW_THREADS
;
4794 DBTxn_id(DBTxnObject
* self
, PyObject
* args
)
4798 if (!PyArg_ParseTuple(args
, ":id"))
4802 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4803 "after txn_commit or txn_abort");
4804 PyErr_SetObject(DBError
, t
);
4808 MYDB_BEGIN_ALLOW_THREADS
;
4810 id
= self
->txn
->id(self
->txn
);
4812 id
= txn_id(self
->txn
);
4814 MYDB_END_ALLOW_THREADS
;
4815 return PyInt_FromLong(id
);
4819 /* --------------------------------------------------------------------- */
4820 /* DBSequence methods */
4824 DBSequence_close(DBSequenceObject
* self
, PyObject
* args
)
4827 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
4829 CHECK_SEQUENCE_NOT_CLOSED(self
)
4831 MYDB_BEGIN_ALLOW_THREADS
4832 err
= self
->sequence
->close(self
->sequence
, flags
);
4833 self
->sequence
= NULL
;
4834 MYDB_END_ALLOW_THREADS
4842 DBSequence_get(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4847 PyObject
*txnobj
= NULL
;
4849 static char* kwnames
[] = {"delta", "txn", "flags", NULL
};
4850 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iOi:get", kwnames
, &delta
, &txnobj
, &flags
))
4852 CHECK_SEQUENCE_NOT_CLOSED(self
)
4854 if (!checkTxnObj(txnobj
, &txn
))
4857 MYDB_BEGIN_ALLOW_THREADS
4858 err
= self
->sequence
->get(self
->sequence
, txn
, delta
, &value
, flags
);
4859 MYDB_END_ALLOW_THREADS
4862 return PyLong_FromLongLong(value
);
4867 DBSequence_get_dbp(DBSequenceObject
* self
, PyObject
* args
)
4869 if (!PyArg_ParseTuple(args
,":get_dbp"))
4871 CHECK_SEQUENCE_NOT_CLOSED(self
)
4872 Py_INCREF(self
->mydb
);
4873 return (PyObject
* )self
->mydb
;
4877 DBSequence_get_key(DBSequenceObject
* self
, PyObject
* args
)
4881 CHECK_SEQUENCE_NOT_CLOSED(self
)
4882 MYDB_BEGIN_ALLOW_THREADS
4883 err
= self
->sequence
->get_key(self
->sequence
, &key
);
4884 MYDB_END_ALLOW_THREADS
4888 return PyString_FromStringAndSize(key
.data
, key
.size
);
4892 DBSequence_init_value(DBSequenceObject
* self
, PyObject
* args
)
4896 if (!PyArg_ParseTuple(args
,"L:init_value", &value
))
4898 CHECK_SEQUENCE_NOT_CLOSED(self
)
4900 MYDB_BEGIN_ALLOW_THREADS
4901 err
= self
->sequence
->initial_value(self
->sequence
, value
);
4902 MYDB_END_ALLOW_THREADS
4910 DBSequence_open(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4914 PyObject
*txnobj
= NULL
;
4918 static char* kwnames
[] = {"key", "txn", "flags", NULL
};
4919 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:open", kwnames
, &keyobj
, &txnobj
, &flags
))
4922 if (!checkTxnObj(txnobj
, &txn
))
4925 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
4928 MYDB_BEGIN_ALLOW_THREADS
4929 err
= self
->sequence
->open(self
->sequence
, txn
, &key
, flags
);
4930 MYDB_END_ALLOW_THREADS
4939 DBSequence_remove(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4942 PyObject
*txnobj
= NULL
;
4945 static char* kwnames
[] = {"txn", "flags", NULL
};
4946 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:remove", kwnames
, &txnobj
, &flags
))
4949 if (!checkTxnObj(txnobj
, &txn
))
4952 CHECK_SEQUENCE_NOT_CLOSED(self
)
4954 MYDB_BEGIN_ALLOW_THREADS
4955 err
= self
->sequence
->remove(self
->sequence
, txn
, flags
);
4956 MYDB_END_ALLOW_THREADS
4963 DBSequence_set_cachesize(DBSequenceObject
* self
, PyObject
* args
)
4966 if (!PyArg_ParseTuple(args
,"i:set_cachesize", &size
))
4968 CHECK_SEQUENCE_NOT_CLOSED(self
)
4970 MYDB_BEGIN_ALLOW_THREADS
4971 err
= self
->sequence
->set_cachesize(self
->sequence
, size
);
4972 MYDB_END_ALLOW_THREADS
4979 DBSequence_get_cachesize(DBSequenceObject
* self
, PyObject
* args
)
4982 if (!PyArg_ParseTuple(args
,":get_cachesize"))
4984 CHECK_SEQUENCE_NOT_CLOSED(self
)
4986 MYDB_BEGIN_ALLOW_THREADS
4987 err
= self
->sequence
->get_cachesize(self
->sequence
, &size
);
4988 MYDB_END_ALLOW_THREADS
4991 return PyInt_FromLong(size
);
4995 DBSequence_set_flags(DBSequenceObject
* self
, PyObject
* args
)
4998 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
5000 CHECK_SEQUENCE_NOT_CLOSED(self
)
5002 MYDB_BEGIN_ALLOW_THREADS
5003 err
= self
->sequence
->set_flags(self
->sequence
, flags
);
5004 MYDB_END_ALLOW_THREADS
5012 DBSequence_get_flags(DBSequenceObject
* self
, PyObject
* args
)
5016 if (!PyArg_ParseTuple(args
,":get_flags"))
5018 CHECK_SEQUENCE_NOT_CLOSED(self
)
5020 MYDB_BEGIN_ALLOW_THREADS
5021 err
= self
->sequence
->get_flags(self
->sequence
, &flags
);
5022 MYDB_END_ALLOW_THREADS
5025 return PyInt_FromLong((int)flags
);
5029 DBSequence_set_range(DBSequenceObject
* self
, PyObject
* args
)
5033 if (!PyArg_ParseTuple(args
,"(LL):set_range", &min
, &max
))
5035 CHECK_SEQUENCE_NOT_CLOSED(self
)
5037 MYDB_BEGIN_ALLOW_THREADS
5038 err
= self
->sequence
->set_range(self
->sequence
, min
, max
);
5039 MYDB_END_ALLOW_THREADS
5046 DBSequence_get_range(DBSequenceObject
* self
, PyObject
* args
)
5050 if (!PyArg_ParseTuple(args
,":get_range"))
5052 CHECK_SEQUENCE_NOT_CLOSED(self
)
5054 MYDB_BEGIN_ALLOW_THREADS
5055 err
= self
->sequence
->get_range(self
->sequence
, &min
, &max
);
5056 MYDB_END_ALLOW_THREADS
5059 return Py_BuildValue("(LL)", min
, max
);
5063 DBSequence_stat(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5066 DB_SEQUENCE_STAT
* sp
= NULL
;
5067 PyObject
* dict_stat
;
5068 static char* kwnames
[] = {"flags", NULL
};
5069 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat", kwnames
, &flags
))
5071 CHECK_SEQUENCE_NOT_CLOSED(self
);
5073 MYDB_BEGIN_ALLOW_THREADS
;
5074 err
= self
->sequence
->stat(self
->sequence
, &sp
, flags
);
5075 MYDB_END_ALLOW_THREADS
;
5078 if ((dict_stat
= PyDict_New()) == NULL
) {
5084 #define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name)
5085 #define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
5087 MAKE_INT_ENTRY(wait
);
5088 MAKE_INT_ENTRY(nowait
);
5089 MAKE_LONG_LONG_ENTRY(current
);
5090 MAKE_LONG_LONG_ENTRY(value
);
5091 MAKE_LONG_LONG_ENTRY(last_value
);
5092 MAKE_LONG_LONG_ENTRY(min
);
5093 MAKE_LONG_LONG_ENTRY(max
);
5094 MAKE_INT_ENTRY(cache_size
);
5095 MAKE_INT_ENTRY(flags
);
5097 #undef MAKE_INT_ENTRY
5098 #undef MAKE_LONG_LONG_ENTRY
5106 /* --------------------------------------------------------------------- */
5107 /* Method definition tables and type objects */
5109 static PyMethodDef DB_methods
[] = {
5110 {"append", (PyCFunction
)DB_append
, METH_VARARGS
},
5112 {"associate", (PyCFunction
)DB_associate
, METH_VARARGS
|METH_KEYWORDS
},
5114 {"close", (PyCFunction
)DB_close
, METH_VARARGS
},
5116 {"consume", (PyCFunction
)DB_consume
, METH_VARARGS
|METH_KEYWORDS
},
5117 {"consume_wait", (PyCFunction
)DB_consume_wait
, METH_VARARGS
|METH_KEYWORDS
},
5119 {"cursor", (PyCFunction
)DB_cursor
, METH_VARARGS
|METH_KEYWORDS
},
5120 {"delete", (PyCFunction
)DB_delete
, METH_VARARGS
|METH_KEYWORDS
},
5121 {"fd", (PyCFunction
)DB_fd
, METH_VARARGS
},
5122 {"get", (PyCFunction
)DB_get
, METH_VARARGS
|METH_KEYWORDS
},
5124 {"pget", (PyCFunction
)DB_pget
, METH_VARARGS
|METH_KEYWORDS
},
5126 {"get_both", (PyCFunction
)DB_get_both
, METH_VARARGS
|METH_KEYWORDS
},
5127 {"get_byteswapped", (PyCFunction
)DB_get_byteswapped
,METH_VARARGS
},
5128 {"get_size", (PyCFunction
)DB_get_size
, METH_VARARGS
|METH_KEYWORDS
},
5129 {"get_type", (PyCFunction
)DB_get_type
, METH_VARARGS
},
5130 {"join", (PyCFunction
)DB_join
, METH_VARARGS
},
5131 {"key_range", (PyCFunction
)DB_key_range
, METH_VARARGS
|METH_KEYWORDS
},
5132 {"has_key", (PyCFunction
)DB_has_key
, METH_VARARGS
},
5133 {"items", (PyCFunction
)DB_items
, METH_VARARGS
},
5134 {"keys", (PyCFunction
)DB_keys
, METH_VARARGS
},
5135 {"open", (PyCFunction
)DB_open
, METH_VARARGS
|METH_KEYWORDS
},
5136 {"put", (PyCFunction
)DB_put
, METH_VARARGS
|METH_KEYWORDS
},
5137 {"remove", (PyCFunction
)DB_remove
, METH_VARARGS
|METH_KEYWORDS
},
5138 {"rename", (PyCFunction
)DB_rename
, METH_VARARGS
},
5139 {"set_bt_minkey", (PyCFunction
)DB_set_bt_minkey
, METH_VARARGS
},
5141 {"set_bt_compare", (PyCFunction
)DB_set_bt_compare
, METH_VARARGS
},
5143 {"set_cachesize", (PyCFunction
)DB_set_cachesize
, METH_VARARGS
},
5145 {"set_encrypt", (PyCFunction
)DB_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
5147 {"set_flags", (PyCFunction
)DB_set_flags
, METH_VARARGS
},
5148 {"set_h_ffactor", (PyCFunction
)DB_set_h_ffactor
, METH_VARARGS
},
5149 {"set_h_nelem", (PyCFunction
)DB_set_h_nelem
, METH_VARARGS
},
5150 {"set_lorder", (PyCFunction
)DB_set_lorder
, METH_VARARGS
},
5151 {"set_pagesize", (PyCFunction
)DB_set_pagesize
, METH_VARARGS
},
5152 {"set_re_delim", (PyCFunction
)DB_set_re_delim
, METH_VARARGS
},
5153 {"set_re_len", (PyCFunction
)DB_set_re_len
, METH_VARARGS
},
5154 {"set_re_pad", (PyCFunction
)DB_set_re_pad
, METH_VARARGS
},
5155 {"set_re_source", (PyCFunction
)DB_set_re_source
, METH_VARARGS
},
5157 {"set_q_extentsize",(PyCFunction
)DB_set_q_extentsize
,METH_VARARGS
},
5159 {"stat", (PyCFunction
)DB_stat
, METH_VARARGS
|METH_KEYWORDS
},
5160 {"sync", (PyCFunction
)DB_sync
, METH_VARARGS
},
5162 {"truncate", (PyCFunction
)DB_truncate
, METH_VARARGS
|METH_KEYWORDS
},
5164 {"type", (PyCFunction
)DB_get_type
, METH_VARARGS
},
5165 {"upgrade", (PyCFunction
)DB_upgrade
, METH_VARARGS
},
5166 {"values", (PyCFunction
)DB_values
, METH_VARARGS
},
5167 {"verify", (PyCFunction
)DB_verify
, METH_VARARGS
|METH_KEYWORDS
},
5168 {"set_get_returns_none",(PyCFunction
)DB_set_get_returns_none
, METH_VARARGS
},
5169 {NULL
, NULL
} /* sentinel */
5173 static PyMappingMethods DB_mapping
= {
5174 DB_length
, /*mp_length*/
5175 (binaryfunc
)DB_subscript
, /*mp_subscript*/
5176 (objobjargproc
)DB_ass_sub
, /*mp_ass_subscript*/
5180 static PyMethodDef DBCursor_methods
[] = {
5181 {"close", (PyCFunction
)DBC_close
, METH_VARARGS
},
5182 {"count", (PyCFunction
)DBC_count
, METH_VARARGS
},
5183 {"current", (PyCFunction
)DBC_current
, METH_VARARGS
|METH_KEYWORDS
},
5184 {"delete", (PyCFunction
)DBC_delete
, METH_VARARGS
},
5185 {"dup", (PyCFunction
)DBC_dup
, METH_VARARGS
},
5186 {"first", (PyCFunction
)DBC_first
, METH_VARARGS
|METH_KEYWORDS
},
5187 {"get", (PyCFunction
)DBC_get
, METH_VARARGS
|METH_KEYWORDS
},
5189 {"pget", (PyCFunction
)DBC_pget
, METH_VARARGS
|METH_KEYWORDS
},
5191 {"get_recno", (PyCFunction
)DBC_get_recno
, METH_VARARGS
},
5192 {"last", (PyCFunction
)DBC_last
, METH_VARARGS
|METH_KEYWORDS
},
5193 {"next", (PyCFunction
)DBC_next
, METH_VARARGS
|METH_KEYWORDS
},
5194 {"prev", (PyCFunction
)DBC_prev
, METH_VARARGS
|METH_KEYWORDS
},
5195 {"put", (PyCFunction
)DBC_put
, METH_VARARGS
|METH_KEYWORDS
},
5196 {"set", (PyCFunction
)DBC_set
, METH_VARARGS
|METH_KEYWORDS
},
5197 {"set_range", (PyCFunction
)DBC_set_range
, METH_VARARGS
|METH_KEYWORDS
},
5198 {"get_both", (PyCFunction
)DBC_get_both
, METH_VARARGS
},
5199 {"get_current_size",(PyCFunction
)DBC_get_current_size
, METH_VARARGS
},
5200 {"set_both", (PyCFunction
)DBC_set_both
, METH_VARARGS
},
5201 {"set_recno", (PyCFunction
)DBC_set_recno
, METH_VARARGS
|METH_KEYWORDS
},
5202 {"consume", (PyCFunction
)DBC_consume
, METH_VARARGS
|METH_KEYWORDS
},
5203 {"next_dup", (PyCFunction
)DBC_next_dup
, METH_VARARGS
|METH_KEYWORDS
},
5204 {"next_nodup", (PyCFunction
)DBC_next_nodup
, METH_VARARGS
|METH_KEYWORDS
},
5205 {"prev_nodup", (PyCFunction
)DBC_prev_nodup
, METH_VARARGS
|METH_KEYWORDS
},
5206 {"join_item", (PyCFunction
)DBC_join_item
, METH_VARARGS
},
5207 {NULL
, NULL
} /* sentinel */
5211 static PyMethodDef DBEnv_methods
[] = {
5212 {"close", (PyCFunction
)DBEnv_close
, METH_VARARGS
},
5213 {"open", (PyCFunction
)DBEnv_open
, METH_VARARGS
},
5214 {"remove", (PyCFunction
)DBEnv_remove
, METH_VARARGS
},
5216 {"dbremove", (PyCFunction
)DBEnv_dbremove
, METH_VARARGS
|METH_KEYWORDS
},
5217 {"dbrename", (PyCFunction
)DBEnv_dbrename
, METH_VARARGS
|METH_KEYWORDS
},
5218 {"set_encrypt", (PyCFunction
)DBEnv_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
5221 {"set_timeout", (PyCFunction
)DBEnv_set_timeout
, METH_VARARGS
|METH_KEYWORDS
},
5223 {"set_shm_key", (PyCFunction
)DBEnv_set_shm_key
, METH_VARARGS
},
5224 {"set_cachesize", (PyCFunction
)DBEnv_set_cachesize
, METH_VARARGS
},
5225 {"set_data_dir", (PyCFunction
)DBEnv_set_data_dir
, METH_VARARGS
},
5227 {"set_flags", (PyCFunction
)DBEnv_set_flags
, METH_VARARGS
},
5229 {"set_lg_bsize", (PyCFunction
)DBEnv_set_lg_bsize
, METH_VARARGS
},
5230 {"set_lg_dir", (PyCFunction
)DBEnv_set_lg_dir
, METH_VARARGS
},
5231 {"set_lg_max", (PyCFunction
)DBEnv_set_lg_max
, METH_VARARGS
},
5233 {"set_lg_regionmax",(PyCFunction
)DBEnv_set_lg_regionmax
, METH_VARARGS
},
5235 {"set_lk_detect", (PyCFunction
)DBEnv_set_lk_detect
, METH_VARARGS
},
5237 {"set_lk_max", (PyCFunction
)DBEnv_set_lk_max
, METH_VARARGS
},
5240 {"set_lk_max_locks", (PyCFunction
)DBEnv_set_lk_max_locks
, METH_VARARGS
},
5241 {"set_lk_max_lockers", (PyCFunction
)DBEnv_set_lk_max_lockers
, METH_VARARGS
},
5242 {"set_lk_max_objects", (PyCFunction
)DBEnv_set_lk_max_objects
, METH_VARARGS
},
5244 {"set_mp_mmapsize", (PyCFunction
)DBEnv_set_mp_mmapsize
, METH_VARARGS
},
5245 {"set_tmp_dir", (PyCFunction
)DBEnv_set_tmp_dir
, METH_VARARGS
},
5246 {"txn_begin", (PyCFunction
)DBEnv_txn_begin
, METH_VARARGS
|METH_KEYWORDS
},
5247 {"txn_checkpoint", (PyCFunction
)DBEnv_txn_checkpoint
, METH_VARARGS
},
5248 {"txn_stat", (PyCFunction
)DBEnv_txn_stat
, METH_VARARGS
},
5249 {"set_tx_max", (PyCFunction
)DBEnv_set_tx_max
, METH_VARARGS
},
5250 {"set_tx_timestamp", (PyCFunction
)DBEnv_set_tx_timestamp
, METH_VARARGS
},
5251 {"lock_detect", (PyCFunction
)DBEnv_lock_detect
, METH_VARARGS
},
5252 {"lock_get", (PyCFunction
)DBEnv_lock_get
, METH_VARARGS
},
5253 {"lock_id", (PyCFunction
)DBEnv_lock_id
, METH_VARARGS
},
5254 {"lock_put", (PyCFunction
)DBEnv_lock_put
, METH_VARARGS
},
5255 {"lock_stat", (PyCFunction
)DBEnv_lock_stat
, METH_VARARGS
},
5256 {"log_archive", (PyCFunction
)DBEnv_log_archive
, METH_VARARGS
},
5258 {"log_stat", (PyCFunction
)DBEnv_log_stat
, METH_VARARGS
},
5261 {"lsn_reset", (PyCFunction
)DBEnv_lsn_reset
, METH_VARARGS
|METH_KEYWORDS
},
5263 {"set_get_returns_none",(PyCFunction
)DBEnv_set_get_returns_none
, METH_VARARGS
},
5264 {NULL
, NULL
} /* sentinel */
5268 static PyMethodDef DBTxn_methods
[] = {
5269 {"commit", (PyCFunction
)DBTxn_commit
, METH_VARARGS
},
5270 {"prepare", (PyCFunction
)DBTxn_prepare
, METH_VARARGS
},
5271 {"abort", (PyCFunction
)DBTxn_abort
, METH_VARARGS
},
5272 {"id", (PyCFunction
)DBTxn_id
, METH_VARARGS
},
5273 {NULL
, NULL
} /* sentinel */
5278 static PyMethodDef DBSequence_methods
[] = {
5279 {"close", (PyCFunction
)DBSequence_close
, METH_VARARGS
},
5280 {"get", (PyCFunction
)DBSequence_get
, METH_VARARGS
|METH_KEYWORDS
},
5281 {"get_dbp", (PyCFunction
)DBSequence_get_dbp
, METH_VARARGS
},
5282 {"get_key", (PyCFunction
)DBSequence_get_key
, METH_VARARGS
},
5283 {"init_value", (PyCFunction
)DBSequence_init_value
, METH_VARARGS
},
5284 {"open", (PyCFunction
)DBSequence_open
, METH_VARARGS
|METH_KEYWORDS
},
5285 {"remove", (PyCFunction
)DBSequence_remove
, METH_VARARGS
|METH_KEYWORDS
},
5286 {"set_cachesize", (PyCFunction
)DBSequence_set_cachesize
, METH_VARARGS
},
5287 {"get_cachesize", (PyCFunction
)DBSequence_get_cachesize
, METH_VARARGS
},
5288 {"set_flags", (PyCFunction
)DBSequence_set_flags
, METH_VARARGS
},
5289 {"get_flags", (PyCFunction
)DBSequence_get_flags
, METH_VARARGS
},
5290 {"set_range", (PyCFunction
)DBSequence_set_range
, METH_VARARGS
},
5291 {"get_range", (PyCFunction
)DBSequence_get_range
, METH_VARARGS
},
5292 {"stat", (PyCFunction
)DBSequence_stat
, METH_VARARGS
|METH_KEYWORDS
},
5293 {NULL
, NULL
} /* sentinel */
5299 DB_getattr(DBObject
* self
, char *name
)
5301 return Py_FindMethod(DB_methods
, (PyObject
* )self
, name
);
5306 DBEnv_getattr(DBEnvObject
* self
, char *name
)
5308 if (!strcmp(name
, "db_home")) {
5309 CHECK_ENV_NOT_CLOSED(self
);
5310 if (self
->db_env
->db_home
== NULL
) {
5313 return PyString_FromString(self
->db_env
->db_home
);
5316 return Py_FindMethod(DBEnv_methods
, (PyObject
* )self
, name
);
5321 DBCursor_getattr(DBCursorObject
* self
, char *name
)
5323 return Py_FindMethod(DBCursor_methods
, (PyObject
* )self
, name
);
5327 DBTxn_getattr(DBTxnObject
* self
, char *name
)
5329 return Py_FindMethod(DBTxn_methods
, (PyObject
* )self
, name
);
5333 DBLock_getattr(DBLockObject
* self
, char *name
)
5340 DBSequence_getattr(DBSequenceObject
* self
, char *name
)
5342 return Py_FindMethod(DBSequence_methods
, (PyObject
* )self
, name
);
5346 statichere PyTypeObject DB_Type
= {
5347 PyObject_HEAD_INIT(NULL
)
5350 sizeof(DBObject
), /*tp_basicsize*/
5353 (destructor
)DB_dealloc
, /*tp_dealloc*/
5355 (getattrfunc
)DB_getattr
, /*tp_getattr*/
5360 0, /*tp_as_sequence*/
5361 &DB_mapping
,/*tp_as_mapping*/
5366 0, /* tp_getattro */
5367 0, /* tp_setattro */
5368 0, /* tp_as_buffer */
5369 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5371 0, /* tp_traverse */
5373 0, /* tp_richcompare */
5374 offsetof(DBObject
, in_weakreflist
), /* tp_weaklistoffset */
5379 statichere PyTypeObject DBCursor_Type
= {
5380 PyObject_HEAD_INIT(NULL
)
5382 "DBCursor", /*tp_name*/
5383 sizeof(DBCursorObject
), /*tp_basicsize*/
5386 (destructor
)DBCursor_dealloc
,/*tp_dealloc*/
5388 (getattrfunc
)DBCursor_getattr
, /*tp_getattr*/
5393 0, /*tp_as_sequence*/
5394 0, /*tp_as_mapping*/
5399 0, /* tp_getattro */
5400 0, /* tp_setattro */
5401 0, /* tp_as_buffer */
5402 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5404 0, /* tp_traverse */
5406 0, /* tp_richcompare */
5407 offsetof(DBCursorObject
, in_weakreflist
), /* tp_weaklistoffset */
5412 statichere PyTypeObject DBEnv_Type
= {
5413 PyObject_HEAD_INIT(NULL
)
5415 "DBEnv", /*tp_name*/
5416 sizeof(DBEnvObject
), /*tp_basicsize*/
5419 (destructor
)DBEnv_dealloc
, /*tp_dealloc*/
5421 (getattrfunc
)DBEnv_getattr
, /*tp_getattr*/
5426 0, /*tp_as_sequence*/
5427 0, /*tp_as_mapping*/
5432 0, /* tp_getattro */
5433 0, /* tp_setattro */
5434 0, /* tp_as_buffer */
5435 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5437 0, /* tp_traverse */
5439 0, /* tp_richcompare */
5440 offsetof(DBEnvObject
, in_weakreflist
), /* tp_weaklistoffset */
5444 statichere PyTypeObject DBTxn_Type
= {
5445 PyObject_HEAD_INIT(NULL
)
5447 "DBTxn", /*tp_name*/
5448 sizeof(DBTxnObject
), /*tp_basicsize*/
5451 (destructor
)DBTxn_dealloc
, /*tp_dealloc*/
5453 (getattrfunc
)DBTxn_getattr
, /*tp_getattr*/
5458 0, /*tp_as_sequence*/
5459 0, /*tp_as_mapping*/
5464 0, /* tp_getattro */
5465 0, /* tp_setattro */
5466 0, /* tp_as_buffer */
5467 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5469 0, /* tp_traverse */
5471 0, /* tp_richcompare */
5472 offsetof(DBTxnObject
, in_weakreflist
), /* tp_weaklistoffset */
5477 statichere PyTypeObject DBLock_Type
= {
5478 PyObject_HEAD_INIT(NULL
)
5480 "DBLock", /*tp_name*/
5481 sizeof(DBLockObject
), /*tp_basicsize*/
5484 (destructor
)DBLock_dealloc
, /*tp_dealloc*/
5486 (getattrfunc
)DBLock_getattr
, /*tp_getattr*/
5491 0, /*tp_as_sequence*/
5492 0, /*tp_as_mapping*/
5497 0, /* tp_getattro */
5498 0, /* tp_setattro */
5499 0, /* tp_as_buffer */
5500 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5502 0, /* tp_traverse */
5504 0, /* tp_richcompare */
5505 offsetof(DBLockObject
, in_weakreflist
), /* tp_weaklistoffset */
5510 statichere PyTypeObject DBSequence_Type
= {
5511 PyObject_HEAD_INIT(NULL
)
5513 "DBSequence", /*tp_name*/
5514 sizeof(DBSequenceObject
), /*tp_basicsize*/
5517 (destructor
)DBSequence_dealloc
, /*tp_dealloc*/
5519 (getattrfunc
)DBSequence_getattr
,/*tp_getattr*/
5524 0, /*tp_as_sequence*/
5525 0, /*tp_as_mapping*/
5530 0, /* tp_getattro */
5531 0, /* tp_setattro */
5532 0, /* tp_as_buffer */
5533 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5535 0, /* tp_traverse */
5537 0, /* tp_richcompare */
5538 offsetof(DBSequenceObject
, in_weakreflist
), /* tp_weaklistoffset */
5543 /* --------------------------------------------------------------------- */
5544 /* Module-level functions */
5547 DB_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5549 PyObject
* dbenvobj
= NULL
;
5551 static char* kwnames
[] = { "dbEnv", "flags", NULL
};
5553 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:DB", kwnames
,
5556 if (dbenvobj
== Py_None
)
5558 else if (dbenvobj
&& !DBEnvObject_Check(dbenvobj
)) {
5559 makeTypeError("DBEnv", dbenvobj
);
5563 return (PyObject
* )newDBObject((DBEnvObject
*)dbenvobj
, flags
);
5568 DBEnv_construct(PyObject
* self
, PyObject
* args
)
5571 if (!PyArg_ParseTuple(args
, "|i:DbEnv", &flags
)) return NULL
;
5572 return (PyObject
* )newDBEnvObject(flags
);
5577 DBSequence_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5581 static char* kwnames
[] = { "db", "flags", NULL
};
5583 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|i:DBSequence", kwnames
, &dbobj
, &flags
))
5585 if (!DBObject_Check(dbobj
)) {
5586 makeTypeError("DB", dbobj
);
5589 return (PyObject
* )newDBSequenceObject((DBObject
*)dbobj
, flags
);
5593 static char bsddb_version_doc
[] =
5594 "Returns a tuple of major, minor, and patch release numbers of the\n\
5595 underlying DB library.";
5598 bsddb_version(PyObject
* self
, PyObject
* args
)
5600 int major
, minor
, patch
;
5602 if (!PyArg_ParseTuple(args
, ":version"))
5604 db_version(&major
, &minor
, &patch
);
5605 return Py_BuildValue("(iii)", major
, minor
, patch
);
5609 /* List of functions defined in the module */
5611 static PyMethodDef bsddb_methods
[] = {
5612 {"DB", (PyCFunction
)DB_construct
, METH_VARARGS
| METH_KEYWORDS
},
5613 {"DBEnv", (PyCFunction
)DBEnv_construct
, METH_VARARGS
},
5615 {"DBSequence", (PyCFunction
)DBSequence_construct
, METH_VARARGS
| METH_KEYWORDS
},
5617 {"version", (PyCFunction
)bsddb_version
, METH_VARARGS
, bsddb_version_doc
},
5618 {NULL
, NULL
} /* sentinel */
5622 /* --------------------------------------------------------------------- */
5623 /* Module initialization */
5626 /* Convenience routine to export an integer value.
5627 * Errors are silently ignored, for better or for worse...
5629 #define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
5631 #define MODULE_NAME_MAX_LEN 11
5632 static char _bsddbModuleName
[MODULE_NAME_MAX_LEN
+1] = "_bsddb";
5634 DL_EXPORT(void) init_bsddb(void)
5638 PyObject
* pybsddb_version_s
= PyString_FromString( PY_BSDDB_VERSION
);
5639 PyObject
* db_version_s
= PyString_FromString( DB_VERSION_STRING
);
5640 PyObject
* cvsid_s
= PyString_FromString( rcs_id
);
5642 /* Initialize the type of the new type objects here; doing it here
5643 is required for portability to Windows without requiring C++. */
5644 DB_Type
.ob_type
= &PyType_Type
;
5645 DBCursor_Type
.ob_type
= &PyType_Type
;
5646 DBEnv_Type
.ob_type
= &PyType_Type
;
5647 DBTxn_Type
.ob_type
= &PyType_Type
;
5648 DBLock_Type
.ob_type
= &PyType_Type
;
5650 DBSequence_Type
.ob_type
= &PyType_Type
;
5654 #if defined(WITH_THREAD) && !defined(MYDB_USE_GILSTATE)
5655 /* Save the current interpreter, so callbacks can do the right thing. */
5656 _db_interpreterState
= PyThreadState_GET()->interp
;
5659 /* Create the module and add the functions */
5660 m
= Py_InitModule(_bsddbModuleName
, bsddb_methods
);
5664 /* Add some symbolic constants to the module */
5665 d
= PyModule_GetDict(m
);
5666 PyDict_SetItemString(d
, "__version__", pybsddb_version_s
);
5667 PyDict_SetItemString(d
, "cvsid", cvsid_s
);
5668 PyDict_SetItemString(d
, "DB_VERSION_STRING", db_version_s
);
5669 Py_DECREF(pybsddb_version_s
);
5670 pybsddb_version_s
= NULL
;
5673 Py_DECREF(db_version_s
);
5674 db_version_s
= NULL
;
5676 ADD_INT(d
, DB_VERSION_MAJOR
);
5677 ADD_INT(d
, DB_VERSION_MINOR
);
5678 ADD_INT(d
, DB_VERSION_PATCH
);
5680 ADD_INT(d
, DB_MAX_PAGES
);
5681 ADD_INT(d
, DB_MAX_RECORDS
);
5684 ADD_INT(d
, DB_RPCCLIENT
);
5686 ADD_INT(d
, DB_CLIENT
);
5687 /* allow apps to be written using DB_RPCCLIENT on older BerkeleyDB */
5688 _addIntToDict(d
, "DB_RPCCLIENT", DB_CLIENT
);
5690 ADD_INT(d
, DB_XA_CREATE
);
5692 ADD_INT(d
, DB_CREATE
);
5693 ADD_INT(d
, DB_NOMMAP
);
5694 ADD_INT(d
, DB_THREAD
);
5696 ADD_INT(d
, DB_FORCE
);
5697 ADD_INT(d
, DB_INIT_CDB
);
5698 ADD_INT(d
, DB_INIT_LOCK
);
5699 ADD_INT(d
, DB_INIT_LOG
);
5700 ADD_INT(d
, DB_INIT_MPOOL
);
5701 ADD_INT(d
, DB_INIT_TXN
);
5703 ADD_INT(d
, DB_JOINENV
);
5706 ADD_INT(d
, DB_RECOVER
);
5707 ADD_INT(d
, DB_RECOVER_FATAL
);
5708 ADD_INT(d
, DB_TXN_NOSYNC
);
5709 ADD_INT(d
, DB_USE_ENVIRON
);
5710 ADD_INT(d
, DB_USE_ENVIRON_ROOT
);
5712 ADD_INT(d
, DB_LOCKDOWN
);
5713 ADD_INT(d
, DB_PRIVATE
);
5714 ADD_INT(d
, DB_SYSTEM_MEM
);
5716 ADD_INT(d
, DB_TXN_SYNC
);
5717 ADD_INT(d
, DB_TXN_NOWAIT
);
5719 ADD_INT(d
, DB_EXCL
);
5720 ADD_INT(d
, DB_FCNTL_LOCKING
);
5721 ADD_INT(d
, DB_ODDFILESIZE
);
5722 ADD_INT(d
, DB_RDWRMASTER
);
5723 ADD_INT(d
, DB_RDONLY
);
5724 ADD_INT(d
, DB_TRUNCATE
);
5726 ADD_INT(d
, DB_EXTENT
);
5727 ADD_INT(d
, DB_CDB_ALLDB
);
5728 ADD_INT(d
, DB_VERIFY
);
5730 ADD_INT(d
, DB_UPGRADE
);
5732 ADD_INT(d
, DB_AGGRESSIVE
);
5733 ADD_INT(d
, DB_NOORDERCHK
);
5734 ADD_INT(d
, DB_ORDERCHKONLY
);
5735 ADD_INT(d
, DB_PR_PAGE
);
5737 ADD_INT(d
, DB_VRFY_FLAGMASK
);
5738 ADD_INT(d
, DB_PR_HEADERS
);
5740 ADD_INT(d
, DB_PR_RECOVERYTEST
);
5741 ADD_INT(d
, DB_SALVAGE
);
5743 ADD_INT(d
, DB_LOCK_NORUN
);
5744 ADD_INT(d
, DB_LOCK_DEFAULT
);
5745 ADD_INT(d
, DB_LOCK_OLDEST
);
5746 ADD_INT(d
, DB_LOCK_RANDOM
);
5747 ADD_INT(d
, DB_LOCK_YOUNGEST
);
5749 ADD_INT(d
, DB_LOCK_MAXLOCKS
);
5750 ADD_INT(d
, DB_LOCK_MINLOCKS
);
5751 ADD_INT(d
, DB_LOCK_MINWRITE
);
5756 /* docs say to use zero instead */
5757 _addIntToDict(d
, "DB_LOCK_CONFLICT", 0);
5759 ADD_INT(d
, DB_LOCK_CONFLICT
);
5762 ADD_INT(d
, DB_LOCK_DUMP
);
5763 ADD_INT(d
, DB_LOCK_GET
);
5764 ADD_INT(d
, DB_LOCK_INHERIT
);
5765 ADD_INT(d
, DB_LOCK_PUT
);
5766 ADD_INT(d
, DB_LOCK_PUT_ALL
);
5767 ADD_INT(d
, DB_LOCK_PUT_OBJ
);
5769 ADD_INT(d
, DB_LOCK_NG
);
5770 ADD_INT(d
, DB_LOCK_READ
);
5771 ADD_INT(d
, DB_LOCK_WRITE
);
5772 ADD_INT(d
, DB_LOCK_NOWAIT
);
5774 ADD_INT(d
, DB_LOCK_WAIT
);
5776 ADD_INT(d
, DB_LOCK_IWRITE
);
5777 ADD_INT(d
, DB_LOCK_IREAD
);
5778 ADD_INT(d
, DB_LOCK_IWR
);
5781 ADD_INT(d
, DB_LOCK_DIRTY
);
5783 ADD_INT(d
, DB_LOCK_READ_UNCOMMITTED
); /* renamed in 4.4 */
5785 ADD_INT(d
, DB_LOCK_WWRITE
);
5788 ADD_INT(d
, DB_LOCK_RECORD
);
5789 ADD_INT(d
, DB_LOCK_UPGRADE
);
5791 ADD_INT(d
, DB_LOCK_SWITCH
);
5794 ADD_INT(d
, DB_LOCK_UPGRADE_WRITE
);
5797 ADD_INT(d
, DB_LOCK_NOWAIT
);
5798 ADD_INT(d
, DB_LOCK_RECORD
);
5799 ADD_INT(d
, DB_LOCK_UPGRADE
);
5802 ADD_INT(d
, DB_LSTAT_ABORTED
);
5804 ADD_INT(d
, DB_LSTAT_ERR
);
5806 ADD_INT(d
, DB_LSTAT_FREE
);
5807 ADD_INT(d
, DB_LSTAT_HELD
);
5809 ADD_INT(d
, DB_LSTAT_NOGRANT
);
5811 ADD_INT(d
, DB_LSTAT_PENDING
);
5812 ADD_INT(d
, DB_LSTAT_WAITING
);
5815 ADD_INT(d
, DB_ARCH_ABS
);
5816 ADD_INT(d
, DB_ARCH_DATA
);
5817 ADD_INT(d
, DB_ARCH_LOG
);
5819 ADD_INT(d
, DB_ARCH_REMOVE
);
5822 ADD_INT(d
, DB_BTREE
);
5823 ADD_INT(d
, DB_HASH
);
5824 ADD_INT(d
, DB_RECNO
);
5825 ADD_INT(d
, DB_QUEUE
);
5826 ADD_INT(d
, DB_UNKNOWN
);
5829 ADD_INT(d
, DB_DUPSORT
);
5830 ADD_INT(d
, DB_RECNUM
);
5831 ADD_INT(d
, DB_RENUMBER
);
5832 ADD_INT(d
, DB_REVSPLITOFF
);
5833 ADD_INT(d
, DB_SNAPSHOT
);
5835 ADD_INT(d
, DB_JOIN_NOSORT
);
5837 ADD_INT(d
, DB_AFTER
);
5838 ADD_INT(d
, DB_APPEND
);
5839 ADD_INT(d
, DB_BEFORE
);
5841 ADD_INT(d
, DB_CACHED_COUNTS
);
5844 _addIntToDict(d
, "DB_CHECKPOINT", 0);
5846 ADD_INT(d
, DB_CHECKPOINT
);
5847 ADD_INT(d
, DB_CURLSN
);
5849 #if ((DBVER >= 33) && (DBVER <= 41))
5850 ADD_INT(d
, DB_COMMIT
);
5852 ADD_INT(d
, DB_CONSUME
);
5854 ADD_INT(d
, DB_CONSUME_WAIT
);
5856 ADD_INT(d
, DB_CURRENT
);
5858 ADD_INT(d
, DB_FAST_STAT
);
5860 ADD_INT(d
, DB_FIRST
);
5861 ADD_INT(d
, DB_FLUSH
);
5862 ADD_INT(d
, DB_GET_BOTH
);
5863 ADD_INT(d
, DB_GET_RECNO
);
5864 ADD_INT(d
, DB_JOIN_ITEM
);
5865 ADD_INT(d
, DB_KEYFIRST
);
5866 ADD_INT(d
, DB_KEYLAST
);
5867 ADD_INT(d
, DB_LAST
);
5868 ADD_INT(d
, DB_NEXT
);
5869 ADD_INT(d
, DB_NEXT_DUP
);
5870 ADD_INT(d
, DB_NEXT_NODUP
);
5871 ADD_INT(d
, DB_NODUPDATA
);
5872 ADD_INT(d
, DB_NOOVERWRITE
);
5873 ADD_INT(d
, DB_NOSYNC
);
5874 ADD_INT(d
, DB_POSITION
);
5875 ADD_INT(d
, DB_PREV
);
5876 ADD_INT(d
, DB_PREV_NODUP
);
5878 ADD_INT(d
, DB_RECORDCOUNT
);
5881 ADD_INT(d
, DB_SET_RANGE
);
5882 ADD_INT(d
, DB_SET_RECNO
);
5883 ADD_INT(d
, DB_WRITECURSOR
);
5885 ADD_INT(d
, DB_OPFLAGS_MASK
);
5888 ADD_INT(d
, DB_DIRTY_READ
);
5889 ADD_INT(d
, DB_MULTIPLE
);
5890 ADD_INT(d
, DB_MULTIPLE_KEY
);
5894 ADD_INT(d
, DB_READ_UNCOMMITTED
); /* replaces DB_DIRTY_READ in 4.4 */
5895 ADD_INT(d
, DB_READ_COMMITTED
);
5899 ADD_INT(d
, DB_DONOTINDEX
);
5903 _addIntToDict(d
, "DB_INCOMPLETE", 0);
5905 ADD_INT(d
, DB_INCOMPLETE
);
5907 ADD_INT(d
, DB_KEYEMPTY
);
5908 ADD_INT(d
, DB_KEYEXIST
);
5909 ADD_INT(d
, DB_LOCK_DEADLOCK
);
5910 ADD_INT(d
, DB_LOCK_NOTGRANTED
);
5911 ADD_INT(d
, DB_NOSERVER
);
5912 ADD_INT(d
, DB_NOSERVER_HOME
);
5913 ADD_INT(d
, DB_NOSERVER_ID
);
5914 ADD_INT(d
, DB_NOTFOUND
);
5915 ADD_INT(d
, DB_OLD_VERSION
);
5916 ADD_INT(d
, DB_RUNRECOVERY
);
5917 ADD_INT(d
, DB_VERIFY_BAD
);
5919 ADD_INT(d
, DB_PAGE_NOTFOUND
);
5920 ADD_INT(d
, DB_SECONDARY_BAD
);
5923 ADD_INT(d
, DB_STAT_CLEAR
);
5924 ADD_INT(d
, DB_REGION_INIT
);
5925 ADD_INT(d
, DB_NOLOCKING
);
5926 ADD_INT(d
, DB_YIELDCPU
);
5927 ADD_INT(d
, DB_PANIC_ENVIRONMENT
);
5928 ADD_INT(d
, DB_NOPANIC
);
5932 ADD_INT(d
, DB_TIME_NOTGRANTED
);
5933 ADD_INT(d
, DB_TXN_NOT_DURABLE
);
5934 ADD_INT(d
, DB_TXN_WRITE_NOSYNC
);
5935 ADD_INT(d
, DB_LOG_AUTOREMOVE
);
5936 ADD_INT(d
, DB_DIRECT_LOG
);
5937 ADD_INT(d
, DB_DIRECT_DB
);
5938 ADD_INT(d
, DB_INIT_REP
);
5939 ADD_INT(d
, DB_ENCRYPT
);
5940 ADD_INT(d
, DB_CHKSUM
);
5944 ADD_INT(d
, DB_LOG_INMEMORY
);
5945 ADD_INT(d
, DB_BUFFER_SMALL
);
5946 ADD_INT(d
, DB_SEQ_DEC
);
5947 ADD_INT(d
, DB_SEQ_INC
);
5948 ADD_INT(d
, DB_SEQ_WRAP
);
5952 ADD_INT(d
, DB_ENCRYPT_AES
);
5953 ADD_INT(d
, DB_AUTO_COMMIT
);
5955 /* allow berkeleydb 4.1 aware apps to run on older versions */
5956 _addIntToDict(d
, "DB_AUTO_COMMIT", 0);
5970 ADD_INT(d
, DB_SET_LOCK_TIMEOUT
);
5971 ADD_INT(d
, DB_SET_TXN_TIMEOUT
);
5974 /* The exception name must be correct for pickled exception *
5975 * objects to unpickle properly. */
5976 #ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
5977 #define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
5979 #define PYBSDDB_EXCEPTION_BASE "bsddb.db."
5982 /* All the rest of the exceptions derive only from DBError */
5983 #define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
5984 PyDict_SetItemString(d, #name, name)
5986 /* The base exception class is DBError */
5987 DBError
= NULL
; /* used in MAKE_EX so that it derives from nothing */
5990 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
5991 * from both DBError and KeyError, since the API only supports
5992 * using one base class. */
5993 PyDict_SetItemString(d
, "KeyError", PyExc_KeyError
);
5994 PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
5995 "class DBKeyEmptyError(DBError, KeyError): pass",
5996 Py_file_input
, d
, d
);
5997 DBNotFoundError
= PyDict_GetItemString(d
, "DBNotFoundError");
5998 DBKeyEmptyError
= PyDict_GetItemString(d
, "DBKeyEmptyError");
5999 PyDict_DelItemString(d
, "KeyError");
6002 #if !INCOMPLETE_IS_WARNING
6003 MAKE_EX(DBIncompleteError
);
6005 MAKE_EX(DBCursorClosedError
);
6006 MAKE_EX(DBKeyEmptyError
);
6007 MAKE_EX(DBKeyExistError
);
6008 MAKE_EX(DBLockDeadlockError
);
6009 MAKE_EX(DBLockNotGrantedError
);
6010 MAKE_EX(DBOldVersionError
);
6011 MAKE_EX(DBRunRecoveryError
);
6012 MAKE_EX(DBVerifyBadError
);
6013 MAKE_EX(DBNoServerError
);
6014 MAKE_EX(DBNoServerHomeError
);
6015 MAKE_EX(DBNoServerIDError
);
6017 MAKE_EX(DBPageNotFoundError
);
6018 MAKE_EX(DBSecondaryBadError
);
6021 MAKE_EX(DBInvalidArgError
);
6022 MAKE_EX(DBAccessError
);
6023 MAKE_EX(DBNoSpaceError
);
6024 MAKE_EX(DBNoMemoryError
);
6025 MAKE_EX(DBAgainError
);
6026 MAKE_EX(DBBusyError
);
6027 MAKE_EX(DBFileExistsError
);
6028 MAKE_EX(DBNoSuchFileError
);
6029 MAKE_EX(DBPermissionsError
);
6033 /* Check for errors */
6034 if (PyErr_Occurred()) {
6036 Py_FatalError("can't initialize module _bsddb");
6040 /* allow this module to be named _pybsddb so that it can be installed
6041 * and imported on top of python >= 2.3 that includes its own older
6042 * copy of the library named _bsddb without importing the old version. */
6043 DL_EXPORT(void) init_pybsddb(void)
6045 strncpy(_bsddbModuleName
, "_pybsddb", MODULE_NAME_MAX_LEN
);