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 Berkeley DB 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 who based his work on a
43 * similar package by Robin Dunn <robin@alldunn.com> which wrapped
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@krypto.org> was once again the maintainer.
53 * Since January 2008, new maintainer is Jesus Cea <jcea@jcea.es>.
54 * Jesus Cea licenses this code to PSF under a Contributor Agreement.
56 * Use the pybsddb-users@lists.sf.net mailing list for all questions.
57 * Things can change faster than the header of this file is updated. This
58 * file is shared with the PyBSDDB project at SourceForge:
60 * http://pybsddb.sf.net
62 * This file should remain backward compatible with Python 2.1, but see PEP
63 * 291 for the most current backward compatibility requirements:
65 * http://www.python.org/peps/pep-0291.html
67 * This module contains 6 types:
70 * DBCursor (Database Cursor)
71 * DBEnv (database environment)
72 * DBTxn (An explicit database transaction)
73 * DBLock (A lock handle)
74 * DBSequence (Sequence)
78 /* --------------------------------------------------------------------- */
81 * Portions of this module, associated unit tests and build scripts are the
82 * result of a contract with The Written Word (http://thewrittenword.com/)
83 * Many thanks go out to them for causing me to raise the bar on quality and
84 * functionality, resulting in a better bsddb3 package for all of us to use.
89 /* --------------------------------------------------------------------- */
91 #include <stddef.h> /* for offsetof() */
94 #define COMPILING_BSDDB_C
96 #undef COMPILING_BSDDB_C
98 static char *rcs_id
= "$Id$";
100 /* --------------------------------------------------------------------- */
101 /* Various macro definitions */
103 #if (PY_VERSION_HEX < 0x02050000)
104 typedef int Py_ssize_t
;
107 #if (PY_VERSION_HEX < 0x02060000) /* really: before python trunk r63675 */
108 /* This code now uses PyBytes* API function names instead of PyString*.
109 * These #defines map to their equivalent on earlier python versions. */
110 #define PyBytes_FromStringAndSize PyString_FromStringAndSize
111 #define PyBytes_FromString PyString_FromString
112 #define PyBytes_AsStringAndSize PyString_AsStringAndSize
113 #define PyBytes_Check PyString_Check
114 #define PyBytes_GET_SIZE PyString_GET_SIZE
115 #define PyBytes_AS_STRING PyString_AS_STRING
118 #if (PY_VERSION_HEX >= 0x03000000)
119 #define NUMBER_Check PyLong_Check
120 #define NUMBER_AsLong PyLong_AsLong
121 #define NUMBER_FromLong PyLong_FromLong
123 #define NUMBER_Check PyInt_Check
124 #define NUMBER_AsLong PyInt_AsLong
125 #define NUMBER_FromLong PyInt_FromLong
130 /* These are for when calling Python --> C */
131 #define MYDB_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS;
132 #define MYDB_END_ALLOW_THREADS Py_END_ALLOW_THREADS;
134 /* For 2.3, use the PyGILState_ calls */
135 #if (PY_VERSION_HEX >= 0x02030000)
136 #define MYDB_USE_GILSTATE
139 /* and these are for calling C --> Python */
140 #if defined(MYDB_USE_GILSTATE)
141 #define MYDB_BEGIN_BLOCK_THREADS \
142 PyGILState_STATE __savestate = PyGILState_Ensure();
143 #define MYDB_END_BLOCK_THREADS \
144 PyGILState_Release(__savestate);
145 #else /* MYDB_USE_GILSTATE */
146 /* Pre GILState API - do it the long old way */
147 static PyInterpreterState
* _db_interpreterState
= NULL
;
148 #define MYDB_BEGIN_BLOCK_THREADS { \
149 PyThreadState* prevState; \
150 PyThreadState* newState; \
151 PyEval_AcquireLock(); \
152 newState = PyThreadState_New(_db_interpreterState); \
153 prevState = PyThreadState_Swap(newState);
155 #define MYDB_END_BLOCK_THREADS \
156 newState = PyThreadState_Swap(prevState); \
157 PyThreadState_Clear(newState); \
158 PyEval_ReleaseLock(); \
159 PyThreadState_Delete(newState); \
161 #endif /* MYDB_USE_GILSTATE */
164 /* Compiled without threads - avoid all this cruft */
165 #define MYDB_BEGIN_ALLOW_THREADS
166 #define MYDB_END_ALLOW_THREADS
167 #define MYDB_BEGIN_BLOCK_THREADS
168 #define MYDB_END_BLOCK_THREADS
172 /* Should DB_INCOMPLETE be turned into a warning or an exception? */
173 #define INCOMPLETE_IS_WARNING 1
175 /* --------------------------------------------------------------------- */
178 static PyObject
* DBError
; /* Base class, all others derive from this */
179 static PyObject
* DBCursorClosedError
; /* raised when trying to use a closed cursor object */
180 static PyObject
* DBKeyEmptyError
; /* DB_KEYEMPTY: also derives from KeyError */
181 static PyObject
* DBKeyExistError
; /* DB_KEYEXIST */
182 static PyObject
* DBLockDeadlockError
; /* DB_LOCK_DEADLOCK */
183 static PyObject
* DBLockNotGrantedError
; /* DB_LOCK_NOTGRANTED */
184 static PyObject
* DBNotFoundError
; /* DB_NOTFOUND: also derives from KeyError */
185 static PyObject
* DBOldVersionError
; /* DB_OLD_VERSION */
186 static PyObject
* DBRunRecoveryError
; /* DB_RUNRECOVERY */
187 static PyObject
* DBVerifyBadError
; /* DB_VERIFY_BAD */
188 static PyObject
* DBNoServerError
; /* DB_NOSERVER */
189 static PyObject
* DBNoServerHomeError
; /* DB_NOSERVER_HOME */
190 static PyObject
* DBNoServerIDError
; /* DB_NOSERVER_ID */
191 static PyObject
* DBPageNotFoundError
; /* DB_PAGE_NOTFOUND */
192 static PyObject
* DBSecondaryBadError
; /* DB_SECONDARY_BAD */
194 #if !INCOMPLETE_IS_WARNING
195 static PyObject
* DBIncompleteError
; /* DB_INCOMPLETE */
198 static PyObject
* DBInvalidArgError
; /* EINVAL */
199 static PyObject
* DBAccessError
; /* EACCES */
200 static PyObject
* DBNoSpaceError
; /* ENOSPC */
201 static PyObject
* DBNoMemoryError
; /* DB_BUFFER_SMALL (ENOMEM when < 4.3) */
202 static PyObject
* DBAgainError
; /* EAGAIN */
203 static PyObject
* DBBusyError
; /* EBUSY */
204 static PyObject
* DBFileExistsError
; /* EEXIST */
205 static PyObject
* DBNoSuchFileError
; /* ENOENT */
206 static PyObject
* DBPermissionsError
; /* EPERM */
209 static PyObject
* DBRepHandleDeadError
; /* DB_REP_HANDLE_DEAD */
212 static PyObject
* DBRepUnavailError
; /* DB_REP_UNAVAIL */
215 #define DB_BUFFER_SMALL ENOMEM
219 /* --------------------------------------------------------------------- */
220 /* Structure definitions */
222 #if PYTHON_API_VERSION < 1010
223 #error "Python 2.1 or later required"
227 /* Defaults for moduleFlags in DBEnvObject and DBObject. */
228 #define DEFAULT_GET_RETURNS_NONE 1
229 #define DEFAULT_CURSOR_SET_RETURNS_NONE 1 /* 0 in pybsddb < 4.2, python < 2.4 */
232 /* See comment in Python 2.6 "object.h" */
233 #ifndef staticforward
234 #define staticforward static
237 #define statichere static
240 staticforward PyTypeObject DB_Type
, DBCursor_Type
, DBEnv_Type
, DBTxn_Type
,
243 staticforward PyTypeObject DBSequence_Type
;
247 /* for compatibility with Python 2.5 and earlier */
248 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
251 #define DBObject_Check(v) (Py_TYPE(v) == &DB_Type)
252 #define DBCursorObject_Check(v) (Py_TYPE(v) == &DBCursor_Type)
253 #define DBEnvObject_Check(v) (Py_TYPE(v) == &DBEnv_Type)
254 #define DBTxnObject_Check(v) (Py_TYPE(v) == &DBTxn_Type)
255 #define DBLockObject_Check(v) (Py_TYPE(v) == &DBLock_Type)
257 #define DBSequenceObject_Check(v) (Py_TYPE(v) == &DBSequence_Type)
261 #define _DBC_close(dbc) dbc->c_close(dbc)
262 #define _DBC_count(dbc,a,b) dbc->c_count(dbc,a,b)
263 #define _DBC_del(dbc,a) dbc->c_del(dbc,a)
264 #define _DBC_dup(dbc,a,b) dbc->c_dup(dbc,a,b)
265 #define _DBC_get(dbc,a,b,c) dbc->c_get(dbc,a,b,c)
266 #define _DBC_pget(dbc,a,b,c,d) dbc->c_pget(dbc,a,b,c,d)
267 #define _DBC_put(dbc,a,b,c) dbc->c_put(dbc,a,b,c)
269 #define _DBC_close(dbc) dbc->close(dbc)
270 #define _DBC_count(dbc,a,b) dbc->count(dbc,a,b)
271 #define _DBC_del(dbc,a) dbc->del(dbc,a)
272 #define _DBC_dup(dbc,a,b) dbc->dup(dbc,a,b)
273 #define _DBC_get(dbc,a,b,c) dbc->get(dbc,a,b,c)
274 #define _DBC_pget(dbc,a,b,c,d) dbc->pget(dbc,a,b,c,d)
275 #define _DBC_put(dbc,a,b,c) dbc->put(dbc,a,b,c)
279 /* --------------------------------------------------------------------- */
280 /* Utility macros and functions */
282 #define INSERT_IN_DOUBLE_LINKED_LIST(backlink,object) \
284 object->sibling_next=backlink; \
285 object->sibling_prev_p=&(backlink); \
287 if (object->sibling_next) { \
288 object->sibling_next->sibling_prev_p=&(object->sibling_next); \
292 #define EXTRACT_FROM_DOUBLE_LINKED_LIST(object) \
294 if (object->sibling_next) { \
295 object->sibling_next->sibling_prev_p=object->sibling_prev_p; \
297 *(object->sibling_prev_p)=object->sibling_next; \
300 #define EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(object) \
302 if (object->sibling_next) { \
303 object->sibling_next->sibling_prev_p=object->sibling_prev_p; \
305 if (object->sibling_prev_p) { \
306 *(object->sibling_prev_p)=object->sibling_next; \
310 #define INSERT_IN_DOUBLE_LINKED_LIST_TXN(backlink,object) \
312 object->sibling_next_txn=backlink; \
313 object->sibling_prev_p_txn=&(backlink); \
315 if (object->sibling_next_txn) { \
316 object->sibling_next_txn->sibling_prev_p_txn= \
317 &(object->sibling_next_txn); \
321 #define EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(object) \
323 if (object->sibling_next_txn) { \
324 object->sibling_next_txn->sibling_prev_p_txn= \
325 object->sibling_prev_p_txn; \
327 *(object->sibling_prev_p_txn)=object->sibling_next_txn; \
331 #define RETURN_IF_ERR() \
332 if (makeDBError(err)) { \
336 #define RETURN_NONE() Py_INCREF(Py_None); return Py_None;
338 #define _CHECK_OBJECT_NOT_CLOSED(nonNull, pyErrObj, name) \
339 if ((nonNull) == NULL) { \
340 PyObject *errTuple = NULL; \
341 errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
343 PyErr_SetObject((pyErrObj), errTuple); \
344 Py_DECREF(errTuple); \
349 #define CHECK_DB_NOT_CLOSED(dbobj) \
350 _CHECK_OBJECT_NOT_CLOSED(dbobj->db, DBError, DB)
352 #define CHECK_ENV_NOT_CLOSED(env) \
353 _CHECK_OBJECT_NOT_CLOSED(env->db_env, DBError, DBEnv)
355 #define CHECK_CURSOR_NOT_CLOSED(curs) \
356 _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)
359 #define CHECK_SEQUENCE_NOT_CLOSED(curs) \
360 _CHECK_OBJECT_NOT_CLOSED(curs->sequence, DBError, DBSequence)
363 #define CHECK_DBFLAG(mydb, flag) (((mydb)->flags & (flag)) || \
364 (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))
366 #define CLEAR_DBT(dbt) (memset(&(dbt), 0, sizeof(dbt)))
368 #define FREE_DBT(dbt) if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
369 dbt.data != NULL) { free(dbt.data); dbt.data = NULL; }
372 static int makeDBError(int err
);
375 /* Return the access method type of the DBObject */
376 static int _DB_get_type(DBObject
* self
)
381 err
= self
->db
->get_type(self
->db
, &type
);
382 if (makeDBError(err
)) {
389 /* Create a DBT structure (containing key and data values) from Python
390 strings. Returns 1 on success, 0 on an error. */
391 static int make_dbt(PyObject
* obj
, DBT
* dbt
)
394 if (obj
== Py_None
) {
395 /* no need to do anything, the structure has already been zeroed */
397 else if (!PyArg_Parse(obj
, "s#", &dbt
->data
, &dbt
->size
)) {
398 PyErr_SetString(PyExc_TypeError
,
399 #if (PY_VERSION_HEX < 0x03000000)
400 "Data values must be of type string or None.");
402 "Data values must be of type bytes or None.");
410 /* Recno and Queue DBs can have integer keys. This function figures out
411 what's been given, verifies that it's allowed, and then makes the DBT.
413 Caller MUST call FREE_DBT(key) when done. */
415 make_key_dbt(DBObject
* self
, PyObject
* keyobj
, DBT
* key
, int* pflags
)
421 if (keyobj
== Py_None
) {
422 type
= _DB_get_type(self
);
425 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
428 "None keys not allowed for Recno and Queue DB's");
431 /* no need to do anything, the structure has already been zeroed */
434 else if (PyBytes_Check(keyobj
)) {
435 /* verify access method type */
436 type
= _DB_get_type(self
);
439 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
442 #if (PY_VERSION_HEX < 0x03000000)
443 "String keys not allowed for Recno and Queue DB's");
445 "Bytes keys not allowed for Recno and Queue DB's");
451 * NOTE(gps): I don't like doing a data copy here, it seems
452 * wasteful. But without a clean way to tell FREE_DBT if it
453 * should free key->data or not we have to. Other places in
454 * the code check for DB_THREAD and forceably set DBT_MALLOC
455 * when we otherwise would leave flags 0 to indicate that.
457 key
->data
= malloc(PyBytes_GET_SIZE(keyobj
));
458 if (key
->data
== NULL
) {
459 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
462 memcpy(key
->data
, PyBytes_AS_STRING(keyobj
),
463 PyBytes_GET_SIZE(keyobj
));
464 key
->flags
= DB_DBT_REALLOC
;
465 key
->size
= PyBytes_GET_SIZE(keyobj
);
468 else if (NUMBER_Check(keyobj
)) {
469 /* verify access method type */
470 type
= _DB_get_type(self
);
473 if (type
== DB_BTREE
&& pflags
!= NULL
) {
474 /* if BTREE then an Integer key is allowed with the
475 * DB_SET_RECNO flag */
476 *pflags
|= DB_SET_RECNO
;
478 else if (type
!= DB_RECNO
&& type
!= DB_QUEUE
) {
481 "Integer keys only allowed for Recno and Queue DB's");
485 /* Make a key out of the requested recno, use allocated space so DB
486 * will be able to realloc room for the real key if needed. */
487 recno
= NUMBER_AsLong(keyobj
);
488 key
->data
= malloc(sizeof(db_recno_t
));
489 if (key
->data
== NULL
) {
490 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
493 key
->ulen
= key
->size
= sizeof(db_recno_t
);
494 memcpy(key
->data
, &recno
, sizeof(db_recno_t
));
495 key
->flags
= DB_DBT_REALLOC
;
498 PyErr_Format(PyExc_TypeError
,
499 #if (PY_VERSION_HEX < 0x03000000)
500 "String or Integer object expected for key, %s found",
502 "Bytes or Integer object expected for key, %s found",
504 Py_TYPE(keyobj
)->tp_name
);
512 /* Add partial record access to an existing DBT data struct.
513 If dlen and doff are set, then the DB_DBT_PARTIAL flag will be set
514 and the data storage/retrieval will be done using dlen and doff. */
515 static int add_partial_dbt(DBT
* d
, int dlen
, int doff
) {
516 /* if neither were set we do nothing (-1 is the default value) */
517 if ((dlen
== -1) && (doff
== -1)) {
521 if ((dlen
< 0) || (doff
< 0)) {
522 PyErr_SetString(PyExc_TypeError
, "dlen and doff must both be >= 0");
526 d
->flags
= d
->flags
| DB_DBT_PARTIAL
;
527 d
->dlen
= (unsigned int) dlen
;
528 d
->doff
= (unsigned int) doff
;
532 /* a safe strcpy() without the zeroing behaviour and semantics of strncpy. */
533 /* TODO: make this use the native libc strlcpy() when available (BSD) */
534 unsigned int our_strlcpy(char* dest
, const char* src
, unsigned int n
)
536 unsigned int srclen
, copylen
;
538 srclen
= strlen(src
);
541 copylen
= (srclen
> n
-1) ? n
-1 : srclen
;
542 /* populate dest[0] thru dest[copylen-1] */
543 memcpy(dest
, src
, copylen
);
544 /* guarantee null termination */
550 /* Callback used to save away more information about errors from the DB
552 static char _db_errmsg
[1024];
554 static void _db_errorCallback(const char* prefix
, char* msg
)
556 static void _db_errorCallback(const DB_ENV
*db_env
,
557 const char* prefix
, const char* msg
)
560 our_strlcpy(_db_errmsg
, msg
, sizeof(_db_errmsg
));
565 ** We need these functions because some results
566 ** are undefined if pointer is NULL. Some other
567 ** give None instead of "".
569 ** This functions are static and will be
572 static const char *DummyString
= "This string is a simple placeholder";
573 static PyObject
*Build_PyString(const char *p
,int s
)
579 return PyBytes_FromStringAndSize(p
,s
);
582 static PyObject
*BuildValue_S(const void *p
,int s
)
588 return PyBytes_FromStringAndSize(p
, s
);
591 static PyObject
*BuildValue_SS(const void *p1
,int s1
,const void *p2
,int s2
)
604 if (!(a
= PyBytes_FromStringAndSize(p1
, s1
))) {
607 if (!(b
= PyBytes_FromStringAndSize(p2
, s2
))) {
612 #if (PY_VERSION_HEX >= 0x02040000)
613 r
= PyTuple_Pack(2, a
, b
) ;
615 r
= Py_BuildValue("OO", a
, b
);
622 static PyObject
*BuildValue_IS(int i
,const void *p
,int s
)
631 if (!(a
= PyBytes_FromStringAndSize(p
, s
))) {
635 r
= Py_BuildValue("iO", i
, a
);
640 static PyObject
*BuildValue_LS(long l
,const void *p
,int s
)
649 if (!(a
= PyBytes_FromStringAndSize(p
, s
))) {
653 r
= Py_BuildValue("lO", l
, a
);
660 /* make a nice exception object to raise for errors. */
661 static int makeDBError(int err
)
663 char errTxt
[2048]; /* really big, just in case... */
664 PyObject
*errObj
= NULL
;
665 PyObject
*errTuple
= NULL
;
666 int exceptionRaised
= 0;
667 unsigned int bytes_left
;
670 case 0: /* successful, no error */ break;
674 #if INCOMPLETE_IS_WARNING
675 bytes_left
= our_strlcpy(errTxt
, db_strerror(err
), sizeof(errTxt
));
676 /* Ensure that bytes_left never goes negative */
677 if (_db_errmsg
[0] && bytes_left
< (sizeof(errTxt
) - 4)) {
678 bytes_left
= sizeof(errTxt
) - bytes_left
- 4 - 1;
679 assert(bytes_left
>= 0);
680 strcat(errTxt
, " -- ");
681 strncat(errTxt
, _db_errmsg
, bytes_left
);
684 exceptionRaised
= PyErr_Warn(PyExc_RuntimeWarning
, errTxt
);
686 #else /* do an exception instead */
687 errObj
= DBIncompleteError
;
690 #endif /* DBVER < 41 */
692 case DB_KEYEMPTY
: errObj
= DBKeyEmptyError
; break;
693 case DB_KEYEXIST
: errObj
= DBKeyExistError
; break;
694 case DB_LOCK_DEADLOCK
: errObj
= DBLockDeadlockError
; break;
695 case DB_LOCK_NOTGRANTED
: errObj
= DBLockNotGrantedError
; break;
696 case DB_NOTFOUND
: errObj
= DBNotFoundError
; break;
697 case DB_OLD_VERSION
: errObj
= DBOldVersionError
; break;
698 case DB_RUNRECOVERY
: errObj
= DBRunRecoveryError
; break;
699 case DB_VERIFY_BAD
: errObj
= DBVerifyBadError
; break;
700 case DB_NOSERVER
: errObj
= DBNoServerError
; break;
701 case DB_NOSERVER_HOME
: errObj
= DBNoServerHomeError
; break;
702 case DB_NOSERVER_ID
: errObj
= DBNoServerIDError
; break;
703 case DB_PAGE_NOTFOUND
: errObj
= DBPageNotFoundError
; break;
704 case DB_SECONDARY_BAD
: errObj
= DBSecondaryBadError
; break;
705 case DB_BUFFER_SMALL
: errObj
= DBNoMemoryError
; break;
708 /* ENOMEM and DB_BUFFER_SMALL were one and the same until 4.3 */
709 case ENOMEM
: errObj
= PyExc_MemoryError
; break;
711 case EINVAL
: errObj
= DBInvalidArgError
; break;
712 case EACCES
: errObj
= DBAccessError
; break;
713 case ENOSPC
: errObj
= DBNoSpaceError
; break;
714 case EAGAIN
: errObj
= DBAgainError
; break;
715 case EBUSY
: errObj
= DBBusyError
; break;
716 case EEXIST
: errObj
= DBFileExistsError
; break;
717 case ENOENT
: errObj
= DBNoSuchFileError
; break;
718 case EPERM
: errObj
= DBPermissionsError
; break;
721 case DB_REP_HANDLE_DEAD
: errObj
= DBRepHandleDeadError
; break;
724 case DB_REP_UNAVAIL
: errObj
= DBRepUnavailError
; break;
726 default: errObj
= DBError
; break;
729 if (errObj
!= NULL
) {
730 bytes_left
= our_strlcpy(errTxt
, db_strerror(err
), sizeof(errTxt
));
731 /* Ensure that bytes_left never goes negative */
732 if (_db_errmsg
[0] && bytes_left
< (sizeof(errTxt
) - 4)) {
733 bytes_left
= sizeof(errTxt
) - bytes_left
- 4 - 1;
734 assert(bytes_left
>= 0);
735 strcat(errTxt
, " -- ");
736 strncat(errTxt
, _db_errmsg
, bytes_left
);
740 errTuple
= Py_BuildValue("(is)", err
, errTxt
);
741 if (errTuple
== NULL
) {
745 PyErr_SetObject(errObj
, errTuple
);
749 return ((errObj
!= NULL
) || exceptionRaised
);
754 /* set a type exception */
755 static void makeTypeError(char* expected
, PyObject
* found
)
757 PyErr_Format(PyExc_TypeError
, "Expected %s argument, %s found.",
758 expected
, Py_TYPE(found
)->tp_name
);
762 /* verify that an obj is either None or a DBTxn, and set the txn pointer */
763 static int checkTxnObj(PyObject
* txnobj
, DB_TXN
** txn
)
765 if (txnobj
== Py_None
|| txnobj
== NULL
) {
769 if (DBTxnObject_Check(txnobj
)) {
770 *txn
= ((DBTxnObject
*)txnobj
)->txn
;
774 makeTypeError("DBTxn", txnobj
);
779 /* Delete a key from a database
780 Returns 0 on success, -1 on an error. */
781 static int _DB_delete(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, int flags
)
785 MYDB_BEGIN_ALLOW_THREADS
;
786 err
= self
->db
->del(self
->db
, txn
, key
, 0);
787 MYDB_END_ALLOW_THREADS
;
788 if (makeDBError(err
)) {
796 /* Store a key into a database
797 Returns 0 on success, -1 on an error. */
798 static int _DB_put(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, DBT
*data
, int flags
)
802 MYDB_BEGIN_ALLOW_THREADS
;
803 err
= self
->db
->put(self
->db
, txn
, key
, data
, flags
);
804 MYDB_END_ALLOW_THREADS
;
805 if (makeDBError(err
)) {
812 /* Get a key/data pair from a cursor */
813 static PyObject
* _DBCursor_get(DBCursorObject
* self
, int extra_flags
,
814 PyObject
*args
, PyObject
*kwargs
, char *format
)
817 PyObject
* retval
= NULL
;
822 static char* kwnames
[] = { "flags", "dlen", "doff", NULL
};
824 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, format
, kwnames
,
825 &flags
, &dlen
, &doff
))
828 CHECK_CURSOR_NOT_CLOSED(self
);
830 flags
|= extra_flags
;
833 if (!add_partial_dbt(&data
, dlen
, doff
))
836 MYDB_BEGIN_ALLOW_THREADS
;
837 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
);
838 MYDB_END_ALLOW_THREADS
;
840 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
841 && self
->mydb
->moduleFlags
.getReturnsNone
) {
845 else if (makeDBError(err
)) {
848 else { /* otherwise, success! */
850 /* if Recno or Queue, return the key as an Int */
851 switch (_DB_get_type(self
->mydb
)) {
858 retval
= BuildValue_IS(*((db_recno_t
*)key
.data
), data
.data
, data
.size
);
863 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
871 /* add an integer to a dictionary using the given name as a key */
872 static void _addIntToDict(PyObject
* dict
, char *name
, int value
)
874 PyObject
* v
= NUMBER_FromLong((long) value
);
875 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
881 /* The same, when the value is a time_t */
882 static void _addTimeTToDict(PyObject
* dict
, char *name
, time_t value
)
885 /* if the value fits in regular int, use that. */
887 if (sizeof(time_t) > sizeof(long))
888 v
= PyLong_FromLongLong((PY_LONG_LONG
) value
);
891 v
= NUMBER_FromLong((long) value
);
892 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
899 /* add an db_seq_t to a dictionary using the given name as a key */
900 static void _addDb_seq_tToDict(PyObject
* dict
, char *name
, db_seq_t value
)
902 PyObject
* v
= PyLong_FromLongLong(value
);
903 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
910 static void _addDB_lsnToDict(PyObject
* dict
, char *name
, DB_LSN value
)
912 PyObject
*v
= Py_BuildValue("(ll)",value
.file
,value
.offset
);
913 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
919 /* --------------------------------------------------------------------- */
920 /* Allocators and deallocators */
923 newDBObject(DBEnvObject
* arg
, int flags
)
926 DB_ENV
* db_env
= NULL
;
929 self
= PyObject_New(DBObject
, &DB_Type
);
936 self
->myenvobj
= NULL
;
938 self
->children_cursors
= NULL
;
940 self
->children_sequences
= NULL
;
942 self
->associateCallback
= NULL
;
943 self
->btCompareCallback
= NULL
;
944 self
->primaryDBType
= 0;
946 self
->private_obj
= Py_None
;
947 self
->in_weakreflist
= NULL
;
949 /* keep a reference to our python DBEnv object */
952 self
->myenvobj
= arg
;
953 db_env
= arg
->db_env
;
954 INSERT_IN_DOUBLE_LINKED_LIST(self
->myenvobj
->children_dbs
,self
);
956 self
->sibling_prev_p
=NULL
;
957 self
->sibling_next
=NULL
;
960 self
->sibling_prev_p_txn
=NULL
;
961 self
->sibling_next_txn
=NULL
;
964 self
->moduleFlags
= self
->myenvobj
->moduleFlags
;
966 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
967 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
969 MYDB_BEGIN_ALLOW_THREADS
;
970 err
= db_create(&self
->db
, db_env
, flags
);
971 if (self
->db
!= NULL
) {
972 self
->db
->set_errcall(self
->db
, _db_errorCallback
);
973 self
->db
->app_private
= (void*)self
;
975 MYDB_END_ALLOW_THREADS
;
976 /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
977 * list so that a DBEnv can refuse to close without aborting any open
978 * DBTxns and closing any open DBs first. */
979 if (makeDBError(err
)) {
980 if (self
->myenvobj
) {
981 Py_DECREF(self
->myenvobj
);
982 self
->myenvobj
= NULL
;
991 /* Forward declaration */
992 static PyObject
*DB_close_internal(DBObject
* self
, int flags
, int do_not_close
);
995 DB_dealloc(DBObject
* self
)
999 if (self
->db
!= NULL
) {
1000 dummy
=DB_close_internal(self
, 0, 0);
1002 ** Raising exceptions while doing
1003 ** garbage collection is a fatal error.
1010 if (self
->in_weakreflist
!= NULL
) {
1011 PyObject_ClearWeakRefs((PyObject
*) self
);
1013 if (self
->myenvobj
) {
1014 Py_DECREF(self
->myenvobj
);
1015 self
->myenvobj
= NULL
;
1017 if (self
->associateCallback
!= NULL
) {
1018 Py_DECREF(self
->associateCallback
);
1019 self
->associateCallback
= NULL
;
1021 if (self
->btCompareCallback
!= NULL
) {
1022 Py_DECREF(self
->btCompareCallback
);
1023 self
->btCompareCallback
= NULL
;
1025 Py_DECREF(self
->private_obj
);
1029 static DBCursorObject
*
1030 newDBCursorObject(DBC
* dbc
, DBTxnObject
*txn
, DBObject
* db
)
1032 DBCursorObject
* self
= PyObject_New(DBCursorObject
, &DBCursor_Type
);
1039 INSERT_IN_DOUBLE_LINKED_LIST(self
->mydb
->children_cursors
,self
);
1040 if (txn
&& ((PyObject
*)txn
!=Py_None
)) {
1041 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn
->children_cursors
,self
);
1047 self
->in_weakreflist
= NULL
;
1048 Py_INCREF(self
->mydb
);
1053 /* Forward declaration */
1054 static PyObject
*DBC_close_internal(DBCursorObject
* self
);
1057 DBCursor_dealloc(DBCursorObject
* self
)
1061 if (self
->dbc
!= NULL
) {
1062 dummy
=DBC_close_internal(self
);
1064 ** Raising exceptions while doing
1065 ** garbage collection is a fatal error.
1072 if (self
->in_weakreflist
!= NULL
) {
1073 PyObject_ClearWeakRefs((PyObject
*) self
);
1075 Py_DECREF(self
->mydb
);
1081 newDBEnvObject(int flags
)
1084 DBEnvObject
* self
= PyObject_New(DBEnvObject
, &DBEnv_Type
);
1088 self
->db_env
= NULL
;
1090 self
->flags
= flags
;
1091 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
1092 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
1093 self
->children_dbs
= NULL
;
1094 self
->children_txns
= NULL
;
1096 self
->private_obj
= Py_None
;
1098 self
->rep_transport
= Py_None
;
1099 self
->in_weakreflist
= NULL
;
1100 self
->event_notifyCallback
= NULL
;
1102 MYDB_BEGIN_ALLOW_THREADS
;
1103 err
= db_env_create(&self
->db_env
, flags
);
1104 MYDB_END_ALLOW_THREADS
;
1105 if (makeDBError(err
)) {
1110 self
->db_env
->set_errcall(self
->db_env
, _db_errorCallback
);
1111 self
->db_env
->app_private
= self
;
1116 /* Forward declaration */
1117 static PyObject
*DBEnv_close_internal(DBEnvObject
* self
, int flags
);
1120 DBEnv_dealloc(DBEnvObject
* self
)
1125 dummy
=DBEnv_close_internal(self
, 0);
1127 ** Raising exceptions while doing
1128 ** garbage collection is a fatal error.
1136 Py_XDECREF(self
->event_notifyCallback
);
1137 self
->event_notifyCallback
= NULL
;
1139 if (self
->in_weakreflist
!= NULL
) {
1140 PyObject_ClearWeakRefs((PyObject
*) self
);
1142 Py_DECREF(self
->private_obj
);
1143 Py_DECREF(self
->rep_transport
);
1149 newDBTxnObject(DBEnvObject
* myenv
, DBTxnObject
*parent
, DB_TXN
*txn
, int flags
)
1152 DB_TXN
*parent_txn
= NULL
;
1154 DBTxnObject
* self
= PyObject_New(DBTxnObject
, &DBTxn_Type
);
1158 self
->in_weakreflist
= NULL
;
1159 self
->children_txns
= NULL
;
1160 self
->children_dbs
= NULL
;
1161 self
->children_cursors
= NULL
;
1162 self
->children_sequences
= NULL
;
1163 self
->flag_prepare
= 0;
1164 self
->parent_txn
= NULL
;
1167 if (parent
&& ((PyObject
*)parent
!=Py_None
)) {
1168 parent_txn
= parent
->txn
;
1174 MYDB_BEGIN_ALLOW_THREADS
;
1175 err
= myenv
->db_env
->txn_begin(myenv
->db_env
, parent_txn
, &(self
->txn
), flags
);
1176 MYDB_END_ALLOW_THREADS
;
1178 if (makeDBError(err
)) {
1184 /* Can't use 'parent' because could be 'parent==Py_None' */
1186 self
->parent_txn
= parent
;
1189 INSERT_IN_DOUBLE_LINKED_LIST(parent
->children_txns
, self
);
1191 self
->parent_txn
= NULL
;
1194 INSERT_IN_DOUBLE_LINKED_LIST(myenv
->children_txns
, self
);
1200 /* Forward declaration */
1202 DBTxn_abort_discard_internal(DBTxnObject
* self
, int discard
);
1205 DBTxn_dealloc(DBTxnObject
* self
)
1210 int flag_prepare
= self
->flag_prepare
;
1212 dummy
=DBTxn_abort_discard_internal(self
,0);
1214 ** Raising exceptions while doing
1215 ** garbage collection is a fatal error.
1222 if (!flag_prepare
) {
1223 PyErr_Warn(PyExc_RuntimeWarning
,
1224 "DBTxn aborted in destructor. No prior commit() or abort().");
1228 if (self
->in_weakreflist
!= NULL
) {
1229 PyObject_ClearWeakRefs((PyObject
*) self
);
1233 Py_DECREF(self
->env
);
1235 Py_DECREF(self
->parent_txn
);
1241 static DBLockObject
*
1242 newDBLockObject(DBEnvObject
* myenv
, u_int32_t locker
, DBT
* obj
,
1243 db_lockmode_t lock_mode
, int flags
)
1246 DBLockObject
* self
= PyObject_New(DBLockObject
, &DBLock_Type
);
1249 self
->in_weakreflist
= NULL
;
1251 MYDB_BEGIN_ALLOW_THREADS
;
1252 err
= myenv
->db_env
->lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
,
1254 MYDB_END_ALLOW_THREADS
;
1255 if (makeDBError(err
)) {
1265 DBLock_dealloc(DBLockObject
* self
)
1267 if (self
->in_weakreflist
!= NULL
) {
1268 PyObject_ClearWeakRefs((PyObject
*) self
);
1270 /* TODO: is this lock held? should we release it? */
1277 static DBSequenceObject
*
1278 newDBSequenceObject(DBObject
* mydb
, int flags
)
1281 DBSequenceObject
* self
= PyObject_New(DBSequenceObject
, &DBSequence_Type
);
1287 INSERT_IN_DOUBLE_LINKED_LIST(self
->mydb
->children_sequences
,self
);
1290 self
->in_weakreflist
= NULL
;
1292 MYDB_BEGIN_ALLOW_THREADS
;
1293 err
= db_sequence_create(&self
->sequence
, self
->mydb
->db
, flags
);
1294 MYDB_END_ALLOW_THREADS
;
1295 if (makeDBError(err
)) {
1303 /* Forward declaration */
1305 *DBSequence_close_internal(DBSequenceObject
* self
, int flags
, int do_not_close
);
1308 DBSequence_dealloc(DBSequenceObject
* self
)
1312 if (self
->sequence
!= NULL
) {
1313 dummy
=DBSequence_close_internal(self
,0,0);
1315 ** Raising exceptions while doing
1316 ** garbage collection is a fatal error.
1324 if (self
->in_weakreflist
!= NULL
) {
1325 PyObject_ClearWeakRefs((PyObject
*) self
);
1328 Py_DECREF(self
->mydb
);
1333 /* --------------------------------------------------------------------- */
1337 DB_append(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1339 PyObject
* txnobj
= NULL
;
1344 static char* kwnames
[] = { "data", "txn", NULL
};
1346 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O:append", kwnames
,
1350 CHECK_DB_NOT_CLOSED(self
);
1352 /* make a dummy key out of a recno */
1356 key
.size
= sizeof(recno
);
1357 key
.ulen
= key
.size
;
1358 key
.flags
= DB_DBT_USERMEM
;
1360 if (!make_dbt(dataobj
, &data
)) return NULL
;
1361 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1363 if (-1 == _DB_put(self
, txn
, &key
, &data
, DB_APPEND
))
1366 return NUMBER_FromLong(recno
);
1371 _db_associateCallback(DB
* db
, const DBT
* priKey
, const DBT
* priData
,
1374 int retval
= DB_DONOTINDEX
;
1375 DBObject
* secondaryDB
= (DBObject
*)db
->app_private
;
1376 PyObject
* callback
= secondaryDB
->associateCallback
;
1377 int type
= secondaryDB
->primaryDBType
;
1379 PyObject
* result
= NULL
;
1382 if (callback
!= NULL
) {
1383 MYDB_BEGIN_BLOCK_THREADS
;
1385 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
1386 args
= BuildValue_LS(*((db_recno_t
*)priKey
->data
), priData
->data
, priData
->size
);
1388 args
= BuildValue_SS(priKey
->data
, priKey
->size
, priData
->data
, priData
->size
);
1390 result
= PyEval_CallObject(callback
, args
);
1392 if (args
== NULL
|| result
== NULL
) {
1395 else if (result
== Py_None
) {
1396 retval
= DB_DONOTINDEX
;
1398 else if (NUMBER_Check(result
)) {
1399 retval
= NUMBER_AsLong(result
);
1401 else if (PyBytes_Check(result
)) {
1406 PyBytes_AsStringAndSize(result
, &data
, &size
);
1407 secKey
->flags
= DB_DBT_APPMALLOC
; /* DB will free */
1408 secKey
->data
= malloc(size
); /* TODO, check this */
1410 memcpy(secKey
->data
, data
, size
);
1411 secKey
->size
= size
;
1415 PyErr_SetString(PyExc_MemoryError
,
1416 "malloc failed in _db_associateCallback");
1423 "DB associate callback should return DB_DONOTINDEX or string.");
1430 MYDB_END_BLOCK_THREADS
;
1437 DB_associate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1440 DBObject
* secondaryDB
;
1443 PyObject
*txnobj
= NULL
;
1445 static char* kwnames
[] = {"secondaryDB", "callback", "flags", "txn",
1448 static char* kwnames
[] = {"secondaryDB", "callback", "flags", NULL
};
1452 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iO:associate", kwnames
,
1453 &secondaryDB
, &callback
, &flags
,
1456 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|i:associate", kwnames
,
1457 &secondaryDB
, &callback
, &flags
)) {
1463 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1466 CHECK_DB_NOT_CLOSED(self
);
1467 if (!DBObject_Check(secondaryDB
)) {
1468 makeTypeError("DB", (PyObject
*)secondaryDB
);
1471 CHECK_DB_NOT_CLOSED(secondaryDB
);
1472 if (callback
== Py_None
) {
1475 else if (!PyCallable_Check(callback
)) {
1476 makeTypeError("Callable", callback
);
1480 /* Save a reference to the callback in the secondary DB. */
1481 Py_XDECREF(secondaryDB
->associateCallback
);
1482 Py_XINCREF(callback
);
1483 secondaryDB
->associateCallback
= callback
;
1484 secondaryDB
->primaryDBType
= _DB_get_type(self
);
1486 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1487 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1488 * The global interepreter lock is not initialized until the first
1489 * thread is created using thread.start_new_thread() or fork() is
1490 * called. that would cause the ALLOW_THREADS here to segfault due
1491 * to a null pointer reference if no threads or child processes
1492 * have been created. This works around that and is a no-op if
1493 * threads have already been initialized.
1494 * (see pybsddb-users mailing list post on 2002-08-07)
1497 PyEval_InitThreads();
1499 MYDB_BEGIN_ALLOW_THREADS
;
1501 err
= self
->db
->associate(self
->db
,
1504 _db_associateCallback
,
1507 err
= self
->db
->associate(self
->db
,
1509 _db_associateCallback
,
1512 MYDB_END_ALLOW_THREADS
;
1515 Py_XDECREF(secondaryDB
->associateCallback
);
1516 secondaryDB
->associateCallback
= NULL
;
1517 secondaryDB
->primaryDBType
= 0;
1526 DB_close_internal(DBObject
* self
, int flags
, int do_not_close
)
1531 if (self
->db
!= NULL
) {
1532 /* Can be NULL if db is not in an environment */
1533 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self
);
1536 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self
);
1540 while(self
->children_cursors
) {
1541 dummy
=DBC_close_internal(self
->children_cursors
);
1546 while(self
->children_sequences
) {
1547 dummy
=DBSequence_close_internal(self
->children_sequences
,0,0);
1553 ** "do_not_close" is used to dispose all related objects in the
1554 ** tree, without actually releasing the "root" object.
1555 ** This is done, for example, because function calls like
1556 ** "DB.verify()" implicitly close the underlying handle. So
1557 ** the handle doesn't need to be closed, but related objects
1558 ** must be cleaned up.
1560 if (!do_not_close
) {
1561 MYDB_BEGIN_ALLOW_THREADS
;
1562 err
= self
->db
->close(self
->db
, flags
);
1563 MYDB_END_ALLOW_THREADS
;
1572 DB_close(DBObject
* self
, PyObject
* args
)
1575 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
1577 return DB_close_internal(self
, flags
, 0);
1582 _DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1584 int err
, flags
=0, type
;
1585 PyObject
* txnobj
= NULL
;
1586 PyObject
* retval
= NULL
;
1589 static char* kwnames
[] = { "txn", "flags", NULL
};
1591 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:consume", kwnames
,
1595 CHECK_DB_NOT_CLOSED(self
);
1596 type
= _DB_get_type(self
);
1599 if (type
!= DB_QUEUE
) {
1600 PyErr_SetString(PyExc_TypeError
,
1601 "Consume methods only allowed for Queue DB's");
1604 if (!checkTxnObj(txnobj
, &txn
))
1609 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1610 /* Tell Berkeley DB to malloc the return value (thread safe) */
1611 data
.flags
= DB_DBT_MALLOC
;
1612 key
.flags
= DB_DBT_MALLOC
;
1615 MYDB_BEGIN_ALLOW_THREADS
;
1616 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
|consume_flag
);
1617 MYDB_END_ALLOW_THREADS
;
1619 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1620 && self
->moduleFlags
.getReturnsNone
) {
1626 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
1636 DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1638 return _DB_consume(self
, args
, kwargs
, DB_CONSUME
);
1642 DB_consume_wait(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
,
1645 return _DB_consume(self
, args
, kwargs
, DB_CONSUME_WAIT
);
1650 DB_cursor(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1654 PyObject
* txnobj
= NULL
;
1656 static char* kwnames
[] = { "txn", "flags", NULL
};
1658 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
1661 CHECK_DB_NOT_CLOSED(self
);
1662 if (!checkTxnObj(txnobj
, &txn
))
1665 MYDB_BEGIN_ALLOW_THREADS
;
1666 err
= self
->db
->cursor(self
->db
, txn
, &dbc
, flags
);
1667 MYDB_END_ALLOW_THREADS
;
1669 return (PyObject
*) newDBCursorObject(dbc
, (DBTxnObject
*)txnobj
, self
);
1674 DB_delete(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1676 PyObject
* txnobj
= NULL
;
1681 static char* kwnames
[] = { "key", "txn", "flags", NULL
};
1683 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:delete", kwnames
,
1684 &keyobj
, &txnobj
, &flags
))
1686 CHECK_DB_NOT_CLOSED(self
);
1687 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1689 if (!checkTxnObj(txnobj
, &txn
)) {
1694 if (-1 == _DB_delete(self
, txn
, &key
, 0)) {
1705 DB_fd(DBObject
* self
)
1709 CHECK_DB_NOT_CLOSED(self
);
1711 MYDB_BEGIN_ALLOW_THREADS
;
1712 err
= self
->db
->fd(self
->db
, &the_fd
);
1713 MYDB_END_ALLOW_THREADS
;
1715 return NUMBER_FromLong(the_fd
);
1720 DB_get(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1723 PyObject
* txnobj
= NULL
;
1725 PyObject
* dfltobj
= NULL
;
1726 PyObject
* retval
= NULL
;
1731 static char* kwnames
[] = {"key", "default", "txn", "flags", "dlen",
1734 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:get", kwnames
,
1735 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1739 CHECK_DB_NOT_CLOSED(self
);
1740 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1742 if (!checkTxnObj(txnobj
, &txn
)) {
1748 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1749 /* Tell Berkeley DB to malloc the return value (thread safe) */
1750 data
.flags
= DB_DBT_MALLOC
;
1752 if (!add_partial_dbt(&data
, dlen
, doff
)) {
1757 MYDB_BEGIN_ALLOW_THREADS
;
1758 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1759 MYDB_END_ALLOW_THREADS
;
1761 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && (dfltobj
!= NULL
)) {
1766 else if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1767 && self
->moduleFlags
.getReturnsNone
) {
1773 if (flags
& DB_SET_RECNO
) /* return both key and data */
1774 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
1775 else /* return just the data */
1776 retval
= Build_PyString(data
.data
, data
.size
);
1786 DB_pget(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1789 PyObject
* txnobj
= NULL
;
1791 PyObject
* dfltobj
= NULL
;
1792 PyObject
* retval
= NULL
;
1795 DBT key
, pkey
, data
;
1797 static char* kwnames
[] = {"key", "default", "txn", "flags", "dlen",
1800 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:pget", kwnames
,
1801 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1805 CHECK_DB_NOT_CLOSED(self
);
1806 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1808 if (!checkTxnObj(txnobj
, &txn
)) {
1814 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1815 /* Tell Berkeley DB to malloc the return value (thread safe) */
1816 data
.flags
= DB_DBT_MALLOC
;
1818 if (!add_partial_dbt(&data
, dlen
, doff
)) {
1824 pkey
.flags
= DB_DBT_MALLOC
;
1826 MYDB_BEGIN_ALLOW_THREADS
;
1827 err
= self
->db
->pget(self
->db
, txn
, &key
, &pkey
, &data
, flags
);
1828 MYDB_END_ALLOW_THREADS
;
1830 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && (dfltobj
!= NULL
)) {
1835 else if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1836 && self
->moduleFlags
.getReturnsNone
) {
1844 dataObj
= Build_PyString(data
.data
, data
.size
);
1846 if (self
->primaryDBType
== DB_RECNO
||
1847 self
->primaryDBType
== DB_QUEUE
)
1848 pkeyObj
= NUMBER_FromLong(*(int *)pkey
.data
);
1850 pkeyObj
= Build_PyString(pkey
.data
, pkey
.size
);
1852 if (flags
& DB_SET_RECNO
) /* return key , pkey and data */
1855 int type
= _DB_get_type(self
);
1856 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
1857 keyObj
= NUMBER_FromLong(*(int *)key
.data
);
1859 keyObj
= Build_PyString(key
.data
, key
.size
);
1860 #if (PY_VERSION_HEX >= 0x02040000)
1861 retval
= PyTuple_Pack(3, keyObj
, pkeyObj
, dataObj
);
1863 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
1867 else /* return just the pkey and data */
1869 #if (PY_VERSION_HEX >= 0x02040000)
1870 retval
= PyTuple_Pack(2, pkeyObj
, dataObj
);
1872 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
1887 /* Return size of entry */
1889 DB_get_size(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1892 PyObject
* txnobj
= NULL
;
1894 PyObject
* retval
= NULL
;
1897 static char* kwnames
[] = { "key", "txn", NULL
};
1899 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O:get_size", kwnames
,
1902 CHECK_DB_NOT_CLOSED(self
);
1903 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1905 if (!checkTxnObj(txnobj
, &txn
)) {
1911 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
1912 thus getting the record size. */
1913 data
.flags
= DB_DBT_USERMEM
;
1915 MYDB_BEGIN_ALLOW_THREADS
;
1916 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1917 MYDB_END_ALLOW_THREADS
;
1918 if (err
== DB_BUFFER_SMALL
) {
1919 retval
= NUMBER_FromLong((long)data
.size
);
1931 DB_get_both(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1934 PyObject
* txnobj
= NULL
;
1937 PyObject
* retval
= NULL
;
1941 static char* kwnames
[] = { "key", "data", "txn", "flags", NULL
};
1943 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oi:get_both", kwnames
,
1944 &keyobj
, &dataobj
, &txnobj
, &flags
))
1947 CHECK_DB_NOT_CLOSED(self
);
1948 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1950 if ( !make_dbt(dataobj
, &data
) ||
1951 !checkTxnObj(txnobj
, &txn
) )
1957 flags
|= DB_GET_BOTH
;
1958 orig_data
= data
.data
;
1960 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1961 /* Tell Berkeley DB to malloc the return value (thread safe) */
1962 /* XXX(nnorwitz): At least 4.4.20 and 4.5.20 require this flag. */
1963 data
.flags
= DB_DBT_MALLOC
;
1966 MYDB_BEGIN_ALLOW_THREADS
;
1967 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1968 MYDB_END_ALLOW_THREADS
;
1970 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1971 && self
->moduleFlags
.getReturnsNone
) {
1977 /* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */
1978 retval
= Build_PyString(data
.data
, data
.size
);
1980 /* Even though the flags require DB_DBT_MALLOC, data is not always
1981 allocated. 4.4: allocated, 4.5: *not* allocated. :-( */
1982 if (data
.data
!= orig_data
)
1993 DB_get_byteswapped(DBObject
* self
)
1998 CHECK_DB_NOT_CLOSED(self
);
2000 MYDB_BEGIN_ALLOW_THREADS
;
2001 err
= self
->db
->get_byteswapped(self
->db
, &retval
);
2002 MYDB_END_ALLOW_THREADS
;
2004 return NUMBER_FromLong(retval
);
2009 DB_get_type(DBObject
* self
)
2013 CHECK_DB_NOT_CLOSED(self
);
2015 type
= _DB_get_type(self
);
2018 return NUMBER_FromLong(type
);
2023 DB_join(DBObject
* self
, PyObject
* args
)
2027 PyObject
* cursorsObj
;
2031 if (!PyArg_ParseTuple(args
,"O|i:join", &cursorsObj
, &flags
))
2034 CHECK_DB_NOT_CLOSED(self
);
2036 if (!PySequence_Check(cursorsObj
)) {
2037 PyErr_SetString(PyExc_TypeError
,
2038 "Sequence of DBCursor objects expected");
2042 length
= PyObject_Length(cursorsObj
);
2043 cursors
= malloc((length
+1) * sizeof(DBC
*));
2049 cursors
[length
] = NULL
;
2050 for (x
=0; x
<length
; x
++) {
2051 PyObject
* item
= PySequence_GetItem(cursorsObj
, x
);
2056 if (!DBCursorObject_Check(item
)) {
2057 PyErr_SetString(PyExc_TypeError
,
2058 "Sequence of DBCursor objects expected");
2062 cursors
[x
] = ((DBCursorObject
*)item
)->dbc
;
2066 MYDB_BEGIN_ALLOW_THREADS
;
2067 err
= self
->db
->join(self
->db
, cursors
, &dbc
, flags
);
2068 MYDB_END_ALLOW_THREADS
;
2072 /* FIXME: this is a buggy interface. The returned cursor
2073 contains internal references to the passed in cursors
2074 but does not hold python references to them or prevent
2075 them from being closed prematurely. This can cause
2076 python to crash when things are done in the wrong order. */
2077 return (PyObject
*) newDBCursorObject(dbc
, NULL
, self
);
2082 DB_key_range(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2085 PyObject
* txnobj
= NULL
;
2090 static char* kwnames
[] = { "key", "txn", "flags", NULL
};
2092 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:key_range", kwnames
,
2093 &keyobj
, &txnobj
, &flags
))
2095 CHECK_DB_NOT_CLOSED(self
);
2096 if (!make_dbt(keyobj
, &key
))
2097 /* BTree only, don't need to allow for an int key */
2099 if (!checkTxnObj(txnobj
, &txn
))
2102 MYDB_BEGIN_ALLOW_THREADS
;
2103 err
= self
->db
->key_range(self
->db
, txn
, &key
, &range
, flags
);
2104 MYDB_END_ALLOW_THREADS
;
2107 return Py_BuildValue("ddd", range
.less
, range
.equal
, range
.greater
);
2112 DB_open(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2114 int err
, type
= DB_UNKNOWN
, flags
=0, mode
=0660;
2115 char* filename
= NULL
;
2116 char* dbname
= NULL
;
2118 PyObject
*txnobj
= NULL
;
2121 static char* kwnames
[] = {
2122 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL
};
2123 /* without dbname */
2124 static char* kwnames_basic
[] = {
2125 "filename", "dbtype", "flags", "mode", "txn", NULL
};
2128 static char* kwnames
[] = {
2129 "filename", "dbname", "dbtype", "flags", "mode", NULL
};
2130 /* without dbname */
2131 static char* kwnames_basic
[] = {
2132 "filename", "dbtype", "flags", "mode", NULL
};
2136 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziiiO:open", kwnames
,
2137 &filename
, &dbname
, &type
, &flags
, &mode
,
2140 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziii:open", kwnames
,
2141 &filename
, &dbname
, &type
, &flags
,
2146 type
= DB_UNKNOWN
; flags
= 0; mode
= 0660;
2147 filename
= NULL
; dbname
= NULL
;
2149 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iiiO:open",
2151 &filename
, &type
, &flags
, &mode
,
2155 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iii:open",
2157 &filename
, &type
, &flags
, &mode
))
2163 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
2166 if (NULL
== self
->db
) {
2167 PyObject
*t
= Py_BuildValue("(is)", 0,
2168 "Cannot call open() twice for DB object");
2170 PyErr_SetObject(DBError
, t
);
2177 if (txn
) { /* Can't use 'txnobj' because could be 'txnobj==Py_None' */
2178 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject
*)txnobj
)->children_dbs
,self
);
2179 self
->txn
=(DBTxnObject
*)txnobj
;
2187 MYDB_BEGIN_ALLOW_THREADS
;
2189 err
= self
->db
->open(self
->db
, txn
, filename
, dbname
, type
, flags
, mode
);
2191 err
= self
->db
->open(self
->db
, filename
, dbname
, type
, flags
, mode
);
2193 MYDB_END_ALLOW_THREADS
;
2194 if (makeDBError(err
)) {
2197 dummy
=DB_close_internal(self
, 0, 0);
2203 self
->db
->get_flags(self
->db
, &self
->setflags
);
2206 self
->flags
= flags
;
2213 DB_put(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2216 PyObject
* txnobj
= NULL
;
2219 PyObject
* keyobj
, *dataobj
, *retval
;
2222 static char* kwnames
[] = { "key", "data", "txn", "flags", "dlen",
2225 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oiii:put", kwnames
,
2226 &keyobj
, &dataobj
, &txnobj
, &flags
, &dlen
, &doff
))
2229 CHECK_DB_NOT_CLOSED(self
);
2230 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2232 if ( !make_dbt(dataobj
, &data
) ||
2233 !add_partial_dbt(&data
, dlen
, doff
) ||
2234 !checkTxnObj(txnobj
, &txn
) )
2240 if (-1 == _DB_put(self
, txn
, &key
, &data
, flags
)) {
2245 if (flags
& DB_APPEND
)
2246 retval
= NUMBER_FromLong(*((db_recno_t
*)key
.data
));
2258 DB_remove(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2261 char* database
= NULL
;
2263 static char* kwnames
[] = { "filename", "dbname", "flags", NULL
};
2265 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zi:remove", kwnames
,
2266 &filename
, &database
, &flags
))
2268 CHECK_DB_NOT_CLOSED(self
);
2270 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self
);
2272 MYDB_BEGIN_ALLOW_THREADS
;
2273 err
= self
->db
->remove(self
->db
, filename
, database
, flags
);
2274 MYDB_END_ALLOW_THREADS
;
2284 DB_rename(DBObject
* self
, PyObject
* args
)
2291 if (!PyArg_ParseTuple(args
, "sss|i:rename", &filename
, &database
, &newname
,
2294 CHECK_DB_NOT_CLOSED(self
);
2296 MYDB_BEGIN_ALLOW_THREADS
;
2297 err
= self
->db
->rename(self
->db
, filename
, database
, newname
, flags
);
2298 MYDB_END_ALLOW_THREADS
;
2305 DB_get_private(DBObject
* self
)
2307 /* We can give out the private field even if db is closed */
2308 Py_INCREF(self
->private_obj
);
2309 return self
->private_obj
;
2313 DB_set_private(DBObject
* self
, PyObject
* private_obj
)
2315 /* We can set the private field even if db is closed */
2316 Py_DECREF(self
->private_obj
);
2317 Py_INCREF(private_obj
);
2318 self
->private_obj
= private_obj
;
2324 DB_set_bt_minkey(DBObject
* self
, PyObject
* args
)
2328 if (!PyArg_ParseTuple(args
,"i:set_bt_minkey", &minkey
))
2330 CHECK_DB_NOT_CLOSED(self
);
2332 MYDB_BEGIN_ALLOW_THREADS
;
2333 err
= self
->db
->set_bt_minkey(self
->db
, minkey
);
2334 MYDB_END_ALLOW_THREADS
;
2340 _default_cmp(const DBT
*leftKey
,
2341 const DBT
*rightKey
)
2344 int lsize
= leftKey
->size
, rsize
= rightKey
->size
;
2346 res
= memcmp(leftKey
->data
, rightKey
->data
,
2347 lsize
< rsize
? lsize
: rsize
);
2350 if (lsize
< rsize
) {
2353 else if (lsize
> rsize
) {
2361 _db_compareCallback(DB
* db
,
2363 const DBT
*rightKey
)
2367 PyObject
*result
= NULL
;
2368 DBObject
*self
= (DBObject
*)db
->app_private
;
2370 if (self
== NULL
|| self
->btCompareCallback
== NULL
) {
2371 MYDB_BEGIN_BLOCK_THREADS
;
2372 PyErr_SetString(PyExc_TypeError
,
2374 ? "DB_bt_compare db is NULL."
2375 : "DB_bt_compare callback is NULL."));
2376 /* we're in a callback within the DB code, we can't raise */
2378 res
= _default_cmp(leftKey
, rightKey
);
2379 MYDB_END_BLOCK_THREADS
;
2381 MYDB_BEGIN_BLOCK_THREADS
;
2383 args
= BuildValue_SS(leftKey
->data
, leftKey
->size
, rightKey
->data
, rightKey
->size
);
2385 /* XXX(twouters) I highly doubt this INCREF is correct */
2387 result
= PyEval_CallObject(self
->btCompareCallback
, args
);
2389 if (args
== NULL
|| result
== NULL
) {
2390 /* we're in a callback within the DB code, we can't raise */
2392 res
= _default_cmp(leftKey
, rightKey
);
2393 } else if (NUMBER_Check(result
)) {
2394 res
= NUMBER_AsLong(result
);
2396 PyErr_SetString(PyExc_TypeError
,
2397 "DB_bt_compare callback MUST return an int.");
2398 /* we're in a callback within the DB code, we can't raise */
2400 res
= _default_cmp(leftKey
, rightKey
);
2406 MYDB_END_BLOCK_THREADS
;
2412 DB_set_bt_compare(DBObject
* self
, PyObject
* comparator
)
2415 PyObject
*tuple
, *result
;
2417 CHECK_DB_NOT_CLOSED(self
);
2419 if (!PyCallable_Check(comparator
)) {
2420 makeTypeError("Callable", comparator
);
2425 * Perform a test call of the comparator function with two empty
2426 * string objects here. verify that it returns an int (0).
2429 tuple
= Py_BuildValue("(ss)", "", "");
2430 result
= PyEval_CallObject(comparator
, tuple
);
2434 if (!NUMBER_Check(result
)) {
2435 PyErr_SetString(PyExc_TypeError
,
2436 "callback MUST return an int");
2438 } else if (NUMBER_AsLong(result
) != 0) {
2439 PyErr_SetString(PyExc_TypeError
,
2440 "callback failed to return 0 on two empty strings");
2445 /* We don't accept multiple set_bt_compare operations, in order to
2446 * simplify the code. This would have no real use, as one cannot
2447 * change the function once the db is opened anyway */
2448 if (self
->btCompareCallback
!= NULL
) {
2449 PyErr_SetString(PyExc_RuntimeError
, "set_bt_compare() cannot be called more than once");
2453 Py_INCREF(comparator
);
2454 self
->btCompareCallback
= comparator
;
2456 /* This is to workaround a problem with un-initialized threads (see
2457 comment in DB_associate) */
2459 PyEval_InitThreads();
2462 err
= self
->db
->set_bt_compare(self
->db
, _db_compareCallback
);
2465 /* restore the old state in case of error */
2466 Py_DECREF(comparator
);
2467 self
->btCompareCallback
= NULL
;
2476 DB_set_cachesize(DBObject
* self
, PyObject
* args
)
2479 int gbytes
= 0, bytes
= 0, ncache
= 0;
2481 if (!PyArg_ParseTuple(args
,"ii|i:set_cachesize",
2482 &gbytes
,&bytes
,&ncache
))
2484 CHECK_DB_NOT_CLOSED(self
);
2486 MYDB_BEGIN_ALLOW_THREADS
;
2487 err
= self
->db
->set_cachesize(self
->db
, gbytes
, bytes
, ncache
);
2488 MYDB_END_ALLOW_THREADS
;
2495 DB_set_flags(DBObject
* self
, PyObject
* args
)
2499 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
2501 CHECK_DB_NOT_CLOSED(self
);
2503 MYDB_BEGIN_ALLOW_THREADS
;
2504 err
= self
->db
->set_flags(self
->db
, flags
);
2505 MYDB_END_ALLOW_THREADS
;
2508 self
->setflags
|= flags
;
2514 DB_set_h_ffactor(DBObject
* self
, PyObject
* args
)
2518 if (!PyArg_ParseTuple(args
,"i:set_h_ffactor", &ffactor
))
2520 CHECK_DB_NOT_CLOSED(self
);
2522 MYDB_BEGIN_ALLOW_THREADS
;
2523 err
= self
->db
->set_h_ffactor(self
->db
, ffactor
);
2524 MYDB_END_ALLOW_THREADS
;
2531 DB_set_h_nelem(DBObject
* self
, PyObject
* args
)
2535 if (!PyArg_ParseTuple(args
,"i:set_h_nelem", &nelem
))
2537 CHECK_DB_NOT_CLOSED(self
);
2539 MYDB_BEGIN_ALLOW_THREADS
;
2540 err
= self
->db
->set_h_nelem(self
->db
, nelem
);
2541 MYDB_END_ALLOW_THREADS
;
2548 DB_set_lorder(DBObject
* self
, PyObject
* args
)
2552 if (!PyArg_ParseTuple(args
,"i:set_lorder", &lorder
))
2554 CHECK_DB_NOT_CLOSED(self
);
2556 MYDB_BEGIN_ALLOW_THREADS
;
2557 err
= self
->db
->set_lorder(self
->db
, lorder
);
2558 MYDB_END_ALLOW_THREADS
;
2565 DB_set_pagesize(DBObject
* self
, PyObject
* args
)
2569 if (!PyArg_ParseTuple(args
,"i:set_pagesize", &pagesize
))
2571 CHECK_DB_NOT_CLOSED(self
);
2573 MYDB_BEGIN_ALLOW_THREADS
;
2574 err
= self
->db
->set_pagesize(self
->db
, pagesize
);
2575 MYDB_END_ALLOW_THREADS
;
2582 DB_set_re_delim(DBObject
* self
, PyObject
* args
)
2587 if (!PyArg_ParseTuple(args
,"b:set_re_delim", &delim
)) {
2589 if (!PyArg_ParseTuple(args
,"c:set_re_delim", &delim
))
2593 CHECK_DB_NOT_CLOSED(self
);
2595 MYDB_BEGIN_ALLOW_THREADS
;
2596 err
= self
->db
->set_re_delim(self
->db
, delim
);
2597 MYDB_END_ALLOW_THREADS
;
2603 DB_set_re_len(DBObject
* self
, PyObject
* args
)
2607 if (!PyArg_ParseTuple(args
,"i:set_re_len", &len
))
2609 CHECK_DB_NOT_CLOSED(self
);
2611 MYDB_BEGIN_ALLOW_THREADS
;
2612 err
= self
->db
->set_re_len(self
->db
, len
);
2613 MYDB_END_ALLOW_THREADS
;
2620 DB_set_re_pad(DBObject
* self
, PyObject
* args
)
2625 if (!PyArg_ParseTuple(args
,"b:set_re_pad", &pad
)) {
2627 if (!PyArg_ParseTuple(args
,"c:set_re_pad", &pad
))
2630 CHECK_DB_NOT_CLOSED(self
);
2632 MYDB_BEGIN_ALLOW_THREADS
;
2633 err
= self
->db
->set_re_pad(self
->db
, pad
);
2634 MYDB_END_ALLOW_THREADS
;
2641 DB_set_re_source(DBObject
* self
, PyObject
* args
)
2646 if (!PyArg_ParseTuple(args
,"s:set_re_source", &re_source
))
2648 CHECK_DB_NOT_CLOSED(self
);
2650 MYDB_BEGIN_ALLOW_THREADS
;
2651 err
= self
->db
->set_re_source(self
->db
, re_source
);
2652 MYDB_END_ALLOW_THREADS
;
2659 DB_set_q_extentsize(DBObject
* self
, PyObject
* args
)
2664 if (!PyArg_ParseTuple(args
,"i:set_q_extentsize", &extentsize
))
2666 CHECK_DB_NOT_CLOSED(self
);
2668 MYDB_BEGIN_ALLOW_THREADS
;
2669 err
= self
->db
->set_q_extentsize(self
->db
, extentsize
);
2670 MYDB_END_ALLOW_THREADS
;
2676 DB_stat(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2678 int err
, flags
= 0, type
;
2682 PyObject
* txnobj
= NULL
;
2684 static char* kwnames
[] = { "flags", "txn", NULL
};
2686 static char* kwnames
[] = { "flags", NULL
};
2690 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iO:stat", kwnames
,
2693 if (!checkTxnObj(txnobj
, &txn
))
2696 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat", kwnames
, &flags
))
2699 CHECK_DB_NOT_CLOSED(self
);
2701 MYDB_BEGIN_ALLOW_THREADS
;
2703 err
= self
->db
->stat(self
->db
, txn
, &sp
, flags
);
2705 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2707 MYDB_END_ALLOW_THREADS
;
2712 /* Turn the stat structure into a dictionary */
2713 type
= _DB_get_type(self
);
2714 if ((type
== -1) || ((d
= PyDict_New()) == NULL
)) {
2719 #define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
2720 #define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
2721 #define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
2725 MAKE_HASH_ENTRY(magic
);
2726 MAKE_HASH_ENTRY(version
);
2727 MAKE_HASH_ENTRY(nkeys
);
2728 MAKE_HASH_ENTRY(ndata
);
2730 MAKE_HASH_ENTRY(pagecnt
);
2732 MAKE_HASH_ENTRY(pagesize
);
2734 MAKE_HASH_ENTRY(nelem
);
2736 MAKE_HASH_ENTRY(ffactor
);
2737 MAKE_HASH_ENTRY(buckets
);
2738 MAKE_HASH_ENTRY(free
);
2739 MAKE_HASH_ENTRY(bfree
);
2740 MAKE_HASH_ENTRY(bigpages
);
2741 MAKE_HASH_ENTRY(big_bfree
);
2742 MAKE_HASH_ENTRY(overflows
);
2743 MAKE_HASH_ENTRY(ovfl_free
);
2744 MAKE_HASH_ENTRY(dup
);
2745 MAKE_HASH_ENTRY(dup_free
);
2750 MAKE_BT_ENTRY(magic
);
2751 MAKE_BT_ENTRY(version
);
2752 MAKE_BT_ENTRY(nkeys
);
2753 MAKE_BT_ENTRY(ndata
);
2755 MAKE_BT_ENTRY(pagecnt
);
2757 MAKE_BT_ENTRY(pagesize
);
2758 MAKE_BT_ENTRY(minkey
);
2759 MAKE_BT_ENTRY(re_len
);
2760 MAKE_BT_ENTRY(re_pad
);
2761 MAKE_BT_ENTRY(levels
);
2762 MAKE_BT_ENTRY(int_pg
);
2763 MAKE_BT_ENTRY(leaf_pg
);
2764 MAKE_BT_ENTRY(dup_pg
);
2765 MAKE_BT_ENTRY(over_pg
);
2767 MAKE_BT_ENTRY(empty_pg
);
2769 MAKE_BT_ENTRY(free
);
2770 MAKE_BT_ENTRY(int_pgfree
);
2771 MAKE_BT_ENTRY(leaf_pgfree
);
2772 MAKE_BT_ENTRY(dup_pgfree
);
2773 MAKE_BT_ENTRY(over_pgfree
);
2777 MAKE_QUEUE_ENTRY(magic
);
2778 MAKE_QUEUE_ENTRY(version
);
2779 MAKE_QUEUE_ENTRY(nkeys
);
2780 MAKE_QUEUE_ENTRY(ndata
);
2781 MAKE_QUEUE_ENTRY(pagesize
);
2783 MAKE_QUEUE_ENTRY(extentsize
);
2785 MAKE_QUEUE_ENTRY(pages
);
2786 MAKE_QUEUE_ENTRY(re_len
);
2787 MAKE_QUEUE_ENTRY(re_pad
);
2788 MAKE_QUEUE_ENTRY(pgfree
);
2790 MAKE_QUEUE_ENTRY(start
);
2792 MAKE_QUEUE_ENTRY(first_recno
);
2793 MAKE_QUEUE_ENTRY(cur_recno
);
2797 PyErr_SetString(PyExc_TypeError
, "Unknown DB type, unable to stat");
2802 #undef MAKE_HASH_ENTRY
2803 #undef MAKE_BT_ENTRY
2804 #undef MAKE_QUEUE_ENTRY
2811 DB_sync(DBObject
* self
, PyObject
* args
)
2816 if (!PyArg_ParseTuple(args
,"|i:sync", &flags
))
2818 CHECK_DB_NOT_CLOSED(self
);
2820 MYDB_BEGIN_ALLOW_THREADS
;
2821 err
= self
->db
->sync(self
->db
, flags
);
2822 MYDB_END_ALLOW_THREADS
;
2829 DB_truncate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2833 PyObject
* txnobj
= NULL
;
2835 static char* kwnames
[] = { "txn", "flags", NULL
};
2837 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
2840 CHECK_DB_NOT_CLOSED(self
);
2841 if (!checkTxnObj(txnobj
, &txn
))
2844 MYDB_BEGIN_ALLOW_THREADS
;
2845 err
= self
->db
->truncate(self
->db
, txn
, &count
, flags
);
2846 MYDB_END_ALLOW_THREADS
;
2848 return NUMBER_FromLong(count
);
2853 DB_upgrade(DBObject
* self
, PyObject
* args
)
2858 if (!PyArg_ParseTuple(args
,"s|i:upgrade", &filename
, &flags
))
2860 CHECK_DB_NOT_CLOSED(self
);
2862 MYDB_BEGIN_ALLOW_THREADS
;
2863 err
= self
->db
->upgrade(self
->db
, filename
, flags
);
2864 MYDB_END_ALLOW_THREADS
;
2871 DB_verify(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2876 char* outFileName
=NULL
;
2878 static char* kwnames
[] = { "filename", "dbname", "outfile", "flags",
2881 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zzi:verify", kwnames
,
2882 &fileName
, &dbName
, &outFileName
, &flags
))
2885 CHECK_DB_NOT_CLOSED(self
);
2887 outFile
= fopen(outFileName
, "w");
2888 /* XXX(nnorwitz): it should probably be an exception if outFile
2891 { /* DB.verify acts as a DB handle destructor (like close) */
2894 error
=DB_close_internal(self
, 0, 1);
2900 MYDB_BEGIN_ALLOW_THREADS
;
2901 err
= self
->db
->verify(self
->db
, fileName
, dbName
, outFile
, flags
);
2902 MYDB_END_ALLOW_THREADS
;
2904 self
->db
= NULL
; /* Implicit close; related objects already released */
2915 DB_set_get_returns_none(DBObject
* self
, PyObject
* args
)
2920 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
2922 CHECK_DB_NOT_CLOSED(self
);
2924 if (self
->moduleFlags
.getReturnsNone
)
2926 if (self
->moduleFlags
.cursorSetReturnsNone
)
2928 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
2929 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
2930 return NUMBER_FromLong(oldValue
);
2935 DB_set_encrypt(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2939 char *passwd
= NULL
;
2940 static char* kwnames
[] = { "passwd", "flags", NULL
};
2942 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
2947 MYDB_BEGIN_ALLOW_THREADS
;
2948 err
= self
->db
->set_encrypt(self
->db
, passwd
, flags
);
2949 MYDB_END_ALLOW_THREADS
;
2954 #endif /* DBVER >= 41 */
2957 /*-------------------------------------------------------------- */
2958 /* Mapping and Dictionary-like access routines */
2960 Py_ssize_t
DB_length(PyObject
* _self
)
2963 Py_ssize_t size
= 0;
2966 DBObject
* self
= (DBObject
*)_self
;
2968 if (self
->db
== NULL
) {
2969 PyObject
*t
= Py_BuildValue("(is)", 0, "DB object has been closed");
2971 PyErr_SetObject(DBError
, t
);
2977 if (self
->haveStat
) { /* Has the stat function been called recently? If
2978 so, we can use the cached value. */
2979 flags
= DB_FAST_STAT
;
2982 MYDB_BEGIN_ALLOW_THREADS
;
2983 redo_stat_for_length
:
2985 err
= self
->db
->stat(self
->db
, /*txnid*/ NULL
, &sp
, flags
);
2987 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2990 /* All the stat structures have matching fields upto the ndata field,
2991 so we can use any of them for the type cast */
2992 size
= ((DB_BTREE_STAT
*)sp
)->bt_ndata
;
2994 /* A size of 0 could mean that Berkeley DB no longer had the stat values cached.
2995 * redo a full stat to make sure.
2996 * Fixes SF python bug 1493322, pybsddb bug 1184012
2998 if (size
== 0 && (flags
& DB_FAST_STAT
)) {
3002 goto redo_stat_for_length
;
3005 MYDB_END_ALLOW_THREADS
;
3017 PyObject
* DB_subscript(DBObject
* self
, PyObject
* keyobj
)
3024 CHECK_DB_NOT_CLOSED(self
);
3025 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
3029 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
3030 /* Tell Berkeley DB to malloc the return value (thread safe) */
3031 data
.flags
= DB_DBT_MALLOC
;
3033 MYDB_BEGIN_ALLOW_THREADS
;
3034 err
= self
->db
->get(self
->db
, NULL
, &key
, &data
, 0);
3035 MYDB_END_ALLOW_THREADS
;
3036 if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
3037 PyErr_SetObject(PyExc_KeyError
, keyobj
);
3040 else if (makeDBError(err
)) {
3044 retval
= Build_PyString(data
.data
, data
.size
);
3054 DB_ass_sub(DBObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
)
3060 if (self
->db
== NULL
) {
3061 PyObject
*t
= Py_BuildValue("(is)", 0, "DB object has been closed");
3063 PyErr_SetObject(DBError
, t
);
3069 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
3072 if (dataobj
!= NULL
) {
3073 if (!make_dbt(dataobj
, &data
))
3076 if (self
->setflags
& (DB_DUP
|DB_DUPSORT
))
3077 /* dictionaries shouldn't have duplicate keys */
3078 flags
= DB_NOOVERWRITE
;
3079 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
3081 if ((retval
== -1) && (self
->setflags
& (DB_DUP
|DB_DUPSORT
))) {
3082 /* try deleting any old record that matches and then PUT it
3084 _DB_delete(self
, NULL
, &key
, 0);
3086 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
3091 /* dataobj == NULL, so delete the key */
3092 retval
= _DB_delete(self
, NULL
, &key
, 0);
3100 DB_has_key(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3105 PyObject
* txnobj
= NULL
;
3107 static char* kwnames
[] = {"key","txn", NULL
};
3109 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O:has_key", kwnames
,
3113 CHECK_DB_NOT_CLOSED(self
);
3114 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
3116 if (!checkTxnObj(txnobj
, &txn
)) {
3121 /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
3122 it has a record but can't allocate a buffer for the data. This saves
3123 having to deal with data we won't be using.
3126 data
.flags
= DB_DBT_USERMEM
;
3128 MYDB_BEGIN_ALLOW_THREADS
;
3129 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, 0);
3130 MYDB_END_ALLOW_THREADS
;
3133 if (err
== DB_BUFFER_SMALL
|| err
== 0) {
3134 return NUMBER_FromLong(1);
3135 } else if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
3136 return NUMBER_FromLong(0);
3144 #define _KEYS_LIST 1
3145 #define _VALUES_LIST 2
3146 #define _ITEMS_LIST 3
3149 _DB_make_list(DBObject
* self
, DB_TXN
* txn
, int type
)
3156 PyObject
* item
= NULL
;
3158 CHECK_DB_NOT_CLOSED(self
);
3162 dbtype
= _DB_get_type(self
);
3166 list
= PyList_New(0);
3171 MYDB_BEGIN_ALLOW_THREADS
;
3172 err
= self
->db
->cursor(self
->db
, txn
, &cursor
, 0);
3173 MYDB_END_ALLOW_THREADS
;
3174 if (makeDBError(err
)) {
3179 while (1) { /* use the cursor to traverse the DB, collecting items */
3180 MYDB_BEGIN_ALLOW_THREADS
;
3181 err
= _DBC_get(cursor
, &key
, &data
, DB_NEXT
);
3182 MYDB_END_ALLOW_THREADS
;
3185 /* for any error, break out of the loop */
3195 item
= Build_PyString(key
.data
, key
.size
);
3199 item
= NUMBER_FromLong(*((db_recno_t
*)key
.data
));
3205 item
= Build_PyString(data
.data
, data
.size
);
3213 item
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
3217 item
= BuildValue_IS(*((db_recno_t
*)key
.data
), data
.data
, data
.size
);
3222 PyErr_Format(PyExc_ValueError
, "Unknown key type 0x%x", type
);
3231 if (PyList_Append(list
, item
)) {
3240 /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
3241 if (err
!= DB_NOTFOUND
&& err
!= DB_KEYEMPTY
&& makeDBError(err
)) {
3247 MYDB_BEGIN_ALLOW_THREADS
;
3249 MYDB_END_ALLOW_THREADS
;
3255 DB_keys(DBObject
* self
, PyObject
* args
)
3257 PyObject
* txnobj
= NULL
;
3260 if (!PyArg_UnpackTuple(args
, "keys", 0, 1, &txnobj
))
3262 if (!checkTxnObj(txnobj
, &txn
))
3264 return _DB_make_list(self
, txn
, _KEYS_LIST
);
3269 DB_items(DBObject
* self
, PyObject
* args
)
3271 PyObject
* txnobj
= NULL
;
3274 if (!PyArg_UnpackTuple(args
, "items", 0, 1, &txnobj
))
3276 if (!checkTxnObj(txnobj
, &txn
))
3278 return _DB_make_list(self
, txn
, _ITEMS_LIST
);
3283 DB_values(DBObject
* self
, PyObject
* args
)
3285 PyObject
* txnobj
= NULL
;
3288 if (!PyArg_UnpackTuple(args
, "values", 0, 1, &txnobj
))
3290 if (!checkTxnObj(txnobj
, &txn
))
3292 return _DB_make_list(self
, txn
, _VALUES_LIST
);
3295 /* --------------------------------------------------------------------- */
3296 /* DBCursor methods */
3300 DBC_close_internal(DBCursorObject
* self
)
3304 if (self
->dbc
!= NULL
) {
3305 EXTRACT_FROM_DOUBLE_LINKED_LIST(self
);
3307 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self
);
3311 MYDB_BEGIN_ALLOW_THREADS
;
3312 err
= _DBC_close(self
->dbc
);
3313 MYDB_END_ALLOW_THREADS
;
3321 DBC_close(DBCursorObject
* self
)
3323 return DBC_close_internal(self
);
3328 DBC_count(DBCursorObject
* self
, PyObject
* args
)
3334 if (!PyArg_ParseTuple(args
, "|i:count", &flags
))
3337 CHECK_CURSOR_NOT_CLOSED(self
);
3339 MYDB_BEGIN_ALLOW_THREADS
;
3340 err
= _DBC_count(self
->dbc
, &count
, flags
);
3341 MYDB_END_ALLOW_THREADS
;
3344 return NUMBER_FromLong(count
);
3349 DBC_current(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3351 return _DBCursor_get(self
,DB_CURRENT
,args
,kwargs
,"|iii:current");
3356 DBC_delete(DBCursorObject
* self
, PyObject
* args
)
3360 if (!PyArg_ParseTuple(args
, "|i:delete", &flags
))
3363 CHECK_CURSOR_NOT_CLOSED(self
);
3365 MYDB_BEGIN_ALLOW_THREADS
;
3366 err
= _DBC_del(self
->dbc
, flags
);
3367 MYDB_END_ALLOW_THREADS
;
3370 self
->mydb
->haveStat
= 0;
3376 DBC_dup(DBCursorObject
* self
, PyObject
* args
)
3381 if (!PyArg_ParseTuple(args
, "|i:dup", &flags
))
3384 CHECK_CURSOR_NOT_CLOSED(self
);
3386 MYDB_BEGIN_ALLOW_THREADS
;
3387 err
= _DBC_dup(self
->dbc
, &dbc
, flags
);
3388 MYDB_END_ALLOW_THREADS
;
3391 return (PyObject
*) newDBCursorObject(dbc
, self
->txn
, self
->mydb
);
3395 DBC_first(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3397 return _DBCursor_get(self
,DB_FIRST
,args
,kwargs
,"|iii:first");
3402 DBC_get(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3405 PyObject
* keyobj
= NULL
;
3406 PyObject
* dataobj
= NULL
;
3407 PyObject
* retval
= NULL
;
3411 static char* kwnames
[] = { "key","data", "flags", "dlen", "doff",
3416 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:get", &kwnames
[2],
3417 &flags
, &dlen
, &doff
))
3420 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:get",
3422 &keyobj
, &flags
, &dlen
, &doff
))
3425 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:get",
3426 kwnames
, &keyobj
, &dataobj
,
3427 &flags
, &dlen
, &doff
))
3434 CHECK_CURSOR_NOT_CLOSED(self
);
3436 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3438 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
3439 (!add_partial_dbt(&data
, dlen
, doff
)) )
3441 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3445 MYDB_BEGIN_ALLOW_THREADS
;
3446 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
);
3447 MYDB_END_ALLOW_THREADS
;
3449 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3450 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3454 else if (makeDBError(err
)) {
3458 switch (_DB_get_type(self
->mydb
)) {
3465 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
3469 retval
= BuildValue_IS(*((db_recno_t
*)key
.data
), data
.data
, data
.size
);
3473 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3478 DBC_pget(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3481 PyObject
* keyobj
= NULL
;
3482 PyObject
* dataobj
= NULL
;
3483 PyObject
* retval
= NULL
;
3486 DBT key
, pkey
, data
;
3487 static char* kwnames_keyOnly
[] = { "key", "flags", "dlen", "doff", NULL
};
3488 static char* kwnames
[] = { "key", "data", "flags", "dlen", "doff", NULL
};
3492 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:pget", &kwnames
[2],
3493 &flags
, &dlen
, &doff
))
3496 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:pget",
3498 &keyobj
, &flags
, &dlen
, &doff
))
3501 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:pget",
3502 kwnames
, &keyobj
, &dataobj
,
3503 &flags
, &dlen
, &doff
))
3510 CHECK_CURSOR_NOT_CLOSED(self
);
3512 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3514 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
3515 (!add_partial_dbt(&data
, dlen
, doff
)) ) {
3516 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3521 pkey
.flags
= DB_DBT_MALLOC
;
3523 MYDB_BEGIN_ALLOW_THREADS
;
3524 err
= _DBC_pget(self
->dbc
, &key
, &pkey
, &data
, flags
);
3525 MYDB_END_ALLOW_THREADS
;
3527 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3528 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3532 else if (makeDBError(err
)) {
3538 dataObj
= Build_PyString(data
.data
, data
.size
);
3540 if (self
->mydb
->primaryDBType
== DB_RECNO
||
3541 self
->mydb
->primaryDBType
== DB_QUEUE
)
3542 pkeyObj
= NUMBER_FromLong(*(int *)pkey
.data
);
3544 pkeyObj
= Build_PyString(pkey
.data
, pkey
.size
);
3546 if (key
.data
&& key
.size
) /* return key, pkey and data */
3549 int type
= _DB_get_type(self
->mydb
);
3550 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
3551 keyObj
= NUMBER_FromLong(*(int *)key
.data
);
3553 keyObj
= Build_PyString(key
.data
, key
.size
);
3554 #if (PY_VERSION_HEX >= 0x02040000)
3555 retval
= PyTuple_Pack(3, keyObj
, pkeyObj
, dataObj
);
3557 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
3560 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3562 else /* return just the pkey and data */
3564 #if (PY_VERSION_HEX >= 0x02040000)
3565 retval
= PyTuple_Pack(2, pkeyObj
, dataObj
);
3567 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
3574 /* the only time REALLOC should be set is if we used an integer
3575 * key that make_key_dbt malloc'd for us. always free these. */
3576 if (key
.flags
& DB_DBT_REALLOC
) { /* 'make_key_dbt' could do a 'malloc' */
3584 DBC_get_recno(DBCursorObject
* self
)
3591 CHECK_CURSOR_NOT_CLOSED(self
);
3596 MYDB_BEGIN_ALLOW_THREADS
;
3597 err
= _DBC_get(self
->dbc
, &key
, &data
, DB_GET_RECNO
);
3598 MYDB_END_ALLOW_THREADS
;
3601 recno
= *((db_recno_t
*)data
.data
);
3602 return NUMBER_FromLong(recno
);
3607 DBC_last(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3609 return _DBCursor_get(self
,DB_LAST
,args
,kwargs
,"|iii:last");
3614 DBC_next(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3616 return _DBCursor_get(self
,DB_NEXT
,args
,kwargs
,"|iii:next");
3621 DBC_prev(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3623 return _DBCursor_get(self
,DB_PREV
,args
,kwargs
,"|iii:prev");
3628 DBC_put(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3631 PyObject
* keyobj
, *dataobj
;
3633 static char* kwnames
[] = { "key", "data", "flags", "dlen", "doff",
3638 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iii:put", kwnames
,
3639 &keyobj
, &dataobj
, &flags
, &dlen
, &doff
))
3642 CHECK_CURSOR_NOT_CLOSED(self
);
3644 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3646 if (!make_dbt(dataobj
, &data
) ||
3647 !add_partial_dbt(&data
, dlen
, doff
) )
3649 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3653 MYDB_BEGIN_ALLOW_THREADS
;
3654 err
= _DBC_put(self
->dbc
, &key
, &data
, flags
);
3655 MYDB_END_ALLOW_THREADS
;
3656 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3658 self
->mydb
->haveStat
= 0;
3664 DBC_set(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3668 PyObject
* retval
, *keyobj
;
3669 static char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
3673 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set", kwnames
,
3674 &keyobj
, &flags
, &dlen
, &doff
))
3677 CHECK_CURSOR_NOT_CLOSED(self
);
3679 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3683 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3684 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3688 MYDB_BEGIN_ALLOW_THREADS
;
3689 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
|DB_SET
);
3690 MYDB_END_ALLOW_THREADS
;
3691 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3692 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3696 else if (makeDBError(err
)) {
3700 switch (_DB_get_type(self
->mydb
)) {
3707 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
3711 retval
= BuildValue_IS(*((db_recno_t
*)key
.data
), data
.data
, data
.size
);
3714 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3716 /* the only time REALLOC should be set is if we used an integer
3717 * key that make_key_dbt malloc'd for us. always free these. */
3718 if (key
.flags
& DB_DBT_REALLOC
) {
3719 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3727 DBC_set_range(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3731 PyObject
* retval
, *keyobj
;
3732 static char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
3736 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set_range", kwnames
,
3737 &keyobj
, &flags
, &dlen
, &doff
))
3740 CHECK_CURSOR_NOT_CLOSED(self
);
3742 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3746 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3747 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3750 MYDB_BEGIN_ALLOW_THREADS
;
3751 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RANGE
);
3752 MYDB_END_ALLOW_THREADS
;
3753 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3754 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3758 else if (makeDBError(err
)) {
3762 switch (_DB_get_type(self
->mydb
)) {
3769 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
3773 retval
= BuildValue_IS(*((db_recno_t
*)key
.data
), data
.data
, data
.size
);
3776 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3778 /* the only time REALLOC should be set is if we used an integer
3779 * key that make_key_dbt malloc'd for us. always free these. */
3780 if (key
.flags
& DB_DBT_REALLOC
) {
3781 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3788 _DBC_get_set_both(DBCursorObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
,
3789 int flags
, unsigned int returnsNone
)
3795 /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
3796 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3798 if (!make_dbt(dataobj
, &data
)) {
3799 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3803 MYDB_BEGIN_ALLOW_THREADS
;
3804 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
|DB_GET_BOTH
);
3805 MYDB_END_ALLOW_THREADS
;
3806 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && returnsNone
) {
3810 else if (makeDBError(err
)) {
3814 switch (_DB_get_type(self
->mydb
)) {
3821 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
3825 retval
= BuildValue_IS(*((db_recno_t
*)key
.data
), data
.data
, data
.size
);
3830 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3835 DBC_get_both(DBCursorObject
* self
, PyObject
* args
)
3838 PyObject
*keyobj
, *dataobj
;
3840 if (!PyArg_ParseTuple(args
, "OO|i:get_both", &keyobj
, &dataobj
, &flags
))
3843 /* if the cursor is closed, self->mydb may be invalid */
3844 CHECK_CURSOR_NOT_CLOSED(self
);
3846 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3847 self
->mydb
->moduleFlags
.getReturnsNone
);
3850 /* Return size of entry */
3852 DBC_get_current_size(DBCursorObject
* self
)
3854 int err
, flags
=DB_CURRENT
;
3855 PyObject
* retval
= NULL
;
3858 CHECK_CURSOR_NOT_CLOSED(self
);
3862 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
3863 getting the record size. */
3864 data
.flags
= DB_DBT_USERMEM
;
3866 MYDB_BEGIN_ALLOW_THREADS
;
3867 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
);
3868 MYDB_END_ALLOW_THREADS
;
3869 if (err
== DB_BUFFER_SMALL
|| !err
) {
3870 /* DB_BUFFER_SMALL means positive size, !err means zero length value */
3871 retval
= NUMBER_FromLong((long)data
.size
);
3880 DBC_set_both(DBCursorObject
* self
, PyObject
* args
)
3883 PyObject
*keyobj
, *dataobj
;
3885 if (!PyArg_ParseTuple(args
, "OO|i:set_both", &keyobj
, &dataobj
, &flags
))
3888 /* if the cursor is closed, self->mydb may be invalid */
3889 CHECK_CURSOR_NOT_CLOSED(self
);
3891 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3892 self
->mydb
->moduleFlags
.cursorSetReturnsNone
);
3897 DBC_set_recno(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3899 int err
, irecno
, flags
=0;
3905 static char* kwnames
[] = { "recno","flags", "dlen", "doff", NULL
};
3907 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|iii:set_recno", kwnames
,
3908 &irecno
, &flags
, &dlen
, &doff
))
3911 CHECK_CURSOR_NOT_CLOSED(self
);
3914 recno
= (db_recno_t
) irecno
;
3915 /* use allocated space so DB will be able to realloc room for the real
3917 key
.data
= malloc(sizeof(db_recno_t
));
3918 if (key
.data
== NULL
) {
3919 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
3922 key
.size
= sizeof(db_recno_t
);
3923 key
.ulen
= key
.size
;
3924 memcpy(key
.data
, &recno
, sizeof(db_recno_t
));
3925 key
.flags
= DB_DBT_REALLOC
;
3928 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3933 MYDB_BEGIN_ALLOW_THREADS
;
3934 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RECNO
);
3935 MYDB_END_ALLOW_THREADS
;
3936 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3937 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3941 else if (makeDBError(err
)) {
3944 else { /* Can only be used for BTrees, so no need to return int key */
3945 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
3954 DBC_consume(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3956 return _DBCursor_get(self
,DB_CONSUME
,args
,kwargs
,"|iii:consume");
3961 DBC_next_dup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3963 return _DBCursor_get(self
,DB_NEXT_DUP
,args
,kwargs
,"|iii:next_dup");
3968 DBC_next_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3970 return _DBCursor_get(self
,DB_NEXT_NODUP
,args
,kwargs
,"|iii:next_nodup");
3975 DBC_prev_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3977 return _DBCursor_get(self
,DB_PREV_NODUP
,args
,kwargs
,"|iii:prev_nodup");
3982 DBC_join_item(DBCursorObject
* self
, PyObject
* args
)
3988 if (!PyArg_ParseTuple(args
, "|i:join_item", &flags
))
3991 CHECK_CURSOR_NOT_CLOSED(self
);
3996 MYDB_BEGIN_ALLOW_THREADS
;
3997 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
| DB_JOIN_ITEM
);
3998 MYDB_END_ALLOW_THREADS
;
3999 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
4000 && self
->mydb
->moduleFlags
.getReturnsNone
) {
4004 else if (makeDBError(err
)) {
4008 retval
= BuildValue_S(key
.data
, key
.size
);
4016 /* --------------------------------------------------------------------- */
4021 DBEnv_close_internal(DBEnvObject
* self
, int flags
)
4026 if (!self
->closed
) { /* Don't close more than once */
4027 while(self
->children_txns
) {
4028 dummy
=DBTxn_abort_discard_internal(self
->children_txns
,0);
4031 while(self
->children_dbs
) {
4032 dummy
=DB_close_internal(self
->children_dbs
, 0, 0);
4039 MYDB_BEGIN_ALLOW_THREADS
;
4040 err
= self
->db_env
->close(self
->db_env
, flags
);
4041 MYDB_END_ALLOW_THREADS
;
4042 /* after calling DBEnv->close, regardless of error, this DBEnv
4043 * may not be accessed again (Berkeley DB docs). */
4044 self
->db_env
= NULL
;
4051 DBEnv_close(DBEnvObject
* self
, PyObject
* args
)
4055 if (!PyArg_ParseTuple(args
, "|i:close", &flags
))
4057 return DBEnv_close_internal(self
, flags
);
4062 DBEnv_open(DBEnvObject
* self
, PyObject
* args
)
4064 int err
, flags
=0, mode
=0660;
4067 if (!PyArg_ParseTuple(args
, "z|ii:open", &db_home
, &flags
, &mode
))
4070 CHECK_ENV_NOT_CLOSED(self
);
4072 MYDB_BEGIN_ALLOW_THREADS
;
4073 err
= self
->db_env
->open(self
->db_env
, db_home
, flags
, mode
);
4074 MYDB_END_ALLOW_THREADS
;
4077 self
->flags
= flags
;
4083 DBEnv_remove(DBEnvObject
* self
, PyObject
* args
)
4088 if (!PyArg_ParseTuple(args
, "s|i:remove", &db_home
, &flags
))
4090 CHECK_ENV_NOT_CLOSED(self
);
4091 MYDB_BEGIN_ALLOW_THREADS
;
4092 err
= self
->db_env
->remove(self
->db_env
, db_home
, flags
);
4093 MYDB_END_ALLOW_THREADS
;
4100 DBEnv_dbremove(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4105 char *database
= NULL
;
4106 PyObject
*txnobj
= NULL
;
4108 static char* kwnames
[] = { "file", "database", "txn", "flags",
4111 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zOi:dbremove", kwnames
,
4112 &file
, &database
, &txnobj
, &flags
)) {
4115 if (!checkTxnObj(txnobj
, &txn
)) {
4118 CHECK_ENV_NOT_CLOSED(self
);
4119 MYDB_BEGIN_ALLOW_THREADS
;
4120 err
= self
->db_env
->dbremove(self
->db_env
, txn
, file
, database
, flags
);
4121 MYDB_END_ALLOW_THREADS
;
4127 DBEnv_dbrename(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4132 char *database
= NULL
;
4133 char *newname
= NULL
;
4134 PyObject
*txnobj
= NULL
;
4136 static char* kwnames
[] = { "file", "database", "newname", "txn",
4139 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "szs|Oi:dbrename", kwnames
,
4140 &file
, &database
, &newname
, &txnobj
, &flags
)) {
4143 if (!checkTxnObj(txnobj
, &txn
)) {
4146 CHECK_ENV_NOT_CLOSED(self
);
4147 MYDB_BEGIN_ALLOW_THREADS
;
4148 err
= self
->db_env
->dbrename(self
->db_env
, txn
, file
, database
, newname
,
4150 MYDB_END_ALLOW_THREADS
;
4156 DBEnv_set_encrypt(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4160 char *passwd
= NULL
;
4161 static char* kwnames
[] = { "passwd", "flags", NULL
};
4163 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
4168 MYDB_BEGIN_ALLOW_THREADS
;
4169 err
= self
->db_env
->set_encrypt(self
->db_env
, passwd
, flags
);
4170 MYDB_END_ALLOW_THREADS
;
4175 #endif /* DBVER >= 41 */
4178 DBEnv_set_timeout(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4182 u_int32_t timeout
= 0;
4183 static char* kwnames
[] = { "timeout", "flags", NULL
};
4185 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ii:set_timeout", kwnames
,
4186 &timeout
, &flags
)) {
4190 MYDB_BEGIN_ALLOW_THREADS
;
4191 err
= self
->db_env
->set_timeout(self
->db_env
, (db_timeout_t
)timeout
, flags
);
4192 MYDB_END_ALLOW_THREADS
;
4199 DBEnv_set_shm_key(DBEnvObject
* self
, PyObject
* args
)
4204 if (!PyArg_ParseTuple(args
, "l:set_shm_key", &shm_key
))
4206 CHECK_ENV_NOT_CLOSED(self
);
4208 err
= self
->db_env
->set_shm_key(self
->db_env
, shm_key
);
4214 DBEnv_set_cachesize(DBEnvObject
* self
, PyObject
* args
)
4216 int err
, gbytes
=0, bytes
=0, ncache
=0;
4218 if (!PyArg_ParseTuple(args
, "ii|i:set_cachesize",
4219 &gbytes
, &bytes
, &ncache
))
4221 CHECK_ENV_NOT_CLOSED(self
);
4223 MYDB_BEGIN_ALLOW_THREADS
;
4224 err
= self
->db_env
->set_cachesize(self
->db_env
, gbytes
, bytes
, ncache
);
4225 MYDB_END_ALLOW_THREADS
;
4232 DBEnv_set_flags(DBEnvObject
* self
, PyObject
* args
)
4234 int err
, flags
=0, onoff
=0;
4236 if (!PyArg_ParseTuple(args
, "ii:set_flags",
4239 CHECK_ENV_NOT_CLOSED(self
);
4241 MYDB_BEGIN_ALLOW_THREADS
;
4242 err
= self
->db_env
->set_flags(self
->db_env
, flags
, onoff
);
4243 MYDB_END_ALLOW_THREADS
;
4251 DBEnv_log_set_config(DBEnvObject
* self
, PyObject
* args
)
4253 int err
, flags
, onoff
;
4255 if (!PyArg_ParseTuple(args
, "ii:log_set_config",
4258 CHECK_ENV_NOT_CLOSED(self
);
4260 MYDB_BEGIN_ALLOW_THREADS
;
4261 err
= self
->db_env
->log_set_config(self
->db_env
, flags
, onoff
);
4262 MYDB_END_ALLOW_THREADS
;
4266 #endif /* DBVER >= 47 */
4270 DBEnv_set_data_dir(DBEnvObject
* self
, PyObject
* args
)
4275 if (!PyArg_ParseTuple(args
, "s:set_data_dir", &dir
))
4277 CHECK_ENV_NOT_CLOSED(self
);
4279 MYDB_BEGIN_ALLOW_THREADS
;
4280 err
= self
->db_env
->set_data_dir(self
->db_env
, dir
);
4281 MYDB_END_ALLOW_THREADS
;
4288 DBEnv_set_lg_bsize(DBEnvObject
* self
, PyObject
* args
)
4292 if (!PyArg_ParseTuple(args
, "i:set_lg_bsize", &lg_bsize
))
4294 CHECK_ENV_NOT_CLOSED(self
);
4296 MYDB_BEGIN_ALLOW_THREADS
;
4297 err
= self
->db_env
->set_lg_bsize(self
->db_env
, lg_bsize
);
4298 MYDB_END_ALLOW_THREADS
;
4305 DBEnv_set_lg_dir(DBEnvObject
* self
, PyObject
* args
)
4310 if (!PyArg_ParseTuple(args
, "s:set_lg_dir", &dir
))
4312 CHECK_ENV_NOT_CLOSED(self
);
4314 MYDB_BEGIN_ALLOW_THREADS
;
4315 err
= self
->db_env
->set_lg_dir(self
->db_env
, dir
);
4316 MYDB_END_ALLOW_THREADS
;
4322 DBEnv_set_lg_max(DBEnvObject
* self
, PyObject
* args
)
4326 if (!PyArg_ParseTuple(args
, "i:set_lg_max", &lg_max
))
4328 CHECK_ENV_NOT_CLOSED(self
);
4330 MYDB_BEGIN_ALLOW_THREADS
;
4331 err
= self
->db_env
->set_lg_max(self
->db_env
, lg_max
);
4332 MYDB_END_ALLOW_THREADS
;
4339 DBEnv_get_lg_max(DBEnvObject
* self
)
4344 CHECK_ENV_NOT_CLOSED(self
);
4346 MYDB_BEGIN_ALLOW_THREADS
;
4347 err
= self
->db_env
->get_lg_max(self
->db_env
, &lg_max
);
4348 MYDB_END_ALLOW_THREADS
;
4350 return NUMBER_FromLong(lg_max
);
4356 DBEnv_set_lg_regionmax(DBEnvObject
* self
, PyObject
* args
)
4360 if (!PyArg_ParseTuple(args
, "i:set_lg_regionmax", &lg_max
))
4362 CHECK_ENV_NOT_CLOSED(self
);
4364 MYDB_BEGIN_ALLOW_THREADS
;
4365 err
= self
->db_env
->set_lg_regionmax(self
->db_env
, lg_max
);
4366 MYDB_END_ALLOW_THREADS
;
4373 DBEnv_set_lk_detect(DBEnvObject
* self
, PyObject
* args
)
4377 if (!PyArg_ParseTuple(args
, "i:set_lk_detect", &lk_detect
))
4379 CHECK_ENV_NOT_CLOSED(self
);
4381 MYDB_BEGIN_ALLOW_THREADS
;
4382 err
= self
->db_env
->set_lk_detect(self
->db_env
, lk_detect
);
4383 MYDB_END_ALLOW_THREADS
;
4391 DBEnv_set_lk_max(DBEnvObject
* self
, PyObject
* args
)
4395 if (!PyArg_ParseTuple(args
, "i:set_lk_max", &max
))
4397 CHECK_ENV_NOT_CLOSED(self
);
4399 MYDB_BEGIN_ALLOW_THREADS
;
4400 err
= self
->db_env
->set_lk_max(self
->db_env
, max
);
4401 MYDB_END_ALLOW_THREADS
;
4410 DBEnv_set_lk_max_locks(DBEnvObject
* self
, PyObject
* args
)
4414 if (!PyArg_ParseTuple(args
, "i:set_lk_max_locks", &max
))
4416 CHECK_ENV_NOT_CLOSED(self
);
4418 MYDB_BEGIN_ALLOW_THREADS
;
4419 err
= self
->db_env
->set_lk_max_locks(self
->db_env
, max
);
4420 MYDB_END_ALLOW_THREADS
;
4427 DBEnv_set_lk_max_lockers(DBEnvObject
* self
, PyObject
* args
)
4431 if (!PyArg_ParseTuple(args
, "i:set_lk_max_lockers", &max
))
4433 CHECK_ENV_NOT_CLOSED(self
);
4435 MYDB_BEGIN_ALLOW_THREADS
;
4436 err
= self
->db_env
->set_lk_max_lockers(self
->db_env
, max
);
4437 MYDB_END_ALLOW_THREADS
;
4444 DBEnv_set_lk_max_objects(DBEnvObject
* self
, PyObject
* args
)
4448 if (!PyArg_ParseTuple(args
, "i:set_lk_max_objects", &max
))
4450 CHECK_ENV_NOT_CLOSED(self
);
4452 MYDB_BEGIN_ALLOW_THREADS
;
4453 err
= self
->db_env
->set_lk_max_objects(self
->db_env
, max
);
4454 MYDB_END_ALLOW_THREADS
;
4461 DBEnv_set_mp_mmapsize(DBEnvObject
* self
, PyObject
* args
)
4463 int err
, mp_mmapsize
;
4465 if (!PyArg_ParseTuple(args
, "i:set_mp_mmapsize", &mp_mmapsize
))
4467 CHECK_ENV_NOT_CLOSED(self
);
4469 MYDB_BEGIN_ALLOW_THREADS
;
4470 err
= self
->db_env
->set_mp_mmapsize(self
->db_env
, mp_mmapsize
);
4471 MYDB_END_ALLOW_THREADS
;
4478 DBEnv_set_tmp_dir(DBEnvObject
* self
, PyObject
* args
)
4483 if (!PyArg_ParseTuple(args
, "s:set_tmp_dir", &dir
))
4485 CHECK_ENV_NOT_CLOSED(self
);
4487 MYDB_BEGIN_ALLOW_THREADS
;
4488 err
= self
->db_env
->set_tmp_dir(self
->db_env
, dir
);
4489 MYDB_END_ALLOW_THREADS
;
4496 DBEnv_txn_recover(DBEnvObject
* self
)
4498 int flags
= DB_FIRST
;
4500 PyObject
*list
, *tuple
, *gid
;
4502 #define PREPLIST_LEN 16
4503 DB_PREPLIST preplist
[PREPLIST_LEN
];
4506 CHECK_ENV_NOT_CLOSED(self
);
4512 MYDB_BEGIN_ALLOW_THREADS
4513 err
=self
->db_env
->txn_recover(self
->db_env
,
4514 preplist
, PREPLIST_LEN
, &retp
, flags
);
4516 MYDB_END_ALLOW_THREADS
4522 flags
=DB_NEXT
; /* Prepare for next loop pass */
4523 for (i
=0; i
<retp
; i
++) {
4524 gid
=PyBytes_FromStringAndSize((char *)(preplist
[i
].gid
),
4530 txn
=newDBTxnObject(self
, NULL
, preplist
[i
].txn
, flags
);
4536 txn
->flag_prepare
=1; /* Recover state */
4537 tuple
=PyTuple_New(2);
4544 if (PyTuple_SetItem(tuple
, 0, gid
)) {
4551 if (PyTuple_SetItem(tuple
, 1, (PyObject
*)txn
)) {
4554 Py_DECREF(tuple
); /* This delete the "gid" also */
4557 if (PyList_Append(list
, tuple
)) {
4559 Py_DECREF(tuple
);/* This delete the "gid" and the "txn" also */
4569 DBEnv_txn_begin(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4572 PyObject
* txnobj
= NULL
;
4574 static char* kwnames
[] = { "parent", "flags", NULL
};
4576 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:txn_begin", kwnames
,
4580 if (!checkTxnObj(txnobj
, &txn
))
4582 CHECK_ENV_NOT_CLOSED(self
);
4584 return (PyObject
*)newDBTxnObject(self
, (DBTxnObject
*)txnobj
, NULL
, flags
);
4589 DBEnv_txn_checkpoint(DBEnvObject
* self
, PyObject
* args
)
4591 int err
, kbyte
=0, min
=0, flags
=0;
4593 if (!PyArg_ParseTuple(args
, "|iii:txn_checkpoint", &kbyte
, &min
, &flags
))
4595 CHECK_ENV_NOT_CLOSED(self
);
4597 MYDB_BEGIN_ALLOW_THREADS
;
4598 err
= self
->db_env
->txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
4599 MYDB_END_ALLOW_THREADS
;
4606 DBEnv_set_tx_max(DBEnvObject
* self
, PyObject
* args
)
4610 if (!PyArg_ParseTuple(args
, "i:set_tx_max", &max
))
4612 CHECK_ENV_NOT_CLOSED(self
);
4614 err
= self
->db_env
->set_tx_max(self
->db_env
, max
);
4621 DBEnv_set_tx_timestamp(DBEnvObject
* self
, PyObject
* args
)
4627 if (!PyArg_ParseTuple(args
, "l:set_tx_timestamp", &stamp
))
4629 CHECK_ENV_NOT_CLOSED(self
);
4630 timestamp
= (time_t)stamp
;
4631 err
= self
->db_env
->set_tx_timestamp(self
->db_env
, ×tamp
);
4638 DBEnv_lock_detect(DBEnvObject
* self
, PyObject
* args
)
4640 int err
, atype
, flags
=0;
4643 if (!PyArg_ParseTuple(args
, "i|i:lock_detect", &atype
, &flags
))
4645 CHECK_ENV_NOT_CLOSED(self
);
4647 MYDB_BEGIN_ALLOW_THREADS
;
4648 err
= self
->db_env
->lock_detect(self
->db_env
, flags
, atype
, &aborted
);
4649 MYDB_END_ALLOW_THREADS
;
4651 return NUMBER_FromLong(aborted
);
4656 DBEnv_lock_get(DBEnvObject
* self
, PyObject
* args
)
4659 int locker
, lock_mode
;
4663 if (!PyArg_ParseTuple(args
, "iOi|i:lock_get", &locker
, &objobj
, &lock_mode
, &flags
))
4667 if (!make_dbt(objobj
, &obj
))
4670 return (PyObject
*)newDBLockObject(self
, locker
, &obj
, lock_mode
, flags
);
4675 DBEnv_lock_id(DBEnvObject
* self
)
4680 CHECK_ENV_NOT_CLOSED(self
);
4681 MYDB_BEGIN_ALLOW_THREADS
;
4682 err
= self
->db_env
->lock_id(self
->db_env
, &theID
);
4683 MYDB_END_ALLOW_THREADS
;
4686 return NUMBER_FromLong((long)theID
);
4690 DBEnv_lock_id_free(DBEnvObject
* self
, PyObject
* args
)
4695 if (!PyArg_ParseTuple(args
, "I:lock_id_free", &theID
))
4698 CHECK_ENV_NOT_CLOSED(self
);
4699 MYDB_BEGIN_ALLOW_THREADS
;
4700 err
= self
->db_env
->lock_id_free(self
->db_env
, theID
);
4701 MYDB_END_ALLOW_THREADS
;
4707 DBEnv_lock_put(DBEnvObject
* self
, PyObject
* args
)
4710 DBLockObject
* dblockobj
;
4712 if (!PyArg_ParseTuple(args
, "O!:lock_put", &DBLock_Type
, &dblockobj
))
4715 CHECK_ENV_NOT_CLOSED(self
);
4716 MYDB_BEGIN_ALLOW_THREADS
;
4717 err
= self
->db_env
->lock_put(self
->db_env
, &dblockobj
->lock
);
4718 MYDB_END_ALLOW_THREADS
;
4725 DBEnv_lsn_reset(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4729 u_int32_t flags
= 0;
4730 static char* kwnames
[] = { "file", "flags", NULL
};
4732 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|i:lsn_reset", kwnames
,
4735 CHECK_ENV_NOT_CLOSED(self
);
4737 MYDB_BEGIN_ALLOW_THREADS
;
4738 err
= self
->db_env
->lsn_reset(self
->db_env
, file
, flags
);
4739 MYDB_END_ALLOW_THREADS
;
4743 #endif /* DBVER >= 4.4 */
4746 DBEnv_log_stat(DBEnvObject
* self
, PyObject
* args
)
4749 DB_LOG_STAT
* statp
= NULL
;
4751 u_int32_t flags
= 0;
4753 if (!PyArg_ParseTuple(args
, "|i:log_stat", &flags
))
4755 CHECK_ENV_NOT_CLOSED(self
);
4757 MYDB_BEGIN_ALLOW_THREADS
;
4758 err
= self
->db_env
->log_stat(self
->db_env
, &statp
, flags
);
4759 MYDB_END_ALLOW_THREADS
;
4762 /* Turn the stat structure into a dictionary */
4770 #define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
4773 MAKE_ENTRY(version
);
4775 MAKE_ENTRY(lg_bsize
);
4777 MAKE_ENTRY(lg_size
);
4783 MAKE_ENTRY(w_mbytes
);
4784 MAKE_ENTRY(w_bytes
);
4785 MAKE_ENTRY(wc_mbytes
);
4786 MAKE_ENTRY(wc_bytes
);
4788 MAKE_ENTRY(wcount_fill
);
4793 MAKE_ENTRY(cur_file
);
4794 MAKE_ENTRY(cur_offset
);
4795 MAKE_ENTRY(disk_file
);
4796 MAKE_ENTRY(disk_offset
);
4797 MAKE_ENTRY(maxcommitperflush
);
4798 MAKE_ENTRY(mincommitperflush
);
4799 MAKE_ENTRY(regsize
);
4800 MAKE_ENTRY(region_wait
);
4801 MAKE_ENTRY(region_nowait
);
4806 } /* DBEnv_log_stat */
4810 DBEnv_lock_stat(DBEnvObject
* self
, PyObject
* args
)
4815 u_int32_t flags
= 0;
4817 if (!PyArg_ParseTuple(args
, "|i:lock_stat", &flags
))
4819 CHECK_ENV_NOT_CLOSED(self
);
4821 MYDB_BEGIN_ALLOW_THREADS
;
4822 err
= self
->db_env
->lock_stat(self
->db_env
, &sp
, flags
);
4823 MYDB_END_ALLOW_THREADS
;
4826 /* Turn the stat structure into a dictionary */
4833 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4840 MAKE_ENTRY(cur_maxid
);
4843 MAKE_ENTRY(maxlocks
);
4844 MAKE_ENTRY(maxlockers
);
4845 MAKE_ENTRY(maxobjects
);
4847 MAKE_ENTRY(maxnlocks
);
4848 MAKE_ENTRY(nlockers
);
4849 MAKE_ENTRY(maxnlockers
);
4850 MAKE_ENTRY(nobjects
);
4851 MAKE_ENTRY(maxnobjects
);
4852 MAKE_ENTRY(nrequests
);
4853 MAKE_ENTRY(nreleases
);
4855 MAKE_ENTRY(nupgrade
);
4856 MAKE_ENTRY(ndowngrade
);
4859 MAKE_ENTRY(nnowaits
); /* these were renamed in 4.4 */
4860 MAKE_ENTRY(nconflicts
);
4862 MAKE_ENTRY(lock_nowait
);
4863 MAKE_ENTRY(lock_wait
);
4865 MAKE_ENTRY(ndeadlocks
);
4867 MAKE_ENTRY(locktimeout
);
4868 MAKE_ENTRY(txntimeout
);
4870 MAKE_ENTRY(nlocktimeouts
);
4871 MAKE_ENTRY(ntxntimeouts
);
4873 MAKE_ENTRY(objs_wait
);
4874 MAKE_ENTRY(objs_nowait
);
4875 MAKE_ENTRY(lockers_wait
);
4876 MAKE_ENTRY(lockers_nowait
);
4878 MAKE_ENTRY(lock_wait
);
4879 MAKE_ENTRY(lock_nowait
);
4881 MAKE_ENTRY(locks_wait
);
4882 MAKE_ENTRY(locks_nowait
);
4884 MAKE_ENTRY(hash_len
);
4886 MAKE_ENTRY(regsize
);
4887 MAKE_ENTRY(region_wait
);
4888 MAKE_ENTRY(region_nowait
);
4896 DBEnv_log_flush(DBEnvObject
* self
)
4900 CHECK_ENV_NOT_CLOSED(self
);
4902 MYDB_BEGIN_ALLOW_THREADS
4903 err
= self
->db_env
->log_flush(self
->db_env
, NULL
);
4904 MYDB_END_ALLOW_THREADS
4911 DBEnv_log_archive(DBEnvObject
* self
, PyObject
* args
)
4915 char **log_list
= NULL
;
4917 PyObject
* item
= NULL
;
4919 if (!PyArg_ParseTuple(args
, "|i:log_archive", &flags
))
4922 CHECK_ENV_NOT_CLOSED(self
);
4923 MYDB_BEGIN_ALLOW_THREADS
;
4924 err
= self
->db_env
->log_archive(self
->db_env
, &log_list
, flags
);
4925 MYDB_END_ALLOW_THREADS
;
4928 list
= PyList_New(0);
4936 char **log_list_start
;
4937 for (log_list_start
= log_list
; *log_list
!= NULL
; ++log_list
) {
4938 item
= PyBytes_FromString (*log_list
);
4944 if (PyList_Append(list
, item
)) {
4952 free(log_list_start
);
4959 DBEnv_txn_stat(DBEnvObject
* self
, PyObject
* args
)
4966 if (!PyArg_ParseTuple(args
, "|i:txn_stat", &flags
))
4968 CHECK_ENV_NOT_CLOSED(self
);
4970 MYDB_BEGIN_ALLOW_THREADS
;
4971 err
= self
->db_env
->txn_stat(self
->db_env
, &sp
, flags
);
4972 MYDB_END_ALLOW_THREADS
;
4975 /* Turn the stat structure into a dictionary */
4982 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4983 #define MAKE_TIME_T_ENTRY(name) _addTimeTToDict(d, #name, sp->st_##name)
4984 #define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(d, #name, sp->st_##name)
4986 MAKE_DB_LSN_ENTRY(last_ckp
);
4987 MAKE_TIME_T_ENTRY(time_ckp
);
4988 MAKE_ENTRY(last_txnid
);
4989 MAKE_ENTRY(maxtxns
);
4990 MAKE_ENTRY(nactive
);
4991 MAKE_ENTRY(maxnactive
);
4993 MAKE_ENTRY(nsnapshot
);
4994 MAKE_ENTRY(maxnsnapshot
);
4996 MAKE_ENTRY(nbegins
);
4997 MAKE_ENTRY(naborts
);
4998 MAKE_ENTRY(ncommits
);
4999 MAKE_ENTRY(nrestores
);
5000 MAKE_ENTRY(regsize
);
5001 MAKE_ENTRY(region_wait
);
5002 MAKE_ENTRY(region_nowait
);
5004 #undef MAKE_DB_LSN_ENTRY
5006 #undef MAKE_TIME_T_ENTRY
5013 DBEnv_set_get_returns_none(DBEnvObject
* self
, PyObject
* args
)
5018 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
5020 CHECK_ENV_NOT_CLOSED(self
);
5022 if (self
->moduleFlags
.getReturnsNone
)
5024 if (self
->moduleFlags
.cursorSetReturnsNone
)
5026 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
5027 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
5028 return NUMBER_FromLong(oldValue
);
5032 DBEnv_get_private(DBEnvObject
* self
)
5034 /* We can give out the private field even if dbenv is closed */
5035 Py_INCREF(self
->private_obj
);
5036 return self
->private_obj
;
5040 DBEnv_set_private(DBEnvObject
* self
, PyObject
* private_obj
)
5042 /* We can set the private field even if dbenv is closed */
5043 Py_DECREF(self
->private_obj
);
5044 Py_INCREF(private_obj
);
5045 self
->private_obj
= private_obj
;
5051 DBEnv_set_rpc_server(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5055 long cl_timeout
=0, sv_timeout
=0;
5057 static char* kwnames
[] = { "host", "cl_timeout", "sv_timeout", NULL
};
5059 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|ll:set_rpc_server", kwnames
,
5060 &host
, &cl_timeout
, &sv_timeout
))
5062 CHECK_ENV_NOT_CLOSED(self
);
5064 MYDB_BEGIN_ALLOW_THREADS
;
5065 err
= self
->db_env
->set_rpc_server(self
->db_env
, NULL
, host
, cl_timeout
,
5067 MYDB_END_ALLOW_THREADS
;
5073 DBEnv_set_verbose(DBEnvObject
* self
, PyObject
* args
)
5078 if (!PyArg_ParseTuple(args
, "ii:set_verbose", &which
, &onoff
)) {
5081 CHECK_ENV_NOT_CLOSED(self
);
5082 MYDB_BEGIN_ALLOW_THREADS
;
5083 err
= self
->db_env
->set_verbose(self
->db_env
, which
, onoff
);
5084 MYDB_END_ALLOW_THREADS
;
5091 DBEnv_get_verbose(DBEnvObject
* self
, PyObject
* args
)
5097 if (!PyArg_ParseTuple(args
, "i:get_verbose", &which
)) {
5100 CHECK_ENV_NOT_CLOSED(self
);
5101 MYDB_BEGIN_ALLOW_THREADS
;
5102 err
= self
->db_env
->get_verbose(self
->db_env
, which
, &verbose
);
5103 MYDB_END_ALLOW_THREADS
;
5105 return PyBool_FromLong(verbose
);
5111 _dbenv_event_notifyCallback(DB_ENV
* db_env
, u_int32_t event
, void *event_info
)
5116 PyObject
* result
= NULL
;
5118 MYDB_BEGIN_BLOCK_THREADS
;
5119 dbenv
= (DBEnvObject
*)db_env
->app_private
;
5120 callback
= dbenv
->event_notifyCallback
;
5122 if (event
== DB_EVENT_REP_NEWMASTER
) {
5123 args
= Py_BuildValue("(Oii)", dbenv
, event
, *((int *)event_info
));
5125 args
= Py_BuildValue("(OiO)", dbenv
, event
, Py_None
);
5128 result
= PyEval_CallObject(callback
, args
);
5130 if ((!args
) || (!result
)) {
5136 MYDB_END_BLOCK_THREADS
;
5142 DBEnv_set_event_notify(DBEnvObject
* self
, PyObject
* notifyFunc
)
5146 CHECK_ENV_NOT_CLOSED(self
);
5148 if (!PyCallable_Check(notifyFunc
)) {
5149 makeTypeError("Callable", notifyFunc
);
5153 Py_XDECREF(self
->event_notifyCallback
);
5154 Py_INCREF(notifyFunc
);
5155 self
->event_notifyCallback
= notifyFunc
;
5157 /* This is to workaround a problem with un-initialized threads (see
5158 comment in DB_associate) */
5160 PyEval_InitThreads();
5163 MYDB_BEGIN_ALLOW_THREADS
;
5164 err
= self
->db_env
->set_event_notify(self
->db_env
, _dbenv_event_notifyCallback
);
5165 MYDB_END_ALLOW_THREADS
;
5168 Py_DECREF(notifyFunc
);
5169 self
->event_notifyCallback
= NULL
;
5178 /* --------------------------------------------------------------------- */
5179 /* REPLICATION METHODS: Base Replication */
5183 DBEnv_rep_process_message(DBEnvObject
* self
, PyObject
* args
)
5186 PyObject
*control_py
, *rec_py
;
5193 if (!PyArg_ParseTuple(args
, "OOi:rep_process_message", &control_py
,
5196 CHECK_ENV_NOT_CLOSED(self
);
5198 if (!make_dbt(control_py
, &control
))
5200 if (!make_dbt(rec_py
, &rec
))
5203 MYDB_BEGIN_ALLOW_THREADS
;
5205 err
= self
->db_env
->rep_process_message(self
->db_env
, &control
, &rec
,
5209 err
= self
->db_env
->rep_process_message(self
->db_env
, &control
, &rec
,
5212 err
= self
->db_env
->rep_process_message(self
->db_env
, &control
, &rec
,
5216 MYDB_END_ALLOW_THREADS
;
5218 case DB_REP_NEWMASTER
:
5219 return Py_BuildValue("(iO)", envid
, Py_None
);
5222 case DB_REP_DUPMASTER
:
5223 case DB_REP_HOLDELECTION
:
5225 case DB_REP_IGNORE
:
5226 case DB_REP_JOIN_FAILURE
:
5228 return Py_BuildValue("(iO)", err
, Py_None
);
5230 case DB_REP_NEWSITE
:
5234 if (!(tmp
= PyBytes_FromStringAndSize(rec
.data
, rec
.size
))) {
5238 r
= Py_BuildValue("(iO)", err
, tmp
);
5244 case DB_REP_NOTPERM
:
5245 case DB_REP_ISPERM
:
5246 return Py_BuildValue("(i(ll))", err
, lsn
.file
, lsn
.offset
);
5251 return Py_BuildValue("(OO)", Py_None
, Py_None
);
5255 _DBEnv_rep_transportCallback(DB_ENV
* db_env
, const DBT
* control
, const DBT
* rec
,
5256 const DB_LSN
*lsn
, int envid
, u_int32_t flags
)
5259 PyObject
* rep_transport
;
5262 PyObject
* result
= NULL
;
5265 MYDB_BEGIN_BLOCK_THREADS
;
5266 dbenv
= (DBEnvObject
*)db_env
->app_private
;
5267 rep_transport
= dbenv
->rep_transport
;
5270 ** The errors in 'a' or 'b' are detected in "Py_BuildValue".
5272 a
= PyBytes_FromStringAndSize(control
->data
, control
->size
);
5273 b
= PyBytes_FromStringAndSize(rec
->data
, rec
->size
);
5275 args
= Py_BuildValue(
5276 #if (PY_VERSION_HEX >= 0x02040000)
5283 lsn
->file
, lsn
->offset
, envid
, flags
);
5285 result
= PyEval_CallObject(rep_transport
, args
);
5288 if ((!args
) || (!result
)) {
5296 MYDB_END_BLOCK_THREADS
;
5302 _DBEnv_rep_transportCallbackOLD(DB_ENV
* db_env
, const DBT
* control
, const DBT
* rec
,
5303 int envid
, u_int32_t flags
)
5307 lsn
.file
= -1; /* Dummy values */
5309 return _DBEnv_rep_transportCallback(db_env
, control
, rec
, &lsn
, envid
,
5315 DBEnv_rep_set_transport(DBEnvObject
* self
, PyObject
* args
)
5319 PyObject
*rep_transport
;
5321 if (!PyArg_ParseTuple(args
, "iO:rep_set_transport", &envid
, &rep_transport
))
5323 CHECK_ENV_NOT_CLOSED(self
);
5324 if (!PyCallable_Check(rep_transport
)) {
5325 makeTypeError("Callable", rep_transport
);
5329 MYDB_BEGIN_ALLOW_THREADS
;
5331 err
= self
->db_env
->rep_set_transport(self
->db_env
, envid
,
5332 &_DBEnv_rep_transportCallback
);
5335 err
= self
->db_env
->set_rep_transport(self
->db_env
, envid
,
5336 &_DBEnv_rep_transportCallback
);
5338 err
= self
->db_env
->set_rep_transport(self
->db_env
, envid
,
5339 &_DBEnv_rep_transportCallbackOLD
);
5342 MYDB_END_ALLOW_THREADS
;
5345 Py_DECREF(self
->rep_transport
);
5346 Py_INCREF(rep_transport
);
5347 self
->rep_transport
= rep_transport
;
5353 DBEnv_rep_set_request(DBEnvObject
* self
, PyObject
* args
)
5356 unsigned int minimum
, maximum
;
5358 if (!PyArg_ParseTuple(args
,"II:rep_set_request", &minimum
, &maximum
))
5360 CHECK_ENV_NOT_CLOSED(self
);
5362 MYDB_BEGIN_ALLOW_THREADS
;
5363 err
= self
->db_env
->rep_set_request(self
->db_env
, minimum
, maximum
);
5364 MYDB_END_ALLOW_THREADS
;
5370 DBEnv_rep_get_request(DBEnvObject
* self
)
5373 u_int32_t minimum
, maximum
;
5375 CHECK_ENV_NOT_CLOSED(self
);
5376 MYDB_BEGIN_ALLOW_THREADS
;
5377 err
= self
->db_env
->rep_get_request(self
->db_env
, &minimum
, &maximum
);
5378 MYDB_END_ALLOW_THREADS
;
5380 #if (PY_VERSION_HEX >= 0x02040000)
5381 return Py_BuildValue("II", minimum
, maximum
);
5383 return Py_BuildValue("ii", minimum
, maximum
);
5390 DBEnv_rep_set_limit(DBEnvObject
* self
, PyObject
* args
)
5395 if (!PyArg_ParseTuple(args
,"i:rep_set_limit", &limit
))
5397 CHECK_ENV_NOT_CLOSED(self
);
5399 MYDB_BEGIN_ALLOW_THREADS
;
5400 err
= self
->db_env
->rep_set_limit(self
->db_env
, 0, limit
);
5401 MYDB_END_ALLOW_THREADS
;
5407 DBEnv_rep_get_limit(DBEnvObject
* self
)
5410 u_int32_t gbytes
, bytes
;
5412 CHECK_ENV_NOT_CLOSED(self
);
5413 MYDB_BEGIN_ALLOW_THREADS
;
5414 err
= self
->db_env
->rep_get_limit(self
->db_env
, &gbytes
, &bytes
);
5415 MYDB_END_ALLOW_THREADS
;
5417 return NUMBER_FromLong(bytes
);
5423 DBEnv_rep_set_config(DBEnvObject
* self
, PyObject
* args
)
5429 if (!PyArg_ParseTuple(args
,"ii:rep_set_config", &which
, &onoff
))
5431 CHECK_ENV_NOT_CLOSED(self
);
5433 MYDB_BEGIN_ALLOW_THREADS
;
5434 err
= self
->db_env
->rep_set_config(self
->db_env
, which
, onoff
);
5435 MYDB_END_ALLOW_THREADS
;
5441 DBEnv_rep_get_config(DBEnvObject
* self
, PyObject
* args
)
5447 if (!PyArg_ParseTuple(args
, "i:rep_get_config", &which
)) {
5450 CHECK_ENV_NOT_CLOSED(self
);
5451 MYDB_BEGIN_ALLOW_THREADS
;
5452 err
= self
->db_env
->rep_get_config(self
->db_env
, which
, &onoff
);
5453 MYDB_END_ALLOW_THREADS
;
5455 return PyBool_FromLong(onoff
);
5461 DBEnv_rep_elect(DBEnvObject
* self
, PyObject
* args
)
5464 u_int32_t nsites
, nvotes
;
5466 if (!PyArg_ParseTuple(args
, "II:rep_elect", &nsites
, &nvotes
)) {
5469 CHECK_ENV_NOT_CLOSED(self
);
5470 MYDB_BEGIN_ALLOW_THREADS
;
5471 err
= self
->db_env
->rep_elect(self
->db_env
, nvotes
, nvotes
, 0);
5472 MYDB_END_ALLOW_THREADS
;
5479 DBEnv_rep_start(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5482 PyObject
*cdata_py
= Py_None
;
5485 static char* kwnames
[] = {"flags","cdata", NULL
};
5487 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,
5488 "i|O:rep_start", kwnames
, &flags
, &cdata_py
))
5492 CHECK_ENV_NOT_CLOSED(self
);
5494 if (!make_dbt(cdata_py
, &cdata
))
5497 MYDB_BEGIN_ALLOW_THREADS
;
5498 err
= self
->db_env
->rep_start(self
->db_env
, cdata
.size
? &cdata
: NULL
,
5500 MYDB_END_ALLOW_THREADS
;
5507 DBEnv_rep_sync(DBEnvObject
* self
)
5511 CHECK_ENV_NOT_CLOSED(self
);
5512 MYDB_BEGIN_ALLOW_THREADS
;
5513 err
= self
->db_env
->rep_sync(self
->db_env
, 0);
5514 MYDB_END_ALLOW_THREADS
;
5523 DBEnv_rep_set_nsites(DBEnvObject
* self
, PyObject
* args
)
5528 if (!PyArg_ParseTuple(args
, "i:rep_set_nsites", &nsites
)) {
5531 CHECK_ENV_NOT_CLOSED(self
);
5532 MYDB_BEGIN_ALLOW_THREADS
;
5533 err
= self
->db_env
->rep_set_nsites(self
->db_env
, nsites
);
5534 MYDB_END_ALLOW_THREADS
;
5540 DBEnv_rep_get_nsites(DBEnvObject
* self
)
5549 CHECK_ENV_NOT_CLOSED(self
);
5550 MYDB_BEGIN_ALLOW_THREADS
;
5551 err
= self
->db_env
->rep_get_nsites(self
->db_env
, &nsites
);
5552 MYDB_END_ALLOW_THREADS
;
5554 return NUMBER_FromLong(nsites
);
5558 DBEnv_rep_set_priority(DBEnvObject
* self
, PyObject
* args
)
5563 if (!PyArg_ParseTuple(args
, "i:rep_set_priority", &priority
)) {
5566 CHECK_ENV_NOT_CLOSED(self
);
5567 MYDB_BEGIN_ALLOW_THREADS
;
5568 err
= self
->db_env
->rep_set_priority(self
->db_env
, priority
);
5569 MYDB_END_ALLOW_THREADS
;
5575 DBEnv_rep_get_priority(DBEnvObject
* self
)
5584 CHECK_ENV_NOT_CLOSED(self
);
5585 MYDB_BEGIN_ALLOW_THREADS
;
5586 err
= self
->db_env
->rep_get_priority(self
->db_env
, &priority
);
5587 MYDB_END_ALLOW_THREADS
;
5589 return NUMBER_FromLong(priority
);
5593 DBEnv_rep_set_timeout(DBEnvObject
* self
, PyObject
* args
)
5598 if (!PyArg_ParseTuple(args
, "ii:rep_set_timeout", &which
, &timeout
)) {
5601 CHECK_ENV_NOT_CLOSED(self
);
5602 MYDB_BEGIN_ALLOW_THREADS
;
5603 err
= self
->db_env
->rep_set_timeout(self
->db_env
, which
, timeout
);
5604 MYDB_END_ALLOW_THREADS
;
5610 DBEnv_rep_get_timeout(DBEnvObject
* self
, PyObject
* args
)
5616 if (!PyArg_ParseTuple(args
, "i:rep_get_timeout", &which
)) {
5619 CHECK_ENV_NOT_CLOSED(self
);
5620 MYDB_BEGIN_ALLOW_THREADS
;
5621 err
= self
->db_env
->rep_get_timeout(self
->db_env
, which
, &timeout
);
5622 MYDB_END_ALLOW_THREADS
;
5624 return NUMBER_FromLong(timeout
);
5628 /* --------------------------------------------------------------------- */
5629 /* REPLICATION METHODS: Replication Manager */
5633 DBEnv_repmgr_start(DBEnvObject
* self
, PyObject
* args
, PyObject
*
5637 int nthreads
, flags
;
5638 static char* kwnames
[] = {"nthreads","flags", NULL
};
5640 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,
5641 "ii:repmgr_start", kwnames
, &nthreads
, &flags
))
5645 CHECK_ENV_NOT_CLOSED(self
);
5646 MYDB_BEGIN_ALLOW_THREADS
;
5647 err
= self
->db_env
->repmgr_start(self
->db_env
, nthreads
, flags
);
5648 MYDB_END_ALLOW_THREADS
;
5654 DBEnv_repmgr_set_local_site(DBEnvObject
* self
, PyObject
* args
, PyObject
*
5661 static char* kwnames
[] = {"host", "port", "flags", NULL
};
5663 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,
5664 "si|i:repmgr_set_local_site", kwnames
, &host
, &port
, &flags
))
5668 CHECK_ENV_NOT_CLOSED(self
);
5669 MYDB_BEGIN_ALLOW_THREADS
;
5670 err
= self
->db_env
->repmgr_set_local_site(self
->db_env
, host
, port
, flags
);
5671 MYDB_END_ALLOW_THREADS
;
5677 DBEnv_repmgr_add_remote_site(DBEnvObject
* self
, PyObject
* args
, PyObject
*
5685 static char* kwnames
[] = {"host", "port", "flags", NULL
};
5687 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,
5688 "si|i:repmgr_add_remote_site", kwnames
, &host
, &port
, &flags
))
5692 CHECK_ENV_NOT_CLOSED(self
);
5693 MYDB_BEGIN_ALLOW_THREADS
;
5694 err
= self
->db_env
->repmgr_add_remote_site(self
->db_env
, host
, port
, &eidp
, flags
);
5695 MYDB_END_ALLOW_THREADS
;
5697 return NUMBER_FromLong(eidp
);
5701 DBEnv_repmgr_set_ack_policy(DBEnvObject
* self
, PyObject
* args
)
5706 if (!PyArg_ParseTuple(args
, "i:repmgr_set_ack_policy", &ack_policy
))
5710 CHECK_ENV_NOT_CLOSED(self
);
5711 MYDB_BEGIN_ALLOW_THREADS
;
5712 err
= self
->db_env
->repmgr_set_ack_policy(self
->db_env
, ack_policy
);
5713 MYDB_END_ALLOW_THREADS
;
5719 DBEnv_repmgr_get_ack_policy(DBEnvObject
* self
)
5724 CHECK_ENV_NOT_CLOSED(self
);
5725 MYDB_BEGIN_ALLOW_THREADS
;
5726 err
= self
->db_env
->repmgr_get_ack_policy(self
->db_env
, &ack_policy
);
5727 MYDB_END_ALLOW_THREADS
;
5729 return NUMBER_FromLong(ack_policy
);
5733 DBEnv_repmgr_site_list(DBEnvObject
* self
)
5736 unsigned int countp
;
5737 DB_REPMGR_SITE
*listp
;
5738 PyObject
*stats
, *key
, *tuple
;
5740 CHECK_ENV_NOT_CLOSED(self
);
5741 MYDB_BEGIN_ALLOW_THREADS
;
5742 err
= self
->db_env
->repmgr_site_list(self
->db_env
, &countp
, &listp
);
5743 MYDB_END_ALLOW_THREADS
;
5747 if (stats
== NULL
) {
5753 key
=NUMBER_FromLong(listp
[countp
].eid
);
5759 #if (PY_VERSION_HEX >= 0x02040000)
5760 tuple
=Py_BuildValue("(sII)", listp
[countp
].host
,
5761 listp
[countp
].port
, listp
[countp
].status
);
5763 tuple
=Py_BuildValue("(sii)", listp
[countp
].host
,
5764 listp
[countp
].port
, listp
[countp
].status
);
5772 if(PyDict_SetItem(stats
, key
, tuple
)) {
5787 DBEnv_repmgr_stat_print(DBEnvObject
* self
, PyObject
* args
, PyObject
*kwargs
)
5791 static char* kwnames
[] = { "flags", NULL
};
5793 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:repmgr_stat_print",
5798 CHECK_ENV_NOT_CLOSED(self
);
5799 MYDB_BEGIN_ALLOW_THREADS
;
5800 err
= self
->db_env
->repmgr_stat_print(self
->db_env
, flags
);
5801 MYDB_END_ALLOW_THREADS
;
5807 DBEnv_repmgr_stat(DBEnvObject
* self
, PyObject
* args
, PyObject
*kwargs
)
5811 DB_REPMGR_STAT
*statp
;
5813 static char* kwnames
[] = { "flags", NULL
};
5815 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:repmgr_stat",
5820 CHECK_ENV_NOT_CLOSED(self
);
5821 MYDB_BEGIN_ALLOW_THREADS
;
5822 err
= self
->db_env
->repmgr_stat(self
->db_env
, &statp
, flags
);
5823 MYDB_END_ALLOW_THREADS
;
5827 if (stats
== NULL
) {
5832 #define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
5834 MAKE_ENTRY(perm_failed
);
5835 MAKE_ENTRY(msgs_queued
);
5836 MAKE_ENTRY(msgs_dropped
);
5837 MAKE_ENTRY(connection_drop
);
5838 MAKE_ENTRY(connect_fail
);
5848 /* --------------------------------------------------------------------- */
5852 static void _close_transaction_cursors(DBTxnObject
* txn
)
5856 while(txn
->children_cursors
) {
5857 PyErr_Warn(PyExc_RuntimeWarning
,
5858 "Must close cursors before resolving a transaction.");
5859 dummy
=DBC_close_internal(txn
->children_cursors
);
5864 static void _promote_transaction_dbs_and_sequences(DBTxnObject
*txn
)
5868 DBSequenceObject
*dbs
;
5871 while (txn
->children_dbs
) {
5872 db
=txn
->children_dbs
;
5873 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(db
);
5874 if (txn
->parent_txn
) {
5875 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn
->parent_txn
->children_dbs
,db
);
5876 db
->txn
=txn
->parent_txn
;
5878 /* The db is already linked to its environment,
5879 ** so nothing to do.
5886 while (txn
->children_sequences
) {
5887 dbs
=txn
->children_sequences
;
5888 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(dbs
);
5889 if (txn
->parent_txn
) {
5890 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn
->parent_txn
->children_sequences
,dbs
);
5891 dbs
->txn
=txn
->parent_txn
;
5893 /* The sequence is already linked to its
5894 ** parent db. Nothing to do.
5904 DBTxn_commit(DBTxnObject
* self
, PyObject
* args
)
5909 if (!PyArg_ParseTuple(args
, "|i:commit", &flags
))
5912 _close_transaction_cursors(self
);
5915 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
5916 "after txn_commit, txn_abort "
5919 PyErr_SetObject(DBError
, t
);
5924 self
->flag_prepare
=0;
5926 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
5928 EXTRACT_FROM_DOUBLE_LINKED_LIST(self
);
5930 MYDB_BEGIN_ALLOW_THREADS
;
5931 err
= txn
->commit(txn
, flags
);
5932 MYDB_END_ALLOW_THREADS
;
5934 _promote_transaction_dbs_and_sequences(self
);
5941 DBTxn_prepare(DBTxnObject
* self
, PyObject
* args
)
5947 if (!PyArg_ParseTuple(args
, "s#:prepare", &gid
, &gid_size
))
5950 if (gid_size
!= DB_XIDDATASIZE
) {
5951 PyErr_SetString(PyExc_TypeError
,
5952 "gid must be DB_XIDDATASIZE bytes long");
5957 PyObject
*t
= Py_BuildValue("(is)", 0,"DBTxn must not be used "
5958 "after txn_commit, txn_abort "
5961 PyErr_SetObject(DBError
, t
);
5966 self
->flag_prepare
=1; /* Prepare state */
5967 MYDB_BEGIN_ALLOW_THREADS
;
5968 err
= self
->txn
->prepare(self
->txn
, (u_int8_t
*)gid
);
5969 MYDB_END_ALLOW_THREADS
;
5976 DBTxn_abort_discard_internal(DBTxnObject
* self
, int discard
)
5983 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
5984 "after txn_commit, txn_abort "
5987 PyErr_SetObject(DBError
, t
);
5993 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
5995 _close_transaction_cursors(self
);
5997 while (self
->children_sequences
) {
5998 dummy
=DBSequence_close_internal(self
->children_sequences
,0,0);
6002 while (self
->children_dbs
) {
6003 dummy
=DB_close_internal(self
->children_dbs
, 0, 0);
6007 EXTRACT_FROM_DOUBLE_LINKED_LIST(self
);
6009 MYDB_BEGIN_ALLOW_THREADS
;
6011 assert(!self
->flag_prepare
);
6012 err
= txn
->discard(txn
,0);
6015 ** If the transaction is in the "prepare" or "recover" state,
6016 ** we better do not implicitly abort it.
6018 if (!self
->flag_prepare
) {
6019 err
= txn
->abort(txn
);
6022 MYDB_END_ALLOW_THREADS
;
6028 DBTxn_abort(DBTxnObject
* self
)
6030 self
->flag_prepare
=0;
6031 _close_transaction_cursors(self
);
6033 return DBTxn_abort_discard_internal(self
,0);
6037 DBTxn_discard(DBTxnObject
* self
)
6039 self
->flag_prepare
=0;
6040 _close_transaction_cursors(self
);
6042 return DBTxn_abort_discard_internal(self
,1);
6047 DBTxn_id(DBTxnObject
* self
)
6052 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
6053 "after txn_commit, txn_abort "
6056 PyErr_SetObject(DBError
, t
);
6061 MYDB_BEGIN_ALLOW_THREADS
;
6062 id
= self
->txn
->id(self
->txn
);
6063 MYDB_END_ALLOW_THREADS
;
6064 return NUMBER_FromLong(id
);
6068 /* --------------------------------------------------------------------- */
6069 /* DBSequence methods */
6073 DBSequence_close_internal(DBSequenceObject
* self
, int flags
, int do_not_close
)
6077 if (self
->sequence
!=NULL
) {
6078 EXTRACT_FROM_DOUBLE_LINKED_LIST(self
);
6080 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self
);
6085 ** "do_not_close" is used to dispose all related objects in the
6086 ** tree, without actually releasing the "root" object.
6087 ** This is done, for example, because function calls like
6088 ** "DBSequence.remove()" implicitly close the underlying handle. So
6089 ** the handle doesn't need to be closed, but related objects
6090 ** must be cleaned up.
6092 if (!do_not_close
) {
6093 MYDB_BEGIN_ALLOW_THREADS
6094 err
= self
->sequence
->close(self
->sequence
, flags
);
6095 MYDB_END_ALLOW_THREADS
6097 self
->sequence
= NULL
;
6106 DBSequence_close(DBSequenceObject
* self
, PyObject
* args
)
6109 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
6112 return DBSequence_close_internal(self
,flags
,0);
6116 DBSequence_get(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
6121 PyObject
*txnobj
= NULL
;
6123 static char* kwnames
[] = {"delta", "txn", "flags", NULL
};
6124 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iOi:get", kwnames
, &delta
, &txnobj
, &flags
))
6126 CHECK_SEQUENCE_NOT_CLOSED(self
)
6128 if (!checkTxnObj(txnobj
, &txn
))
6131 MYDB_BEGIN_ALLOW_THREADS
6132 err
= self
->sequence
->get(self
->sequence
, txn
, delta
, &value
, flags
);
6133 MYDB_END_ALLOW_THREADS
6136 return PyLong_FromLongLong(value
);
6140 DBSequence_get_dbp(DBSequenceObject
* self
)
6142 CHECK_SEQUENCE_NOT_CLOSED(self
)
6143 Py_INCREF(self
->mydb
);
6144 return (PyObject
* )self
->mydb
;
6148 DBSequence_get_key(DBSequenceObject
* self
)
6152 PyObject
*retval
= NULL
;
6154 key
.flags
= DB_DBT_MALLOC
;
6155 CHECK_SEQUENCE_NOT_CLOSED(self
)
6156 MYDB_BEGIN_ALLOW_THREADS
6157 err
= self
->sequence
->get_key(self
->sequence
, &key
);
6158 MYDB_END_ALLOW_THREADS
6161 retval
= Build_PyString(key
.data
, key
.size
);
6170 DBSequence_init_value(DBSequenceObject
* self
, PyObject
* args
)
6175 if (!PyArg_ParseTuple(args
,"L:init_value", &value
))
6177 CHECK_SEQUENCE_NOT_CLOSED(self
)
6179 value2
=value
; /* If truncation, compiler should show a warning */
6180 MYDB_BEGIN_ALLOW_THREADS
6181 err
= self
->sequence
->initial_value(self
->sequence
, value2
);
6182 MYDB_END_ALLOW_THREADS
6190 DBSequence_open(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
6194 PyObject
*txnobj
= NULL
;
6198 static char* kwnames
[] = {"key", "txn", "flags", NULL
};
6199 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:open", kwnames
, &keyobj
, &txnobj
, &flags
))
6202 if (!checkTxnObj(txnobj
, &txn
))
6205 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
6208 MYDB_BEGIN_ALLOW_THREADS
6209 err
= self
->sequence
->open(self
->sequence
, txn
, &key
, flags
);
6210 MYDB_END_ALLOW_THREADS
6216 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject
*)txnobj
)->children_sequences
,self
);
6217 self
->txn
=(DBTxnObject
*)txnobj
;
6224 DBSequence_remove(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
6228 PyObject
*txnobj
= NULL
;
6231 static char* kwnames
[] = {"txn", "flags", NULL
};
6232 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:remove", kwnames
, &txnobj
, &flags
))
6235 if (!checkTxnObj(txnobj
, &txn
))
6238 CHECK_SEQUENCE_NOT_CLOSED(self
)
6240 MYDB_BEGIN_ALLOW_THREADS
6241 err
= self
->sequence
->remove(self
->sequence
, txn
, flags
);
6242 MYDB_END_ALLOW_THREADS
6244 dummy
=DBSequence_close_internal(self
,flags
,1);
6252 DBSequence_set_cachesize(DBSequenceObject
* self
, PyObject
* args
)
6255 if (!PyArg_ParseTuple(args
,"i:set_cachesize", &size
))
6257 CHECK_SEQUENCE_NOT_CLOSED(self
)
6259 MYDB_BEGIN_ALLOW_THREADS
6260 err
= self
->sequence
->set_cachesize(self
->sequence
, size
);
6261 MYDB_END_ALLOW_THREADS
6268 DBSequence_get_cachesize(DBSequenceObject
* self
)
6272 CHECK_SEQUENCE_NOT_CLOSED(self
)
6274 MYDB_BEGIN_ALLOW_THREADS
6275 err
= self
->sequence
->get_cachesize(self
->sequence
, &size
);
6276 MYDB_END_ALLOW_THREADS
6279 return NUMBER_FromLong(size
);
6283 DBSequence_set_flags(DBSequenceObject
* self
, PyObject
* args
)
6286 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
6288 CHECK_SEQUENCE_NOT_CLOSED(self
)
6290 MYDB_BEGIN_ALLOW_THREADS
6291 err
= self
->sequence
->set_flags(self
->sequence
, flags
);
6292 MYDB_END_ALLOW_THREADS
6299 DBSequence_get_flags(DBSequenceObject
* self
)
6304 CHECK_SEQUENCE_NOT_CLOSED(self
)
6306 MYDB_BEGIN_ALLOW_THREADS
6307 err
= self
->sequence
->get_flags(self
->sequence
, &flags
);
6308 MYDB_END_ALLOW_THREADS
6311 return NUMBER_FromLong((int)flags
);
6315 DBSequence_set_range(DBSequenceObject
* self
, PyObject
* args
)
6318 PY_LONG_LONG min
, max
;
6319 db_seq_t min2
, max2
;
6320 if (!PyArg_ParseTuple(args
,"(LL):set_range", &min
, &max
))
6322 CHECK_SEQUENCE_NOT_CLOSED(self
)
6324 min2
=min
; /* If truncation, compiler should show a warning */
6326 MYDB_BEGIN_ALLOW_THREADS
6327 err
= self
->sequence
->set_range(self
->sequence
, min2
, max2
);
6328 MYDB_END_ALLOW_THREADS
6335 DBSequence_get_range(DBSequenceObject
* self
)
6338 PY_LONG_LONG min
, max
;
6339 db_seq_t min2
, max2
;
6341 CHECK_SEQUENCE_NOT_CLOSED(self
)
6343 MYDB_BEGIN_ALLOW_THREADS
6344 err
= self
->sequence
->get_range(self
->sequence
, &min2
, &max2
);
6345 MYDB_END_ALLOW_THREADS
6348 min
=min2
; /* If truncation, compiler should show a warning */
6350 return Py_BuildValue("(LL)", min
, max
);
6354 DBSequence_stat(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
6357 DB_SEQUENCE_STAT
* sp
= NULL
;
6358 PyObject
* dict_stat
;
6359 static char* kwnames
[] = {"flags", NULL
};
6360 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat", kwnames
, &flags
))
6362 CHECK_SEQUENCE_NOT_CLOSED(self
);
6364 MYDB_BEGIN_ALLOW_THREADS
;
6365 err
= self
->sequence
->stat(self
->sequence
, &sp
, flags
);
6366 MYDB_END_ALLOW_THREADS
;
6369 if ((dict_stat
= PyDict_New()) == NULL
) {
6375 #define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name)
6376 #define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
6378 MAKE_INT_ENTRY(wait
);
6379 MAKE_INT_ENTRY(nowait
);
6380 MAKE_LONG_LONG_ENTRY(current
);
6381 MAKE_LONG_LONG_ENTRY(value
);
6382 MAKE_LONG_LONG_ENTRY(last_value
);
6383 MAKE_LONG_LONG_ENTRY(min
);
6384 MAKE_LONG_LONG_ENTRY(max
);
6385 MAKE_INT_ENTRY(cache_size
);
6386 MAKE_INT_ENTRY(flags
);
6388 #undef MAKE_INT_ENTRY
6389 #undef MAKE_LONG_LONG_ENTRY
6397 /* --------------------------------------------------------------------- */
6398 /* Method definition tables and type objects */
6400 static PyMethodDef DB_methods
[] = {
6401 {"append", (PyCFunction
)DB_append
, METH_VARARGS
|METH_KEYWORDS
},
6402 {"associate", (PyCFunction
)DB_associate
, METH_VARARGS
|METH_KEYWORDS
},
6403 {"close", (PyCFunction
)DB_close
, METH_VARARGS
},
6404 {"consume", (PyCFunction
)DB_consume
, METH_VARARGS
|METH_KEYWORDS
},
6405 {"consume_wait", (PyCFunction
)DB_consume_wait
, METH_VARARGS
|METH_KEYWORDS
},
6406 {"cursor", (PyCFunction
)DB_cursor
, METH_VARARGS
|METH_KEYWORDS
},
6407 {"delete", (PyCFunction
)DB_delete
, METH_VARARGS
|METH_KEYWORDS
},
6408 {"fd", (PyCFunction
)DB_fd
, METH_NOARGS
},
6409 {"get", (PyCFunction
)DB_get
, METH_VARARGS
|METH_KEYWORDS
},
6410 {"pget", (PyCFunction
)DB_pget
, METH_VARARGS
|METH_KEYWORDS
},
6411 {"get_both", (PyCFunction
)DB_get_both
, METH_VARARGS
|METH_KEYWORDS
},
6412 {"get_byteswapped", (PyCFunction
)DB_get_byteswapped
,METH_NOARGS
},
6413 {"get_size", (PyCFunction
)DB_get_size
, METH_VARARGS
|METH_KEYWORDS
},
6414 {"get_type", (PyCFunction
)DB_get_type
, METH_NOARGS
},
6415 {"join", (PyCFunction
)DB_join
, METH_VARARGS
},
6416 {"key_range", (PyCFunction
)DB_key_range
, METH_VARARGS
|METH_KEYWORDS
},
6417 {"has_key", (PyCFunction
)DB_has_key
, METH_VARARGS
|METH_KEYWORDS
},
6418 {"items", (PyCFunction
)DB_items
, METH_VARARGS
},
6419 {"keys", (PyCFunction
)DB_keys
, METH_VARARGS
},
6420 {"open", (PyCFunction
)DB_open
, METH_VARARGS
|METH_KEYWORDS
},
6421 {"put", (PyCFunction
)DB_put
, METH_VARARGS
|METH_KEYWORDS
},
6422 {"remove", (PyCFunction
)DB_remove
, METH_VARARGS
|METH_KEYWORDS
},
6423 {"rename", (PyCFunction
)DB_rename
, METH_VARARGS
},
6424 {"set_bt_minkey", (PyCFunction
)DB_set_bt_minkey
, METH_VARARGS
},
6425 {"set_bt_compare", (PyCFunction
)DB_set_bt_compare
, METH_O
},
6426 {"set_cachesize", (PyCFunction
)DB_set_cachesize
, METH_VARARGS
},
6428 {"set_encrypt", (PyCFunction
)DB_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
6430 {"set_flags", (PyCFunction
)DB_set_flags
, METH_VARARGS
},
6431 {"set_h_ffactor", (PyCFunction
)DB_set_h_ffactor
, METH_VARARGS
},
6432 {"set_h_nelem", (PyCFunction
)DB_set_h_nelem
, METH_VARARGS
},
6433 {"set_lorder", (PyCFunction
)DB_set_lorder
, METH_VARARGS
},
6434 {"set_pagesize", (PyCFunction
)DB_set_pagesize
, METH_VARARGS
},
6435 {"set_re_delim", (PyCFunction
)DB_set_re_delim
, METH_VARARGS
},
6436 {"set_re_len", (PyCFunction
)DB_set_re_len
, METH_VARARGS
},
6437 {"set_re_pad", (PyCFunction
)DB_set_re_pad
, METH_VARARGS
},
6438 {"set_re_source", (PyCFunction
)DB_set_re_source
, METH_VARARGS
},
6439 {"set_q_extentsize",(PyCFunction
)DB_set_q_extentsize
, METH_VARARGS
},
6440 {"set_private", (PyCFunction
)DB_set_private
, METH_O
},
6441 {"get_private", (PyCFunction
)DB_get_private
, METH_NOARGS
},
6442 {"stat", (PyCFunction
)DB_stat
, METH_VARARGS
|METH_KEYWORDS
},
6443 {"sync", (PyCFunction
)DB_sync
, METH_VARARGS
},
6444 {"truncate", (PyCFunction
)DB_truncate
, METH_VARARGS
|METH_KEYWORDS
},
6445 {"type", (PyCFunction
)DB_get_type
, METH_NOARGS
},
6446 {"upgrade", (PyCFunction
)DB_upgrade
, METH_VARARGS
},
6447 {"values", (PyCFunction
)DB_values
, METH_VARARGS
},
6448 {"verify", (PyCFunction
)DB_verify
, METH_VARARGS
|METH_KEYWORDS
},
6449 {"set_get_returns_none",(PyCFunction
)DB_set_get_returns_none
, METH_VARARGS
},
6450 {NULL
, NULL
} /* sentinel */
6454 static PyMappingMethods DB_mapping
= {
6455 DB_length
, /*mp_length*/
6456 (binaryfunc
)DB_subscript
, /*mp_subscript*/
6457 (objobjargproc
)DB_ass_sub
, /*mp_ass_subscript*/
6461 static PyMethodDef DBCursor_methods
[] = {
6462 {"close", (PyCFunction
)DBC_close
, METH_NOARGS
},
6463 {"count", (PyCFunction
)DBC_count
, METH_VARARGS
},
6464 {"current", (PyCFunction
)DBC_current
, METH_VARARGS
|METH_KEYWORDS
},
6465 {"delete", (PyCFunction
)DBC_delete
, METH_VARARGS
},
6466 {"dup", (PyCFunction
)DBC_dup
, METH_VARARGS
},
6467 {"first", (PyCFunction
)DBC_first
, METH_VARARGS
|METH_KEYWORDS
},
6468 {"get", (PyCFunction
)DBC_get
, METH_VARARGS
|METH_KEYWORDS
},
6469 {"pget", (PyCFunction
)DBC_pget
, METH_VARARGS
|METH_KEYWORDS
},
6470 {"get_recno", (PyCFunction
)DBC_get_recno
, METH_NOARGS
},
6471 {"last", (PyCFunction
)DBC_last
, METH_VARARGS
|METH_KEYWORDS
},
6472 {"next", (PyCFunction
)DBC_next
, METH_VARARGS
|METH_KEYWORDS
},
6473 {"prev", (PyCFunction
)DBC_prev
, METH_VARARGS
|METH_KEYWORDS
},
6474 {"put", (PyCFunction
)DBC_put
, METH_VARARGS
|METH_KEYWORDS
},
6475 {"set", (PyCFunction
)DBC_set
, METH_VARARGS
|METH_KEYWORDS
},
6476 {"set_range", (PyCFunction
)DBC_set_range
, METH_VARARGS
|METH_KEYWORDS
},
6477 {"get_both", (PyCFunction
)DBC_get_both
, METH_VARARGS
},
6478 {"get_current_size",(PyCFunction
)DBC_get_current_size
, METH_NOARGS
},
6479 {"set_both", (PyCFunction
)DBC_set_both
, METH_VARARGS
},
6480 {"set_recno", (PyCFunction
)DBC_set_recno
, METH_VARARGS
|METH_KEYWORDS
},
6481 {"consume", (PyCFunction
)DBC_consume
, METH_VARARGS
|METH_KEYWORDS
},
6482 {"next_dup", (PyCFunction
)DBC_next_dup
, METH_VARARGS
|METH_KEYWORDS
},
6483 {"next_nodup", (PyCFunction
)DBC_next_nodup
, METH_VARARGS
|METH_KEYWORDS
},
6484 {"prev_nodup", (PyCFunction
)DBC_prev_nodup
, METH_VARARGS
|METH_KEYWORDS
},
6485 {"join_item", (PyCFunction
)DBC_join_item
, METH_VARARGS
},
6486 {NULL
, NULL
} /* sentinel */
6490 static PyMethodDef DBEnv_methods
[] = {
6491 {"close", (PyCFunction
)DBEnv_close
, METH_VARARGS
},
6492 {"open", (PyCFunction
)DBEnv_open
, METH_VARARGS
},
6493 {"remove", (PyCFunction
)DBEnv_remove
, METH_VARARGS
},
6495 {"dbremove", (PyCFunction
)DBEnv_dbremove
, METH_VARARGS
|METH_KEYWORDS
},
6496 {"dbrename", (PyCFunction
)DBEnv_dbrename
, METH_VARARGS
|METH_KEYWORDS
},
6497 {"set_encrypt", (PyCFunction
)DBEnv_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
6499 {"set_timeout", (PyCFunction
)DBEnv_set_timeout
, METH_VARARGS
|METH_KEYWORDS
},
6500 {"set_shm_key", (PyCFunction
)DBEnv_set_shm_key
, METH_VARARGS
},
6501 {"set_cachesize", (PyCFunction
)DBEnv_set_cachesize
, METH_VARARGS
},
6502 {"set_data_dir", (PyCFunction
)DBEnv_set_data_dir
, METH_VARARGS
},
6503 {"set_flags", (PyCFunction
)DBEnv_set_flags
, METH_VARARGS
},
6505 {"log_set_config", (PyCFunction
)DBEnv_log_set_config
, METH_VARARGS
},
6507 {"set_lg_bsize", (PyCFunction
)DBEnv_set_lg_bsize
, METH_VARARGS
},
6508 {"set_lg_dir", (PyCFunction
)DBEnv_set_lg_dir
, METH_VARARGS
},
6509 {"set_lg_max", (PyCFunction
)DBEnv_set_lg_max
, METH_VARARGS
},
6511 {"get_lg_max", (PyCFunction
)DBEnv_get_lg_max
, METH_NOARGS
},
6513 {"set_lg_regionmax",(PyCFunction
)DBEnv_set_lg_regionmax
, METH_VARARGS
},
6514 {"set_lk_detect", (PyCFunction
)DBEnv_set_lk_detect
, METH_VARARGS
},
6516 {"set_lk_max", (PyCFunction
)DBEnv_set_lk_max
, METH_VARARGS
},
6518 {"set_lk_max_locks", (PyCFunction
)DBEnv_set_lk_max_locks
, METH_VARARGS
},
6519 {"set_lk_max_lockers", (PyCFunction
)DBEnv_set_lk_max_lockers
, METH_VARARGS
},
6520 {"set_lk_max_objects", (PyCFunction
)DBEnv_set_lk_max_objects
, METH_VARARGS
},
6521 {"set_mp_mmapsize", (PyCFunction
)DBEnv_set_mp_mmapsize
, METH_VARARGS
},
6522 {"set_tmp_dir", (PyCFunction
)DBEnv_set_tmp_dir
, METH_VARARGS
},
6523 {"txn_begin", (PyCFunction
)DBEnv_txn_begin
, METH_VARARGS
|METH_KEYWORDS
},
6524 {"txn_checkpoint", (PyCFunction
)DBEnv_txn_checkpoint
, METH_VARARGS
},
6525 {"txn_stat", (PyCFunction
)DBEnv_txn_stat
, METH_VARARGS
},
6526 {"set_tx_max", (PyCFunction
)DBEnv_set_tx_max
, METH_VARARGS
},
6527 {"set_tx_timestamp", (PyCFunction
)DBEnv_set_tx_timestamp
, METH_VARARGS
},
6528 {"lock_detect", (PyCFunction
)DBEnv_lock_detect
, METH_VARARGS
},
6529 {"lock_get", (PyCFunction
)DBEnv_lock_get
, METH_VARARGS
},
6530 {"lock_id", (PyCFunction
)DBEnv_lock_id
, METH_NOARGS
},
6531 {"lock_id_free", (PyCFunction
)DBEnv_lock_id_free
, METH_VARARGS
},
6532 {"lock_put", (PyCFunction
)DBEnv_lock_put
, METH_VARARGS
},
6533 {"lock_stat", (PyCFunction
)DBEnv_lock_stat
, METH_VARARGS
},
6534 {"log_archive", (PyCFunction
)DBEnv_log_archive
, METH_VARARGS
},
6535 {"log_flush", (PyCFunction
)DBEnv_log_flush
, METH_NOARGS
},
6536 {"log_stat", (PyCFunction
)DBEnv_log_stat
, METH_VARARGS
},
6538 {"lsn_reset", (PyCFunction
)DBEnv_lsn_reset
, METH_VARARGS
|METH_KEYWORDS
},
6540 {"set_get_returns_none",(PyCFunction
)DBEnv_set_get_returns_none
, METH_VARARGS
},
6541 {"txn_recover", (PyCFunction
)DBEnv_txn_recover
, METH_NOARGS
},
6542 {"set_rpc_server", (PyCFunction
)DBEnv_set_rpc_server
,
6543 METH_VARARGS
||METH_KEYWORDS
},
6544 {"set_verbose", (PyCFunction
)DBEnv_set_verbose
, METH_VARARGS
},
6546 {"get_verbose", (PyCFunction
)DBEnv_get_verbose
, METH_VARARGS
},
6548 {"set_private", (PyCFunction
)DBEnv_set_private
, METH_O
},
6549 {"get_private", (PyCFunction
)DBEnv_get_private
, METH_NOARGS
},
6550 {"rep_start", (PyCFunction
)DBEnv_rep_start
,
6551 METH_VARARGS
|METH_KEYWORDS
},
6552 {"rep_set_transport", (PyCFunction
)DBEnv_rep_set_transport
, METH_VARARGS
},
6553 {"rep_process_message", (PyCFunction
)DBEnv_rep_process_message
,
6556 {"rep_elect", (PyCFunction
)DBEnv_rep_elect
, METH_VARARGS
},
6559 {"rep_set_config", (PyCFunction
)DBEnv_rep_set_config
, METH_VARARGS
},
6560 {"rep_get_config", (PyCFunction
)DBEnv_rep_get_config
, METH_VARARGS
},
6561 {"rep_sync", (PyCFunction
)DBEnv_rep_sync
, METH_NOARGS
},
6564 {"rep_set_limit", (PyCFunction
)DBEnv_rep_set_limit
, METH_VARARGS
},
6565 {"rep_get_limit", (PyCFunction
)DBEnv_rep_get_limit
, METH_NOARGS
},
6568 {"rep_set_request", (PyCFunction
)DBEnv_rep_set_request
, METH_VARARGS
},
6569 {"rep_get_request", (PyCFunction
)DBEnv_rep_get_request
, METH_NOARGS
},
6572 {"set_event_notify", (PyCFunction
)DBEnv_set_event_notify
, METH_O
},
6575 {"rep_set_nsites", (PyCFunction
)DBEnv_rep_set_nsites
, METH_VARARGS
},
6576 {"rep_get_nsites", (PyCFunction
)DBEnv_rep_get_nsites
, METH_NOARGS
},
6577 {"rep_set_priority", (PyCFunction
)DBEnv_rep_set_priority
, METH_VARARGS
},
6578 {"rep_get_priority", (PyCFunction
)DBEnv_rep_get_priority
, METH_NOARGS
},
6579 {"rep_set_timeout", (PyCFunction
)DBEnv_rep_set_timeout
, METH_VARARGS
},
6580 {"rep_get_timeout", (PyCFunction
)DBEnv_rep_get_timeout
, METH_VARARGS
},
6583 {"repmgr_start", (PyCFunction
)DBEnv_repmgr_start
,
6584 METH_VARARGS
|METH_KEYWORDS
},
6585 {"repmgr_set_local_site", (PyCFunction
)DBEnv_repmgr_set_local_site
,
6586 METH_VARARGS
|METH_KEYWORDS
},
6587 {"repmgr_add_remote_site", (PyCFunction
)DBEnv_repmgr_add_remote_site
,
6588 METH_VARARGS
|METH_KEYWORDS
},
6589 {"repmgr_set_ack_policy", (PyCFunction
)DBEnv_repmgr_set_ack_policy
,
6591 {"repmgr_get_ack_policy", (PyCFunction
)DBEnv_repmgr_get_ack_policy
,
6593 {"repmgr_site_list", (PyCFunction
)DBEnv_repmgr_site_list
,
6597 {"repmgr_stat", (PyCFunction
)DBEnv_repmgr_stat
,
6598 METH_VARARGS
|METH_KEYWORDS
},
6599 {"repmgr_stat_print", (PyCFunction
)DBEnv_repmgr_stat_print
,
6600 METH_VARARGS
|METH_KEYWORDS
},
6602 {NULL
, NULL
} /* sentinel */
6606 static PyMethodDef DBTxn_methods
[] = {
6607 {"commit", (PyCFunction
)DBTxn_commit
, METH_VARARGS
},
6608 {"prepare", (PyCFunction
)DBTxn_prepare
, METH_VARARGS
},
6609 {"discard", (PyCFunction
)DBTxn_discard
, METH_NOARGS
},
6610 {"abort", (PyCFunction
)DBTxn_abort
, METH_NOARGS
},
6611 {"id", (PyCFunction
)DBTxn_id
, METH_NOARGS
},
6612 {NULL
, NULL
} /* sentinel */
6617 static PyMethodDef DBSequence_methods
[] = {
6618 {"close", (PyCFunction
)DBSequence_close
, METH_VARARGS
},
6619 {"get", (PyCFunction
)DBSequence_get
, METH_VARARGS
|METH_KEYWORDS
},
6620 {"get_dbp", (PyCFunction
)DBSequence_get_dbp
, METH_NOARGS
},
6621 {"get_key", (PyCFunction
)DBSequence_get_key
, METH_NOARGS
},
6622 {"init_value", (PyCFunction
)DBSequence_init_value
, METH_VARARGS
},
6623 {"open", (PyCFunction
)DBSequence_open
, METH_VARARGS
|METH_KEYWORDS
},
6624 {"remove", (PyCFunction
)DBSequence_remove
, METH_VARARGS
|METH_KEYWORDS
},
6625 {"set_cachesize", (PyCFunction
)DBSequence_set_cachesize
, METH_VARARGS
},
6626 {"get_cachesize", (PyCFunction
)DBSequence_get_cachesize
, METH_NOARGS
},
6627 {"set_flags", (PyCFunction
)DBSequence_set_flags
, METH_VARARGS
},
6628 {"get_flags", (PyCFunction
)DBSequence_get_flags
, METH_NOARGS
},
6629 {"set_range", (PyCFunction
)DBSequence_set_range
, METH_VARARGS
},
6630 {"get_range", (PyCFunction
)DBSequence_get_range
, METH_NOARGS
},
6631 {"stat", (PyCFunction
)DBSequence_stat
, METH_VARARGS
|METH_KEYWORDS
},
6632 {NULL
, NULL
} /* sentinel */
6638 DBEnv_db_home_get(DBEnvObject
* self
)
6640 const char *home
= NULL
;
6642 CHECK_ENV_NOT_CLOSED(self
);
6645 self
->db_env
->get_home(self
->db_env
, &home
);
6647 home
=self
->db_env
->db_home
;
6653 return PyBytes_FromString(home
);
6656 static PyGetSetDef DBEnv_getsets
[] = {
6657 {"db_home", (getter
)DBEnv_db_home_get
, NULL
,},
6662 statichere PyTypeObject DB_Type
= {
6663 #if (PY_VERSION_HEX < 0x03000000)
6664 PyObject_HEAD_INIT(NULL
)
6667 PyVarObject_HEAD_INIT(NULL
, 0)
6670 sizeof(DBObject
), /*tp_basicsize*/
6673 (destructor
)DB_dealloc
, /*tp_dealloc*/
6680 0, /*tp_as_sequence*/
6681 &DB_mapping
,/*tp_as_mapping*/
6685 0, /* tp_getattro */
6686 0, /* tp_setattro */
6687 0, /* tp_as_buffer */
6688 #if (PY_VERSION_HEX < 0x03000000)
6689 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
6691 Py_TPFLAGS_DEFAULT
, /* tp_flags */
6694 0, /* tp_traverse */
6696 0, /* tp_richcompare */
6697 offsetof(DBObject
, in_weakreflist
), /* tp_weaklistoffset */
6700 DB_methods
, /*tp_methods*/
6705 statichere PyTypeObject DBCursor_Type
= {
6706 #if (PY_VERSION_HEX < 0x03000000)
6707 PyObject_HEAD_INIT(NULL
)
6710 PyVarObject_HEAD_INIT(NULL
, 0)
6712 "DBCursor", /*tp_name*/
6713 sizeof(DBCursorObject
), /*tp_basicsize*/
6716 (destructor
)DBCursor_dealloc
,/*tp_dealloc*/
6723 0, /*tp_as_sequence*/
6724 0, /*tp_as_mapping*/
6731 #if (PY_VERSION_HEX < 0x03000000)
6732 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
6734 Py_TPFLAGS_DEFAULT
, /* tp_flags */
6737 0, /* tp_traverse */
6739 0, /* tp_richcompare */
6740 offsetof(DBCursorObject
, in_weakreflist
), /* tp_weaklistoffset */
6743 DBCursor_methods
, /*tp_methods*/
6748 statichere PyTypeObject DBEnv_Type
= {
6749 #if (PY_VERSION_HEX < 0x03000000)
6750 PyObject_HEAD_INIT(NULL
)
6753 PyVarObject_HEAD_INIT(NULL
, 0)
6755 "DBEnv", /*tp_name*/
6756 sizeof(DBEnvObject
), /*tp_basicsize*/
6759 (destructor
)DBEnv_dealloc
, /*tp_dealloc*/
6766 0, /*tp_as_sequence*/
6767 0, /*tp_as_mapping*/
6771 0, /* tp_getattro */
6772 0, /* tp_setattro */
6773 0, /* tp_as_buffer */
6774 #if (PY_VERSION_HEX < 0x03000000)
6775 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
6777 Py_TPFLAGS_DEFAULT
, /* tp_flags */
6780 0, /* tp_traverse */
6782 0, /* tp_richcompare */
6783 offsetof(DBEnvObject
, in_weakreflist
), /* tp_weaklistoffset */
6785 0, /* tp_iternext */
6786 DBEnv_methods
, /* tp_methods */
6788 DBEnv_getsets
, /* tp_getsets */
6791 statichere PyTypeObject DBTxn_Type
= {
6792 #if (PY_VERSION_HEX < 0x03000000)
6793 PyObject_HEAD_INIT(NULL
)
6796 PyVarObject_HEAD_INIT(NULL
, 0)
6798 "DBTxn", /*tp_name*/
6799 sizeof(DBTxnObject
), /*tp_basicsize*/
6802 (destructor
)DBTxn_dealloc
, /*tp_dealloc*/
6809 0, /*tp_as_sequence*/
6810 0, /*tp_as_mapping*/
6814 0, /* tp_getattro */
6815 0, /* tp_setattro */
6816 0, /* tp_as_buffer */
6817 #if (PY_VERSION_HEX < 0x03000000)
6818 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
6820 Py_TPFLAGS_DEFAULT
, /* tp_flags */
6823 0, /* tp_traverse */
6825 0, /* tp_richcompare */
6826 offsetof(DBTxnObject
, in_weakreflist
), /* tp_weaklistoffset */
6829 DBTxn_methods
, /*tp_methods*/
6834 statichere PyTypeObject DBLock_Type
= {
6835 #if (PY_VERSION_HEX < 0x03000000)
6836 PyObject_HEAD_INIT(NULL
)
6839 PyVarObject_HEAD_INIT(NULL
, 0)
6841 "DBLock", /*tp_name*/
6842 sizeof(DBLockObject
), /*tp_basicsize*/
6845 (destructor
)DBLock_dealloc
, /*tp_dealloc*/
6852 0, /*tp_as_sequence*/
6853 0, /*tp_as_mapping*/
6857 0, /* tp_getattro */
6858 0, /* tp_setattro */
6859 0, /* tp_as_buffer */
6860 #if (PY_VERSION_HEX < 0x03000000)
6861 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
6863 Py_TPFLAGS_DEFAULT
, /* tp_flags */
6866 0, /* tp_traverse */
6868 0, /* tp_richcompare */
6869 offsetof(DBLockObject
, in_weakreflist
), /* tp_weaklistoffset */
6873 statichere PyTypeObject DBSequence_Type
= {
6874 #if (PY_VERSION_HEX < 0x03000000)
6875 PyObject_HEAD_INIT(NULL
)
6878 PyVarObject_HEAD_INIT(NULL
, 0)
6880 "DBSequence", /*tp_name*/
6881 sizeof(DBSequenceObject
), /*tp_basicsize*/
6884 (destructor
)DBSequence_dealloc
, /*tp_dealloc*/
6891 0, /*tp_as_sequence*/
6892 0, /*tp_as_mapping*/
6896 0, /* tp_getattro */
6897 0, /* tp_setattro */
6898 0, /* tp_as_buffer */
6899 #if (PY_VERSION_HEX < 0x03000000)
6900 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
6902 Py_TPFLAGS_DEFAULT
, /* tp_flags */
6905 0, /* tp_traverse */
6907 0, /* tp_richcompare */
6908 offsetof(DBSequenceObject
, in_weakreflist
), /* tp_weaklistoffset */
6911 DBSequence_methods
, /*tp_methods*/
6916 /* --------------------------------------------------------------------- */
6917 /* Module-level functions */
6920 DB_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
6922 PyObject
* dbenvobj
= NULL
;
6924 static char* kwnames
[] = { "dbEnv", "flags", NULL
};
6926 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:DB", kwnames
,
6929 if (dbenvobj
== Py_None
)
6931 else if (dbenvobj
&& !DBEnvObject_Check(dbenvobj
)) {
6932 makeTypeError("DBEnv", dbenvobj
);
6936 return (PyObject
* )newDBObject((DBEnvObject
*)dbenvobj
, flags
);
6941 DBEnv_construct(PyObject
* self
, PyObject
* args
)
6944 if (!PyArg_ParseTuple(args
, "|i:DbEnv", &flags
)) return NULL
;
6945 return (PyObject
* )newDBEnvObject(flags
);
6950 DBSequence_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
6954 static char* kwnames
[] = { "db", "flags", NULL
};
6956 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|i:DBSequence", kwnames
, &dbobj
, &flags
))
6958 if (!DBObject_Check(dbobj
)) {
6959 makeTypeError("DB", dbobj
);
6962 return (PyObject
* )newDBSequenceObject((DBObject
*)dbobj
, flags
);
6966 static char bsddb_version_doc
[] =
6967 "Returns a tuple of major, minor, and patch release numbers of the\n\
6968 underlying DB library.";
6971 bsddb_version(PyObject
* self
)
6973 int major
, minor
, patch
;
6975 db_version(&major
, &minor
, &patch
);
6976 return Py_BuildValue("(iii)", major
, minor
, patch
);
6980 /* List of functions defined in the module */
6981 static PyMethodDef bsddb_methods
[] = {
6982 {"DB", (PyCFunction
)DB_construct
, METH_VARARGS
| METH_KEYWORDS
},
6983 {"DBEnv", (PyCFunction
)DBEnv_construct
, METH_VARARGS
},
6985 {"DBSequence", (PyCFunction
)DBSequence_construct
, METH_VARARGS
| METH_KEYWORDS
},
6987 {"version", (PyCFunction
)bsddb_version
, METH_NOARGS
, bsddb_version_doc
},
6988 {NULL
, NULL
} /* sentinel */
6993 static BSDDB_api bsddb_api
;
6996 /* --------------------------------------------------------------------- */
6997 /* Module initialization */
7000 /* Convenience routine to export an integer value.
7001 * Errors are silently ignored, for better or for worse...
7003 #define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
7005 #define MODULE_NAME_MAX_LEN 11
7006 static char _bsddbModuleName
[MODULE_NAME_MAX_LEN
+1] = "_bsddb";
7008 #if (PY_VERSION_HEX >= 0x03000000)
7009 static struct PyModuleDef bsddbmodule
= {
7010 PyModuleDef_HEAD_INIT
,
7011 _bsddbModuleName
, /* Name of module */
7012 NULL
, /* module documentation, may be NULL */
7013 -1, /* size of per-interpreter state of the module,
7014 or -1 if the module keeps state in global variables. */
7017 NULL
, /* Traverse */
7024 #if (PY_VERSION_HEX < 0x03000000)
7025 DL_EXPORT(void) init_bsddb(void)
7027 PyMODINIT_FUNC
PyInit__bsddb(void) /* Note the two underscores */
7032 PyObject
* pybsddb_version_s
= PyBytes_FromString( PY_BSDDB_VERSION
);
7033 PyObject
* db_version_s
= PyBytes_FromString( DB_VERSION_STRING
);
7034 PyObject
* cvsid_s
= PyBytes_FromString( rcs_id
);
7037 /* Initialize object types */
7038 if ((PyType_Ready(&DB_Type
) < 0)
7039 || (PyType_Ready(&DBCursor_Type
) < 0)
7040 || (PyType_Ready(&DBEnv_Type
) < 0)
7041 || (PyType_Ready(&DBTxn_Type
) < 0)
7042 || (PyType_Ready(&DBLock_Type
) < 0)
7044 || (PyType_Ready(&DBSequence_Type
) < 0)
7047 #if (PY_VERSION_HEX < 0x03000000)
7054 #if defined(WITH_THREAD) && !defined(MYDB_USE_GILSTATE)
7055 /* Save the current interpreter, so callbacks can do the right thing. */
7056 _db_interpreterState
= PyThreadState_GET()->interp
;
7059 /* Create the module and add the functions */
7060 #if (PY_VERSION_HEX < 0x03000000)
7061 m
= Py_InitModule(_bsddbModuleName
, bsddb_methods
);
7063 m
=PyModule_Create(&bsddbmodule
);
7066 #if (PY_VERSION_HEX < 0x03000000)
7073 /* Add some symbolic constants to the module */
7074 d
= PyModule_GetDict(m
);
7075 PyDict_SetItemString(d
, "__version__", pybsddb_version_s
);
7076 PyDict_SetItemString(d
, "cvsid", cvsid_s
);
7077 PyDict_SetItemString(d
, "DB_VERSION_STRING", db_version_s
);
7078 Py_DECREF(pybsddb_version_s
);
7079 pybsddb_version_s
= NULL
;
7082 Py_DECREF(db_version_s
);
7083 db_version_s
= NULL
;
7085 ADD_INT(d
, DB_VERSION_MAJOR
);
7086 ADD_INT(d
, DB_VERSION_MINOR
);
7087 ADD_INT(d
, DB_VERSION_PATCH
);
7089 ADD_INT(d
, DB_MAX_PAGES
);
7090 ADD_INT(d
, DB_MAX_RECORDS
);
7093 ADD_INT(d
, DB_RPCCLIENT
);
7095 ADD_INT(d
, DB_CLIENT
);
7096 /* allow apps to be written using DB_RPCCLIENT on older Berkeley DB */
7097 _addIntToDict(d
, "DB_RPCCLIENT", DB_CLIENT
);
7099 ADD_INT(d
, DB_XA_CREATE
);
7101 ADD_INT(d
, DB_CREATE
);
7102 ADD_INT(d
, DB_NOMMAP
);
7103 ADD_INT(d
, DB_THREAD
);
7105 ADD_INT(d
, DB_MULTIVERSION
);
7108 ADD_INT(d
, DB_FORCE
);
7109 ADD_INT(d
, DB_INIT_CDB
);
7110 ADD_INT(d
, DB_INIT_LOCK
);
7111 ADD_INT(d
, DB_INIT_LOG
);
7112 ADD_INT(d
, DB_INIT_MPOOL
);
7113 ADD_INT(d
, DB_INIT_TXN
);
7114 ADD_INT(d
, DB_JOINENV
);
7116 ADD_INT(d
, DB_XIDDATASIZE
);
7118 ADD_INT(d
, DB_RECOVER
);
7119 ADD_INT(d
, DB_RECOVER_FATAL
);
7120 ADD_INT(d
, DB_TXN_NOSYNC
);
7121 ADD_INT(d
, DB_USE_ENVIRON
);
7122 ADD_INT(d
, DB_USE_ENVIRON_ROOT
);
7124 ADD_INT(d
, DB_LOCKDOWN
);
7125 ADD_INT(d
, DB_PRIVATE
);
7126 ADD_INT(d
, DB_SYSTEM_MEM
);
7128 ADD_INT(d
, DB_TXN_SYNC
);
7129 ADD_INT(d
, DB_TXN_NOWAIT
);
7131 ADD_INT(d
, DB_EXCL
);
7132 ADD_INT(d
, DB_FCNTL_LOCKING
);
7133 ADD_INT(d
, DB_ODDFILESIZE
);
7134 ADD_INT(d
, DB_RDWRMASTER
);
7135 ADD_INT(d
, DB_RDONLY
);
7136 ADD_INT(d
, DB_TRUNCATE
);
7137 ADD_INT(d
, DB_EXTENT
);
7138 ADD_INT(d
, DB_CDB_ALLDB
);
7139 ADD_INT(d
, DB_VERIFY
);
7140 ADD_INT(d
, DB_UPGRADE
);
7142 ADD_INT(d
, DB_AGGRESSIVE
);
7143 ADD_INT(d
, DB_NOORDERCHK
);
7144 ADD_INT(d
, DB_ORDERCHKONLY
);
7145 ADD_INT(d
, DB_PR_PAGE
);
7147 ADD_INT(d
, DB_PR_RECOVERYTEST
);
7148 ADD_INT(d
, DB_SALVAGE
);
7150 ADD_INT(d
, DB_LOCK_NORUN
);
7151 ADD_INT(d
, DB_LOCK_DEFAULT
);
7152 ADD_INT(d
, DB_LOCK_OLDEST
);
7153 ADD_INT(d
, DB_LOCK_RANDOM
);
7154 ADD_INT(d
, DB_LOCK_YOUNGEST
);
7155 ADD_INT(d
, DB_LOCK_MAXLOCKS
);
7156 ADD_INT(d
, DB_LOCK_MINLOCKS
);
7157 ADD_INT(d
, DB_LOCK_MINWRITE
);
7159 ADD_INT(d
, DB_LOCK_EXPIRE
);
7161 ADD_INT(d
, DB_LOCK_MAXWRITE
);
7164 _addIntToDict(d
, "DB_LOCK_CONFLICT", 0);
7166 ADD_INT(d
, DB_LOCK_DUMP
);
7167 ADD_INT(d
, DB_LOCK_GET
);
7168 ADD_INT(d
, DB_LOCK_INHERIT
);
7169 ADD_INT(d
, DB_LOCK_PUT
);
7170 ADD_INT(d
, DB_LOCK_PUT_ALL
);
7171 ADD_INT(d
, DB_LOCK_PUT_OBJ
);
7173 ADD_INT(d
, DB_LOCK_NG
);
7174 ADD_INT(d
, DB_LOCK_READ
);
7175 ADD_INT(d
, DB_LOCK_WRITE
);
7176 ADD_INT(d
, DB_LOCK_NOWAIT
);
7177 ADD_INT(d
, DB_LOCK_WAIT
);
7178 ADD_INT(d
, DB_LOCK_IWRITE
);
7179 ADD_INT(d
, DB_LOCK_IREAD
);
7180 ADD_INT(d
, DB_LOCK_IWR
);
7182 ADD_INT(d
, DB_LOCK_DIRTY
);
7184 ADD_INT(d
, DB_LOCK_READ_UNCOMMITTED
); /* renamed in 4.4 */
7186 ADD_INT(d
, DB_LOCK_WWRITE
);
7188 ADD_INT(d
, DB_LOCK_RECORD
);
7189 ADD_INT(d
, DB_LOCK_UPGRADE
);
7190 ADD_INT(d
, DB_LOCK_SWITCH
);
7191 ADD_INT(d
, DB_LOCK_UPGRADE_WRITE
);
7193 ADD_INT(d
, DB_LOCK_NOWAIT
);
7194 ADD_INT(d
, DB_LOCK_RECORD
);
7195 ADD_INT(d
, DB_LOCK_UPGRADE
);
7197 ADD_INT(d
, DB_LSTAT_ABORTED
);
7199 ADD_INT(d
, DB_LSTAT_ERR
);
7201 ADD_INT(d
, DB_LSTAT_FREE
);
7202 ADD_INT(d
, DB_LSTAT_HELD
);
7204 ADD_INT(d
, DB_LSTAT_PENDING
);
7205 ADD_INT(d
, DB_LSTAT_WAITING
);
7207 ADD_INT(d
, DB_ARCH_ABS
);
7208 ADD_INT(d
, DB_ARCH_DATA
);
7209 ADD_INT(d
, DB_ARCH_LOG
);
7211 ADD_INT(d
, DB_ARCH_REMOVE
);
7214 ADD_INT(d
, DB_BTREE
);
7215 ADD_INT(d
, DB_HASH
);
7216 ADD_INT(d
, DB_RECNO
);
7217 ADD_INT(d
, DB_QUEUE
);
7218 ADD_INT(d
, DB_UNKNOWN
);
7221 ADD_INT(d
, DB_DUPSORT
);
7222 ADD_INT(d
, DB_RECNUM
);
7223 ADD_INT(d
, DB_RENUMBER
);
7224 ADD_INT(d
, DB_REVSPLITOFF
);
7225 ADD_INT(d
, DB_SNAPSHOT
);
7227 ADD_INT(d
, DB_JOIN_NOSORT
);
7229 ADD_INT(d
, DB_AFTER
);
7230 ADD_INT(d
, DB_APPEND
);
7231 ADD_INT(d
, DB_BEFORE
);
7233 ADD_INT(d
, DB_CACHED_COUNTS
);
7237 _addIntToDict(d
, "DB_CHECKPOINT", 0);
7239 ADD_INT(d
, DB_CHECKPOINT
);
7240 ADD_INT(d
, DB_CURLSN
);
7243 ADD_INT(d
, DB_COMMIT
);
7245 ADD_INT(d
, DB_CONSUME
);
7246 ADD_INT(d
, DB_CONSUME_WAIT
);
7247 ADD_INT(d
, DB_CURRENT
);
7248 ADD_INT(d
, DB_FAST_STAT
);
7249 ADD_INT(d
, DB_FIRST
);
7250 ADD_INT(d
, DB_FLUSH
);
7251 ADD_INT(d
, DB_GET_BOTH
);
7252 ADD_INT(d
, DB_GET_RECNO
);
7253 ADD_INT(d
, DB_JOIN_ITEM
);
7254 ADD_INT(d
, DB_KEYFIRST
);
7255 ADD_INT(d
, DB_KEYLAST
);
7256 ADD_INT(d
, DB_LAST
);
7257 ADD_INT(d
, DB_NEXT
);
7258 ADD_INT(d
, DB_NEXT_DUP
);
7259 ADD_INT(d
, DB_NEXT_NODUP
);
7260 ADD_INT(d
, DB_NODUPDATA
);
7261 ADD_INT(d
, DB_NOOVERWRITE
);
7262 ADD_INT(d
, DB_NOSYNC
);
7263 ADD_INT(d
, DB_POSITION
);
7264 ADD_INT(d
, DB_PREV
);
7265 ADD_INT(d
, DB_PREV_NODUP
);
7267 ADD_INT(d
, DB_RECORDCOUNT
);
7270 ADD_INT(d
, DB_SET_RANGE
);
7271 ADD_INT(d
, DB_SET_RECNO
);
7272 ADD_INT(d
, DB_WRITECURSOR
);
7274 ADD_INT(d
, DB_OPFLAGS_MASK
);
7276 ADD_INT(d
, DB_DIRTY_READ
);
7277 ADD_INT(d
, DB_MULTIPLE
);
7278 ADD_INT(d
, DB_MULTIPLE_KEY
);
7281 ADD_INT(d
, DB_READ_UNCOMMITTED
); /* replaces DB_DIRTY_READ in 4.4 */
7282 ADD_INT(d
, DB_READ_COMMITTED
);
7285 ADD_INT(d
, DB_DONOTINDEX
);
7288 _addIntToDict(d
, "DB_INCOMPLETE", 0);
7290 ADD_INT(d
, DB_INCOMPLETE
);
7292 ADD_INT(d
, DB_KEYEMPTY
);
7293 ADD_INT(d
, DB_KEYEXIST
);
7294 ADD_INT(d
, DB_LOCK_DEADLOCK
);
7295 ADD_INT(d
, DB_LOCK_NOTGRANTED
);
7296 ADD_INT(d
, DB_NOSERVER
);
7297 ADD_INT(d
, DB_NOSERVER_HOME
);
7298 ADD_INT(d
, DB_NOSERVER_ID
);
7299 ADD_INT(d
, DB_NOTFOUND
);
7300 ADD_INT(d
, DB_OLD_VERSION
);
7301 ADD_INT(d
, DB_RUNRECOVERY
);
7302 ADD_INT(d
, DB_VERIFY_BAD
);
7303 ADD_INT(d
, DB_PAGE_NOTFOUND
);
7304 ADD_INT(d
, DB_SECONDARY_BAD
);
7305 ADD_INT(d
, DB_STAT_CLEAR
);
7306 ADD_INT(d
, DB_REGION_INIT
);
7307 ADD_INT(d
, DB_NOLOCKING
);
7308 ADD_INT(d
, DB_YIELDCPU
);
7309 ADD_INT(d
, DB_PANIC_ENVIRONMENT
);
7310 ADD_INT(d
, DB_NOPANIC
);
7313 ADD_INT(d
, DB_OVERWRITE
);
7317 ADD_INT(d
, DB_REGISTER
);
7321 ADD_INT(d
, DB_TIME_NOTGRANTED
);
7322 ADD_INT(d
, DB_TXN_NOT_DURABLE
);
7323 ADD_INT(d
, DB_TXN_WRITE_NOSYNC
);
7324 ADD_INT(d
, DB_DIRECT_DB
);
7325 ADD_INT(d
, DB_INIT_REP
);
7326 ADD_INT(d
, DB_ENCRYPT
);
7327 ADD_INT(d
, DB_CHKSUM
);
7330 #if (DBVER >= 42) && (DBVER < 47)
7331 ADD_INT(d
, DB_LOG_AUTOREMOVE
);
7332 ADD_INT(d
, DB_DIRECT_LOG
);
7336 ADD_INT(d
, DB_LOG_DIRECT
);
7337 ADD_INT(d
, DB_LOG_DSYNC
);
7338 ADD_INT(d
, DB_LOG_IN_MEMORY
);
7339 ADD_INT(d
, DB_LOG_AUTO_REMOVE
);
7340 ADD_INT(d
, DB_LOG_ZERO
);
7344 ADD_INT(d
, DB_DSYNC_DB
);
7348 ADD_INT(d
, DB_TXN_SNAPSHOT
);
7351 ADD_INT(d
, DB_VERB_DEADLOCK
);
7353 ADD_INT(d
, DB_VERB_FILEOPS
);
7354 ADD_INT(d
, DB_VERB_FILEOPS_ALL
);
7356 ADD_INT(d
, DB_VERB_RECOVERY
);
7358 ADD_INT(d
, DB_VERB_REGISTER
);
7360 ADD_INT(d
, DB_VERB_REPLICATION
);
7361 ADD_INT(d
, DB_VERB_WAITSFOR
);
7364 ADD_INT(d
, DB_EVENT_PANIC
);
7365 ADD_INT(d
, DB_EVENT_REP_CLIENT
);
7367 ADD_INT(d
, DB_EVENT_REP_ELECTED
);
7369 ADD_INT(d
, DB_EVENT_REP_MASTER
);
7370 ADD_INT(d
, DB_EVENT_REP_NEWMASTER
);
7372 ADD_INT(d
, DB_EVENT_REP_PERM_FAILED
);
7374 ADD_INT(d
, DB_EVENT_REP_STARTUPDONE
);
7375 ADD_INT(d
, DB_EVENT_WRITE_FAILED
);
7378 ADD_INT(d
, DB_REP_DUPMASTER
);
7379 ADD_INT(d
, DB_REP_HOLDELECTION
);
7381 ADD_INT(d
, DB_REP_IGNORE
);
7382 ADD_INT(d
, DB_REP_JOIN_FAILURE
);
7385 ADD_INT(d
, DB_REP_ISPERM
);
7386 ADD_INT(d
, DB_REP_NOTPERM
);
7388 ADD_INT(d
, DB_REP_NEWSITE
);
7390 ADD_INT(d
, DB_REP_MASTER
);
7391 ADD_INT(d
, DB_REP_CLIENT
);
7393 ADD_INT(d
, DB_REP_ELECTION
);
7395 ADD_INT(d
, DB_REP_ACK_TIMEOUT
);
7396 ADD_INT(d
, DB_REP_CONNECTION_RETRY
);
7397 ADD_INT(d
, DB_REP_ELECTION_TIMEOUT
);
7398 ADD_INT(d
, DB_REP_ELECTION_RETRY
);
7401 ADD_INT(d
, DB_REP_CHECKPOINT_DELAY
);
7402 ADD_INT(d
, DB_REP_FULL_ELECTION_TIMEOUT
);
7406 ADD_INT(d
, DB_REPMGR_PEER
);
7407 ADD_INT(d
, DB_REPMGR_ACKS_ALL
);
7408 ADD_INT(d
, DB_REPMGR_ACKS_ALL_PEERS
);
7409 ADD_INT(d
, DB_REPMGR_ACKS_NONE
);
7410 ADD_INT(d
, DB_REPMGR_ACKS_ONE
);
7411 ADD_INT(d
, DB_REPMGR_ACKS_ONE_PEER
);
7412 ADD_INT(d
, DB_REPMGR_ACKS_QUORUM
);
7413 ADD_INT(d
, DB_REPMGR_CONNECTED
);
7414 ADD_INT(d
, DB_REPMGR_DISCONNECTED
);
7415 ADD_INT(d
, DB_STAT_CLEAR
);
7416 ADD_INT(d
, DB_STAT_ALL
);
7420 ADD_INT(d
, DB_BUFFER_SMALL
);
7421 ADD_INT(d
, DB_SEQ_DEC
);
7422 ADD_INT(d
, DB_SEQ_INC
);
7423 ADD_INT(d
, DB_SEQ_WRAP
);
7426 #if (DBVER >= 43) && (DBVER < 47)
7427 ADD_INT(d
, DB_LOG_INMEMORY
);
7428 ADD_INT(d
, DB_DSYNC_LOG
);
7432 ADD_INT(d
, DB_ENCRYPT_AES
);
7433 ADD_INT(d
, DB_AUTO_COMMIT
);
7435 /* allow Berkeley DB 4.1 aware apps to run on older versions */
7436 _addIntToDict(d
, "DB_AUTO_COMMIT", 0);
7449 ADD_INT(d
, DB_SET_LOCK_TIMEOUT
);
7450 ADD_INT(d
, DB_SET_TXN_TIMEOUT
);
7452 /* The exception name must be correct for pickled exception *
7453 * objects to unpickle properly. */
7454 #ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
7455 #define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
7457 #define PYBSDDB_EXCEPTION_BASE "bsddb.db."
7460 /* All the rest of the exceptions derive only from DBError */
7461 #define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
7462 PyDict_SetItemString(d, #name, name)
7464 /* The base exception class is DBError */
7465 DBError
= NULL
; /* used in MAKE_EX so that it derives from nothing */
7468 #if (PY_VERSION_HEX < 0x03000000)
7469 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
7470 * from both DBError and KeyError, since the API only supports
7471 * using one base class. */
7472 PyDict_SetItemString(d
, "KeyError", PyExc_KeyError
);
7473 PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
7474 "class DBKeyEmptyError(DBError, KeyError): pass",
7475 Py_file_input
, d
, d
);
7476 DBNotFoundError
= PyDict_GetItemString(d
, "DBNotFoundError");
7477 DBKeyEmptyError
= PyDict_GetItemString(d
, "DBKeyEmptyError");
7478 PyDict_DelItemString(d
, "KeyError");
7480 /* Since Python 2.5, PyErr_NewException() accepts a tuple, to be able to
7481 ** derive from several classes. We use this new API only for Python 3.0,
7487 bases
= PyTuple_Pack(2, DBError
, PyExc_KeyError
);
7489 #define MAKE_EX2(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, bases, NULL); \
7490 PyDict_SetItemString(d, #name, name)
7491 MAKE_EX2(DBNotFoundError
);
7492 MAKE_EX2(DBKeyEmptyError
);
7501 #if !INCOMPLETE_IS_WARNING
7502 MAKE_EX(DBIncompleteError
);
7504 MAKE_EX(DBCursorClosedError
);
7505 MAKE_EX(DBKeyEmptyError
);
7506 MAKE_EX(DBKeyExistError
);
7507 MAKE_EX(DBLockDeadlockError
);
7508 MAKE_EX(DBLockNotGrantedError
);
7509 MAKE_EX(DBOldVersionError
);
7510 MAKE_EX(DBRunRecoveryError
);
7511 MAKE_EX(DBVerifyBadError
);
7512 MAKE_EX(DBNoServerError
);
7513 MAKE_EX(DBNoServerHomeError
);
7514 MAKE_EX(DBNoServerIDError
);
7515 MAKE_EX(DBPageNotFoundError
);
7516 MAKE_EX(DBSecondaryBadError
);
7518 MAKE_EX(DBInvalidArgError
);
7519 MAKE_EX(DBAccessError
);
7520 MAKE_EX(DBNoSpaceError
);
7521 MAKE_EX(DBNoMemoryError
);
7522 MAKE_EX(DBAgainError
);
7523 MAKE_EX(DBBusyError
);
7524 MAKE_EX(DBFileExistsError
);
7525 MAKE_EX(DBNoSuchFileError
);
7526 MAKE_EX(DBPermissionsError
);
7529 MAKE_EX(DBRepHandleDeadError
);
7532 MAKE_EX(DBRepUnavailError
);
7536 /* Initiliase the C API structure and add it to the module */
7537 bsddb_api
.db_type
= &DB_Type
;
7538 bsddb_api
.dbcursor_type
= &DBCursor_Type
;
7539 bsddb_api
.dbenv_type
= &DBEnv_Type
;
7540 bsddb_api
.dbtxn_type
= &DBTxn_Type
;
7541 bsddb_api
.dblock_type
= &DBLock_Type
;
7543 bsddb_api
.dbsequence_type
= &DBSequence_Type
;
7545 bsddb_api
.makeDBError
= makeDBError
;
7547 py_api
= PyCObject_FromVoidPtr((void*)&bsddb_api
, NULL
);
7548 PyDict_SetItemString(d
, "api", py_api
);
7551 /* Check for errors */
7552 if (PyErr_Occurred()) {
7554 Py_FatalError("can't initialize module _bsddb/_pybsddb");
7558 #if (PY_VERSION_HEX < 0x03000000)
7565 /* allow this module to be named _pybsddb so that it can be installed
7566 * and imported on top of python >= 2.3 that includes its own older
7567 * copy of the library named _bsddb without importing the old version. */
7568 #if (PY_VERSION_HEX < 0x03000000)
7569 DL_EXPORT(void) init_pybsddb(void)
7571 PyMODINIT_FUNC
PyInit__pybsddb(void) /* Note the two underscores */
7574 strncpy(_bsddbModuleName
, "_pybsddb", MODULE_NAME_MAX_LEN
);
7575 #if (PY_VERSION_HEX < 0x03000000)
7578 return PyInit__bsddb(); /* Note the two underscores */