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)
76 * More datatypes added:
78 * DBLogCursor (Log Cursor)
82 /* --------------------------------------------------------------------- */
85 * Portions of this module, associated unit tests and build scripts are the
86 * result of a contract with The Written Word (http://thewrittenword.com/)
87 * Many thanks go out to them for causing me to raise the bar on quality and
88 * functionality, resulting in a better bsddb3 package for all of us to use.
93 /* --------------------------------------------------------------------- */
95 #include <stddef.h> /* for offsetof() */
98 #define COMPILING_BSDDB_C
100 #undef COMPILING_BSDDB_C
102 static char *rcs_id
= "$Id$";
104 /* --------------------------------------------------------------------- */
105 /* Various macro definitions */
107 #if (PY_VERSION_HEX < 0x02050000)
108 typedef int Py_ssize_t
;
111 #if (PY_VERSION_HEX < 0x02060000) /* really: before python trunk r63675 */
112 /* This code now uses PyBytes* API function names instead of PyString*.
113 * These #defines map to their equivalent on earlier python versions. */
114 #define PyBytes_FromStringAndSize PyString_FromStringAndSize
115 #define PyBytes_FromString PyString_FromString
116 #define PyBytes_AsStringAndSize PyString_AsStringAndSize
117 #define PyBytes_Check PyString_Check
118 #define PyBytes_GET_SIZE PyString_GET_SIZE
119 #define PyBytes_AS_STRING PyString_AS_STRING
122 #if (PY_VERSION_HEX >= 0x03000000)
123 #define NUMBER_Check PyLong_Check
124 #define NUMBER_AsLong PyLong_AsLong
125 #define NUMBER_FromLong PyLong_FromLong
127 #define NUMBER_Check PyInt_Check
128 #define NUMBER_AsLong PyInt_AsLong
129 #define NUMBER_FromLong PyInt_FromLong
134 /* These are for when calling Python --> C */
135 #define MYDB_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS;
136 #define MYDB_END_ALLOW_THREADS Py_END_ALLOW_THREADS;
138 /* For 2.3, use the PyGILState_ calls */
139 #if (PY_VERSION_HEX >= 0x02030000)
140 #define MYDB_USE_GILSTATE
143 /* and these are for calling C --> Python */
144 #if defined(MYDB_USE_GILSTATE)
145 #define MYDB_BEGIN_BLOCK_THREADS \
146 PyGILState_STATE __savestate = PyGILState_Ensure();
147 #define MYDB_END_BLOCK_THREADS \
148 PyGILState_Release(__savestate);
149 #else /* MYDB_USE_GILSTATE */
150 /* Pre GILState API - do it the long old way */
151 static PyInterpreterState
* _db_interpreterState
= NULL
;
152 #define MYDB_BEGIN_BLOCK_THREADS { \
153 PyThreadState* prevState; \
154 PyThreadState* newState; \
155 PyEval_AcquireLock(); \
156 newState = PyThreadState_New(_db_interpreterState); \
157 prevState = PyThreadState_Swap(newState);
159 #define MYDB_END_BLOCK_THREADS \
160 newState = PyThreadState_Swap(prevState); \
161 PyThreadState_Clear(newState); \
162 PyEval_ReleaseLock(); \
163 PyThreadState_Delete(newState); \
165 #endif /* MYDB_USE_GILSTATE */
168 /* Compiled without threads - avoid all this cruft */
169 #define MYDB_BEGIN_ALLOW_THREADS
170 #define MYDB_END_ALLOW_THREADS
171 #define MYDB_BEGIN_BLOCK_THREADS
172 #define MYDB_END_BLOCK_THREADS
176 /* --------------------------------------------------------------------- */
179 static PyObject
* DBError
; /* Base class, all others derive from this */
180 static PyObject
* DBCursorClosedError
; /* raised when trying to use a closed cursor object */
181 static PyObject
* DBKeyEmptyError
; /* DB_KEYEMPTY: also derives from KeyError */
182 static PyObject
* DBKeyExistError
; /* DB_KEYEXIST */
183 static PyObject
* DBLockDeadlockError
; /* DB_LOCK_DEADLOCK */
184 static PyObject
* DBLockNotGrantedError
; /* DB_LOCK_NOTGRANTED */
185 static PyObject
* DBNotFoundError
; /* DB_NOTFOUND: also derives from KeyError */
186 static PyObject
* DBOldVersionError
; /* DB_OLD_VERSION */
187 static PyObject
* DBRunRecoveryError
; /* DB_RUNRECOVERY */
188 static PyObject
* DBVerifyBadError
; /* DB_VERIFY_BAD */
189 static PyObject
* DBNoServerError
; /* DB_NOSERVER */
190 static PyObject
* DBNoServerHomeError
; /* DB_NOSERVER_HOME */
191 static PyObject
* DBNoServerIDError
; /* DB_NOSERVER_ID */
192 static PyObject
* DBPageNotFoundError
; /* DB_PAGE_NOTFOUND */
193 static PyObject
* DBSecondaryBadError
; /* DB_SECONDARY_BAD */
195 static PyObject
* DBInvalidArgError
; /* EINVAL */
196 static PyObject
* DBAccessError
; /* EACCES */
197 static PyObject
* DBNoSpaceError
; /* ENOSPC */
198 static PyObject
* DBNoMemoryError
; /* DB_BUFFER_SMALL (ENOMEM when < 4.3) */
199 static PyObject
* DBAgainError
; /* EAGAIN */
200 static PyObject
* DBBusyError
; /* EBUSY */
201 static PyObject
* DBFileExistsError
; /* EEXIST */
202 static PyObject
* DBNoSuchFileError
; /* ENOENT */
203 static PyObject
* DBPermissionsError
; /* EPERM */
206 static PyObject
* DBRepHandleDeadError
; /* DB_REP_HANDLE_DEAD */
209 static PyObject
* DBRepLockoutError
; /* DB_REP_LOCKOUT */
213 static PyObject
* DBRepLeaseExpiredError
; /* DB_REP_LEASE_EXPIRED */
217 static PyObject
* DBForeignConflictError
; /* DB_FOREIGN_CONFLICT */
221 static PyObject
* DBRepUnavailError
; /* DB_REP_UNAVAIL */
224 #define DB_BUFFER_SMALL ENOMEM
228 #define DB_GID_SIZE DB_XIDDATASIZE
232 /* --------------------------------------------------------------------- */
233 /* Structure definitions */
235 #if PYTHON_API_VERSION < 1010
236 #error "Python 2.1 or later required"
240 /* Defaults for moduleFlags in DBEnvObject and DBObject. */
241 #define DEFAULT_GET_RETURNS_NONE 1
242 #define DEFAULT_CURSOR_SET_RETURNS_NONE 1 /* 0 in pybsddb < 4.2, python < 2.4 */
245 /* See comment in Python 2.6 "object.h" */
246 #ifndef staticforward
247 #define staticforward static
250 #define statichere static
253 staticforward PyTypeObject DB_Type
, DBCursor_Type
, DBEnv_Type
, DBTxn_Type
,
254 DBLock_Type
, DBLogCursor_Type
;
256 staticforward PyTypeObject DBSequence_Type
;
260 /* for compatibility with Python 2.5 and earlier */
261 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
264 #define DBObject_Check(v) (Py_TYPE(v) == &DB_Type)
265 #define DBCursorObject_Check(v) (Py_TYPE(v) == &DBCursor_Type)
266 #define DBLogCursorObject_Check(v) (Py_TYPE(v) == &DBLogCursor_Type)
267 #define DBEnvObject_Check(v) (Py_TYPE(v) == &DBEnv_Type)
268 #define DBTxnObject_Check(v) (Py_TYPE(v) == &DBTxn_Type)
269 #define DBLockObject_Check(v) (Py_TYPE(v) == &DBLock_Type)
271 #define DBSequenceObject_Check(v) (Py_TYPE(v) == &DBSequence_Type)
275 #define _DBC_close(dbc) dbc->c_close(dbc)
276 #define _DBC_count(dbc,a,b) dbc->c_count(dbc,a,b)
277 #define _DBC_del(dbc,a) dbc->c_del(dbc,a)
278 #define _DBC_dup(dbc,a,b) dbc->c_dup(dbc,a,b)
279 #define _DBC_get(dbc,a,b,c) dbc->c_get(dbc,a,b,c)
280 #define _DBC_pget(dbc,a,b,c,d) dbc->c_pget(dbc,a,b,c,d)
281 #define _DBC_put(dbc,a,b,c) dbc->c_put(dbc,a,b,c)
283 #define _DBC_close(dbc) dbc->close(dbc)
284 #define _DBC_count(dbc,a,b) dbc->count(dbc,a,b)
285 #define _DBC_del(dbc,a) dbc->del(dbc,a)
286 #define _DBC_dup(dbc,a,b) dbc->dup(dbc,a,b)
287 #define _DBC_get(dbc,a,b,c) dbc->get(dbc,a,b,c)
288 #define _DBC_pget(dbc,a,b,c,d) dbc->pget(dbc,a,b,c,d)
289 #define _DBC_put(dbc,a,b,c) dbc->put(dbc,a,b,c)
293 /* --------------------------------------------------------------------- */
294 /* Utility macros and functions */
296 #define INSERT_IN_DOUBLE_LINKED_LIST(backlink,object) \
298 object->sibling_next=backlink; \
299 object->sibling_prev_p=&(backlink); \
301 if (object->sibling_next) { \
302 object->sibling_next->sibling_prev_p=&(object->sibling_next); \
306 #define EXTRACT_FROM_DOUBLE_LINKED_LIST(object) \
308 if (object->sibling_next) { \
309 object->sibling_next->sibling_prev_p=object->sibling_prev_p; \
311 *(object->sibling_prev_p)=object->sibling_next; \
314 #define EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(object) \
316 if (object->sibling_next) { \
317 object->sibling_next->sibling_prev_p=object->sibling_prev_p; \
319 if (object->sibling_prev_p) { \
320 *(object->sibling_prev_p)=object->sibling_next; \
324 #define INSERT_IN_DOUBLE_LINKED_LIST_TXN(backlink,object) \
326 object->sibling_next_txn=backlink; \
327 object->sibling_prev_p_txn=&(backlink); \
329 if (object->sibling_next_txn) { \
330 object->sibling_next_txn->sibling_prev_p_txn= \
331 &(object->sibling_next_txn); \
335 #define EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(object) \
337 if (object->sibling_next_txn) { \
338 object->sibling_next_txn->sibling_prev_p_txn= \
339 object->sibling_prev_p_txn; \
341 *(object->sibling_prev_p_txn)=object->sibling_next_txn; \
345 #define RETURN_IF_ERR() \
346 if (makeDBError(err)) { \
350 #define RETURN_NONE() Py_INCREF(Py_None); return Py_None;
352 #define _CHECK_OBJECT_NOT_CLOSED(nonNull, pyErrObj, name) \
353 if ((nonNull) == NULL) { \
354 PyObject *errTuple = NULL; \
355 errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
357 PyErr_SetObject((pyErrObj), errTuple); \
358 Py_DECREF(errTuple); \
363 #define CHECK_DB_NOT_CLOSED(dbobj) \
364 _CHECK_OBJECT_NOT_CLOSED(dbobj->db, DBError, DB)
366 #define CHECK_ENV_NOT_CLOSED(env) \
367 _CHECK_OBJECT_NOT_CLOSED(env->db_env, DBError, DBEnv)
369 #define CHECK_CURSOR_NOT_CLOSED(curs) \
370 _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)
372 #define CHECK_LOGCURSOR_NOT_CLOSED(logcurs) \
373 _CHECK_OBJECT_NOT_CLOSED(logcurs->logc, DBCursorClosedError, DBLogCursor)
376 #define CHECK_SEQUENCE_NOT_CLOSED(curs) \
377 _CHECK_OBJECT_NOT_CLOSED(curs->sequence, DBError, DBSequence)
380 #define CHECK_DBFLAG(mydb, flag) (((mydb)->flags & (flag)) || \
381 (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))
383 #define CLEAR_DBT(dbt) (memset(&(dbt), 0, sizeof(dbt)))
385 #define FREE_DBT(dbt) if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
386 dbt.data != NULL) { free(dbt.data); dbt.data = NULL; }
389 static int makeDBError(int err
);
392 /* Return the access method type of the DBObject */
393 static int _DB_get_type(DBObject
* self
)
398 err
= self
->db
->get_type(self
->db
, &type
);
399 if (makeDBError(err
)) {
406 /* Create a DBT structure (containing key and data values) from Python
407 strings. Returns 1 on success, 0 on an error. */
408 static int make_dbt(PyObject
* obj
, DBT
* dbt
)
411 if (obj
== Py_None
) {
412 /* no need to do anything, the structure has already been zeroed */
414 else if (!PyArg_Parse(obj
, "s#", &dbt
->data
, &dbt
->size
)) {
415 PyErr_SetString(PyExc_TypeError
,
416 #if (PY_VERSION_HEX < 0x03000000)
417 "Data values must be of type string or None.");
419 "Data values must be of type bytes or None.");
427 /* Recno and Queue DBs can have integer keys. This function figures out
428 what's been given, verifies that it's allowed, and then makes the DBT.
430 Caller MUST call FREE_DBT(key) when done. */
432 make_key_dbt(DBObject
* self
, PyObject
* keyobj
, DBT
* key
, int* pflags
)
438 if (keyobj
== Py_None
) {
439 type
= _DB_get_type(self
);
442 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
445 "None keys not allowed for Recno and Queue DB's");
448 /* no need to do anything, the structure has already been zeroed */
451 else if (PyBytes_Check(keyobj
)) {
452 /* verify access method type */
453 type
= _DB_get_type(self
);
456 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
459 #if (PY_VERSION_HEX < 0x03000000)
460 "String keys not allowed for Recno and Queue DB's");
462 "Bytes keys not allowed for Recno and Queue DB's");
468 * NOTE(gps): I don't like doing a data copy here, it seems
469 * wasteful. But without a clean way to tell FREE_DBT if it
470 * should free key->data or not we have to. Other places in
471 * the code check for DB_THREAD and forceably set DBT_MALLOC
472 * when we otherwise would leave flags 0 to indicate that.
474 key
->data
= malloc(PyBytes_GET_SIZE(keyobj
));
475 if (key
->data
== NULL
) {
476 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
479 memcpy(key
->data
, PyBytes_AS_STRING(keyobj
),
480 PyBytes_GET_SIZE(keyobj
));
481 key
->flags
= DB_DBT_REALLOC
;
482 key
->size
= PyBytes_GET_SIZE(keyobj
);
485 else if (NUMBER_Check(keyobj
)) {
486 /* verify access method type */
487 type
= _DB_get_type(self
);
490 if (type
== DB_BTREE
&& pflags
!= NULL
) {
491 /* if BTREE then an Integer key is allowed with the
492 * DB_SET_RECNO flag */
493 *pflags
|= DB_SET_RECNO
;
495 else if (type
!= DB_RECNO
&& type
!= DB_QUEUE
) {
498 "Integer keys only allowed for Recno and Queue DB's");
502 /* Make a key out of the requested recno, use allocated space so DB
503 * will be able to realloc room for the real key if needed. */
504 recno
= NUMBER_AsLong(keyobj
);
505 key
->data
= malloc(sizeof(db_recno_t
));
506 if (key
->data
== NULL
) {
507 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
510 key
->ulen
= key
->size
= sizeof(db_recno_t
);
511 memcpy(key
->data
, &recno
, sizeof(db_recno_t
));
512 key
->flags
= DB_DBT_REALLOC
;
515 PyErr_Format(PyExc_TypeError
,
516 #if (PY_VERSION_HEX < 0x03000000)
517 "String or Integer object expected for key, %s found",
519 "Bytes or Integer object expected for key, %s found",
521 Py_TYPE(keyobj
)->tp_name
);
529 /* Add partial record access to an existing DBT data struct.
530 If dlen and doff are set, then the DB_DBT_PARTIAL flag will be set
531 and the data storage/retrieval will be done using dlen and doff. */
532 static int add_partial_dbt(DBT
* d
, int dlen
, int doff
) {
533 /* if neither were set we do nothing (-1 is the default value) */
534 if ((dlen
== -1) && (doff
== -1)) {
538 if ((dlen
< 0) || (doff
< 0)) {
539 PyErr_SetString(PyExc_TypeError
, "dlen and doff must both be >= 0");
543 d
->flags
= d
->flags
| DB_DBT_PARTIAL
;
544 d
->dlen
= (unsigned int) dlen
;
545 d
->doff
= (unsigned int) doff
;
549 /* a safe strcpy() without the zeroing behaviour and semantics of strncpy. */
550 /* TODO: make this use the native libc strlcpy() when available (BSD) */
551 unsigned int our_strlcpy(char* dest
, const char* src
, unsigned int n
)
553 unsigned int srclen
, copylen
;
555 srclen
= strlen(src
);
558 copylen
= (srclen
> n
-1) ? n
-1 : srclen
;
559 /* populate dest[0] thru dest[copylen-1] */
560 memcpy(dest
, src
, copylen
);
561 /* guarantee null termination */
567 /* Callback used to save away more information about errors from the DB
569 static char _db_errmsg
[1024];
571 static void _db_errorCallback(const char* prefix
, char* msg
)
573 static void _db_errorCallback(const DB_ENV
*db_env
,
574 const char* prefix
, const char* msg
)
577 our_strlcpy(_db_errmsg
, msg
, sizeof(_db_errmsg
));
582 ** We need these functions because some results
583 ** are undefined if pointer is NULL. Some other
584 ** give None instead of "".
586 ** This functions are static and will be
589 static const char *DummyString
= "This string is a simple placeholder";
590 static PyObject
*Build_PyString(const char *p
,int s
)
596 return PyBytes_FromStringAndSize(p
,s
);
599 static PyObject
*BuildValue_S(const void *p
,int s
)
605 return PyBytes_FromStringAndSize(p
, s
);
608 static PyObject
*BuildValue_SS(const void *p1
,int s1
,const void *p2
,int s2
)
621 if (!(a
= PyBytes_FromStringAndSize(p1
, s1
))) {
624 if (!(b
= PyBytes_FromStringAndSize(p2
, s2
))) {
629 #if (PY_VERSION_HEX >= 0x02040000)
630 r
= PyTuple_Pack(2, a
, b
) ;
632 r
= Py_BuildValue("OO", a
, b
);
639 static PyObject
*BuildValue_IS(int i
,const void *p
,int s
)
648 if (!(a
= PyBytes_FromStringAndSize(p
, s
))) {
652 r
= Py_BuildValue("iO", i
, a
);
657 static PyObject
*BuildValue_LS(long l
,const void *p
,int s
)
666 if (!(a
= PyBytes_FromStringAndSize(p
, s
))) {
670 r
= Py_BuildValue("lO", l
, a
);
677 /* make a nice exception object to raise for errors. */
678 static int makeDBError(int err
)
680 char errTxt
[2048]; /* really big, just in case... */
681 PyObject
*errObj
= NULL
;
682 PyObject
*errTuple
= NULL
;
683 int exceptionRaised
= 0;
684 unsigned int bytes_left
;
687 case 0: /* successful, no error */
690 case DB_KEYEMPTY
: errObj
= DBKeyEmptyError
; break;
691 case DB_KEYEXIST
: errObj
= DBKeyExistError
; break;
692 case DB_LOCK_DEADLOCK
: errObj
= DBLockDeadlockError
; break;
693 case DB_LOCK_NOTGRANTED
: errObj
= DBLockNotGrantedError
; break;
694 case DB_NOTFOUND
: errObj
= DBNotFoundError
; break;
695 case DB_OLD_VERSION
: errObj
= DBOldVersionError
; break;
696 case DB_RUNRECOVERY
: errObj
= DBRunRecoveryError
; break;
697 case DB_VERIFY_BAD
: errObj
= DBVerifyBadError
; break;
698 case DB_NOSERVER
: errObj
= DBNoServerError
; break;
699 case DB_NOSERVER_HOME
: errObj
= DBNoServerHomeError
; break;
700 case DB_NOSERVER_ID
: errObj
= DBNoServerIDError
; break;
701 case DB_PAGE_NOTFOUND
: errObj
= DBPageNotFoundError
; break;
702 case DB_SECONDARY_BAD
: errObj
= DBSecondaryBadError
; break;
703 case DB_BUFFER_SMALL
: errObj
= DBNoMemoryError
; break;
706 /* ENOMEM and DB_BUFFER_SMALL were one and the same until 4.3 */
707 case ENOMEM
: errObj
= PyExc_MemoryError
; break;
709 case EINVAL
: errObj
= DBInvalidArgError
; break;
710 case EACCES
: errObj
= DBAccessError
; break;
711 case ENOSPC
: errObj
= DBNoSpaceError
; break;
712 case EAGAIN
: errObj
= DBAgainError
; break;
713 case EBUSY
: errObj
= DBBusyError
; break;
714 case EEXIST
: errObj
= DBFileExistsError
; break;
715 case ENOENT
: errObj
= DBNoSuchFileError
; break;
716 case EPERM
: errObj
= DBPermissionsError
; break;
719 case DB_REP_HANDLE_DEAD
: errObj
= DBRepHandleDeadError
; break;
722 case DB_REP_LOCKOUT
: errObj
= DBRepLockoutError
; break;
726 case DB_REP_LEASE_EXPIRED
: errObj
= DBRepLeaseExpiredError
; break;
730 case DB_FOREIGN_CONFLICT
: errObj
= DBForeignConflictError
; break;
733 case DB_REP_UNAVAIL
: errObj
= DBRepUnavailError
; break;
735 default: errObj
= DBError
; break;
738 if (errObj
!= NULL
) {
739 bytes_left
= our_strlcpy(errTxt
, db_strerror(err
), sizeof(errTxt
));
740 /* Ensure that bytes_left never goes negative */
741 if (_db_errmsg
[0] && bytes_left
< (sizeof(errTxt
) - 4)) {
742 bytes_left
= sizeof(errTxt
) - bytes_left
- 4 - 1;
743 assert(bytes_left
>= 0);
744 strcat(errTxt
, " -- ");
745 strncat(errTxt
, _db_errmsg
, bytes_left
);
749 errTuple
= Py_BuildValue("(is)", err
, errTxt
);
750 if (errTuple
== NULL
) {
754 PyErr_SetObject(errObj
, errTuple
);
758 return ((errObj
!= NULL
) || exceptionRaised
);
763 /* set a type exception */
764 static void makeTypeError(char* expected
, PyObject
* found
)
766 PyErr_Format(PyExc_TypeError
, "Expected %s argument, %s found.",
767 expected
, Py_TYPE(found
)->tp_name
);
771 /* verify that an obj is either None or a DBTxn, and set the txn pointer */
772 static int checkTxnObj(PyObject
* txnobj
, DB_TXN
** txn
)
774 if (txnobj
== Py_None
|| txnobj
== NULL
) {
778 if (DBTxnObject_Check(txnobj
)) {
779 *txn
= ((DBTxnObject
*)txnobj
)->txn
;
783 makeTypeError("DBTxn", txnobj
);
788 /* Delete a key from a database
789 Returns 0 on success, -1 on an error. */
790 static int _DB_delete(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, int flags
)
794 MYDB_BEGIN_ALLOW_THREADS
;
795 err
= self
->db
->del(self
->db
, txn
, key
, 0);
796 MYDB_END_ALLOW_THREADS
;
797 if (makeDBError(err
)) {
804 /* Store a key into a database
805 Returns 0 on success, -1 on an error. */
806 static int _DB_put(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, DBT
*data
, int flags
)
810 MYDB_BEGIN_ALLOW_THREADS
;
811 err
= self
->db
->put(self
->db
, txn
, key
, data
, flags
);
812 MYDB_END_ALLOW_THREADS
;
813 if (makeDBError(err
)) {
819 /* Get a key/data pair from a cursor */
820 static PyObject
* _DBCursor_get(DBCursorObject
* self
, int extra_flags
,
821 PyObject
*args
, PyObject
*kwargs
, char *format
)
824 PyObject
* retval
= NULL
;
829 static char* kwnames
[] = { "flags", "dlen", "doff", NULL
};
831 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, format
, kwnames
,
832 &flags
, &dlen
, &doff
))
835 CHECK_CURSOR_NOT_CLOSED(self
);
837 flags
|= extra_flags
;
840 if (!add_partial_dbt(&data
, dlen
, doff
))
843 MYDB_BEGIN_ALLOW_THREADS
;
844 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
);
845 MYDB_END_ALLOW_THREADS
;
847 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
848 && self
->mydb
->moduleFlags
.getReturnsNone
) {
852 else if (makeDBError(err
)) {
855 else { /* otherwise, success! */
857 /* if Recno or Queue, return the key as an Int */
858 switch (_DB_get_type(self
->mydb
)) {
865 retval
= BuildValue_IS(*((db_recno_t
*)key
.data
), data
.data
, data
.size
);
870 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
878 /* add an integer to a dictionary using the given name as a key */
879 static void _addIntToDict(PyObject
* dict
, char *name
, int value
)
881 PyObject
* v
= NUMBER_FromLong((long) value
);
882 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
888 /* The same, when the value is a time_t */
889 static void _addTimeTToDict(PyObject
* dict
, char *name
, time_t value
)
892 /* if the value fits in regular int, use that. */
894 if (sizeof(time_t) > sizeof(long))
895 v
= PyLong_FromLongLong((PY_LONG_LONG
) value
);
898 v
= NUMBER_FromLong((long) value
);
899 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
906 /* add an db_seq_t to a dictionary using the given name as a key */
907 static void _addDb_seq_tToDict(PyObject
* dict
, char *name
, db_seq_t value
)
909 PyObject
* v
= PyLong_FromLongLong(value
);
910 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
917 static void _addDB_lsnToDict(PyObject
* dict
, char *name
, DB_LSN value
)
919 PyObject
*v
= Py_BuildValue("(ll)",value
.file
,value
.offset
);
920 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
926 /* --------------------------------------------------------------------- */
927 /* Allocators and deallocators */
930 newDBObject(DBEnvObject
* arg
, int flags
)
933 DB_ENV
* db_env
= NULL
;
936 self
= PyObject_New(DBObject
, &DB_Type
);
942 self
->myenvobj
= NULL
;
944 self
->children_cursors
= NULL
;
946 self
->children_sequences
= NULL
;
948 self
->associateCallback
= NULL
;
949 self
->btCompareCallback
= NULL
;
950 self
->primaryDBType
= 0;
952 self
->private_obj
= Py_None
;
953 self
->in_weakreflist
= NULL
;
955 /* keep a reference to our python DBEnv object */
958 self
->myenvobj
= arg
;
959 db_env
= arg
->db_env
;
960 INSERT_IN_DOUBLE_LINKED_LIST(self
->myenvobj
->children_dbs
,self
);
962 self
->sibling_prev_p
=NULL
;
963 self
->sibling_next
=NULL
;
966 self
->sibling_prev_p_txn
=NULL
;
967 self
->sibling_next_txn
=NULL
;
970 self
->moduleFlags
= self
->myenvobj
->moduleFlags
;
972 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
973 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
975 MYDB_BEGIN_ALLOW_THREADS
;
976 err
= db_create(&self
->db
, db_env
, flags
);
977 if (self
->db
!= NULL
) {
978 self
->db
->set_errcall(self
->db
, _db_errorCallback
);
979 self
->db
->app_private
= (void*)self
;
981 MYDB_END_ALLOW_THREADS
;
982 /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
983 * list so that a DBEnv can refuse to close without aborting any open
984 * DBTxns and closing any open DBs first. */
985 if (makeDBError(err
)) {
986 if (self
->myenvobj
) {
987 Py_DECREF(self
->myenvobj
);
988 self
->myenvobj
= NULL
;
997 /* Forward declaration */
998 static PyObject
*DB_close_internal(DBObject
* self
, int flags
, int do_not_close
);
1001 DB_dealloc(DBObject
* self
)
1005 if (self
->db
!= NULL
) {
1006 dummy
=DB_close_internal(self
, 0, 0);
1008 ** Raising exceptions while doing
1009 ** garbage collection is a fatal error.
1016 if (self
->in_weakreflist
!= NULL
) {
1017 PyObject_ClearWeakRefs((PyObject
*) self
);
1019 if (self
->myenvobj
) {
1020 Py_DECREF(self
->myenvobj
);
1021 self
->myenvobj
= NULL
;
1023 if (self
->associateCallback
!= NULL
) {
1024 Py_DECREF(self
->associateCallback
);
1025 self
->associateCallback
= NULL
;
1027 if (self
->btCompareCallback
!= NULL
) {
1028 Py_DECREF(self
->btCompareCallback
);
1029 self
->btCompareCallback
= NULL
;
1031 Py_DECREF(self
->private_obj
);
1035 static DBCursorObject
*
1036 newDBCursorObject(DBC
* dbc
, DBTxnObject
*txn
, DBObject
* db
)
1038 DBCursorObject
* self
= PyObject_New(DBCursorObject
, &DBCursor_Type
);
1045 INSERT_IN_DOUBLE_LINKED_LIST(self
->mydb
->children_cursors
,self
);
1046 if (txn
&& ((PyObject
*)txn
!=Py_None
)) {
1047 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn
->children_cursors
,self
);
1053 self
->in_weakreflist
= NULL
;
1054 Py_INCREF(self
->mydb
);
1059 /* Forward declaration */
1060 static PyObject
*DBC_close_internal(DBCursorObject
* self
);
1063 DBCursor_dealloc(DBCursorObject
* self
)
1067 if (self
->dbc
!= NULL
) {
1068 dummy
=DBC_close_internal(self
);
1070 ** Raising exceptions while doing
1071 ** garbage collection is a fatal error.
1078 if (self
->in_weakreflist
!= NULL
) {
1079 PyObject_ClearWeakRefs((PyObject
*) self
);
1081 Py_DECREF(self
->mydb
);
1086 static DBLogCursorObject
*
1087 newDBLogCursorObject(DB_LOGC
* dblogc
, DBEnvObject
* env
)
1089 DBLogCursorObject
* self
;
1091 self
= PyObject_New(DBLogCursorObject
, &DBLogCursor_Type
);
1096 self
->logc
= dblogc
;
1099 INSERT_IN_DOUBLE_LINKED_LIST(self
->env
->children_logcursors
, self
);
1101 self
->in_weakreflist
= NULL
;
1102 Py_INCREF(self
->env
);
1107 /* Forward declaration */
1108 static PyObject
*DBLogCursor_close_internal(DBLogCursorObject
* self
);
1111 DBLogCursor_dealloc(DBLogCursorObject
* self
)
1115 if (self
->logc
!= NULL
) {
1116 dummy
= DBLogCursor_close_internal(self
);
1118 ** Raising exceptions while doing
1119 ** garbage collection is a fatal error.
1126 if (self
->in_weakreflist
!= NULL
) {
1127 PyObject_ClearWeakRefs((PyObject
*) self
);
1129 Py_DECREF(self
->env
);
1135 newDBEnvObject(int flags
)
1138 DBEnvObject
* self
= PyObject_New(DBEnvObject
, &DBEnv_Type
);
1142 self
->db_env
= NULL
;
1144 self
->flags
= flags
;
1145 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
1146 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
1147 self
->children_dbs
= NULL
;
1148 self
->children_txns
= NULL
;
1149 self
->children_logcursors
= NULL
;
1151 self
->private_obj
= Py_None
;
1153 self
->rep_transport
= Py_None
;
1154 self
->in_weakreflist
= NULL
;
1155 self
->event_notifyCallback
= NULL
;
1157 MYDB_BEGIN_ALLOW_THREADS
;
1158 err
= db_env_create(&self
->db_env
, flags
);
1159 MYDB_END_ALLOW_THREADS
;
1160 if (makeDBError(err
)) {
1165 self
->db_env
->set_errcall(self
->db_env
, _db_errorCallback
);
1166 self
->db_env
->app_private
= self
;
1171 /* Forward declaration */
1172 static PyObject
*DBEnv_close_internal(DBEnvObject
* self
, int flags
);
1175 DBEnv_dealloc(DBEnvObject
* self
)
1180 dummy
=DBEnv_close_internal(self
, 0);
1182 ** Raising exceptions while doing
1183 ** garbage collection is a fatal error.
1191 Py_XDECREF(self
->event_notifyCallback
);
1192 self
->event_notifyCallback
= NULL
;
1194 if (self
->in_weakreflist
!= NULL
) {
1195 PyObject_ClearWeakRefs((PyObject
*) self
);
1197 Py_DECREF(self
->private_obj
);
1198 Py_DECREF(self
->rep_transport
);
1204 newDBTxnObject(DBEnvObject
* myenv
, DBTxnObject
*parent
, DB_TXN
*txn
, int flags
)
1207 DB_TXN
*parent_txn
= NULL
;
1209 DBTxnObject
* self
= PyObject_New(DBTxnObject
, &DBTxn_Type
);
1213 self
->in_weakreflist
= NULL
;
1214 self
->children_txns
= NULL
;
1215 self
->children_dbs
= NULL
;
1216 self
->children_cursors
= NULL
;
1217 self
->children_sequences
= NULL
;
1218 self
->flag_prepare
= 0;
1219 self
->parent_txn
= NULL
;
1221 /* We initialize just in case "txn_begin" fails */
1224 if (parent
&& ((PyObject
*)parent
!=Py_None
)) {
1225 parent_txn
= parent
->txn
;
1231 MYDB_BEGIN_ALLOW_THREADS
;
1232 err
= myenv
->db_env
->txn_begin(myenv
->db_env
, parent_txn
, &(self
->txn
), flags
);
1233 MYDB_END_ALLOW_THREADS
;
1235 if (makeDBError(err
)) {
1236 /* Free object half initialized */
1242 /* Can't use 'parent' because could be 'parent==Py_None' */
1244 self
->parent_txn
= parent
;
1247 INSERT_IN_DOUBLE_LINKED_LIST(parent
->children_txns
, self
);
1249 self
->parent_txn
= NULL
;
1252 INSERT_IN_DOUBLE_LINKED_LIST(myenv
->children_txns
, self
);
1258 /* Forward declaration */
1260 DBTxn_abort_discard_internal(DBTxnObject
* self
, int discard
);
1263 DBTxn_dealloc(DBTxnObject
* self
)
1268 int flag_prepare
= self
->flag_prepare
;
1270 dummy
=DBTxn_abort_discard_internal(self
, 0);
1272 ** Raising exceptions while doing
1273 ** garbage collection is a fatal error.
1280 if (!flag_prepare
) {
1281 PyErr_Warn(PyExc_RuntimeWarning
,
1282 "DBTxn aborted in destructor. No prior commit() or abort().");
1286 if (self
->in_weakreflist
!= NULL
) {
1287 PyObject_ClearWeakRefs((PyObject
*) self
);
1291 Py_DECREF(self
->env
);
1294 ** We can have "self->env==NULL" and "self->parent_txn==NULL"
1295 ** if something happens when creating the transaction object
1296 ** and we abort the object while half done.
1298 Py_XDECREF(self
->parent_txn
);
1304 static DBLockObject
*
1305 newDBLockObject(DBEnvObject
* myenv
, u_int32_t locker
, DBT
* obj
,
1306 db_lockmode_t lock_mode
, int flags
)
1309 DBLockObject
* self
= PyObject_New(DBLockObject
, &DBLock_Type
);
1312 self
->in_weakreflist
= NULL
;
1313 self
->lock_initialized
= 0; /* Just in case the call fails */
1315 MYDB_BEGIN_ALLOW_THREADS
;
1316 err
= myenv
->db_env
->lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
,
1318 MYDB_END_ALLOW_THREADS
;
1319 if (makeDBError(err
)) {
1323 self
->lock_initialized
= 1;
1331 DBLock_dealloc(DBLockObject
* self
)
1333 if (self
->in_weakreflist
!= NULL
) {
1334 PyObject_ClearWeakRefs((PyObject
*) self
);
1336 /* TODO: is this lock held? should we release it? */
1337 /* CAUTION: The lock can be not initialized if the creation has failed */
1344 static DBSequenceObject
*
1345 newDBSequenceObject(DBObject
* mydb
, int flags
)
1348 DBSequenceObject
* self
= PyObject_New(DBSequenceObject
, &DBSequence_Type
);
1354 INSERT_IN_DOUBLE_LINKED_LIST(self
->mydb
->children_sequences
,self
);
1357 self
->in_weakreflist
= NULL
;
1358 self
->sequence
= NULL
; /* Just in case the call fails */
1360 MYDB_BEGIN_ALLOW_THREADS
;
1361 err
= db_sequence_create(&self
->sequence
, self
->mydb
->db
, flags
);
1362 MYDB_END_ALLOW_THREADS
;
1363 if (makeDBError(err
)) {
1371 /* Forward declaration */
1373 *DBSequence_close_internal(DBSequenceObject
* self
, int flags
, int do_not_close
);
1376 DBSequence_dealloc(DBSequenceObject
* self
)
1380 if (self
->sequence
!= NULL
) {
1381 dummy
=DBSequence_close_internal(self
,0,0);
1383 ** Raising exceptions while doing
1384 ** garbage collection is a fatal error.
1392 if (self
->in_weakreflist
!= NULL
) {
1393 PyObject_ClearWeakRefs((PyObject
*) self
);
1396 Py_DECREF(self
->mydb
);
1401 /* --------------------------------------------------------------------- */
1405 DB_append(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1407 PyObject
* txnobj
= NULL
;
1412 static char* kwnames
[] = { "data", "txn", NULL
};
1414 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O:append", kwnames
,
1418 CHECK_DB_NOT_CLOSED(self
);
1420 /* make a dummy key out of a recno */
1424 key
.size
= sizeof(recno
);
1425 key
.ulen
= key
.size
;
1426 key
.flags
= DB_DBT_USERMEM
;
1428 if (!make_dbt(dataobj
, &data
)) return NULL
;
1429 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1431 if (-1 == _DB_put(self
, txn
, &key
, &data
, DB_APPEND
))
1434 return NUMBER_FromLong(recno
);
1439 _db_associateCallback(DB
* db
, const DBT
* priKey
, const DBT
* priData
,
1442 int retval
= DB_DONOTINDEX
;
1443 DBObject
* secondaryDB
= (DBObject
*)db
->app_private
;
1444 PyObject
* callback
= secondaryDB
->associateCallback
;
1445 int type
= secondaryDB
->primaryDBType
;
1447 PyObject
* result
= NULL
;
1450 if (callback
!= NULL
) {
1451 MYDB_BEGIN_BLOCK_THREADS
;
1453 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
1454 args
= BuildValue_LS(*((db_recno_t
*)priKey
->data
), priData
->data
, priData
->size
);
1456 args
= BuildValue_SS(priKey
->data
, priKey
->size
, priData
->data
, priData
->size
);
1458 result
= PyEval_CallObject(callback
, args
);
1460 if (args
== NULL
|| result
== NULL
) {
1463 else if (result
== Py_None
) {
1464 retval
= DB_DONOTINDEX
;
1466 else if (NUMBER_Check(result
)) {
1467 retval
= NUMBER_AsLong(result
);
1469 else if (PyBytes_Check(result
)) {
1474 PyBytes_AsStringAndSize(result
, &data
, &size
);
1475 secKey
->flags
= DB_DBT_APPMALLOC
; /* DB will free */
1476 secKey
->data
= malloc(size
); /* TODO, check this */
1478 memcpy(secKey
->data
, data
, size
);
1479 secKey
->size
= size
;
1483 PyErr_SetString(PyExc_MemoryError
,
1484 "malloc failed in _db_associateCallback");
1489 else if (PyList_Check(result
))
1496 listlen
= PyList_Size(result
);
1498 dbts
= (DBT
*)malloc(sizeof(DBT
) * listlen
);
1500 for (i
=0; i
<listlen
; i
++)
1502 if (!PyBytes_Check(PyList_GetItem(result
, i
)))
1506 #if (PY_VERSION_HEX < 0x03000000)
1507 "The list returned by DB->associate callback should be a list of strings.");
1509 "The list returned by DB->associate callback should be a list of bytes.");
1514 PyBytes_AsStringAndSize(
1515 PyList_GetItem(result
, i
),
1519 dbts
[i
].data
= malloc(size
); /* TODO, check this */
1523 memcpy(dbts
[i
].data
, data
, size
);
1524 dbts
[i
].size
= size
;
1525 dbts
[i
].ulen
= dbts
[i
].size
;
1526 dbts
[i
].flags
= DB_DBT_APPMALLOC
; /* DB will free */
1530 PyErr_SetString(PyExc_MemoryError
,
1531 "malloc failed in _db_associateCallback (list)");
1538 secKey
->data
= dbts
;
1539 secKey
->size
= listlen
;
1540 secKey
->flags
= DB_DBT_APPMALLOC
| DB_DBT_MULTIPLE
;
1547 #if (PY_VERSION_HEX < 0x03000000)
1548 "DB associate callback should return DB_DONOTINDEX/string/list of strings.");
1550 "DB associate callback should return DB_DONOTINDEX/bytes/list of bytes.");
1558 MYDB_END_BLOCK_THREADS
;
1565 DB_associate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1568 DBObject
* secondaryDB
;
1570 PyObject
*txnobj
= NULL
;
1572 static char* kwnames
[] = {"secondaryDB", "callback", "flags", "txn",
1575 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iO:associate", kwnames
,
1576 &secondaryDB
, &callback
, &flags
,
1581 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1583 CHECK_DB_NOT_CLOSED(self
);
1584 if (!DBObject_Check(secondaryDB
)) {
1585 makeTypeError("DB", (PyObject
*)secondaryDB
);
1588 CHECK_DB_NOT_CLOSED(secondaryDB
);
1589 if (callback
== Py_None
) {
1592 else if (!PyCallable_Check(callback
)) {
1593 makeTypeError("Callable", callback
);
1597 /* Save a reference to the callback in the secondary DB. */
1598 Py_XDECREF(secondaryDB
->associateCallback
);
1599 Py_XINCREF(callback
);
1600 secondaryDB
->associateCallback
= callback
;
1601 secondaryDB
->primaryDBType
= _DB_get_type(self
);
1603 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1604 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1605 * The global interepreter lock is not initialized until the first
1606 * thread is created using thread.start_new_thread() or fork() is
1607 * called. that would cause the ALLOW_THREADS here to segfault due
1608 * to a null pointer reference if no threads or child processes
1609 * have been created. This works around that and is a no-op if
1610 * threads have already been initialized.
1611 * (see pybsddb-users mailing list post on 2002-08-07)
1614 PyEval_InitThreads();
1616 MYDB_BEGIN_ALLOW_THREADS
;
1617 err
= self
->db
->associate(self
->db
,
1620 _db_associateCallback
,
1622 MYDB_END_ALLOW_THREADS
;
1625 Py_XDECREF(secondaryDB
->associateCallback
);
1626 secondaryDB
->associateCallback
= NULL
;
1627 secondaryDB
->primaryDBType
= 0;
1636 DB_close_internal(DBObject
* self
, int flags
, int do_not_close
)
1641 if (self
->db
!= NULL
) {
1642 /* Can be NULL if db is not in an environment */
1643 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self
);
1646 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self
);
1650 while(self
->children_cursors
) {
1651 dummy
=DBC_close_internal(self
->children_cursors
);
1656 while(self
->children_sequences
) {
1657 dummy
=DBSequence_close_internal(self
->children_sequences
,0,0);
1663 ** "do_not_close" is used to dispose all related objects in the
1664 ** tree, without actually releasing the "root" object.
1665 ** This is done, for example, because function calls like
1666 ** "DB.verify()" implicitly close the underlying handle. So
1667 ** the handle doesn't need to be closed, but related objects
1668 ** must be cleaned up.
1670 if (!do_not_close
) {
1671 MYDB_BEGIN_ALLOW_THREADS
;
1672 err
= self
->db
->close(self
->db
, flags
);
1673 MYDB_END_ALLOW_THREADS
;
1682 DB_close(DBObject
* self
, PyObject
* args
)
1685 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
1687 return DB_close_internal(self
, flags
, 0);
1692 _DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1694 int err
, flags
=0, type
;
1695 PyObject
* txnobj
= NULL
;
1696 PyObject
* retval
= NULL
;
1699 static char* kwnames
[] = { "txn", "flags", NULL
};
1701 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:consume", kwnames
,
1705 CHECK_DB_NOT_CLOSED(self
);
1706 type
= _DB_get_type(self
);
1709 if (type
!= DB_QUEUE
) {
1710 PyErr_SetString(PyExc_TypeError
,
1711 "Consume methods only allowed for Queue DB's");
1714 if (!checkTxnObj(txnobj
, &txn
))
1719 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1720 /* Tell Berkeley DB to malloc the return value (thread safe) */
1721 data
.flags
= DB_DBT_MALLOC
;
1722 key
.flags
= DB_DBT_MALLOC
;
1725 MYDB_BEGIN_ALLOW_THREADS
;
1726 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
|consume_flag
);
1727 MYDB_END_ALLOW_THREADS
;
1729 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1730 && self
->moduleFlags
.getReturnsNone
) {
1736 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
1746 DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1748 return _DB_consume(self
, args
, kwargs
, DB_CONSUME
);
1752 DB_consume_wait(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
,
1755 return _DB_consume(self
, args
, kwargs
, DB_CONSUME_WAIT
);
1760 DB_cursor(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1764 PyObject
* txnobj
= NULL
;
1766 static char* kwnames
[] = { "txn", "flags", NULL
};
1768 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
1771 CHECK_DB_NOT_CLOSED(self
);
1772 if (!checkTxnObj(txnobj
, &txn
))
1775 MYDB_BEGIN_ALLOW_THREADS
;
1776 err
= self
->db
->cursor(self
->db
, txn
, &dbc
, flags
);
1777 MYDB_END_ALLOW_THREADS
;
1779 return (PyObject
*) newDBCursorObject(dbc
, (DBTxnObject
*)txnobj
, self
);
1784 DB_delete(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1786 PyObject
* txnobj
= NULL
;
1791 static char* kwnames
[] = { "key", "txn", "flags", NULL
};
1793 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:delete", kwnames
,
1794 &keyobj
, &txnobj
, &flags
))
1796 CHECK_DB_NOT_CLOSED(self
);
1797 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1799 if (!checkTxnObj(txnobj
, &txn
)) {
1804 if (-1 == _DB_delete(self
, txn
, &key
, 0)) {
1816 ** This function is available since Berkeley DB 4.4,
1817 ** but 4.6 version is so buggy that we only support
1818 ** it from BDB 4.7 and newer.
1821 DB_compact(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1823 PyObject
* txnobj
= NULL
;
1824 PyObject
*startobj
= NULL
, *stopobj
= NULL
;
1827 DBT
*start_p
= NULL
, *stop_p
= NULL
;
1830 DB_COMPACT c_data
= { 0 };
1831 static char* kwnames
[] = { "txn", "start", "stop", "flags",
1832 "compact_fillpercent", "compact_pages",
1833 "compact_timeout", NULL
};
1836 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OOOiiiI:compact", kwnames
,
1837 &txnobj
, &startobj
, &stopobj
, &flags
,
1838 &c_data
.compact_fillpercent
,
1839 &c_data
.compact_pages
,
1840 &c_data
.compact_timeout
))
1843 CHECK_DB_NOT_CLOSED(self
);
1844 if (!checkTxnObj(txnobj
, &txn
)) {
1848 if (startobj
&& make_key_dbt(self
, startobj
, &start
, NULL
)) {
1851 if (stopobj
&& make_key_dbt(self
, stopobj
, &stop
, NULL
)) {
1855 MYDB_BEGIN_ALLOW_THREADS
;
1856 err
= self
->db
->compact(self
->db
, txn
, start_p
, stop_p
, &c_data
,
1858 MYDB_END_ALLOW_THREADS
;
1867 return PyLong_FromUnsignedLong(c_data
.compact_pages_truncated
);
1873 DB_fd(DBObject
* self
)
1877 CHECK_DB_NOT_CLOSED(self
);
1879 MYDB_BEGIN_ALLOW_THREADS
;
1880 err
= self
->db
->fd(self
->db
, &the_fd
);
1881 MYDB_END_ALLOW_THREADS
;
1883 return NUMBER_FromLong(the_fd
);
1889 DB_exists(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1892 PyObject
* txnobj
= NULL
;
1897 static char* kwnames
[] = {"key", "txn", "flags", NULL
};
1899 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:exists", kwnames
,
1900 &keyobj
, &txnobj
, &flags
))
1903 CHECK_DB_NOT_CLOSED(self
);
1904 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1906 if (!checkTxnObj(txnobj
, &txn
)) {
1911 MYDB_BEGIN_ALLOW_THREADS
;
1912 err
= self
->db
->exists(self
->db
, txn
, &key
, flags
);
1913 MYDB_END_ALLOW_THREADS
;
1921 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)) {
1922 Py_INCREF(Py_False
);
1927 ** If we reach there, there was an error. The
1928 ** "return" should be unreachable.
1931 assert(0); /* This coude SHOULD be unreachable */
1937 DB_get(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1940 PyObject
* txnobj
= NULL
;
1942 PyObject
* dfltobj
= NULL
;
1943 PyObject
* retval
= NULL
;
1948 static char* kwnames
[] = {"key", "default", "txn", "flags", "dlen",
1951 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:get", kwnames
,
1952 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1956 CHECK_DB_NOT_CLOSED(self
);
1957 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1959 if (!checkTxnObj(txnobj
, &txn
)) {
1965 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1966 /* Tell Berkeley DB to malloc the return value (thread safe) */
1967 data
.flags
= DB_DBT_MALLOC
;
1969 if (!add_partial_dbt(&data
, dlen
, doff
)) {
1974 MYDB_BEGIN_ALLOW_THREADS
;
1975 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1976 MYDB_END_ALLOW_THREADS
;
1978 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && (dfltobj
!= NULL
)) {
1983 else if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1984 && self
->moduleFlags
.getReturnsNone
) {
1990 if (flags
& DB_SET_RECNO
) /* return both key and data */
1991 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
1992 else /* return just the data */
1993 retval
= Build_PyString(data
.data
, data
.size
);
2003 DB_pget(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2006 PyObject
* txnobj
= NULL
;
2008 PyObject
* dfltobj
= NULL
;
2009 PyObject
* retval
= NULL
;
2012 DBT key
, pkey
, data
;
2014 static char* kwnames
[] = {"key", "default", "txn", "flags", "dlen",
2017 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:pget", kwnames
,
2018 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
2022 CHECK_DB_NOT_CLOSED(self
);
2023 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
2025 if (!checkTxnObj(txnobj
, &txn
)) {
2031 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2032 /* Tell Berkeley DB to malloc the return value (thread safe) */
2033 data
.flags
= DB_DBT_MALLOC
;
2035 if (!add_partial_dbt(&data
, dlen
, doff
)) {
2041 pkey
.flags
= DB_DBT_MALLOC
;
2043 MYDB_BEGIN_ALLOW_THREADS
;
2044 err
= self
->db
->pget(self
->db
, txn
, &key
, &pkey
, &data
, flags
);
2045 MYDB_END_ALLOW_THREADS
;
2047 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && (dfltobj
!= NULL
)) {
2052 else if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
2053 && self
->moduleFlags
.getReturnsNone
) {
2061 dataObj
= Build_PyString(data
.data
, data
.size
);
2063 if (self
->primaryDBType
== DB_RECNO
||
2064 self
->primaryDBType
== DB_QUEUE
)
2065 pkeyObj
= NUMBER_FromLong(*(int *)pkey
.data
);
2067 pkeyObj
= Build_PyString(pkey
.data
, pkey
.size
);
2069 if (flags
& DB_SET_RECNO
) /* return key , pkey and data */
2072 int type
= _DB_get_type(self
);
2073 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
2074 keyObj
= NUMBER_FromLong(*(int *)key
.data
);
2076 keyObj
= Build_PyString(key
.data
, key
.size
);
2077 #if (PY_VERSION_HEX >= 0x02040000)
2078 retval
= PyTuple_Pack(3, keyObj
, pkeyObj
, dataObj
);
2080 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
2084 else /* return just the pkey and data */
2086 #if (PY_VERSION_HEX >= 0x02040000)
2087 retval
= PyTuple_Pack(2, pkeyObj
, dataObj
);
2089 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
2104 /* Return size of entry */
2106 DB_get_size(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2109 PyObject
* txnobj
= NULL
;
2111 PyObject
* retval
= NULL
;
2114 static char* kwnames
[] = { "key", "txn", NULL
};
2116 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O:get_size", kwnames
,
2119 CHECK_DB_NOT_CLOSED(self
);
2120 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
2122 if (!checkTxnObj(txnobj
, &txn
)) {
2128 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
2129 thus getting the record size. */
2130 data
.flags
= DB_DBT_USERMEM
;
2132 MYDB_BEGIN_ALLOW_THREADS
;
2133 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
2134 MYDB_END_ALLOW_THREADS
;
2135 if (err
== DB_BUFFER_SMALL
) {
2136 retval
= NUMBER_FromLong((long)data
.size
);
2148 DB_get_both(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2151 PyObject
* txnobj
= NULL
;
2154 PyObject
* retval
= NULL
;
2158 static char* kwnames
[] = { "key", "data", "txn", "flags", NULL
};
2160 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oi:get_both", kwnames
,
2161 &keyobj
, &dataobj
, &txnobj
, &flags
))
2164 CHECK_DB_NOT_CLOSED(self
);
2165 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2167 if ( !make_dbt(dataobj
, &data
) ||
2168 !checkTxnObj(txnobj
, &txn
) )
2174 flags
|= DB_GET_BOTH
;
2175 orig_data
= data
.data
;
2177 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2178 /* Tell Berkeley DB to malloc the return value (thread safe) */
2179 /* XXX(nnorwitz): At least 4.4.20 and 4.5.20 require this flag. */
2180 data
.flags
= DB_DBT_MALLOC
;
2183 MYDB_BEGIN_ALLOW_THREADS
;
2184 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
2185 MYDB_END_ALLOW_THREADS
;
2187 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
2188 && self
->moduleFlags
.getReturnsNone
) {
2194 /* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */
2195 retval
= Build_PyString(data
.data
, data
.size
);
2197 /* Even though the flags require DB_DBT_MALLOC, data is not always
2198 allocated. 4.4: allocated, 4.5: *not* allocated. :-( */
2199 if (data
.data
!= orig_data
)
2210 DB_get_byteswapped(DBObject
* self
)
2215 CHECK_DB_NOT_CLOSED(self
);
2217 MYDB_BEGIN_ALLOW_THREADS
;
2218 err
= self
->db
->get_byteswapped(self
->db
, &retval
);
2219 MYDB_END_ALLOW_THREADS
;
2221 return NUMBER_FromLong(retval
);
2226 DB_get_type(DBObject
* self
)
2230 CHECK_DB_NOT_CLOSED(self
);
2232 type
= _DB_get_type(self
);
2235 return NUMBER_FromLong(type
);
2240 DB_join(DBObject
* self
, PyObject
* args
)
2244 PyObject
* cursorsObj
;
2248 if (!PyArg_ParseTuple(args
,"O|i:join", &cursorsObj
, &flags
))
2251 CHECK_DB_NOT_CLOSED(self
);
2253 if (!PySequence_Check(cursorsObj
)) {
2254 PyErr_SetString(PyExc_TypeError
,
2255 "Sequence of DBCursor objects expected");
2259 length
= PyObject_Length(cursorsObj
);
2260 cursors
= malloc((length
+1) * sizeof(DBC
*));
2266 cursors
[length
] = NULL
;
2267 for (x
=0; x
<length
; x
++) {
2268 PyObject
* item
= PySequence_GetItem(cursorsObj
, x
);
2273 if (!DBCursorObject_Check(item
)) {
2274 PyErr_SetString(PyExc_TypeError
,
2275 "Sequence of DBCursor objects expected");
2279 cursors
[x
] = ((DBCursorObject
*)item
)->dbc
;
2283 MYDB_BEGIN_ALLOW_THREADS
;
2284 err
= self
->db
->join(self
->db
, cursors
, &dbc
, flags
);
2285 MYDB_END_ALLOW_THREADS
;
2289 /* FIXME: this is a buggy interface. The returned cursor
2290 contains internal references to the passed in cursors
2291 but does not hold python references to them or prevent
2292 them from being closed prematurely. This can cause
2293 python to crash when things are done in the wrong order. */
2294 return (PyObject
*) newDBCursorObject(dbc
, NULL
, self
);
2299 DB_key_range(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2302 PyObject
* txnobj
= NULL
;
2307 static char* kwnames
[] = { "key", "txn", "flags", NULL
};
2309 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:key_range", kwnames
,
2310 &keyobj
, &txnobj
, &flags
))
2312 CHECK_DB_NOT_CLOSED(self
);
2313 if (!make_dbt(keyobj
, &key
))
2314 /* BTree only, don't need to allow for an int key */
2316 if (!checkTxnObj(txnobj
, &txn
))
2319 MYDB_BEGIN_ALLOW_THREADS
;
2320 err
= self
->db
->key_range(self
->db
, txn
, &key
, &range
, flags
);
2321 MYDB_END_ALLOW_THREADS
;
2324 return Py_BuildValue("ddd", range
.less
, range
.equal
, range
.greater
);
2329 DB_open(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2331 int err
, type
= DB_UNKNOWN
, flags
=0, mode
=0660;
2332 char* filename
= NULL
;
2333 char* dbname
= NULL
;
2334 PyObject
*txnobj
= NULL
;
2337 static char* kwnames
[] = {
2338 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL
};
2339 /* without dbname */
2340 static char* kwnames_basic
[] = {
2341 "filename", "dbtype", "flags", "mode", "txn", NULL
};
2343 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziiiO:open", kwnames
,
2344 &filename
, &dbname
, &type
, &flags
, &mode
,
2348 type
= DB_UNKNOWN
; flags
= 0; mode
= 0660;
2349 filename
= NULL
; dbname
= NULL
;
2350 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iiiO:open",
2352 &filename
, &type
, &flags
, &mode
,
2357 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
2359 if (NULL
== self
->db
) {
2360 PyObject
*t
= Py_BuildValue("(is)", 0,
2361 "Cannot call open() twice for DB object");
2363 PyErr_SetObject(DBError
, t
);
2369 if (txn
) { /* Can't use 'txnobj' because could be 'txnobj==Py_None' */
2370 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject
*)txnobj
)->children_dbs
,self
);
2371 self
->txn
=(DBTxnObject
*)txnobj
;
2376 MYDB_BEGIN_ALLOW_THREADS
;
2377 err
= self
->db
->open(self
->db
, txn
, filename
, dbname
, type
, flags
, mode
);
2378 MYDB_END_ALLOW_THREADS
;
2380 if (makeDBError(err
)) {
2383 dummy
=DB_close_internal(self
, 0, 0);
2389 self
->db
->get_flags(self
->db
, &self
->setflags
);
2392 self
->flags
= flags
;
2399 DB_put(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2402 PyObject
* txnobj
= NULL
;
2405 PyObject
* keyobj
, *dataobj
, *retval
;
2408 static char* kwnames
[] = { "key", "data", "txn", "flags", "dlen",
2411 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oiii:put", kwnames
,
2412 &keyobj
, &dataobj
, &txnobj
, &flags
, &dlen
, &doff
))
2415 CHECK_DB_NOT_CLOSED(self
);
2416 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2418 if ( !make_dbt(dataobj
, &data
) ||
2419 !add_partial_dbt(&data
, dlen
, doff
) ||
2420 !checkTxnObj(txnobj
, &txn
) )
2426 if (-1 == _DB_put(self
, txn
, &key
, &data
, flags
)) {
2431 if (flags
& DB_APPEND
)
2432 retval
= NUMBER_FromLong(*((db_recno_t
*)key
.data
));
2444 DB_remove(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2447 char* database
= NULL
;
2449 static char* kwnames
[] = { "filename", "dbname", "flags", NULL
};
2451 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zi:remove", kwnames
,
2452 &filename
, &database
, &flags
))
2454 CHECK_DB_NOT_CLOSED(self
);
2456 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self
);
2458 MYDB_BEGIN_ALLOW_THREADS
;
2459 err
= self
->db
->remove(self
->db
, filename
, database
, flags
);
2460 MYDB_END_ALLOW_THREADS
;
2470 DB_rename(DBObject
* self
, PyObject
* args
)
2477 if (!PyArg_ParseTuple(args
, "sss|i:rename", &filename
, &database
, &newname
,
2480 CHECK_DB_NOT_CLOSED(self
);
2482 MYDB_BEGIN_ALLOW_THREADS
;
2483 err
= self
->db
->rename(self
->db
, filename
, database
, newname
, flags
);
2484 MYDB_END_ALLOW_THREADS
;
2491 DB_get_private(DBObject
* self
)
2493 /* We can give out the private field even if db is closed */
2494 Py_INCREF(self
->private_obj
);
2495 return self
->private_obj
;
2499 DB_set_private(DBObject
* self
, PyObject
* private_obj
)
2501 /* We can set the private field even if db is closed */
2502 Py_DECREF(self
->private_obj
);
2503 Py_INCREF(private_obj
);
2504 self
->private_obj
= private_obj
;
2510 DB_set_priority(DBObject
* self
, PyObject
* args
)
2514 if (!PyArg_ParseTuple(args
,"i:set_priority", &priority
))
2516 CHECK_DB_NOT_CLOSED(self
);
2518 MYDB_BEGIN_ALLOW_THREADS
;
2519 err
= self
->db
->set_priority(self
->db
, priority
);
2520 MYDB_END_ALLOW_THREADS
;
2526 DB_get_priority(DBObject
* self
)
2529 DB_CACHE_PRIORITY priority
;
2531 CHECK_DB_NOT_CLOSED(self
);
2533 MYDB_BEGIN_ALLOW_THREADS
;
2534 err
= self
->db
->get_priority(self
->db
, &priority
);
2535 MYDB_END_ALLOW_THREADS
;
2537 return NUMBER_FromLong(priority
);
2542 DB_set_q_extentsize(DBObject
* self
, PyObject
* args
)
2545 u_int32_t extentsize
;
2547 if (!PyArg_ParseTuple(args
,"i:set_q_extentsize", &extentsize
))
2549 CHECK_DB_NOT_CLOSED(self
);
2551 MYDB_BEGIN_ALLOW_THREADS
;
2552 err
= self
->db
->set_q_extentsize(self
->db
, extentsize
);
2553 MYDB_END_ALLOW_THREADS
;
2560 DB_get_q_extentsize(DBObject
* self
)
2563 u_int32_t extentsize
;
2565 CHECK_DB_NOT_CLOSED(self
);
2567 MYDB_BEGIN_ALLOW_THREADS
;
2568 err
= self
->db
->get_q_extentsize(self
->db
, &extentsize
);
2569 MYDB_END_ALLOW_THREADS
;
2571 return NUMBER_FromLong(extentsize
);
2576 DB_set_bt_minkey(DBObject
* self
, PyObject
* args
)
2580 if (!PyArg_ParseTuple(args
,"i:set_bt_minkey", &minkey
))
2582 CHECK_DB_NOT_CLOSED(self
);
2584 MYDB_BEGIN_ALLOW_THREADS
;
2585 err
= self
->db
->set_bt_minkey(self
->db
, minkey
);
2586 MYDB_END_ALLOW_THREADS
;
2593 DB_get_bt_minkey(DBObject
* self
)
2596 u_int32_t bt_minkey
;
2598 CHECK_DB_NOT_CLOSED(self
);
2600 MYDB_BEGIN_ALLOW_THREADS
;
2601 err
= self
->db
->get_bt_minkey(self
->db
, &bt_minkey
);
2602 MYDB_END_ALLOW_THREADS
;
2604 return NUMBER_FromLong(bt_minkey
);
2609 _default_cmp(const DBT
*leftKey
,
2610 const DBT
*rightKey
)
2613 int lsize
= leftKey
->size
, rsize
= rightKey
->size
;
2615 res
= memcmp(leftKey
->data
, rightKey
->data
,
2616 lsize
< rsize
? lsize
: rsize
);
2619 if (lsize
< rsize
) {
2622 else if (lsize
> rsize
) {
2630 _db_compareCallback(DB
* db
,
2632 const DBT
*rightKey
)
2636 PyObject
*result
= NULL
;
2637 DBObject
*self
= (DBObject
*)db
->app_private
;
2639 if (self
== NULL
|| self
->btCompareCallback
== NULL
) {
2640 MYDB_BEGIN_BLOCK_THREADS
;
2641 PyErr_SetString(PyExc_TypeError
,
2643 ? "DB_bt_compare db is NULL."
2644 : "DB_bt_compare callback is NULL."));
2645 /* we're in a callback within the DB code, we can't raise */
2647 res
= _default_cmp(leftKey
, rightKey
);
2648 MYDB_END_BLOCK_THREADS
;
2650 MYDB_BEGIN_BLOCK_THREADS
;
2652 args
= BuildValue_SS(leftKey
->data
, leftKey
->size
, rightKey
->data
, rightKey
->size
);
2654 result
= PyEval_CallObject(self
->btCompareCallback
, args
);
2656 if (args
== NULL
|| result
== NULL
) {
2657 /* we're in a callback within the DB code, we can't raise */
2659 res
= _default_cmp(leftKey
, rightKey
);
2660 } else if (NUMBER_Check(result
)) {
2661 res
= NUMBER_AsLong(result
);
2663 PyErr_SetString(PyExc_TypeError
,
2664 "DB_bt_compare callback MUST return an int.");
2665 /* we're in a callback within the DB code, we can't raise */
2667 res
= _default_cmp(leftKey
, rightKey
);
2673 MYDB_END_BLOCK_THREADS
;
2679 DB_set_bt_compare(DBObject
* self
, PyObject
* comparator
)
2682 PyObject
*tuple
, *result
;
2684 CHECK_DB_NOT_CLOSED(self
);
2686 if (!PyCallable_Check(comparator
)) {
2687 makeTypeError("Callable", comparator
);
2692 * Perform a test call of the comparator function with two empty
2693 * string objects here. verify that it returns an int (0).
2696 tuple
= Py_BuildValue("(ss)", "", "");
2697 result
= PyEval_CallObject(comparator
, tuple
);
2701 if (!NUMBER_Check(result
)) {
2703 PyErr_SetString(PyExc_TypeError
,
2704 "callback MUST return an int");
2706 } else if (NUMBER_AsLong(result
) != 0) {
2708 PyErr_SetString(PyExc_TypeError
,
2709 "callback failed to return 0 on two empty strings");
2714 /* We don't accept multiple set_bt_compare operations, in order to
2715 * simplify the code. This would have no real use, as one cannot
2716 * change the function once the db is opened anyway */
2717 if (self
->btCompareCallback
!= NULL
) {
2718 PyErr_SetString(PyExc_RuntimeError
, "set_bt_compare() cannot be called more than once");
2722 Py_INCREF(comparator
);
2723 self
->btCompareCallback
= comparator
;
2725 /* This is to workaround a problem with un-initialized threads (see
2726 comment in DB_associate) */
2728 PyEval_InitThreads();
2731 err
= self
->db
->set_bt_compare(self
->db
, _db_compareCallback
);
2734 /* restore the old state in case of error */
2735 Py_DECREF(comparator
);
2736 self
->btCompareCallback
= NULL
;
2745 DB_set_cachesize(DBObject
* self
, PyObject
* args
)
2748 int gbytes
= 0, bytes
= 0, ncache
= 0;
2750 if (!PyArg_ParseTuple(args
,"ii|i:set_cachesize",
2751 &gbytes
,&bytes
,&ncache
))
2753 CHECK_DB_NOT_CLOSED(self
);
2755 MYDB_BEGIN_ALLOW_THREADS
;
2756 err
= self
->db
->set_cachesize(self
->db
, gbytes
, bytes
, ncache
);
2757 MYDB_END_ALLOW_THREADS
;
2764 DB_get_cachesize(DBObject
* self
)
2767 u_int32_t gbytes
, bytes
;
2770 CHECK_DB_NOT_CLOSED(self
);
2772 MYDB_BEGIN_ALLOW_THREADS
;
2773 err
= self
->db
->get_cachesize(self
->db
, &gbytes
, &bytes
, &ncache
);
2774 MYDB_END_ALLOW_THREADS
;
2778 return Py_BuildValue("(iii)", gbytes
, bytes
, ncache
);
2783 DB_set_flags(DBObject
* self
, PyObject
* args
)
2787 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
2789 CHECK_DB_NOT_CLOSED(self
);
2791 MYDB_BEGIN_ALLOW_THREADS
;
2792 err
= self
->db
->set_flags(self
->db
, flags
);
2793 MYDB_END_ALLOW_THREADS
;
2796 self
->setflags
|= flags
;
2802 DB_get_flags(DBObject
* self
)
2807 CHECK_DB_NOT_CLOSED(self
);
2809 MYDB_BEGIN_ALLOW_THREADS
;
2810 err
= self
->db
->get_flags(self
->db
, &flags
);
2811 MYDB_END_ALLOW_THREADS
;
2813 return NUMBER_FromLong(flags
);
2818 DB_set_h_ffactor(DBObject
* self
, PyObject
* args
)
2822 if (!PyArg_ParseTuple(args
,"i:set_h_ffactor", &ffactor
))
2824 CHECK_DB_NOT_CLOSED(self
);
2826 MYDB_BEGIN_ALLOW_THREADS
;
2827 err
= self
->db
->set_h_ffactor(self
->db
, ffactor
);
2828 MYDB_END_ALLOW_THREADS
;
2835 DB_get_h_ffactor(DBObject
* self
)
2840 CHECK_DB_NOT_CLOSED(self
);
2842 MYDB_BEGIN_ALLOW_THREADS
;
2843 err
= self
->db
->get_h_ffactor(self
->db
, &ffactor
);
2844 MYDB_END_ALLOW_THREADS
;
2846 return NUMBER_FromLong(ffactor
);
2851 DB_set_h_nelem(DBObject
* self
, PyObject
* args
)
2855 if (!PyArg_ParseTuple(args
,"i:set_h_nelem", &nelem
))
2857 CHECK_DB_NOT_CLOSED(self
);
2859 MYDB_BEGIN_ALLOW_THREADS
;
2860 err
= self
->db
->set_h_nelem(self
->db
, nelem
);
2861 MYDB_END_ALLOW_THREADS
;
2868 DB_get_h_nelem(DBObject
* self
)
2873 CHECK_DB_NOT_CLOSED(self
);
2875 MYDB_BEGIN_ALLOW_THREADS
;
2876 err
= self
->db
->get_h_nelem(self
->db
, &nelem
);
2877 MYDB_END_ALLOW_THREADS
;
2879 return NUMBER_FromLong(nelem
);
2884 DB_set_lorder(DBObject
* self
, PyObject
* args
)
2888 if (!PyArg_ParseTuple(args
,"i:set_lorder", &lorder
))
2890 CHECK_DB_NOT_CLOSED(self
);
2892 MYDB_BEGIN_ALLOW_THREADS
;
2893 err
= self
->db
->set_lorder(self
->db
, lorder
);
2894 MYDB_END_ALLOW_THREADS
;
2901 DB_get_lorder(DBObject
* self
)
2906 CHECK_DB_NOT_CLOSED(self
);
2908 MYDB_BEGIN_ALLOW_THREADS
;
2909 err
= self
->db
->get_lorder(self
->db
, &lorder
);
2910 MYDB_END_ALLOW_THREADS
;
2912 return NUMBER_FromLong(lorder
);
2917 DB_set_pagesize(DBObject
* self
, PyObject
* args
)
2921 if (!PyArg_ParseTuple(args
,"i:set_pagesize", &pagesize
))
2923 CHECK_DB_NOT_CLOSED(self
);
2925 MYDB_BEGIN_ALLOW_THREADS
;
2926 err
= self
->db
->set_pagesize(self
->db
, pagesize
);
2927 MYDB_END_ALLOW_THREADS
;
2934 DB_get_pagesize(DBObject
* self
)
2939 CHECK_DB_NOT_CLOSED(self
);
2941 MYDB_BEGIN_ALLOW_THREADS
;
2942 err
= self
->db
->get_pagesize(self
->db
, &pagesize
);
2943 MYDB_END_ALLOW_THREADS
;
2945 return NUMBER_FromLong(pagesize
);
2950 DB_set_re_delim(DBObject
* self
, PyObject
* args
)
2955 if (!PyArg_ParseTuple(args
,"b:set_re_delim", &delim
)) {
2957 if (!PyArg_ParseTuple(args
,"c:set_re_delim", &delim
))
2961 CHECK_DB_NOT_CLOSED(self
);
2963 MYDB_BEGIN_ALLOW_THREADS
;
2964 err
= self
->db
->set_re_delim(self
->db
, delim
);
2965 MYDB_END_ALLOW_THREADS
;
2972 DB_get_re_delim(DBObject
* self
)
2976 CHECK_DB_NOT_CLOSED(self
);
2978 MYDB_BEGIN_ALLOW_THREADS
;
2979 err
= self
->db
->get_re_delim(self
->db
, &re_delim
);
2980 MYDB_END_ALLOW_THREADS
;
2982 return NUMBER_FromLong(re_delim
);
2987 DB_set_re_len(DBObject
* self
, PyObject
* args
)
2991 if (!PyArg_ParseTuple(args
,"i:set_re_len", &len
))
2993 CHECK_DB_NOT_CLOSED(self
);
2995 MYDB_BEGIN_ALLOW_THREADS
;
2996 err
= self
->db
->set_re_len(self
->db
, len
);
2997 MYDB_END_ALLOW_THREADS
;
3004 DB_get_re_len(DBObject
* self
)
3009 CHECK_DB_NOT_CLOSED(self
);
3011 MYDB_BEGIN_ALLOW_THREADS
;
3012 err
= self
->db
->get_re_len(self
->db
, &re_len
);
3013 MYDB_END_ALLOW_THREADS
;
3015 return NUMBER_FromLong(re_len
);
3020 DB_set_re_pad(DBObject
* self
, PyObject
* args
)
3025 if (!PyArg_ParseTuple(args
,"b:set_re_pad", &pad
)) {
3027 if (!PyArg_ParseTuple(args
,"c:set_re_pad", &pad
))
3030 CHECK_DB_NOT_CLOSED(self
);
3032 MYDB_BEGIN_ALLOW_THREADS
;
3033 err
= self
->db
->set_re_pad(self
->db
, pad
);
3034 MYDB_END_ALLOW_THREADS
;
3041 DB_get_re_pad(DBObject
* self
)
3045 CHECK_DB_NOT_CLOSED(self
);
3047 MYDB_BEGIN_ALLOW_THREADS
;
3048 err
= self
->db
->get_re_pad(self
->db
, &re_pad
);
3049 MYDB_END_ALLOW_THREADS
;
3051 return NUMBER_FromLong(re_pad
);
3056 DB_set_re_source(DBObject
* self
, PyObject
* args
)
3061 if (!PyArg_ParseTuple(args
,"s:set_re_source", &source
))
3063 CHECK_DB_NOT_CLOSED(self
);
3065 MYDB_BEGIN_ALLOW_THREADS
;
3066 err
= self
->db
->set_re_source(self
->db
, source
);
3067 MYDB_END_ALLOW_THREADS
;
3074 DB_get_re_source(DBObject
* self
)
3079 CHECK_DB_NOT_CLOSED(self
);
3081 MYDB_BEGIN_ALLOW_THREADS
;
3082 err
= self
->db
->get_re_source(self
->db
, &source
);
3083 MYDB_END_ALLOW_THREADS
;
3085 return PyBytes_FromString(source
);
3090 DB_stat(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3092 int err
, flags
= 0, type
;
3096 PyObject
* txnobj
= NULL
;
3098 static char* kwnames
[] = { "flags", "txn", NULL
};
3100 static char* kwnames
[] = { "flags", NULL
};
3104 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iO:stat", kwnames
,
3107 if (!checkTxnObj(txnobj
, &txn
))
3110 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat", kwnames
, &flags
))
3113 CHECK_DB_NOT_CLOSED(self
);
3115 MYDB_BEGIN_ALLOW_THREADS
;
3117 err
= self
->db
->stat(self
->db
, txn
, &sp
, flags
);
3119 err
= self
->db
->stat(self
->db
, &sp
, flags
);
3121 MYDB_END_ALLOW_THREADS
;
3124 /* Turn the stat structure into a dictionary */
3125 type
= _DB_get_type(self
);
3126 if ((type
== -1) || ((d
= PyDict_New()) == NULL
)) {
3131 #define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
3132 #define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
3133 #define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
3137 MAKE_HASH_ENTRY(magic
);
3138 MAKE_HASH_ENTRY(version
);
3139 MAKE_HASH_ENTRY(nkeys
);
3140 MAKE_HASH_ENTRY(ndata
);
3142 MAKE_HASH_ENTRY(pagecnt
);
3144 MAKE_HASH_ENTRY(pagesize
);
3145 MAKE_HASH_ENTRY(ffactor
);
3146 MAKE_HASH_ENTRY(buckets
);
3147 MAKE_HASH_ENTRY(free
);
3148 MAKE_HASH_ENTRY(bfree
);
3149 MAKE_HASH_ENTRY(bigpages
);
3150 MAKE_HASH_ENTRY(big_bfree
);
3151 MAKE_HASH_ENTRY(overflows
);
3152 MAKE_HASH_ENTRY(ovfl_free
);
3153 MAKE_HASH_ENTRY(dup
);
3154 MAKE_HASH_ENTRY(dup_free
);
3159 MAKE_BT_ENTRY(magic
);
3160 MAKE_BT_ENTRY(version
);
3161 MAKE_BT_ENTRY(nkeys
);
3162 MAKE_BT_ENTRY(ndata
);
3164 MAKE_BT_ENTRY(pagecnt
);
3166 MAKE_BT_ENTRY(pagesize
);
3167 MAKE_BT_ENTRY(minkey
);
3168 MAKE_BT_ENTRY(re_len
);
3169 MAKE_BT_ENTRY(re_pad
);
3170 MAKE_BT_ENTRY(levels
);
3171 MAKE_BT_ENTRY(int_pg
);
3172 MAKE_BT_ENTRY(leaf_pg
);
3173 MAKE_BT_ENTRY(dup_pg
);
3174 MAKE_BT_ENTRY(over_pg
);
3176 MAKE_BT_ENTRY(empty_pg
);
3178 MAKE_BT_ENTRY(free
);
3179 MAKE_BT_ENTRY(int_pgfree
);
3180 MAKE_BT_ENTRY(leaf_pgfree
);
3181 MAKE_BT_ENTRY(dup_pgfree
);
3182 MAKE_BT_ENTRY(over_pgfree
);
3186 MAKE_QUEUE_ENTRY(magic
);
3187 MAKE_QUEUE_ENTRY(version
);
3188 MAKE_QUEUE_ENTRY(nkeys
);
3189 MAKE_QUEUE_ENTRY(ndata
);
3190 MAKE_QUEUE_ENTRY(pagesize
);
3191 MAKE_QUEUE_ENTRY(extentsize
);
3192 MAKE_QUEUE_ENTRY(pages
);
3193 MAKE_QUEUE_ENTRY(re_len
);
3194 MAKE_QUEUE_ENTRY(re_pad
);
3195 MAKE_QUEUE_ENTRY(pgfree
);
3197 MAKE_QUEUE_ENTRY(start
);
3199 MAKE_QUEUE_ENTRY(first_recno
);
3200 MAKE_QUEUE_ENTRY(cur_recno
);
3204 PyErr_SetString(PyExc_TypeError
, "Unknown DB type, unable to stat");
3209 #undef MAKE_HASH_ENTRY
3210 #undef MAKE_BT_ENTRY
3211 #undef MAKE_QUEUE_ENTRY
3219 DB_stat_print(DBObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3223 static char* kwnames
[] = { "flags", NULL
};
3225 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat_print",
3230 CHECK_DB_NOT_CLOSED(self
);
3231 MYDB_BEGIN_ALLOW_THREADS
;
3232 err
= self
->db
->stat_print(self
->db
, flags
);
3233 MYDB_END_ALLOW_THREADS
;
3241 DB_sync(DBObject
* self
, PyObject
* args
)
3246 if (!PyArg_ParseTuple(args
,"|i:sync", &flags
))
3248 CHECK_DB_NOT_CLOSED(self
);
3250 MYDB_BEGIN_ALLOW_THREADS
;
3251 err
= self
->db
->sync(self
->db
, flags
);
3252 MYDB_END_ALLOW_THREADS
;
3259 DB_truncate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3263 PyObject
* txnobj
= NULL
;
3265 static char* kwnames
[] = { "txn", "flags", NULL
};
3267 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
3270 CHECK_DB_NOT_CLOSED(self
);
3271 if (!checkTxnObj(txnobj
, &txn
))
3274 MYDB_BEGIN_ALLOW_THREADS
;
3275 err
= self
->db
->truncate(self
->db
, txn
, &count
, flags
);
3276 MYDB_END_ALLOW_THREADS
;
3278 return NUMBER_FromLong(count
);
3283 DB_upgrade(DBObject
* self
, PyObject
* args
)
3288 if (!PyArg_ParseTuple(args
,"s|i:upgrade", &filename
, &flags
))
3290 CHECK_DB_NOT_CLOSED(self
);
3292 MYDB_BEGIN_ALLOW_THREADS
;
3293 err
= self
->db
->upgrade(self
->db
, filename
, flags
);
3294 MYDB_END_ALLOW_THREADS
;
3301 DB_verify(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3306 char* outFileName
=NULL
;
3308 static char* kwnames
[] = { "filename", "dbname", "outfile", "flags",
3311 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zzi:verify", kwnames
,
3312 &fileName
, &dbName
, &outFileName
, &flags
))
3315 CHECK_DB_NOT_CLOSED(self
);
3317 outFile
= fopen(outFileName
, "w");
3318 /* XXX(nnorwitz): it should probably be an exception if outFile
3321 { /* DB.verify acts as a DB handle destructor (like close) */
3324 error
=DB_close_internal(self
, 0, 1);
3330 MYDB_BEGIN_ALLOW_THREADS
;
3331 err
= self
->db
->verify(self
->db
, fileName
, dbName
, outFile
, flags
);
3332 MYDB_END_ALLOW_THREADS
;
3334 self
->db
= NULL
; /* Implicit close; related objects already released */
3345 DB_set_get_returns_none(DBObject
* self
, PyObject
* args
)
3350 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
3352 CHECK_DB_NOT_CLOSED(self
);
3354 if (self
->moduleFlags
.getReturnsNone
)
3356 if (self
->moduleFlags
.cursorSetReturnsNone
)
3358 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
3359 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
3360 return NUMBER_FromLong(oldValue
);
3364 DB_set_encrypt(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3368 char *passwd
= NULL
;
3369 static char* kwnames
[] = { "passwd", "flags", NULL
};
3371 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
3376 MYDB_BEGIN_ALLOW_THREADS
;
3377 err
= self
->db
->set_encrypt(self
->db
, passwd
, flags
);
3378 MYDB_END_ALLOW_THREADS
;
3386 DB_get_encrypt_flags(DBObject
* self
)
3391 MYDB_BEGIN_ALLOW_THREADS
;
3392 err
= self
->db
->get_encrypt_flags(self
->db
, &flags
);
3393 MYDB_END_ALLOW_THREADS
;
3397 return NUMBER_FromLong(flags
);
3403 /*-------------------------------------------------------------- */
3404 /* Mapping and Dictionary-like access routines */
3406 Py_ssize_t
DB_length(PyObject
* _self
)
3409 Py_ssize_t size
= 0;
3411 DBObject
* self
= (DBObject
*)_self
;
3413 if (self
->db
== NULL
) {
3414 PyObject
*t
= Py_BuildValue("(is)", 0, "DB object has been closed");
3416 PyErr_SetObject(DBError
, t
);
3422 MYDB_BEGIN_ALLOW_THREADS
;
3424 err
= self
->db
->stat(self
->db
, /*txnid*/ NULL
, &sp
, 0);
3426 err
= self
->db
->stat(self
->db
, &sp
, 0);
3428 MYDB_END_ALLOW_THREADS
;
3430 /* All the stat structures have matching fields upto the ndata field,
3431 so we can use any of them for the type cast */
3432 size
= ((DB_BTREE_STAT
*)sp
)->bt_ndata
;
3442 PyObject
* DB_subscript(DBObject
* self
, PyObject
* keyobj
)
3449 CHECK_DB_NOT_CLOSED(self
);
3450 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
3454 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
3455 /* Tell Berkeley DB to malloc the return value (thread safe) */
3456 data
.flags
= DB_DBT_MALLOC
;
3458 MYDB_BEGIN_ALLOW_THREADS
;
3459 err
= self
->db
->get(self
->db
, NULL
, &key
, &data
, 0);
3460 MYDB_END_ALLOW_THREADS
;
3461 if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
3462 PyErr_SetObject(PyExc_KeyError
, keyobj
);
3465 else if (makeDBError(err
)) {
3469 retval
= Build_PyString(data
.data
, data
.size
);
3479 DB_ass_sub(DBObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
)
3485 if (self
->db
== NULL
) {
3486 PyObject
*t
= Py_BuildValue("(is)", 0, "DB object has been closed");
3488 PyErr_SetObject(DBError
, t
);
3494 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
3497 if (dataobj
!= NULL
) {
3498 if (!make_dbt(dataobj
, &data
))
3501 if (self
->setflags
& (DB_DUP
|DB_DUPSORT
))
3502 /* dictionaries shouldn't have duplicate keys */
3503 flags
= DB_NOOVERWRITE
;
3504 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
3506 if ((retval
== -1) && (self
->setflags
& (DB_DUP
|DB_DUPSORT
))) {
3507 /* try deleting any old record that matches and then PUT it
3509 _DB_delete(self
, NULL
, &key
, 0);
3511 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
3516 /* dataobj == NULL, so delete the key */
3517 retval
= _DB_delete(self
, NULL
, &key
, 0);
3525 _DB_has_key(DBObject
* self
, PyObject
* keyobj
, PyObject
* txnobj
)
3531 CHECK_DB_NOT_CLOSED(self
);
3532 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
3534 if (!checkTxnObj(txnobj
, &txn
)) {
3540 /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
3541 it has a record but can't allocate a buffer for the data. This saves
3542 having to deal with data we won't be using.
3547 data
.flags
= DB_DBT_USERMEM
;
3549 MYDB_BEGIN_ALLOW_THREADS
;
3550 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, 0);
3551 MYDB_END_ALLOW_THREADS
;
3554 MYDB_BEGIN_ALLOW_THREADS
;
3555 err
= self
->db
->exists(self
->db
, txn
, &key
, 0);
3556 MYDB_END_ALLOW_THREADS
;
3562 ** DB_BUFFER_SMALL is only used if we use "get".
3563 ** We can drop it when we only use "exists",
3564 ** when we drop suport for Berkeley DB < 4.6.
3566 if (err
== DB_BUFFER_SMALL
|| err
== 0) {
3569 } else if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
3570 Py_INCREF(Py_False
);
3579 DB_has_key(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3582 PyObject
* txnobj
= NULL
;
3583 static char* kwnames
[] = {"key","txn", NULL
};
3585 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O:has_key", kwnames
,
3589 return _DB_has_key(self
, keyobj
, txnobj
);
3593 static int DB_contains(DBObject
* self
, PyObject
* keyobj
)
3598 result
= _DB_has_key(self
, keyobj
, NULL
) ;
3599 if (result
== NULL
) {
3600 return -1; /* Propague exception */
3602 if (result
!= Py_False
) {
3611 #define _KEYS_LIST 1
3612 #define _VALUES_LIST 2
3613 #define _ITEMS_LIST 3
3616 _DB_make_list(DBObject
* self
, DB_TXN
* txn
, int type
)
3623 PyObject
* item
= NULL
;
3625 CHECK_DB_NOT_CLOSED(self
);
3629 dbtype
= _DB_get_type(self
);
3633 list
= PyList_New(0);
3638 MYDB_BEGIN_ALLOW_THREADS
;
3639 err
= self
->db
->cursor(self
->db
, txn
, &cursor
, 0);
3640 MYDB_END_ALLOW_THREADS
;
3641 if (makeDBError(err
)) {
3646 while (1) { /* use the cursor to traverse the DB, collecting items */
3647 MYDB_BEGIN_ALLOW_THREADS
;
3648 err
= _DBC_get(cursor
, &key
, &data
, DB_NEXT
);
3649 MYDB_END_ALLOW_THREADS
;
3652 /* for any error, break out of the loop */
3662 item
= Build_PyString(key
.data
, key
.size
);
3666 item
= NUMBER_FromLong(*((db_recno_t
*)key
.data
));
3672 item
= Build_PyString(data
.data
, data
.size
);
3680 item
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
3684 item
= BuildValue_IS(*((db_recno_t
*)key
.data
), data
.data
, data
.size
);
3689 PyErr_Format(PyExc_ValueError
, "Unknown key type 0x%x", type
);
3698 if (PyList_Append(list
, item
)) {
3707 /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
3708 if (err
!= DB_NOTFOUND
&& err
!= DB_KEYEMPTY
&& makeDBError(err
)) {
3714 MYDB_BEGIN_ALLOW_THREADS
;
3716 MYDB_END_ALLOW_THREADS
;
3722 DB_keys(DBObject
* self
, PyObject
* args
)
3724 PyObject
* txnobj
= NULL
;
3727 if (!PyArg_UnpackTuple(args
, "keys", 0, 1, &txnobj
))
3729 if (!checkTxnObj(txnobj
, &txn
))
3731 return _DB_make_list(self
, txn
, _KEYS_LIST
);
3736 DB_items(DBObject
* self
, PyObject
* args
)
3738 PyObject
* txnobj
= NULL
;
3741 if (!PyArg_UnpackTuple(args
, "items", 0, 1, &txnobj
))
3743 if (!checkTxnObj(txnobj
, &txn
))
3745 return _DB_make_list(self
, txn
, _ITEMS_LIST
);
3750 DB_values(DBObject
* self
, PyObject
* args
)
3752 PyObject
* txnobj
= NULL
;
3755 if (!PyArg_UnpackTuple(args
, "values", 0, 1, &txnobj
))
3757 if (!checkTxnObj(txnobj
, &txn
))
3759 return _DB_make_list(self
, txn
, _VALUES_LIST
);
3762 /* --------------------------------------------------------------------- */
3763 /* DBLogCursor methods */
3767 DBLogCursor_close_internal(DBLogCursorObject
* self
)
3771 if (self
->logc
!= NULL
) {
3772 EXTRACT_FROM_DOUBLE_LINKED_LIST(self
);
3774 MYDB_BEGIN_ALLOW_THREADS
;
3775 err
= self
->logc
->close(self
->logc
, 0);
3776 MYDB_END_ALLOW_THREADS
;
3784 DBLogCursor_close(DBLogCursorObject
* self
)
3786 return DBLogCursor_close_internal(self
);
3791 _DBLogCursor_get(DBLogCursorObject
* self
, int flag
, DB_LSN
*lsn2
)
3795 DB_LSN lsn
= {0, 0};
3796 PyObject
*dummy
, *retval
;
3799 data
.flags
= DB_DBT_MALLOC
; /* Berkeley DB must do the malloc */
3801 CHECK_LOGCURSOR_NOT_CLOSED(self
);
3806 MYDB_BEGIN_ALLOW_THREADS
;
3807 err
= self
->logc
->get(self
->logc
, &lsn
, &data
, flag
);
3808 MYDB_END_ALLOW_THREADS
;
3810 if (err
== DB_NOTFOUND
) {
3814 else if (makeDBError(err
)) {
3818 retval
= dummy
= BuildValue_S(data
.data
, data
.size
);
3820 retval
= Py_BuildValue("(ii)O", lsn
.file
, lsn
.offset
, dummy
);
3830 DBLogCursor_current(DBLogCursorObject
* self
)
3832 return _DBLogCursor_get(self
, DB_CURRENT
, NULL
);
3836 DBLogCursor_first(DBLogCursorObject
* self
)
3838 return _DBLogCursor_get(self
, DB_FIRST
, NULL
);
3842 DBLogCursor_last(DBLogCursorObject
* self
)
3844 return _DBLogCursor_get(self
, DB_LAST
, NULL
);
3848 DBLogCursor_next(DBLogCursorObject
* self
)
3850 return _DBLogCursor_get(self
, DB_NEXT
, NULL
);
3854 DBLogCursor_prev(DBLogCursorObject
* self
)
3856 return _DBLogCursor_get(self
, DB_PREV
, NULL
);
3860 DBLogCursor_set(DBLogCursorObject
* self
, PyObject
* args
)
3864 if (!PyArg_ParseTuple(args
, "(ii):set", &lsn
.file
, &lsn
.offset
))
3867 return _DBLogCursor_get(self
, DB_SET
, &lsn
);
3872 /* --------------------------------------------------------------------- */
3873 /* DBCursor methods */
3877 DBC_close_internal(DBCursorObject
* self
)
3881 if (self
->dbc
!= NULL
) {
3882 EXTRACT_FROM_DOUBLE_LINKED_LIST(self
);
3884 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self
);
3888 MYDB_BEGIN_ALLOW_THREADS
;
3889 err
= _DBC_close(self
->dbc
);
3890 MYDB_END_ALLOW_THREADS
;
3898 DBC_close(DBCursorObject
* self
)
3900 return DBC_close_internal(self
);
3905 DBC_count(DBCursorObject
* self
, PyObject
* args
)
3911 if (!PyArg_ParseTuple(args
, "|i:count", &flags
))
3914 CHECK_CURSOR_NOT_CLOSED(self
);
3916 MYDB_BEGIN_ALLOW_THREADS
;
3917 err
= _DBC_count(self
->dbc
, &count
, flags
);
3918 MYDB_END_ALLOW_THREADS
;
3921 return NUMBER_FromLong(count
);
3926 DBC_current(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3928 return _DBCursor_get(self
,DB_CURRENT
,args
,kwargs
,"|iii:current");
3933 DBC_delete(DBCursorObject
* self
, PyObject
* args
)
3937 if (!PyArg_ParseTuple(args
, "|i:delete", &flags
))
3940 CHECK_CURSOR_NOT_CLOSED(self
);
3942 MYDB_BEGIN_ALLOW_THREADS
;
3943 err
= _DBC_del(self
->dbc
, flags
);
3944 MYDB_END_ALLOW_THREADS
;
3952 DBC_dup(DBCursorObject
* self
, PyObject
* args
)
3957 if (!PyArg_ParseTuple(args
, "|i:dup", &flags
))
3960 CHECK_CURSOR_NOT_CLOSED(self
);
3962 MYDB_BEGIN_ALLOW_THREADS
;
3963 err
= _DBC_dup(self
->dbc
, &dbc
, flags
);
3964 MYDB_END_ALLOW_THREADS
;
3967 return (PyObject
*) newDBCursorObject(dbc
, self
->txn
, self
->mydb
);
3971 DBC_first(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3973 return _DBCursor_get(self
,DB_FIRST
,args
,kwargs
,"|iii:first");
3978 DBC_get(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3981 PyObject
* keyobj
= NULL
;
3982 PyObject
* dataobj
= NULL
;
3983 PyObject
* retval
= NULL
;
3987 static char* kwnames
[] = { "key","data", "flags", "dlen", "doff",
3992 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:get", &kwnames
[2],
3993 &flags
, &dlen
, &doff
))
3996 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:get",
3998 &keyobj
, &flags
, &dlen
, &doff
))
4001 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:get",
4002 kwnames
, &keyobj
, &dataobj
,
4003 &flags
, &dlen
, &doff
))
4010 CHECK_CURSOR_NOT_CLOSED(self
);
4012 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
4014 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
4015 (!add_partial_dbt(&data
, dlen
, doff
)) )
4017 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
4021 MYDB_BEGIN_ALLOW_THREADS
;
4022 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
);
4023 MYDB_END_ALLOW_THREADS
;
4025 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
4026 && self
->mydb
->moduleFlags
.getReturnsNone
) {
4030 else if (makeDBError(err
)) {
4034 switch (_DB_get_type(self
->mydb
)) {
4041 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
4045 retval
= BuildValue_IS(*((db_recno_t
*)key
.data
), data
.data
, data
.size
);
4049 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
4054 DBC_pget(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
4057 PyObject
* keyobj
= NULL
;
4058 PyObject
* dataobj
= NULL
;
4059 PyObject
* retval
= NULL
;
4062 DBT key
, pkey
, data
;
4063 static char* kwnames_keyOnly
[] = { "key", "flags", "dlen", "doff", NULL
};
4064 static char* kwnames
[] = { "key", "data", "flags", "dlen", "doff", NULL
};
4068 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:pget", &kwnames
[2],
4069 &flags
, &dlen
, &doff
))
4072 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:pget",
4074 &keyobj
, &flags
, &dlen
, &doff
))
4077 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:pget",
4078 kwnames
, &keyobj
, &dataobj
,
4079 &flags
, &dlen
, &doff
))
4086 CHECK_CURSOR_NOT_CLOSED(self
);
4088 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
4090 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
4091 (!add_partial_dbt(&data
, dlen
, doff
)) ) {
4092 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
4097 pkey
.flags
= DB_DBT_MALLOC
;
4099 MYDB_BEGIN_ALLOW_THREADS
;
4100 err
= _DBC_pget(self
->dbc
, &key
, &pkey
, &data
, flags
);
4101 MYDB_END_ALLOW_THREADS
;
4103 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
4104 && self
->mydb
->moduleFlags
.getReturnsNone
) {
4108 else if (makeDBError(err
)) {
4114 dataObj
= Build_PyString(data
.data
, data
.size
);
4116 if (self
->mydb
->primaryDBType
== DB_RECNO
||
4117 self
->mydb
->primaryDBType
== DB_QUEUE
)
4118 pkeyObj
= NUMBER_FromLong(*(int *)pkey
.data
);
4120 pkeyObj
= Build_PyString(pkey
.data
, pkey
.size
);
4122 if (key
.data
&& key
.size
) /* return key, pkey and data */
4125 int type
= _DB_get_type(self
->mydb
);
4126 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
4127 keyObj
= NUMBER_FromLong(*(int *)key
.data
);
4129 keyObj
= Build_PyString(key
.data
, key
.size
);
4130 #if (PY_VERSION_HEX >= 0x02040000)
4131 retval
= PyTuple_Pack(3, keyObj
, pkeyObj
, dataObj
);
4133 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
4136 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
4138 else /* return just the pkey and data */
4140 #if (PY_VERSION_HEX >= 0x02040000)
4141 retval
= PyTuple_Pack(2, pkeyObj
, dataObj
);
4143 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
4150 /* the only time REALLOC should be set is if we used an integer
4151 * key that make_key_dbt malloc'd for us. always free these. */
4152 if (key
.flags
& DB_DBT_REALLOC
) { /* 'make_key_dbt' could do a 'malloc' */
4160 DBC_get_recno(DBCursorObject
* self
)
4167 CHECK_CURSOR_NOT_CLOSED(self
);
4172 MYDB_BEGIN_ALLOW_THREADS
;
4173 err
= _DBC_get(self
->dbc
, &key
, &data
, DB_GET_RECNO
);
4174 MYDB_END_ALLOW_THREADS
;
4177 recno
= *((db_recno_t
*)data
.data
);
4178 return NUMBER_FromLong(recno
);
4183 DBC_last(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
4185 return _DBCursor_get(self
,DB_LAST
,args
,kwargs
,"|iii:last");
4190 DBC_next(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
4192 return _DBCursor_get(self
,DB_NEXT
,args
,kwargs
,"|iii:next");
4197 DBC_prev(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
4199 return _DBCursor_get(self
,DB_PREV
,args
,kwargs
,"|iii:prev");
4204 DBC_put(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4207 PyObject
* keyobj
, *dataobj
;
4209 static char* kwnames
[] = { "key", "data", "flags", "dlen", "doff",
4214 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iii:put", kwnames
,
4215 &keyobj
, &dataobj
, &flags
, &dlen
, &doff
))
4218 CHECK_CURSOR_NOT_CLOSED(self
);
4220 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
4222 if (!make_dbt(dataobj
, &data
) ||
4223 !add_partial_dbt(&data
, dlen
, doff
) )
4225 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
4229 MYDB_BEGIN_ALLOW_THREADS
;
4230 err
= _DBC_put(self
->dbc
, &key
, &data
, flags
);
4231 MYDB_END_ALLOW_THREADS
;
4232 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
4239 DBC_set(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
4243 PyObject
* retval
, *keyobj
;
4244 static char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
4248 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set", kwnames
,
4249 &keyobj
, &flags
, &dlen
, &doff
))
4252 CHECK_CURSOR_NOT_CLOSED(self
);
4254 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
4258 if (!add_partial_dbt(&data
, dlen
, doff
)) {
4259 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
4263 MYDB_BEGIN_ALLOW_THREADS
;
4264 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
|DB_SET
);
4265 MYDB_END_ALLOW_THREADS
;
4266 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
4267 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
4271 else if (makeDBError(err
)) {
4275 switch (_DB_get_type(self
->mydb
)) {
4282 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
4286 retval
= BuildValue_IS(*((db_recno_t
*)key
.data
), data
.data
, data
.size
);
4289 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
4291 /* the only time REALLOC should be set is if we used an integer
4292 * key that make_key_dbt malloc'd for us. always free these. */
4293 if (key
.flags
& DB_DBT_REALLOC
) {
4294 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
4302 DBC_set_range(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4306 PyObject
* retval
, *keyobj
;
4307 static char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
4311 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set_range", kwnames
,
4312 &keyobj
, &flags
, &dlen
, &doff
))
4315 CHECK_CURSOR_NOT_CLOSED(self
);
4317 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
4321 if (!add_partial_dbt(&data
, dlen
, doff
)) {
4322 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
4325 MYDB_BEGIN_ALLOW_THREADS
;
4326 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RANGE
);
4327 MYDB_END_ALLOW_THREADS
;
4328 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
4329 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
4333 else if (makeDBError(err
)) {
4337 switch (_DB_get_type(self
->mydb
)) {
4344 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
4348 retval
= BuildValue_IS(*((db_recno_t
*)key
.data
), data
.data
, data
.size
);
4351 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
4353 /* the only time REALLOC should be set is if we used an integer
4354 * key that make_key_dbt malloc'd for us. always free these. */
4355 if (key
.flags
& DB_DBT_REALLOC
) {
4356 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
4363 _DBC_get_set_both(DBCursorObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
,
4364 int flags
, unsigned int returnsNone
)
4370 /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
4371 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
4373 if (!make_dbt(dataobj
, &data
)) {
4374 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
4378 MYDB_BEGIN_ALLOW_THREADS
;
4379 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
|DB_GET_BOTH
);
4380 MYDB_END_ALLOW_THREADS
;
4381 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && returnsNone
) {
4385 else if (makeDBError(err
)) {
4389 switch (_DB_get_type(self
->mydb
)) {
4396 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
4400 retval
= BuildValue_IS(*((db_recno_t
*)key
.data
), data
.data
, data
.size
);
4405 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
4410 DBC_get_both(DBCursorObject
* self
, PyObject
* args
)
4413 PyObject
*keyobj
, *dataobj
;
4415 if (!PyArg_ParseTuple(args
, "OO|i:get_both", &keyobj
, &dataobj
, &flags
))
4418 /* if the cursor is closed, self->mydb may be invalid */
4419 CHECK_CURSOR_NOT_CLOSED(self
);
4421 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
4422 self
->mydb
->moduleFlags
.getReturnsNone
);
4425 /* Return size of entry */
4427 DBC_get_current_size(DBCursorObject
* self
)
4429 int err
, flags
=DB_CURRENT
;
4430 PyObject
* retval
= NULL
;
4433 CHECK_CURSOR_NOT_CLOSED(self
);
4437 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
4438 getting the record size. */
4439 data
.flags
= DB_DBT_USERMEM
;
4441 MYDB_BEGIN_ALLOW_THREADS
;
4442 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
);
4443 MYDB_END_ALLOW_THREADS
;
4444 if (err
== DB_BUFFER_SMALL
|| !err
) {
4445 /* DB_BUFFER_SMALL means positive size, !err means zero length value */
4446 retval
= NUMBER_FromLong((long)data
.size
);
4455 DBC_set_both(DBCursorObject
* self
, PyObject
* args
)
4458 PyObject
*keyobj
, *dataobj
;
4460 if (!PyArg_ParseTuple(args
, "OO|i:set_both", &keyobj
, &dataobj
, &flags
))
4463 /* if the cursor is closed, self->mydb may be invalid */
4464 CHECK_CURSOR_NOT_CLOSED(self
);
4466 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
4467 self
->mydb
->moduleFlags
.cursorSetReturnsNone
);
4472 DBC_set_recno(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
4474 int err
, irecno
, flags
=0;
4480 static char* kwnames
[] = { "recno","flags", "dlen", "doff", NULL
};
4482 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|iii:set_recno", kwnames
,
4483 &irecno
, &flags
, &dlen
, &doff
))
4486 CHECK_CURSOR_NOT_CLOSED(self
);
4489 recno
= (db_recno_t
) irecno
;
4490 /* use allocated space so DB will be able to realloc room for the real
4492 key
.data
= malloc(sizeof(db_recno_t
));
4493 if (key
.data
== NULL
) {
4494 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
4497 key
.size
= sizeof(db_recno_t
);
4498 key
.ulen
= key
.size
;
4499 memcpy(key
.data
, &recno
, sizeof(db_recno_t
));
4500 key
.flags
= DB_DBT_REALLOC
;
4503 if (!add_partial_dbt(&data
, dlen
, doff
)) {
4508 MYDB_BEGIN_ALLOW_THREADS
;
4509 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RECNO
);
4510 MYDB_END_ALLOW_THREADS
;
4511 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
4512 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
4516 else if (makeDBError(err
)) {
4519 else { /* Can only be used for BTrees, so no need to return int key */
4520 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
4529 DBC_consume(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
4531 return _DBCursor_get(self
,DB_CONSUME
,args
,kwargs
,"|iii:consume");
4536 DBC_next_dup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
4538 return _DBCursor_get(self
,DB_NEXT_DUP
,args
,kwargs
,"|iii:next_dup");
4543 DBC_next_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
4545 return _DBCursor_get(self
,DB_NEXT_NODUP
,args
,kwargs
,"|iii:next_nodup");
4550 DBC_prev_dup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
4552 return _DBCursor_get(self
,DB_PREV_DUP
,args
,kwargs
,"|iii:prev_dup");
4557 DBC_prev_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
4559 return _DBCursor_get(self
,DB_PREV_NODUP
,args
,kwargs
,"|iii:prev_nodup");
4564 DBC_join_item(DBCursorObject
* self
, PyObject
* args
)
4570 if (!PyArg_ParseTuple(args
, "|i:join_item", &flags
))
4573 CHECK_CURSOR_NOT_CLOSED(self
);
4578 MYDB_BEGIN_ALLOW_THREADS
;
4579 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
| DB_JOIN_ITEM
);
4580 MYDB_END_ALLOW_THREADS
;
4581 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
4582 && self
->mydb
->moduleFlags
.getReturnsNone
) {
4586 else if (makeDBError(err
)) {
4590 retval
= BuildValue_S(key
.data
, key
.size
);
4599 DBC_set_priority(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4602 static char* kwnames
[] = { "priority", NULL
};
4604 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i:set_priority", kwnames
,
4608 CHECK_CURSOR_NOT_CLOSED(self
);
4610 MYDB_BEGIN_ALLOW_THREADS
;
4611 err
= self
->dbc
->set_priority(self
->dbc
, priority
);
4612 MYDB_END_ALLOW_THREADS
;
4619 DBC_get_priority(DBCursorObject
* self
)
4622 DB_CACHE_PRIORITY priority
;
4624 CHECK_CURSOR_NOT_CLOSED(self
);
4626 MYDB_BEGIN_ALLOW_THREADS
;
4627 err
= self
->dbc
->get_priority(self
->dbc
, &priority
);
4628 MYDB_END_ALLOW_THREADS
;
4630 return NUMBER_FromLong(priority
);
4636 /* --------------------------------------------------------------------- */
4641 DBEnv_close_internal(DBEnvObject
* self
, int flags
)
4646 if (!self
->closed
) { /* Don't close more than once */
4647 while(self
->children_txns
) {
4648 dummy
= DBTxn_abort_discard_internal(self
->children_txns
, 0);
4651 while(self
->children_dbs
) {
4652 dummy
= DB_close_internal(self
->children_dbs
, 0, 0);
4655 while(self
->children_logcursors
) {
4656 dummy
= DBLogCursor_close_internal(self
->children_logcursors
);
4663 MYDB_BEGIN_ALLOW_THREADS
;
4664 err
= self
->db_env
->close(self
->db_env
, flags
);
4665 MYDB_END_ALLOW_THREADS
;
4666 /* after calling DBEnv->close, regardless of error, this DBEnv
4667 * may not be accessed again (Berkeley DB docs). */
4668 self
->db_env
= NULL
;
4675 DBEnv_close(DBEnvObject
* self
, PyObject
* args
)
4679 if (!PyArg_ParseTuple(args
, "|i:close", &flags
))
4681 return DBEnv_close_internal(self
, flags
);
4686 DBEnv_open(DBEnvObject
* self
, PyObject
* args
)
4688 int err
, flags
=0, mode
=0660;
4691 if (!PyArg_ParseTuple(args
, "z|ii:open", &db_home
, &flags
, &mode
))
4694 CHECK_ENV_NOT_CLOSED(self
);
4696 MYDB_BEGIN_ALLOW_THREADS
;
4697 err
= self
->db_env
->open(self
->db_env
, db_home
, flags
, mode
);
4698 MYDB_END_ALLOW_THREADS
;
4701 self
->flags
= flags
;
4707 DBEnv_memp_stat(DBEnvObject
* self
, PyObject
* args
, PyObject
*kwargs
)
4711 DB_MPOOL_FSTAT
**fsp
, **fsp2
;
4712 PyObject
* d
= NULL
, *d2
, *d3
, *r
;
4713 u_int32_t flags
= 0;
4714 static char* kwnames
[] = { "flags", NULL
};
4716 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:memp_stat",
4720 CHECK_ENV_NOT_CLOSED(self
);
4722 MYDB_BEGIN_ALLOW_THREADS
;
4723 err
= self
->db_env
->memp_stat(self
->db_env
, &gsp
, &fsp
, flags
);
4724 MYDB_END_ALLOW_THREADS
;
4727 /* Turn the stat structure into a dictionary */
4735 #define MAKE_ENTRY(name) _addIntToDict(d, #name, gsp->st_##name)
4740 MAKE_ENTRY(max_ncache
);
4742 MAKE_ENTRY(regsize
);
4744 MAKE_ENTRY(mmapsize
);
4745 MAKE_ENTRY(maxopenfd
);
4746 MAKE_ENTRY(maxwrite
);
4747 MAKE_ENTRY(maxwrite_sleep
);
4750 MAKE_ENTRY(cache_hit
);
4751 MAKE_ENTRY(cache_miss
);
4752 MAKE_ENTRY(page_create
);
4753 MAKE_ENTRY(page_in
);
4754 MAKE_ENTRY(page_out
);
4755 MAKE_ENTRY(ro_evict
);
4756 MAKE_ENTRY(rw_evict
);
4757 MAKE_ENTRY(page_trickle
);
4759 MAKE_ENTRY(page_clean
);
4760 MAKE_ENTRY(page_dirty
);
4761 MAKE_ENTRY(hash_buckets
);
4762 MAKE_ENTRY(hash_searches
);
4763 MAKE_ENTRY(hash_longest
);
4764 MAKE_ENTRY(hash_examined
);
4765 MAKE_ENTRY(hash_nowait
);
4766 MAKE_ENTRY(hash_wait
);
4768 MAKE_ENTRY(hash_max_nowait
);
4770 MAKE_ENTRY(hash_max_wait
);
4771 MAKE_ENTRY(region_wait
);
4772 MAKE_ENTRY(region_nowait
);
4774 MAKE_ENTRY(mvcc_frozen
);
4775 MAKE_ENTRY(mvcc_thawed
);
4776 MAKE_ENTRY(mvcc_freed
);
4779 MAKE_ENTRY(alloc_buckets
);
4780 MAKE_ENTRY(alloc_max_buckets
);
4781 MAKE_ENTRY(alloc_pages
);
4782 MAKE_ENTRY(alloc_max_pages
);
4784 MAKE_ENTRY(io_wait
);
4787 MAKE_ENTRY(sync_interrupted
);
4800 #define MAKE_ENTRY(name) _addIntToDict(d3, #name, (*fsp2)->st_##name)
4801 for(fsp2
=fsp
;*fsp2
; fsp2
++) {
4810 MAKE_ENTRY(pagesize
);
4811 MAKE_ENTRY(cache_hit
);
4812 MAKE_ENTRY(cache_miss
);
4814 MAKE_ENTRY(page_create
);
4815 MAKE_ENTRY(page_in
);
4816 MAKE_ENTRY(page_out
);
4817 if(PyDict_SetItemString(d2
, (*fsp2
)->file_name
, d3
)) {
4831 r
= Py_BuildValue("(OO)", d
, d2
);
4839 DBEnv_memp_stat_print(DBEnvObject
* self
, PyObject
* args
, PyObject
*kwargs
)
4843 static char* kwnames
[] = { "flags", NULL
};
4845 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:memp_stat_print",
4850 CHECK_ENV_NOT_CLOSED(self
);
4851 MYDB_BEGIN_ALLOW_THREADS
;
4852 err
= self
->db_env
->memp_stat_print(self
->db_env
, flags
);
4853 MYDB_END_ALLOW_THREADS
;
4861 DBEnv_memp_trickle(DBEnvObject
* self
, PyObject
* args
)
4863 int err
, percent
, nwrotep
;
4865 if (!PyArg_ParseTuple(args
, "i:memp_trickle", &percent
))
4867 CHECK_ENV_NOT_CLOSED(self
);
4868 MYDB_BEGIN_ALLOW_THREADS
;
4869 err
= self
->db_env
->memp_trickle(self
->db_env
, percent
, &nwrotep
);
4870 MYDB_END_ALLOW_THREADS
;
4872 return NUMBER_FromLong(nwrotep
);
4876 DBEnv_memp_sync(DBEnvObject
* self
, PyObject
* args
)
4879 DB_LSN lsn
= {0, 0};
4880 DB_LSN
*lsn_p
= NULL
;
4882 if (!PyArg_ParseTuple(args
, "|(ii):memp_sync", &lsn
.file
, &lsn
.offset
))
4884 if ((lsn
.file
!=0) || (lsn
.offset
!=0)) {
4887 CHECK_ENV_NOT_CLOSED(self
);
4888 MYDB_BEGIN_ALLOW_THREADS
;
4889 err
= self
->db_env
->memp_sync(self
->db_env
, lsn_p
);
4890 MYDB_END_ALLOW_THREADS
;
4896 DBEnv_remove(DBEnvObject
* self
, PyObject
* args
)
4901 if (!PyArg_ParseTuple(args
, "s|i:remove", &db_home
, &flags
))
4903 CHECK_ENV_NOT_CLOSED(self
);
4904 MYDB_BEGIN_ALLOW_THREADS
;
4905 err
= self
->db_env
->remove(self
->db_env
, db_home
, flags
);
4906 MYDB_END_ALLOW_THREADS
;
4912 DBEnv_dbremove(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4917 char *database
= NULL
;
4918 PyObject
*txnobj
= NULL
;
4920 static char* kwnames
[] = { "file", "database", "txn", "flags",
4923 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zOi:dbremove", kwnames
,
4924 &file
, &database
, &txnobj
, &flags
)) {
4927 if (!checkTxnObj(txnobj
, &txn
)) {
4930 CHECK_ENV_NOT_CLOSED(self
);
4931 MYDB_BEGIN_ALLOW_THREADS
;
4932 err
= self
->db_env
->dbremove(self
->db_env
, txn
, file
, database
, flags
);
4933 MYDB_END_ALLOW_THREADS
;
4939 DBEnv_dbrename(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4944 char *database
= NULL
;
4945 char *newname
= NULL
;
4946 PyObject
*txnobj
= NULL
;
4948 static char* kwnames
[] = { "file", "database", "newname", "txn",
4951 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "szs|Oi:dbrename", kwnames
,
4952 &file
, &database
, &newname
, &txnobj
, &flags
)) {
4955 if (!checkTxnObj(txnobj
, &txn
)) {
4958 CHECK_ENV_NOT_CLOSED(self
);
4959 MYDB_BEGIN_ALLOW_THREADS
;
4960 err
= self
->db_env
->dbrename(self
->db_env
, txn
, file
, database
, newname
,
4962 MYDB_END_ALLOW_THREADS
;
4970 DBEnv_set_encrypt(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4974 char *passwd
= NULL
;
4975 static char* kwnames
[] = { "passwd", "flags", NULL
};
4977 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
4982 MYDB_BEGIN_ALLOW_THREADS
;
4983 err
= self
->db_env
->set_encrypt(self
->db_env
, passwd
, flags
);
4984 MYDB_END_ALLOW_THREADS
;
4992 DBEnv_get_encrypt_flags(DBEnvObject
* self
)
4997 CHECK_ENV_NOT_CLOSED(self
);
4999 MYDB_BEGIN_ALLOW_THREADS
;
5000 err
= self
->db_env
->get_encrypt_flags(self
->db_env
, &flags
);
5001 MYDB_END_ALLOW_THREADS
;
5005 return NUMBER_FromLong(flags
);
5009 DBEnv_get_timeout(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5014 static char* kwnames
[] = {"flag", NULL
};
5016 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i:get_timeout", kwnames
,
5020 CHECK_ENV_NOT_CLOSED(self
);
5022 MYDB_BEGIN_ALLOW_THREADS
;
5023 err
= self
->db_env
->get_timeout(self
->db_env
, &timeout
, flag
);
5024 MYDB_END_ALLOW_THREADS
;
5026 return NUMBER_FromLong(timeout
);
5032 DBEnv_set_timeout(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5036 u_int32_t timeout
= 0;
5037 static char* kwnames
[] = { "timeout", "flags", NULL
};
5039 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ii:set_timeout", kwnames
,
5040 &timeout
, &flags
)) {
5044 MYDB_BEGIN_ALLOW_THREADS
;
5045 err
= self
->db_env
->set_timeout(self
->db_env
, (db_timeout_t
)timeout
, flags
);
5046 MYDB_END_ALLOW_THREADS
;
5053 DBEnv_set_shm_key(DBEnvObject
* self
, PyObject
* args
)
5058 if (!PyArg_ParseTuple(args
, "l:set_shm_key", &shm_key
))
5060 CHECK_ENV_NOT_CLOSED(self
);
5062 err
= self
->db_env
->set_shm_key(self
->db_env
, shm_key
);
5069 DBEnv_get_shm_key(DBEnvObject
* self
)
5074 CHECK_ENV_NOT_CLOSED(self
);
5076 MYDB_BEGIN_ALLOW_THREADS
;
5077 err
= self
->db_env
->get_shm_key(self
->db_env
, &shm_key
);
5078 MYDB_END_ALLOW_THREADS
;
5082 return NUMBER_FromLong(shm_key
);
5088 DBEnv_set_cache_max(DBEnvObject
* self
, PyObject
* args
)
5090 int err
, gbytes
, bytes
;
5092 if (!PyArg_ParseTuple(args
, "ii:set_cache_max",
5095 CHECK_ENV_NOT_CLOSED(self
);
5097 MYDB_BEGIN_ALLOW_THREADS
;
5098 err
= self
->db_env
->set_cache_max(self
->db_env
, gbytes
, bytes
);
5099 MYDB_END_ALLOW_THREADS
;
5105 DBEnv_get_cache_max(DBEnvObject
* self
)
5108 u_int32_t gbytes
, bytes
;
5110 CHECK_ENV_NOT_CLOSED(self
);
5112 MYDB_BEGIN_ALLOW_THREADS
;
5113 err
= self
->db_env
->get_cache_max(self
->db_env
, &gbytes
, &bytes
);
5114 MYDB_END_ALLOW_THREADS
;
5118 return Py_BuildValue("(ii)", gbytes
, bytes
);
5124 DBEnv_set_thread_count(DBEnvObject
* self
, PyObject
* args
)
5129 if (!PyArg_ParseTuple(args
, "i:set_thread_count", &count
))
5131 CHECK_ENV_NOT_CLOSED(self
);
5133 MYDB_BEGIN_ALLOW_THREADS
;
5134 err
= self
->db_env
->set_thread_count(self
->db_env
, count
);
5135 MYDB_END_ALLOW_THREADS
;
5141 DBEnv_get_thread_count(DBEnvObject
* self
)
5146 CHECK_ENV_NOT_CLOSED(self
);
5148 MYDB_BEGIN_ALLOW_THREADS
;
5149 err
= self
->db_env
->get_thread_count(self
->db_env
, &count
);
5150 MYDB_END_ALLOW_THREADS
;
5152 return NUMBER_FromLong(count
);
5157 DBEnv_set_cachesize(DBEnvObject
* self
, PyObject
* args
)
5159 int err
, gbytes
=0, bytes
=0, ncache
=0;
5161 if (!PyArg_ParseTuple(args
, "ii|i:set_cachesize",
5162 &gbytes
, &bytes
, &ncache
))
5164 CHECK_ENV_NOT_CLOSED(self
);
5166 MYDB_BEGIN_ALLOW_THREADS
;
5167 err
= self
->db_env
->set_cachesize(self
->db_env
, gbytes
, bytes
, ncache
);
5168 MYDB_END_ALLOW_THREADS
;
5175 DBEnv_get_cachesize(DBEnvObject
* self
)
5178 u_int32_t gbytes
, bytes
;
5181 CHECK_ENV_NOT_CLOSED(self
);
5183 MYDB_BEGIN_ALLOW_THREADS
;
5184 err
= self
->db_env
->get_cachesize(self
->db_env
, &gbytes
, &bytes
, &ncache
);
5185 MYDB_END_ALLOW_THREADS
;
5189 return Py_BuildValue("(iii)", gbytes
, bytes
, ncache
);
5195 DBEnv_set_flags(DBEnvObject
* self
, PyObject
* args
)
5197 int err
, flags
=0, onoff
=0;
5199 if (!PyArg_ParseTuple(args
, "ii:set_flags",
5202 CHECK_ENV_NOT_CLOSED(self
);
5204 MYDB_BEGIN_ALLOW_THREADS
;
5205 err
= self
->db_env
->set_flags(self
->db_env
, flags
, onoff
);
5206 MYDB_END_ALLOW_THREADS
;
5213 DBEnv_get_flags(DBEnvObject
* self
)
5218 CHECK_ENV_NOT_CLOSED(self
);
5220 MYDB_BEGIN_ALLOW_THREADS
;
5221 err
= self
->db_env
->get_flags(self
->db_env
, &flags
);
5222 MYDB_END_ALLOW_THREADS
;
5224 return NUMBER_FromLong(flags
);
5230 DBEnv_log_set_config(DBEnvObject
* self
, PyObject
* args
)
5232 int err
, flags
, onoff
;
5234 if (!PyArg_ParseTuple(args
, "ii:log_set_config",
5237 CHECK_ENV_NOT_CLOSED(self
);
5239 MYDB_BEGIN_ALLOW_THREADS
;
5240 err
= self
->db_env
->log_set_config(self
->db_env
, flags
, onoff
);
5241 MYDB_END_ALLOW_THREADS
;
5247 DBEnv_log_get_config(DBEnvObject
* self
, PyObject
* args
)
5249 int err
, flag
, onoff
;
5251 if (!PyArg_ParseTuple(args
, "i:log_get_config", &flag
))
5253 CHECK_ENV_NOT_CLOSED(self
);
5255 MYDB_BEGIN_ALLOW_THREADS
;
5256 err
= self
->db_env
->log_get_config(self
->db_env
, flag
, &onoff
);
5257 MYDB_END_ALLOW_THREADS
;
5259 return PyBool_FromLong(onoff
);
5261 #endif /* DBVER >= 47 */
5265 DBEnv_mutex_set_max(DBEnvObject
* self
, PyObject
* args
)
5270 if (!PyArg_ParseTuple(args
, "i:mutex_set_max", &value
))
5273 CHECK_ENV_NOT_CLOSED(self
);
5275 MYDB_BEGIN_ALLOW_THREADS
;
5276 err
= self
->db_env
->mutex_set_max(self
->db_env
, value
);
5277 MYDB_END_ALLOW_THREADS
;
5284 DBEnv_mutex_get_max(DBEnvObject
* self
)
5289 CHECK_ENV_NOT_CLOSED(self
);
5291 MYDB_BEGIN_ALLOW_THREADS
;
5292 err
= self
->db_env
->mutex_get_max(self
->db_env
, &value
);
5293 MYDB_END_ALLOW_THREADS
;
5297 return NUMBER_FromLong(value
);
5301 DBEnv_mutex_set_align(DBEnvObject
* self
, PyObject
* args
)
5306 if (!PyArg_ParseTuple(args
, "i:mutex_set_align", &align
))
5309 CHECK_ENV_NOT_CLOSED(self
);
5311 MYDB_BEGIN_ALLOW_THREADS
;
5312 err
= self
->db_env
->mutex_set_align(self
->db_env
, align
);
5313 MYDB_END_ALLOW_THREADS
;
5320 DBEnv_mutex_get_align(DBEnvObject
* self
)
5325 CHECK_ENV_NOT_CLOSED(self
);
5327 MYDB_BEGIN_ALLOW_THREADS
;
5328 err
= self
->db_env
->mutex_get_align(self
->db_env
, &align
);
5329 MYDB_END_ALLOW_THREADS
;
5333 return NUMBER_FromLong(align
);
5337 DBEnv_mutex_set_increment(DBEnvObject
* self
, PyObject
* args
)
5342 if (!PyArg_ParseTuple(args
, "i:mutex_set_increment", &increment
))
5345 CHECK_ENV_NOT_CLOSED(self
);
5347 MYDB_BEGIN_ALLOW_THREADS
;
5348 err
= self
->db_env
->mutex_set_increment(self
->db_env
, increment
);
5349 MYDB_END_ALLOW_THREADS
;
5356 DBEnv_mutex_get_increment(DBEnvObject
* self
)
5359 u_int32_t increment
;
5361 CHECK_ENV_NOT_CLOSED(self
);
5363 MYDB_BEGIN_ALLOW_THREADS
;
5364 err
= self
->db_env
->mutex_get_increment(self
->db_env
, &increment
);
5365 MYDB_END_ALLOW_THREADS
;
5369 return NUMBER_FromLong(increment
);
5373 DBEnv_mutex_set_tas_spins(DBEnvObject
* self
, PyObject
* args
)
5378 if (!PyArg_ParseTuple(args
, "i:mutex_set_tas_spins", &tas_spins
))
5381 CHECK_ENV_NOT_CLOSED(self
);
5383 MYDB_BEGIN_ALLOW_THREADS
;
5384 err
= self
->db_env
->mutex_set_tas_spins(self
->db_env
, tas_spins
);
5385 MYDB_END_ALLOW_THREADS
;
5392 DBEnv_mutex_get_tas_spins(DBEnvObject
* self
)
5395 u_int32_t tas_spins
;
5397 CHECK_ENV_NOT_CLOSED(self
);
5399 MYDB_BEGIN_ALLOW_THREADS
;
5400 err
= self
->db_env
->mutex_get_tas_spins(self
->db_env
, &tas_spins
);
5401 MYDB_END_ALLOW_THREADS
;
5405 return NUMBER_FromLong(tas_spins
);
5410 DBEnv_set_data_dir(DBEnvObject
* self
, PyObject
* args
)
5415 if (!PyArg_ParseTuple(args
, "s:set_data_dir", &dir
))
5417 CHECK_ENV_NOT_CLOSED(self
);
5419 MYDB_BEGIN_ALLOW_THREADS
;
5420 err
= self
->db_env
->set_data_dir(self
->db_env
, dir
);
5421 MYDB_END_ALLOW_THREADS
;
5428 DBEnv_get_data_dirs(DBEnvObject
* self
)
5436 CHECK_ENV_NOT_CLOSED(self
);
5438 MYDB_BEGIN_ALLOW_THREADS
;
5439 err
= self
->db_env
->get_data_dirs(self
->db_env
, &dirpp
);
5440 MYDB_END_ALLOW_THREADS
;
5445 ** Calculate size. Python C API
5446 ** actually allows for tuple resizing,
5447 ** but this is simple enough.
5449 for (size
=0; *(dirpp
+size
) ; size
++);
5451 tuple
= PyTuple_New(size
);
5455 for (i
=0; i
<size
; i
++) {
5456 item
= PyBytes_FromString (*(dirpp
+i
));
5462 PyTuple_SET_ITEM(tuple
, i
, item
);
5470 DBEnv_set_lg_filemode(DBEnvObject
* self
, PyObject
* args
)
5474 if (!PyArg_ParseTuple(args
, "i:set_lg_filemode", &filemode
))
5476 CHECK_ENV_NOT_CLOSED(self
);
5478 MYDB_BEGIN_ALLOW_THREADS
;
5479 err
= self
->db_env
->set_lg_filemode(self
->db_env
, filemode
);
5480 MYDB_END_ALLOW_THREADS
;
5486 DBEnv_get_lg_filemode(DBEnvObject
* self
)
5490 CHECK_ENV_NOT_CLOSED(self
);
5492 MYDB_BEGIN_ALLOW_THREADS
;
5493 err
= self
->db_env
->get_lg_filemode(self
->db_env
, &filemode
);
5494 MYDB_END_ALLOW_THREADS
;
5496 return NUMBER_FromLong(filemode
);
5501 DBEnv_set_lg_bsize(DBEnvObject
* self
, PyObject
* args
)
5505 if (!PyArg_ParseTuple(args
, "i:set_lg_bsize", &lg_bsize
))
5507 CHECK_ENV_NOT_CLOSED(self
);
5509 MYDB_BEGIN_ALLOW_THREADS
;
5510 err
= self
->db_env
->set_lg_bsize(self
->db_env
, lg_bsize
);
5511 MYDB_END_ALLOW_THREADS
;
5518 DBEnv_get_lg_bsize(DBEnvObject
* self
)
5523 CHECK_ENV_NOT_CLOSED(self
);
5525 MYDB_BEGIN_ALLOW_THREADS
;
5526 err
= self
->db_env
->get_lg_bsize(self
->db_env
, &lg_bsize
);
5527 MYDB_END_ALLOW_THREADS
;
5529 return NUMBER_FromLong(lg_bsize
);
5534 DBEnv_set_lg_dir(DBEnvObject
* self
, PyObject
* args
)
5539 if (!PyArg_ParseTuple(args
, "s:set_lg_dir", &dir
))
5541 CHECK_ENV_NOT_CLOSED(self
);
5543 MYDB_BEGIN_ALLOW_THREADS
;
5544 err
= self
->db_env
->set_lg_dir(self
->db_env
, dir
);
5545 MYDB_END_ALLOW_THREADS
;
5552 DBEnv_get_lg_dir(DBEnvObject
* self
)
5557 CHECK_ENV_NOT_CLOSED(self
);
5559 MYDB_BEGIN_ALLOW_THREADS
;
5560 err
= self
->db_env
->get_lg_dir(self
->db_env
, &dirp
);
5561 MYDB_END_ALLOW_THREADS
;
5563 return PyBytes_FromString(dirp
);
5568 DBEnv_set_lg_max(DBEnvObject
* self
, PyObject
* args
)
5572 if (!PyArg_ParseTuple(args
, "i:set_lg_max", &lg_max
))
5574 CHECK_ENV_NOT_CLOSED(self
);
5576 MYDB_BEGIN_ALLOW_THREADS
;
5577 err
= self
->db_env
->set_lg_max(self
->db_env
, lg_max
);
5578 MYDB_END_ALLOW_THREADS
;
5585 DBEnv_get_lg_max(DBEnvObject
* self
)
5590 CHECK_ENV_NOT_CLOSED(self
);
5592 MYDB_BEGIN_ALLOW_THREADS
;
5593 err
= self
->db_env
->get_lg_max(self
->db_env
, &lg_max
);
5594 MYDB_END_ALLOW_THREADS
;
5596 return NUMBER_FromLong(lg_max
);
5602 DBEnv_set_lg_regionmax(DBEnvObject
* self
, PyObject
* args
)
5606 if (!PyArg_ParseTuple(args
, "i:set_lg_regionmax", &lg_max
))
5608 CHECK_ENV_NOT_CLOSED(self
);
5610 MYDB_BEGIN_ALLOW_THREADS
;
5611 err
= self
->db_env
->set_lg_regionmax(self
->db_env
, lg_max
);
5612 MYDB_END_ALLOW_THREADS
;
5619 DBEnv_get_lg_regionmax(DBEnvObject
* self
)
5622 u_int32_t lg_regionmax
;
5624 CHECK_ENV_NOT_CLOSED(self
);
5626 MYDB_BEGIN_ALLOW_THREADS
;
5627 err
= self
->db_env
->get_lg_regionmax(self
->db_env
, &lg_regionmax
);
5628 MYDB_END_ALLOW_THREADS
;
5630 return NUMBER_FromLong(lg_regionmax
);
5636 DBEnv_set_lk_partitions(DBEnvObject
* self
, PyObject
* args
)
5638 int err
, lk_partitions
;
5640 if (!PyArg_ParseTuple(args
, "i:set_lk_partitions", &lk_partitions
))
5642 CHECK_ENV_NOT_CLOSED(self
);
5644 MYDB_BEGIN_ALLOW_THREADS
;
5645 err
= self
->db_env
->set_lk_partitions(self
->db_env
, lk_partitions
);
5646 MYDB_END_ALLOW_THREADS
;
5652 DBEnv_get_lk_partitions(DBEnvObject
* self
)
5655 u_int32_t lk_partitions
;
5657 CHECK_ENV_NOT_CLOSED(self
);
5659 MYDB_BEGIN_ALLOW_THREADS
;
5660 err
= self
->db_env
->get_lk_partitions(self
->db_env
, &lk_partitions
);
5661 MYDB_END_ALLOW_THREADS
;
5663 return NUMBER_FromLong(lk_partitions
);
5668 DBEnv_set_lk_detect(DBEnvObject
* self
, PyObject
* args
)
5672 if (!PyArg_ParseTuple(args
, "i:set_lk_detect", &lk_detect
))
5674 CHECK_ENV_NOT_CLOSED(self
);
5676 MYDB_BEGIN_ALLOW_THREADS
;
5677 err
= self
->db_env
->set_lk_detect(self
->db_env
, lk_detect
);
5678 MYDB_END_ALLOW_THREADS
;
5685 DBEnv_get_lk_detect(DBEnvObject
* self
)
5688 u_int32_t lk_detect
;
5690 CHECK_ENV_NOT_CLOSED(self
);
5692 MYDB_BEGIN_ALLOW_THREADS
;
5693 err
= self
->db_env
->get_lk_detect(self
->db_env
, &lk_detect
);
5694 MYDB_END_ALLOW_THREADS
;
5696 return NUMBER_FromLong(lk_detect
);
5703 DBEnv_set_lk_max(DBEnvObject
* self
, PyObject
* args
)
5707 if (!PyArg_ParseTuple(args
, "i:set_lk_max", &max
))
5709 CHECK_ENV_NOT_CLOSED(self
);
5711 MYDB_BEGIN_ALLOW_THREADS
;
5712 err
= self
->db_env
->set_lk_max(self
->db_env
, max
);
5713 MYDB_END_ALLOW_THREADS
;
5722 DBEnv_set_lk_max_locks(DBEnvObject
* self
, PyObject
* args
)
5726 if (!PyArg_ParseTuple(args
, "i:set_lk_max_locks", &max
))
5728 CHECK_ENV_NOT_CLOSED(self
);
5730 MYDB_BEGIN_ALLOW_THREADS
;
5731 err
= self
->db_env
->set_lk_max_locks(self
->db_env
, max
);
5732 MYDB_END_ALLOW_THREADS
;
5739 DBEnv_get_lk_max_locks(DBEnvObject
* self
)
5744 CHECK_ENV_NOT_CLOSED(self
);
5746 MYDB_BEGIN_ALLOW_THREADS
;
5747 err
= self
->db_env
->get_lk_max_locks(self
->db_env
, &lk_max
);
5748 MYDB_END_ALLOW_THREADS
;
5750 return NUMBER_FromLong(lk_max
);
5755 DBEnv_set_lk_max_lockers(DBEnvObject
* self
, PyObject
* args
)
5759 if (!PyArg_ParseTuple(args
, "i:set_lk_max_lockers", &max
))
5761 CHECK_ENV_NOT_CLOSED(self
);
5763 MYDB_BEGIN_ALLOW_THREADS
;
5764 err
= self
->db_env
->set_lk_max_lockers(self
->db_env
, max
);
5765 MYDB_END_ALLOW_THREADS
;
5772 DBEnv_get_lk_max_lockers(DBEnvObject
* self
)
5777 CHECK_ENV_NOT_CLOSED(self
);
5779 MYDB_BEGIN_ALLOW_THREADS
;
5780 err
= self
->db_env
->get_lk_max_lockers(self
->db_env
, &lk_max
);
5781 MYDB_END_ALLOW_THREADS
;
5783 return NUMBER_FromLong(lk_max
);
5788 DBEnv_set_lk_max_objects(DBEnvObject
* self
, PyObject
* args
)
5792 if (!PyArg_ParseTuple(args
, "i:set_lk_max_objects", &max
))
5794 CHECK_ENV_NOT_CLOSED(self
);
5796 MYDB_BEGIN_ALLOW_THREADS
;
5797 err
= self
->db_env
->set_lk_max_objects(self
->db_env
, max
);
5798 MYDB_END_ALLOW_THREADS
;
5805 DBEnv_get_lk_max_objects(DBEnvObject
* self
)
5810 CHECK_ENV_NOT_CLOSED(self
);
5812 MYDB_BEGIN_ALLOW_THREADS
;
5813 err
= self
->db_env
->get_lk_max_objects(self
->db_env
, &lk_max
);
5814 MYDB_END_ALLOW_THREADS
;
5816 return NUMBER_FromLong(lk_max
);
5822 DBEnv_get_mp_mmapsize(DBEnvObject
* self
)
5827 CHECK_ENV_NOT_CLOSED(self
);
5829 MYDB_BEGIN_ALLOW_THREADS
;
5830 err
= self
->db_env
->get_mp_mmapsize(self
->db_env
, &mmapsize
);
5831 MYDB_END_ALLOW_THREADS
;
5833 return NUMBER_FromLong(mmapsize
);
5839 DBEnv_set_mp_mmapsize(DBEnvObject
* self
, PyObject
* args
)
5841 int err
, mp_mmapsize
;
5843 if (!PyArg_ParseTuple(args
, "i:set_mp_mmapsize", &mp_mmapsize
))
5845 CHECK_ENV_NOT_CLOSED(self
);
5847 MYDB_BEGIN_ALLOW_THREADS
;
5848 err
= self
->db_env
->set_mp_mmapsize(self
->db_env
, mp_mmapsize
);
5849 MYDB_END_ALLOW_THREADS
;
5856 DBEnv_set_tmp_dir(DBEnvObject
* self
, PyObject
* args
)
5861 if (!PyArg_ParseTuple(args
, "s:set_tmp_dir", &dir
))
5863 CHECK_ENV_NOT_CLOSED(self
);
5865 MYDB_BEGIN_ALLOW_THREADS
;
5866 err
= self
->db_env
->set_tmp_dir(self
->db_env
, dir
);
5867 MYDB_END_ALLOW_THREADS
;
5875 DBEnv_get_tmp_dir(DBEnvObject
* self
)
5880 CHECK_ENV_NOT_CLOSED(self
);
5882 MYDB_BEGIN_ALLOW_THREADS
;
5883 err
= self
->db_env
->get_tmp_dir(self
->db_env
, &dirpp
);
5884 MYDB_END_ALLOW_THREADS
;
5888 return PyBytes_FromString(dirpp
);
5894 DBEnv_txn_recover(DBEnvObject
* self
)
5896 int flags
= DB_FIRST
;
5898 PyObject
*list
, *tuple
, *gid
;
5900 #define PREPLIST_LEN 16
5901 DB_PREPLIST preplist
[PREPLIST_LEN
];
5908 CHECK_ENV_NOT_CLOSED(self
);
5914 MYDB_BEGIN_ALLOW_THREADS
5915 err
=self
->db_env
->txn_recover(self
->db_env
,
5916 preplist
, PREPLIST_LEN
, &retp
, flags
);
5918 MYDB_END_ALLOW_THREADS
5924 flags
=DB_NEXT
; /* Prepare for next loop pass */
5925 for (i
=0; i
<retp
; i
++) {
5926 gid
=PyBytes_FromStringAndSize((char *)(preplist
[i
].gid
),
5932 txn
=newDBTxnObject(self
, NULL
, preplist
[i
].txn
, 0);
5938 txn
->flag_prepare
=1; /* Recover state */
5939 tuple
=PyTuple_New(2);
5946 if (PyTuple_SetItem(tuple
, 0, gid
)) {
5953 if (PyTuple_SetItem(tuple
, 1, (PyObject
*)txn
)) {
5956 Py_DECREF(tuple
); /* This delete the "gid" also */
5959 if (PyList_Append(list
, tuple
)) {
5961 Py_DECREF(tuple
);/* This delete the "gid" and the "txn" also */
5971 DBEnv_txn_begin(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5974 PyObject
* txnobj
= NULL
;
5976 static char* kwnames
[] = { "parent", "flags", NULL
};
5978 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:txn_begin", kwnames
,
5982 if (!checkTxnObj(txnobj
, &txn
))
5984 CHECK_ENV_NOT_CLOSED(self
);
5986 return (PyObject
*)newDBTxnObject(self
, (DBTxnObject
*)txnobj
, NULL
, flags
);
5991 DBEnv_txn_checkpoint(DBEnvObject
* self
, PyObject
* args
)
5993 int err
, kbyte
=0, min
=0, flags
=0;
5995 if (!PyArg_ParseTuple(args
, "|iii:txn_checkpoint", &kbyte
, &min
, &flags
))
5997 CHECK_ENV_NOT_CLOSED(self
);
5999 MYDB_BEGIN_ALLOW_THREADS
;
6000 err
= self
->db_env
->txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
6001 MYDB_END_ALLOW_THREADS
;
6009 DBEnv_get_tx_max(DBEnvObject
* self
)
6014 CHECK_ENV_NOT_CLOSED(self
);
6016 MYDB_BEGIN_ALLOW_THREADS
;
6017 err
= self
->db_env
->get_tx_max(self
->db_env
, &max
);
6018 MYDB_END_ALLOW_THREADS
;
6020 return PyLong_FromUnsignedLong(max
);
6026 DBEnv_set_tx_max(DBEnvObject
* self
, PyObject
* args
)
6030 if (!PyArg_ParseTuple(args
, "i:set_tx_max", &max
))
6032 CHECK_ENV_NOT_CLOSED(self
);
6034 MYDB_BEGIN_ALLOW_THREADS
;
6035 err
= self
->db_env
->set_tx_max(self
->db_env
, max
);
6036 MYDB_END_ALLOW_THREADS
;
6044 DBEnv_get_tx_timestamp(DBEnvObject
* self
)
6049 CHECK_ENV_NOT_CLOSED(self
);
6051 MYDB_BEGIN_ALLOW_THREADS
;
6052 err
= self
->db_env
->get_tx_timestamp(self
->db_env
, ×tamp
);
6053 MYDB_END_ALLOW_THREADS
;
6055 return NUMBER_FromLong(timestamp
);
6060 DBEnv_set_tx_timestamp(DBEnvObject
* self
, PyObject
* args
)
6066 if (!PyArg_ParseTuple(args
, "l:set_tx_timestamp", &stamp
))
6068 CHECK_ENV_NOT_CLOSED(self
);
6069 timestamp
= (time_t)stamp
;
6070 MYDB_BEGIN_ALLOW_THREADS
;
6071 err
= self
->db_env
->set_tx_timestamp(self
->db_env
, ×tamp
);
6072 MYDB_END_ALLOW_THREADS
;
6079 DBEnv_lock_detect(DBEnvObject
* self
, PyObject
* args
)
6081 int err
, atype
, flags
=0;
6084 if (!PyArg_ParseTuple(args
, "i|i:lock_detect", &atype
, &flags
))
6086 CHECK_ENV_NOT_CLOSED(self
);
6088 MYDB_BEGIN_ALLOW_THREADS
;
6089 err
= self
->db_env
->lock_detect(self
->db_env
, flags
, atype
, &aborted
);
6090 MYDB_END_ALLOW_THREADS
;
6092 return NUMBER_FromLong(aborted
);
6097 DBEnv_lock_get(DBEnvObject
* self
, PyObject
* args
)
6100 int locker
, lock_mode
;
6104 if (!PyArg_ParseTuple(args
, "iOi|i:lock_get", &locker
, &objobj
, &lock_mode
, &flags
))
6108 if (!make_dbt(objobj
, &obj
))
6111 return (PyObject
*)newDBLockObject(self
, locker
, &obj
, lock_mode
, flags
);
6116 DBEnv_lock_id(DBEnvObject
* self
)
6121 CHECK_ENV_NOT_CLOSED(self
);
6122 MYDB_BEGIN_ALLOW_THREADS
;
6123 err
= self
->db_env
->lock_id(self
->db_env
, &theID
);
6124 MYDB_END_ALLOW_THREADS
;
6127 return NUMBER_FromLong((long)theID
);
6131 DBEnv_lock_id_free(DBEnvObject
* self
, PyObject
* args
)
6136 if (!PyArg_ParseTuple(args
, "I:lock_id_free", &theID
))
6139 CHECK_ENV_NOT_CLOSED(self
);
6140 MYDB_BEGIN_ALLOW_THREADS
;
6141 err
= self
->db_env
->lock_id_free(self
->db_env
, theID
);
6142 MYDB_END_ALLOW_THREADS
;
6148 DBEnv_lock_put(DBEnvObject
* self
, PyObject
* args
)
6151 DBLockObject
* dblockobj
;
6153 if (!PyArg_ParseTuple(args
, "O!:lock_put", &DBLock_Type
, &dblockobj
))
6156 CHECK_ENV_NOT_CLOSED(self
);
6157 MYDB_BEGIN_ALLOW_THREADS
;
6158 err
= self
->db_env
->lock_put(self
->db_env
, &dblockobj
->lock
);
6159 MYDB_END_ALLOW_THREADS
;
6166 DBEnv_fileid_reset(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
6170 u_int32_t flags
= 0;
6171 static char* kwnames
[] = { "file", "flags", NULL
};
6173 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|i:fileid_reset", kwnames
,
6176 CHECK_ENV_NOT_CLOSED(self
);
6178 MYDB_BEGIN_ALLOW_THREADS
;
6179 err
= self
->db_env
->fileid_reset(self
->db_env
, file
, flags
);
6180 MYDB_END_ALLOW_THREADS
;
6186 DBEnv_lsn_reset(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
6190 u_int32_t flags
= 0;
6191 static char* kwnames
[] = { "file", "flags", NULL
};
6193 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|i:lsn_reset", kwnames
,
6196 CHECK_ENV_NOT_CLOSED(self
);
6198 MYDB_BEGIN_ALLOW_THREADS
;
6199 err
= self
->db_env
->lsn_reset(self
->db_env
, file
, flags
);
6200 MYDB_END_ALLOW_THREADS
;
6204 #endif /* DBVER >= 4.4 */
6209 DBEnv_stat_print(DBEnvObject
* self
, PyObject
* args
, PyObject
*kwargs
)
6213 static char* kwnames
[] = { "flags", NULL
};
6215 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat_print",
6220 CHECK_ENV_NOT_CLOSED(self
);
6221 MYDB_BEGIN_ALLOW_THREADS
;
6222 err
= self
->db_env
->stat_print(self
->db_env
, flags
);
6223 MYDB_END_ALLOW_THREADS
;
6231 DBEnv_log_stat(DBEnvObject
* self
, PyObject
* args
)
6234 DB_LOG_STAT
* statp
= NULL
;
6236 u_int32_t flags
= 0;
6238 if (!PyArg_ParseTuple(args
, "|i:log_stat", &flags
))
6240 CHECK_ENV_NOT_CLOSED(self
);
6242 MYDB_BEGIN_ALLOW_THREADS
;
6243 err
= self
->db_env
->log_stat(self
->db_env
, &statp
, flags
);
6244 MYDB_END_ALLOW_THREADS
;
6247 /* Turn the stat structure into a dictionary */
6255 #define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
6258 MAKE_ENTRY(version
);
6260 MAKE_ENTRY(lg_bsize
);
6262 MAKE_ENTRY(lg_size
);
6265 MAKE_ENTRY(w_mbytes
);
6266 MAKE_ENTRY(w_bytes
);
6267 MAKE_ENTRY(wc_mbytes
);
6268 MAKE_ENTRY(wc_bytes
);
6270 MAKE_ENTRY(wcount_fill
);
6275 MAKE_ENTRY(cur_file
);
6276 MAKE_ENTRY(cur_offset
);
6277 MAKE_ENTRY(disk_file
);
6278 MAKE_ENTRY(disk_offset
);
6279 MAKE_ENTRY(maxcommitperflush
);
6280 MAKE_ENTRY(mincommitperflush
);
6281 MAKE_ENTRY(regsize
);
6282 MAKE_ENTRY(region_wait
);
6283 MAKE_ENTRY(region_nowait
);
6288 } /* DBEnv_log_stat */
6293 DBEnv_log_stat_print(DBEnvObject
* self
, PyObject
* args
, PyObject
*kwargs
)
6297 static char* kwnames
[] = { "flags", NULL
};
6299 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:log_stat_print",
6304 CHECK_ENV_NOT_CLOSED(self
);
6305 MYDB_BEGIN_ALLOW_THREADS
;
6306 err
= self
->db_env
->log_stat_print(self
->db_env
, flags
);
6307 MYDB_END_ALLOW_THREADS
;
6315 DBEnv_lock_stat(DBEnvObject
* self
, PyObject
* args
)
6320 u_int32_t flags
= 0;
6322 if (!PyArg_ParseTuple(args
, "|i:lock_stat", &flags
))
6324 CHECK_ENV_NOT_CLOSED(self
);
6326 MYDB_BEGIN_ALLOW_THREADS
;
6327 err
= self
->db_env
->lock_stat(self
->db_env
, &sp
, flags
);
6328 MYDB_END_ALLOW_THREADS
;
6331 /* Turn the stat structure into a dictionary */
6338 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
6341 MAKE_ENTRY(cur_maxid
);
6343 MAKE_ENTRY(maxlocks
);
6344 MAKE_ENTRY(maxlockers
);
6345 MAKE_ENTRY(maxobjects
);
6347 MAKE_ENTRY(maxnlocks
);
6348 MAKE_ENTRY(nlockers
);
6349 MAKE_ENTRY(maxnlockers
);
6350 MAKE_ENTRY(nobjects
);
6351 MAKE_ENTRY(maxnobjects
);
6352 MAKE_ENTRY(nrequests
);
6353 MAKE_ENTRY(nreleases
);
6355 MAKE_ENTRY(nupgrade
);
6356 MAKE_ENTRY(ndowngrade
);
6359 MAKE_ENTRY(nnowaits
); /* these were renamed in 4.4 */
6360 MAKE_ENTRY(nconflicts
);
6362 MAKE_ENTRY(lock_nowait
);
6363 MAKE_ENTRY(lock_wait
);
6365 MAKE_ENTRY(ndeadlocks
);
6366 MAKE_ENTRY(locktimeout
);
6367 MAKE_ENTRY(txntimeout
);
6368 MAKE_ENTRY(nlocktimeouts
);
6369 MAKE_ENTRY(ntxntimeouts
);
6371 MAKE_ENTRY(objs_wait
);
6372 MAKE_ENTRY(objs_nowait
);
6373 MAKE_ENTRY(lockers_wait
);
6374 MAKE_ENTRY(lockers_nowait
);
6376 MAKE_ENTRY(lock_wait
);
6377 MAKE_ENTRY(lock_nowait
);
6379 MAKE_ENTRY(locks_wait
);
6380 MAKE_ENTRY(locks_nowait
);
6382 MAKE_ENTRY(hash_len
);
6384 MAKE_ENTRY(regsize
);
6385 MAKE_ENTRY(region_wait
);
6386 MAKE_ENTRY(region_nowait
);
6395 DBEnv_lock_stat_print(DBEnvObject
* self
, PyObject
* args
, PyObject
*kwargs
)
6399 static char* kwnames
[] = { "flags", NULL
};
6401 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:lock_stat_print",
6406 CHECK_ENV_NOT_CLOSED(self
);
6407 MYDB_BEGIN_ALLOW_THREADS
;
6408 err
= self
->db_env
->lock_stat_print(self
->db_env
, flags
);
6409 MYDB_END_ALLOW_THREADS
;
6417 DBEnv_log_cursor(DBEnvObject
* self
)
6422 CHECK_ENV_NOT_CLOSED(self
);
6424 MYDB_BEGIN_ALLOW_THREADS
;
6425 err
= self
->db_env
->log_cursor(self
->db_env
, &dblogc
, 0);
6426 MYDB_END_ALLOW_THREADS
;
6428 return (PyObject
*) newDBLogCursorObject(dblogc
, self
);
6433 DBEnv_log_flush(DBEnvObject
* self
)
6437 CHECK_ENV_NOT_CLOSED(self
);
6439 MYDB_BEGIN_ALLOW_THREADS
6440 err
= self
->db_env
->log_flush(self
->db_env
, NULL
);
6441 MYDB_END_ALLOW_THREADS
6448 DBEnv_log_file(DBEnvObject
* self
, PyObject
* args
)
6451 DB_LSN lsn
= {0, 0};
6456 if (!PyArg_ParseTuple(args
, "(ii):log_file", &lsn
.file
, &lsn
.offset
))
6459 CHECK_ENV_NOT_CLOSED(self
);
6462 name
= malloc(size
);
6467 MYDB_BEGIN_ALLOW_THREADS
;
6468 err
= self
->db_env
->log_file(self
->db_env
, &lsn
, name
, size
);
6469 MYDB_END_ALLOW_THREADS
;
6470 if (err
== EINVAL
) {
6476 assert(0); /* Unreachable... supposely */
6480 ** If the final buffer we try is too small, we will
6481 ** get this exception:
6482 ** DBInvalidArgError:
6483 ** (22, 'Invalid argument -- DB_ENV->log_file: name buffer is too short')
6485 } while ((err
== EINVAL
) && (size
<(1<<17)));
6487 RETURN_IF_ERR(); /* Maybe the size is not the problem */
6489 retval
= Py_BuildValue("s", name
);
6497 DBEnv_log_printf(DBEnvObject
* self
, PyObject
* args
, PyObject
*kwargs
)
6501 PyObject
*txnobj
= NULL
;
6503 static char* kwnames
[] = {"string", "txn", NULL
};
6505 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|O:log_printf", kwnames
,
6509 CHECK_ENV_NOT_CLOSED(self
);
6511 if (!checkTxnObj(txnobj
, &txn
))
6515 ** Do not use the format string directly, to avoid attacks.
6517 MYDB_BEGIN_ALLOW_THREADS
;
6518 err
= self
->db_env
->log_printf(self
->db_env
, txn
, "%s", string
);
6519 MYDB_END_ALLOW_THREADS
;
6528 DBEnv_log_archive(DBEnvObject
* self
, PyObject
* args
)
6532 char **log_list
= NULL
;
6534 PyObject
* item
= NULL
;
6536 if (!PyArg_ParseTuple(args
, "|i:log_archive", &flags
))
6539 CHECK_ENV_NOT_CLOSED(self
);
6540 MYDB_BEGIN_ALLOW_THREADS
;
6541 err
= self
->db_env
->log_archive(self
->db_env
, &log_list
, flags
);
6542 MYDB_END_ALLOW_THREADS
;
6545 list
= PyList_New(0);
6553 char **log_list_start
;
6554 for (log_list_start
= log_list
; *log_list
!= NULL
; ++log_list
) {
6555 item
= PyBytes_FromString (*log_list
);
6561 if (PyList_Append(list
, item
)) {
6569 free(log_list_start
);
6577 DBEnv_mutex_stat(DBEnvObject
* self
, PyObject
* args
)
6580 DB_MUTEX_STAT
* statp
= NULL
;
6582 u_int32_t flags
= 0;
6584 if (!PyArg_ParseTuple(args
, "|i:mutex_stat", &flags
))
6586 CHECK_ENV_NOT_CLOSED(self
);
6588 MYDB_BEGIN_ALLOW_THREADS
;
6589 err
= self
->db_env
->mutex_stat(self
->db_env
, &statp
, flags
);
6590 MYDB_END_ALLOW_THREADS
;
6593 /* Turn the stat structure into a dictionary */
6601 #define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
6603 MAKE_ENTRY(mutex_align
);
6604 MAKE_ENTRY(mutex_tas_spins
);
6605 MAKE_ENTRY(mutex_cnt
);
6606 MAKE_ENTRY(mutex_free
);
6607 MAKE_ENTRY(mutex_inuse
);
6608 MAKE_ENTRY(mutex_inuse_max
);
6609 MAKE_ENTRY(regsize
);
6610 MAKE_ENTRY(region_wait
);
6611 MAKE_ENTRY(region_nowait
);
6622 DBEnv_mutex_stat_print(DBEnvObject
* self
, PyObject
* args
, PyObject
*kwargs
)
6626 static char* kwnames
[] = { "flags", NULL
};
6628 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:mutex_stat_print",
6633 CHECK_ENV_NOT_CLOSED(self
);
6634 MYDB_BEGIN_ALLOW_THREADS
;
6635 err
= self
->db_env
->mutex_stat_print(self
->db_env
, flags
);
6636 MYDB_END_ALLOW_THREADS
;
6645 DBEnv_txn_stat_print(DBEnvObject
* self
, PyObject
* args
, PyObject
*kwargs
)
6649 static char* kwnames
[] = { "flags", NULL
};
6651 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat_print",
6657 CHECK_ENV_NOT_CLOSED(self
);
6659 MYDB_BEGIN_ALLOW_THREADS
;
6660 err
= self
->db_env
->txn_stat_print(self
->db_env
, flags
);
6661 MYDB_END_ALLOW_THREADS
;
6669 DBEnv_txn_stat(DBEnvObject
* self
, PyObject
* args
)
6676 if (!PyArg_ParseTuple(args
, "|i:txn_stat", &flags
))
6678 CHECK_ENV_NOT_CLOSED(self
);
6680 MYDB_BEGIN_ALLOW_THREADS
;
6681 err
= self
->db_env
->txn_stat(self
->db_env
, &sp
, flags
);
6682 MYDB_END_ALLOW_THREADS
;
6685 /* Turn the stat structure into a dictionary */
6692 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
6693 #define MAKE_TIME_T_ENTRY(name) _addTimeTToDict(d, #name, sp->st_##name)
6694 #define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(d, #name, sp->st_##name)
6696 MAKE_DB_LSN_ENTRY(last_ckp
);
6697 MAKE_TIME_T_ENTRY(time_ckp
);
6698 MAKE_ENTRY(last_txnid
);
6699 MAKE_ENTRY(maxtxns
);
6700 MAKE_ENTRY(nactive
);
6701 MAKE_ENTRY(maxnactive
);
6703 MAKE_ENTRY(nsnapshot
);
6704 MAKE_ENTRY(maxnsnapshot
);
6706 MAKE_ENTRY(nbegins
);
6707 MAKE_ENTRY(naborts
);
6708 MAKE_ENTRY(ncommits
);
6709 MAKE_ENTRY(nrestores
);
6710 MAKE_ENTRY(regsize
);
6711 MAKE_ENTRY(region_wait
);
6712 MAKE_ENTRY(region_nowait
);
6714 #undef MAKE_DB_LSN_ENTRY
6716 #undef MAKE_TIME_T_ENTRY
6723 DBEnv_set_get_returns_none(DBEnvObject
* self
, PyObject
* args
)
6728 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
6730 CHECK_ENV_NOT_CLOSED(self
);
6732 if (self
->moduleFlags
.getReturnsNone
)
6734 if (self
->moduleFlags
.cursorSetReturnsNone
)
6736 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
6737 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
6738 return NUMBER_FromLong(oldValue
);
6742 DBEnv_get_private(DBEnvObject
* self
)
6744 /* We can give out the private field even if dbenv is closed */
6745 Py_INCREF(self
->private_obj
);
6746 return self
->private_obj
;
6750 DBEnv_set_private(DBEnvObject
* self
, PyObject
* private_obj
)
6752 /* We can set the private field even if dbenv is closed */
6753 Py_DECREF(self
->private_obj
);
6754 Py_INCREF(private_obj
);
6755 self
->private_obj
= private_obj
;
6762 DBEnv_set_rpc_server(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
6766 long cl_timeout
=0, sv_timeout
=0;
6768 static char* kwnames
[] = { "host", "cl_timeout", "sv_timeout", NULL
};
6770 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|ll:set_rpc_server", kwnames
,
6771 &host
, &cl_timeout
, &sv_timeout
))
6773 CHECK_ENV_NOT_CLOSED(self
);
6775 MYDB_BEGIN_ALLOW_THREADS
;
6776 err
= self
->db_env
->set_rpc_server(self
->db_env
, NULL
, host
, cl_timeout
,
6778 MYDB_END_ALLOW_THREADS
;
6786 DBEnv_set_mp_max_openfd(DBEnvObject
* self
, PyObject
* args
)
6791 if (!PyArg_ParseTuple(args
, "i:set_mp_max_openfd", &maxopenfd
)) {
6794 CHECK_ENV_NOT_CLOSED(self
);
6795 MYDB_BEGIN_ALLOW_THREADS
;
6796 err
= self
->db_env
->set_mp_max_openfd(self
->db_env
, maxopenfd
);
6797 MYDB_END_ALLOW_THREADS
;
6803 DBEnv_get_mp_max_openfd(DBEnvObject
* self
)
6808 CHECK_ENV_NOT_CLOSED(self
);
6810 MYDB_BEGIN_ALLOW_THREADS
;
6811 err
= self
->db_env
->get_mp_max_openfd(self
->db_env
, &maxopenfd
);
6812 MYDB_END_ALLOW_THREADS
;
6814 return NUMBER_FromLong(maxopenfd
);
6819 DBEnv_set_mp_max_write(DBEnvObject
* self
, PyObject
* args
)
6822 int maxwrite
, maxwrite_sleep
;
6824 if (!PyArg_ParseTuple(args
, "ii:set_mp_max_write", &maxwrite
,
6828 CHECK_ENV_NOT_CLOSED(self
);
6829 MYDB_BEGIN_ALLOW_THREADS
;
6830 err
= self
->db_env
->set_mp_max_write(self
->db_env
, maxwrite
,
6832 MYDB_END_ALLOW_THREADS
;
6838 DBEnv_get_mp_max_write(DBEnvObject
* self
)
6843 db_timeout_t maxwrite_sleep
;
6848 CHECK_ENV_NOT_CLOSED(self
);
6850 MYDB_BEGIN_ALLOW_THREADS
;
6851 err
= self
->db_env
->get_mp_max_write(self
->db_env
, &maxwrite
,
6853 MYDB_END_ALLOW_THREADS
;
6856 return Py_BuildValue("(ii)", maxwrite
, (int)maxwrite_sleep
);
6862 DBEnv_set_verbose(DBEnvObject
* self
, PyObject
* args
)
6867 if (!PyArg_ParseTuple(args
, "ii:set_verbose", &which
, &onoff
)) {
6870 CHECK_ENV_NOT_CLOSED(self
);
6871 MYDB_BEGIN_ALLOW_THREADS
;
6872 err
= self
->db_env
->set_verbose(self
->db_env
, which
, onoff
);
6873 MYDB_END_ALLOW_THREADS
;
6880 DBEnv_get_verbose(DBEnvObject
* self
, PyObject
* args
)
6886 if (!PyArg_ParseTuple(args
, "i:get_verbose", &which
)) {
6889 CHECK_ENV_NOT_CLOSED(self
);
6890 MYDB_BEGIN_ALLOW_THREADS
;
6891 err
= self
->db_env
->get_verbose(self
->db_env
, which
, &verbose
);
6892 MYDB_END_ALLOW_THREADS
;
6894 return PyBool_FromLong(verbose
);
6900 _dbenv_event_notifyCallback(DB_ENV
* db_env
, u_int32_t event
, void *event_info
)
6905 PyObject
* result
= NULL
;
6907 MYDB_BEGIN_BLOCK_THREADS
;
6908 dbenv
= (DBEnvObject
*)db_env
->app_private
;
6909 callback
= dbenv
->event_notifyCallback
;
6911 if (event
== DB_EVENT_REP_NEWMASTER
) {
6912 args
= Py_BuildValue("(Oii)", dbenv
, event
, *((int *)event_info
));
6914 args
= Py_BuildValue("(OiO)", dbenv
, event
, Py_None
);
6917 result
= PyEval_CallObject(callback
, args
);
6919 if ((!args
) || (!result
)) {
6925 MYDB_END_BLOCK_THREADS
;
6931 DBEnv_set_event_notify(DBEnvObject
* self
, PyObject
* notifyFunc
)
6935 CHECK_ENV_NOT_CLOSED(self
);
6937 if (!PyCallable_Check(notifyFunc
)) {
6938 makeTypeError("Callable", notifyFunc
);
6942 Py_XDECREF(self
->event_notifyCallback
);
6943 Py_INCREF(notifyFunc
);
6944 self
->event_notifyCallback
= notifyFunc
;
6946 /* This is to workaround a problem with un-initialized threads (see
6947 comment in DB_associate) */
6949 PyEval_InitThreads();
6952 MYDB_BEGIN_ALLOW_THREADS
;
6953 err
= self
->db_env
->set_event_notify(self
->db_env
, _dbenv_event_notifyCallback
);
6954 MYDB_END_ALLOW_THREADS
;
6957 Py_DECREF(notifyFunc
);
6958 self
->event_notifyCallback
= NULL
;
6967 /* --------------------------------------------------------------------- */
6968 /* REPLICATION METHODS: Base Replication */
6972 DBEnv_rep_process_message(DBEnvObject
* self
, PyObject
* args
)
6975 PyObject
*control_py
, *rec_py
;
6982 if (!PyArg_ParseTuple(args
, "OOi:rep_process_message", &control_py
,
6985 CHECK_ENV_NOT_CLOSED(self
);
6987 if (!make_dbt(control_py
, &control
))
6989 if (!make_dbt(rec_py
, &rec
))
6992 MYDB_BEGIN_ALLOW_THREADS
;
6994 err
= self
->db_env
->rep_process_message(self
->db_env
, &control
, &rec
,
6998 err
= self
->db_env
->rep_process_message(self
->db_env
, &control
, &rec
,
7001 err
= self
->db_env
->rep_process_message(self
->db_env
, &control
, &rec
,
7005 MYDB_END_ALLOW_THREADS
;
7007 case DB_REP_NEWMASTER
:
7008 return Py_BuildValue("(iO)", envid
, Py_None
);
7011 case DB_REP_DUPMASTER
:
7012 case DB_REP_HOLDELECTION
:
7014 case DB_REP_IGNORE
:
7015 case DB_REP_JOIN_FAILURE
:
7017 return Py_BuildValue("(iO)", err
, Py_None
);
7019 case DB_REP_NEWSITE
:
7023 if (!(tmp
= PyBytes_FromStringAndSize(rec
.data
, rec
.size
))) {
7027 r
= Py_BuildValue("(iO)", err
, tmp
);
7033 case DB_REP_NOTPERM
:
7034 case DB_REP_ISPERM
:
7035 return Py_BuildValue("(i(ll))", err
, lsn
.file
, lsn
.offset
);
7040 return Py_BuildValue("(OO)", Py_None
, Py_None
);
7044 _DBEnv_rep_transportCallback(DB_ENV
* db_env
, const DBT
* control
, const DBT
* rec
,
7045 const DB_LSN
*lsn
, int envid
, u_int32_t flags
)
7048 PyObject
* rep_transport
;
7051 PyObject
* result
= NULL
;
7054 MYDB_BEGIN_BLOCK_THREADS
;
7055 dbenv
= (DBEnvObject
*)db_env
->app_private
;
7056 rep_transport
= dbenv
->rep_transport
;
7059 ** The errors in 'a' or 'b' are detected in "Py_BuildValue".
7061 a
= PyBytes_FromStringAndSize(control
->data
, control
->size
);
7062 b
= PyBytes_FromStringAndSize(rec
->data
, rec
->size
);
7064 args
= Py_BuildValue(
7065 #if (PY_VERSION_HEX >= 0x02040000)
7072 lsn
->file
, lsn
->offset
, envid
, flags
);
7074 result
= PyEval_CallObject(rep_transport
, args
);
7077 if ((!args
) || (!result
)) {
7085 MYDB_END_BLOCK_THREADS
;
7091 _DBEnv_rep_transportCallbackOLD(DB_ENV
* db_env
, const DBT
* control
, const DBT
* rec
,
7092 int envid
, u_int32_t flags
)
7096 lsn
.file
= -1; /* Dummy values */
7098 return _DBEnv_rep_transportCallback(db_env
, control
, rec
, &lsn
, envid
,
7104 DBEnv_rep_set_transport(DBEnvObject
* self
, PyObject
* args
)
7108 PyObject
*rep_transport
;
7110 if (!PyArg_ParseTuple(args
, "iO:rep_set_transport", &envid
, &rep_transport
))
7112 CHECK_ENV_NOT_CLOSED(self
);
7113 if (!PyCallable_Check(rep_transport
)) {
7114 makeTypeError("Callable", rep_transport
);
7118 MYDB_BEGIN_ALLOW_THREADS
;
7120 err
= self
->db_env
->rep_set_transport(self
->db_env
, envid
,
7121 &_DBEnv_rep_transportCallback
);
7124 err
= self
->db_env
->set_rep_transport(self
->db_env
, envid
,
7125 &_DBEnv_rep_transportCallback
);
7127 err
= self
->db_env
->set_rep_transport(self
->db_env
, envid
,
7128 &_DBEnv_rep_transportCallbackOLD
);
7131 MYDB_END_ALLOW_THREADS
;
7134 Py_DECREF(self
->rep_transport
);
7135 Py_INCREF(rep_transport
);
7136 self
->rep_transport
= rep_transport
;
7142 DBEnv_rep_set_request(DBEnvObject
* self
, PyObject
* args
)
7145 unsigned int minimum
, maximum
;
7147 if (!PyArg_ParseTuple(args
,"II:rep_set_request", &minimum
, &maximum
))
7149 CHECK_ENV_NOT_CLOSED(self
);
7151 MYDB_BEGIN_ALLOW_THREADS
;
7152 err
= self
->db_env
->rep_set_request(self
->db_env
, minimum
, maximum
);
7153 MYDB_END_ALLOW_THREADS
;
7159 DBEnv_rep_get_request(DBEnvObject
* self
)
7162 u_int32_t minimum
, maximum
;
7164 CHECK_ENV_NOT_CLOSED(self
);
7165 MYDB_BEGIN_ALLOW_THREADS
;
7166 err
= self
->db_env
->rep_get_request(self
->db_env
, &minimum
, &maximum
);
7167 MYDB_END_ALLOW_THREADS
;
7169 #if (PY_VERSION_HEX >= 0x02040000)
7170 return Py_BuildValue("II", minimum
, maximum
);
7172 return Py_BuildValue("ii", minimum
, maximum
);
7179 DBEnv_rep_set_limit(DBEnvObject
* self
, PyObject
* args
)
7184 if (!PyArg_ParseTuple(args
,"i:rep_set_limit", &limit
))
7186 CHECK_ENV_NOT_CLOSED(self
);
7188 MYDB_BEGIN_ALLOW_THREADS
;
7189 err
= self
->db_env
->rep_set_limit(self
->db_env
, 0, limit
);
7190 MYDB_END_ALLOW_THREADS
;
7196 DBEnv_rep_get_limit(DBEnvObject
* self
)
7199 u_int32_t gbytes
, bytes
;
7201 CHECK_ENV_NOT_CLOSED(self
);
7202 MYDB_BEGIN_ALLOW_THREADS
;
7203 err
= self
->db_env
->rep_get_limit(self
->db_env
, &gbytes
, &bytes
);
7204 MYDB_END_ALLOW_THREADS
;
7206 return NUMBER_FromLong(bytes
);
7212 DBEnv_rep_set_config(DBEnvObject
* self
, PyObject
* args
)
7218 if (!PyArg_ParseTuple(args
,"ii:rep_set_config", &which
, &onoff
))
7220 CHECK_ENV_NOT_CLOSED(self
);
7222 MYDB_BEGIN_ALLOW_THREADS
;
7223 err
= self
->db_env
->rep_set_config(self
->db_env
, which
, onoff
);
7224 MYDB_END_ALLOW_THREADS
;
7230 DBEnv_rep_get_config(DBEnvObject
* self
, PyObject
* args
)
7236 if (!PyArg_ParseTuple(args
, "i:rep_get_config", &which
)) {
7239 CHECK_ENV_NOT_CLOSED(self
);
7240 MYDB_BEGIN_ALLOW_THREADS
;
7241 err
= self
->db_env
->rep_get_config(self
->db_env
, which
, &onoff
);
7242 MYDB_END_ALLOW_THREADS
;
7244 return PyBool_FromLong(onoff
);
7250 DBEnv_rep_elect(DBEnvObject
* self
, PyObject
* args
)
7253 u_int32_t nsites
, nvotes
;
7255 if (!PyArg_ParseTuple(args
, "II:rep_elect", &nsites
, &nvotes
)) {
7258 CHECK_ENV_NOT_CLOSED(self
);
7259 MYDB_BEGIN_ALLOW_THREADS
;
7260 err
= self
->db_env
->rep_elect(self
->db_env
, nvotes
, nvotes
, 0);
7261 MYDB_END_ALLOW_THREADS
;
7268 DBEnv_rep_start(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
7271 PyObject
*cdata_py
= Py_None
;
7274 static char* kwnames
[] = {"flags","cdata", NULL
};
7276 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,
7277 "i|O:rep_start", kwnames
, &flags
, &cdata_py
))
7281 CHECK_ENV_NOT_CLOSED(self
);
7283 if (!make_dbt(cdata_py
, &cdata
))
7286 MYDB_BEGIN_ALLOW_THREADS
;
7287 err
= self
->db_env
->rep_start(self
->db_env
, cdata
.size
? &cdata
: NULL
,
7289 MYDB_END_ALLOW_THREADS
;
7296 DBEnv_rep_sync(DBEnvObject
* self
)
7300 CHECK_ENV_NOT_CLOSED(self
);
7301 MYDB_BEGIN_ALLOW_THREADS
;
7302 err
= self
->db_env
->rep_sync(self
->db_env
, 0);
7303 MYDB_END_ALLOW_THREADS
;
7312 DBEnv_rep_set_nsites(DBEnvObject
* self
, PyObject
* args
)
7317 if (!PyArg_ParseTuple(args
, "i:rep_set_nsites", &nsites
)) {
7320 CHECK_ENV_NOT_CLOSED(self
);
7321 MYDB_BEGIN_ALLOW_THREADS
;
7322 err
= self
->db_env
->rep_set_nsites(self
->db_env
, nsites
);
7323 MYDB_END_ALLOW_THREADS
;
7329 DBEnv_rep_get_nsites(DBEnvObject
* self
)
7338 CHECK_ENV_NOT_CLOSED(self
);
7339 MYDB_BEGIN_ALLOW_THREADS
;
7340 err
= self
->db_env
->rep_get_nsites(self
->db_env
, &nsites
);
7341 MYDB_END_ALLOW_THREADS
;
7343 return NUMBER_FromLong(nsites
);
7347 DBEnv_rep_set_priority(DBEnvObject
* self
, PyObject
* args
)
7352 if (!PyArg_ParseTuple(args
, "i:rep_set_priority", &priority
)) {
7355 CHECK_ENV_NOT_CLOSED(self
);
7356 MYDB_BEGIN_ALLOW_THREADS
;
7357 err
= self
->db_env
->rep_set_priority(self
->db_env
, priority
);
7358 MYDB_END_ALLOW_THREADS
;
7364 DBEnv_rep_get_priority(DBEnvObject
* self
)
7373 CHECK_ENV_NOT_CLOSED(self
);
7374 MYDB_BEGIN_ALLOW_THREADS
;
7375 err
= self
->db_env
->rep_get_priority(self
->db_env
, &priority
);
7376 MYDB_END_ALLOW_THREADS
;
7378 return NUMBER_FromLong(priority
);
7382 DBEnv_rep_set_timeout(DBEnvObject
* self
, PyObject
* args
)
7387 if (!PyArg_ParseTuple(args
, "ii:rep_set_timeout", &which
, &timeout
)) {
7390 CHECK_ENV_NOT_CLOSED(self
);
7391 MYDB_BEGIN_ALLOW_THREADS
;
7392 err
= self
->db_env
->rep_set_timeout(self
->db_env
, which
, timeout
);
7393 MYDB_END_ALLOW_THREADS
;
7399 DBEnv_rep_get_timeout(DBEnvObject
* self
, PyObject
* args
)
7405 if (!PyArg_ParseTuple(args
, "i:rep_get_timeout", &which
)) {
7408 CHECK_ENV_NOT_CLOSED(self
);
7409 MYDB_BEGIN_ALLOW_THREADS
;
7410 err
= self
->db_env
->rep_get_timeout(self
->db_env
, which
, &timeout
);
7411 MYDB_END_ALLOW_THREADS
;
7413 return NUMBER_FromLong(timeout
);
7420 DBEnv_rep_set_clockskew(DBEnvObject
* self
, PyObject
* args
)
7423 unsigned int fast
, slow
;
7425 #if (PY_VERSION_HEX >= 0x02040000)
7426 if (!PyArg_ParseTuple(args
,"II:rep_set_clockskew", &fast
, &slow
))
7429 if (!PyArg_ParseTuple(args
,"ii:rep_set_clockskew", &fast
, &slow
))
7433 CHECK_ENV_NOT_CLOSED(self
);
7435 MYDB_BEGIN_ALLOW_THREADS
;
7436 err
= self
->db_env
->rep_set_clockskew(self
->db_env
, fast
, slow
);
7437 MYDB_END_ALLOW_THREADS
;
7443 DBEnv_rep_get_clockskew(DBEnvObject
* self
)
7446 unsigned int fast
, slow
;
7448 CHECK_ENV_NOT_CLOSED(self
);
7449 MYDB_BEGIN_ALLOW_THREADS
;
7450 err
= self
->db_env
->rep_get_clockskew(self
->db_env
, &fast
, &slow
);
7451 MYDB_END_ALLOW_THREADS
;
7453 #if (PY_VERSION_HEX >= 0x02040000)
7454 return Py_BuildValue("(II)", fast
, slow
);
7456 return Py_BuildValue("(ii)", fast
, slow
);
7463 DBEnv_rep_stat_print(DBEnvObject
* self
, PyObject
* args
, PyObject
*kwargs
)
7467 static char* kwnames
[] = { "flags", NULL
};
7469 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:rep_stat_print",
7474 CHECK_ENV_NOT_CLOSED(self
);
7475 MYDB_BEGIN_ALLOW_THREADS
;
7476 err
= self
->db_env
->rep_stat_print(self
->db_env
, flags
);
7477 MYDB_END_ALLOW_THREADS
;
7484 DBEnv_rep_stat(DBEnvObject
* self
, PyObject
* args
, PyObject
*kwargs
)
7490 static char* kwnames
[] = { "flags", NULL
};
7492 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:rep_stat",
7497 CHECK_ENV_NOT_CLOSED(self
);
7498 MYDB_BEGIN_ALLOW_THREADS
;
7499 err
= self
->db_env
->rep_stat(self
->db_env
, &statp
, flags
);
7500 MYDB_END_ALLOW_THREADS
;
7504 if (stats
== NULL
) {
7509 #define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
7510 #define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(stats , #name, statp->st_##name)
7513 MAKE_ENTRY(bulk_fills
);
7514 MAKE_ENTRY(bulk_overflows
);
7515 MAKE_ENTRY(bulk_records
);
7516 MAKE_ENTRY(bulk_transfers
);
7517 MAKE_ENTRY(client_rerequests
);
7518 MAKE_ENTRY(client_svc_miss
);
7519 MAKE_ENTRY(client_svc_req
);
7521 MAKE_ENTRY(dupmasters
);
7524 MAKE_ENTRY(election_nvotes
);
7525 MAKE_ENTRY(startup_complete
);
7526 MAKE_ENTRY(pg_duplicated
);
7527 MAKE_ENTRY(pg_records
);
7528 MAKE_ENTRY(pg_requested
);
7529 MAKE_ENTRY(next_pg
);
7530 MAKE_ENTRY(waiting_pg
);
7532 MAKE_ENTRY(election_cur_winner
);
7533 MAKE_ENTRY(election_gen
);
7534 MAKE_DB_LSN_ENTRY(election_lsn
);
7535 MAKE_ENTRY(election_nsites
);
7536 MAKE_ENTRY(election_priority
);
7538 MAKE_ENTRY(election_sec
);
7539 MAKE_ENTRY(election_usec
);
7541 MAKE_ENTRY(election_status
);
7542 MAKE_ENTRY(election_tiebreaker
);
7543 MAKE_ENTRY(election_votes
);
7544 MAKE_ENTRY(elections
);
7545 MAKE_ENTRY(elections_won
);
7547 MAKE_ENTRY(env_priority
);
7549 MAKE_ENTRY(log_duplicated
);
7550 MAKE_ENTRY(log_queued
);
7551 MAKE_ENTRY(log_queued_max
);
7552 MAKE_ENTRY(log_queued_total
);
7553 MAKE_ENTRY(log_records
);
7554 MAKE_ENTRY(log_requested
);
7556 MAKE_ENTRY(master_changes
);
7558 MAKE_ENTRY(max_lease_sec
);
7559 MAKE_ENTRY(max_lease_usec
);
7560 MAKE_DB_LSN_ENTRY(max_perm_lsn
);
7562 MAKE_ENTRY(msgs_badgen
);
7563 MAKE_ENTRY(msgs_processed
);
7564 MAKE_ENTRY(msgs_recover
);
7565 MAKE_ENTRY(msgs_send_failures
);
7566 MAKE_ENTRY(msgs_sent
);
7567 MAKE_ENTRY(newsites
);
7568 MAKE_DB_LSN_ENTRY(next_lsn
);
7570 MAKE_ENTRY(nthrottles
);
7571 MAKE_ENTRY(outdated
);
7573 MAKE_ENTRY(startsync_delayed
);
7576 MAKE_ENTRY(txns_applied
);
7577 MAKE_DB_LSN_ENTRY(waiting_lsn
);
7579 #undef MAKE_DB_LSN_ENTRY
7586 /* --------------------------------------------------------------------- */
7587 /* REPLICATION METHODS: Replication Manager */
7591 DBEnv_repmgr_start(DBEnvObject
* self
, PyObject
* args
, PyObject
*
7595 int nthreads
, flags
;
7596 static char* kwnames
[] = {"nthreads","flags", NULL
};
7598 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,
7599 "ii:repmgr_start", kwnames
, &nthreads
, &flags
))
7603 CHECK_ENV_NOT_CLOSED(self
);
7604 MYDB_BEGIN_ALLOW_THREADS
;
7605 err
= self
->db_env
->repmgr_start(self
->db_env
, nthreads
, flags
);
7606 MYDB_END_ALLOW_THREADS
;
7612 DBEnv_repmgr_set_local_site(DBEnvObject
* self
, PyObject
* args
, PyObject
*
7619 static char* kwnames
[] = {"host", "port", "flags", NULL
};
7621 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,
7622 "si|i:repmgr_set_local_site", kwnames
, &host
, &port
, &flags
))
7626 CHECK_ENV_NOT_CLOSED(self
);
7627 MYDB_BEGIN_ALLOW_THREADS
;
7628 err
= self
->db_env
->repmgr_set_local_site(self
->db_env
, host
, port
, flags
);
7629 MYDB_END_ALLOW_THREADS
;
7635 DBEnv_repmgr_add_remote_site(DBEnvObject
* self
, PyObject
* args
, PyObject
*
7643 static char* kwnames
[] = {"host", "port", "flags", NULL
};
7645 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,
7646 "si|i:repmgr_add_remote_site", kwnames
, &host
, &port
, &flags
))
7650 CHECK_ENV_NOT_CLOSED(self
);
7651 MYDB_BEGIN_ALLOW_THREADS
;
7652 err
= self
->db_env
->repmgr_add_remote_site(self
->db_env
, host
, port
, &eidp
, flags
);
7653 MYDB_END_ALLOW_THREADS
;
7655 return NUMBER_FromLong(eidp
);
7659 DBEnv_repmgr_set_ack_policy(DBEnvObject
* self
, PyObject
* args
)
7664 if (!PyArg_ParseTuple(args
, "i:repmgr_set_ack_policy", &ack_policy
))
7668 CHECK_ENV_NOT_CLOSED(self
);
7669 MYDB_BEGIN_ALLOW_THREADS
;
7670 err
= self
->db_env
->repmgr_set_ack_policy(self
->db_env
, ack_policy
);
7671 MYDB_END_ALLOW_THREADS
;
7677 DBEnv_repmgr_get_ack_policy(DBEnvObject
* self
)
7682 CHECK_ENV_NOT_CLOSED(self
);
7683 MYDB_BEGIN_ALLOW_THREADS
;
7684 err
= self
->db_env
->repmgr_get_ack_policy(self
->db_env
, &ack_policy
);
7685 MYDB_END_ALLOW_THREADS
;
7687 return NUMBER_FromLong(ack_policy
);
7691 DBEnv_repmgr_site_list(DBEnvObject
* self
)
7694 unsigned int countp
;
7695 DB_REPMGR_SITE
*listp
;
7696 PyObject
*stats
, *key
, *tuple
;
7698 CHECK_ENV_NOT_CLOSED(self
);
7699 MYDB_BEGIN_ALLOW_THREADS
;
7700 err
= self
->db_env
->repmgr_site_list(self
->db_env
, &countp
, &listp
);
7701 MYDB_END_ALLOW_THREADS
;
7705 if (stats
== NULL
) {
7711 key
=NUMBER_FromLong(listp
[countp
].eid
);
7717 #if (PY_VERSION_HEX >= 0x02040000)
7718 tuple
=Py_BuildValue("(sII)", listp
[countp
].host
,
7719 listp
[countp
].port
, listp
[countp
].status
);
7721 tuple
=Py_BuildValue("(sii)", listp
[countp
].host
,
7722 listp
[countp
].port
, listp
[countp
].status
);
7730 if(PyDict_SetItem(stats
, key
, tuple
)) {
7747 DBEnv_repmgr_stat_print(DBEnvObject
* self
, PyObject
* args
, PyObject
*kwargs
)
7751 static char* kwnames
[] = { "flags", NULL
};
7753 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:repmgr_stat_print",
7758 CHECK_ENV_NOT_CLOSED(self
);
7759 MYDB_BEGIN_ALLOW_THREADS
;
7760 err
= self
->db_env
->repmgr_stat_print(self
->db_env
, flags
);
7761 MYDB_END_ALLOW_THREADS
;
7767 DBEnv_repmgr_stat(DBEnvObject
* self
, PyObject
* args
, PyObject
*kwargs
)
7771 DB_REPMGR_STAT
*statp
;
7773 static char* kwnames
[] = { "flags", NULL
};
7775 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:repmgr_stat",
7780 CHECK_ENV_NOT_CLOSED(self
);
7781 MYDB_BEGIN_ALLOW_THREADS
;
7782 err
= self
->db_env
->repmgr_stat(self
->db_env
, &statp
, flags
);
7783 MYDB_END_ALLOW_THREADS
;
7787 if (stats
== NULL
) {
7792 #define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
7794 MAKE_ENTRY(perm_failed
);
7795 MAKE_ENTRY(msgs_queued
);
7796 MAKE_ENTRY(msgs_dropped
);
7797 MAKE_ENTRY(connection_drop
);
7798 MAKE_ENTRY(connect_fail
);
7808 /* --------------------------------------------------------------------- */
7812 static void _close_transaction_cursors(DBTxnObject
* txn
)
7816 while(txn
->children_cursors
) {
7817 PyErr_Warn(PyExc_RuntimeWarning
,
7818 "Must close cursors before resolving a transaction.");
7819 dummy
=DBC_close_internal(txn
->children_cursors
);
7824 static void _promote_transaction_dbs_and_sequences(DBTxnObject
*txn
)
7828 DBSequenceObject
*dbs
;
7831 while (txn
->children_dbs
) {
7832 db
=txn
->children_dbs
;
7833 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(db
);
7834 if (txn
->parent_txn
) {
7835 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn
->parent_txn
->children_dbs
,db
);
7836 db
->txn
=txn
->parent_txn
;
7838 /* The db is already linked to its environment,
7839 ** so nothing to do.
7846 while (txn
->children_sequences
) {
7847 dbs
=txn
->children_sequences
;
7848 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(dbs
);
7849 if (txn
->parent_txn
) {
7850 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn
->parent_txn
->children_sequences
,dbs
);
7851 dbs
->txn
=txn
->parent_txn
;
7853 /* The sequence is already linked to its
7854 ** parent db. Nothing to do.
7864 DBTxn_commit(DBTxnObject
* self
, PyObject
* args
)
7869 if (!PyArg_ParseTuple(args
, "|i:commit", &flags
))
7872 _close_transaction_cursors(self
);
7875 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
7876 "after txn_commit, txn_abort "
7879 PyErr_SetObject(DBError
, t
);
7884 self
->flag_prepare
=0;
7886 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
7888 EXTRACT_FROM_DOUBLE_LINKED_LIST(self
);
7890 MYDB_BEGIN_ALLOW_THREADS
;
7891 err
= txn
->commit(txn
, flags
);
7892 MYDB_END_ALLOW_THREADS
;
7894 _promote_transaction_dbs_and_sequences(self
);
7901 DBTxn_prepare(DBTxnObject
* self
, PyObject
* args
)
7907 if (!PyArg_ParseTuple(args
, "s#:prepare", &gid
, &gid_size
))
7910 if (gid_size
!= DB_GID_SIZE
) {
7911 PyErr_SetString(PyExc_TypeError
,
7912 "gid must be DB_GID_SIZE bytes long");
7917 PyObject
*t
= Py_BuildValue("(is)", 0,"DBTxn must not be used "
7918 "after txn_commit, txn_abort "
7921 PyErr_SetObject(DBError
, t
);
7926 self
->flag_prepare
=1; /* Prepare state */
7927 MYDB_BEGIN_ALLOW_THREADS
;
7928 err
= self
->txn
->prepare(self
->txn
, (u_int8_t
*)gid
);
7929 MYDB_END_ALLOW_THREADS
;
7936 DBTxn_abort_discard_internal(DBTxnObject
* self
, int discard
)
7943 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
7944 "after txn_commit, txn_abort "
7947 PyErr_SetObject(DBError
, t
);
7953 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
7955 _close_transaction_cursors(self
);
7957 while (self
->children_sequences
) {
7958 dummy
=DBSequence_close_internal(self
->children_sequences
,0,0);
7962 while (self
->children_dbs
) {
7963 dummy
=DB_close_internal(self
->children_dbs
, 0, 0);
7967 EXTRACT_FROM_DOUBLE_LINKED_LIST(self
);
7969 MYDB_BEGIN_ALLOW_THREADS
;
7971 assert(!self
->flag_prepare
);
7972 err
= txn
->discard(txn
,0);
7975 ** If the transaction is in the "prepare" or "recover" state,
7976 ** we better do not implicitly abort it.
7978 if (!self
->flag_prepare
) {
7979 err
= txn
->abort(txn
);
7982 MYDB_END_ALLOW_THREADS
;
7988 DBTxn_abort(DBTxnObject
* self
)
7990 self
->flag_prepare
=0;
7991 _close_transaction_cursors(self
);
7993 return DBTxn_abort_discard_internal(self
,0);
7997 DBTxn_discard(DBTxnObject
* self
)
7999 self
->flag_prepare
=0;
8000 _close_transaction_cursors(self
);
8002 return DBTxn_abort_discard_internal(self
,1);
8007 DBTxn_id(DBTxnObject
* self
)
8012 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
8013 "after txn_commit, txn_abort "
8016 PyErr_SetObject(DBError
, t
);
8021 MYDB_BEGIN_ALLOW_THREADS
;
8022 id
= self
->txn
->id(self
->txn
);
8023 MYDB_END_ALLOW_THREADS
;
8024 return NUMBER_FromLong(id
);
8029 DBTxn_set_timeout(DBTxnObject
* self
, PyObject
* args
, PyObject
* kwargs
)
8033 u_int32_t timeout
= 0;
8034 static char* kwnames
[] = { "timeout", "flags", NULL
};
8036 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ii:set_timeout", kwnames
,
8037 &timeout
, &flags
)) {
8041 MYDB_BEGIN_ALLOW_THREADS
;
8042 err
= self
->txn
->set_timeout(self
->txn
, (db_timeout_t
)timeout
, flags
);
8043 MYDB_END_ALLOW_THREADS
;
8052 DBTxn_set_name(DBTxnObject
* self
, PyObject
* args
)
8057 if (!PyArg_ParseTuple(args
, "s:set_name", &name
))
8060 MYDB_BEGIN_ALLOW_THREADS
;
8061 err
= self
->txn
->set_name(self
->txn
, name
);
8062 MYDB_END_ALLOW_THREADS
;
8072 DBTxn_get_name(DBTxnObject
* self
)
8077 MYDB_BEGIN_ALLOW_THREADS
;
8078 err
= self
->txn
->get_name(self
->txn
, &name
);
8079 MYDB_END_ALLOW_THREADS
;
8082 #if (PY_VERSION_HEX < 0x03000000)
8084 return PyString_FromString("");
8086 return PyString_FromString(name
);
8089 return PyUnicode_FromString("");
8091 return PyUnicode_FromString(name
);
8098 /* --------------------------------------------------------------------- */
8099 /* DBSequence methods */
8103 DBSequence_close_internal(DBSequenceObject
* self
, int flags
, int do_not_close
)
8107 if (self
->sequence
!=NULL
) {
8108 EXTRACT_FROM_DOUBLE_LINKED_LIST(self
);
8110 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self
);
8115 ** "do_not_close" is used to dispose all related objects in the
8116 ** tree, without actually releasing the "root" object.
8117 ** This is done, for example, because function calls like
8118 ** "DBSequence.remove()" implicitly close the underlying handle. So
8119 ** the handle doesn't need to be closed, but related objects
8120 ** must be cleaned up.
8122 if (!do_not_close
) {
8123 MYDB_BEGIN_ALLOW_THREADS
8124 err
= self
->sequence
->close(self
->sequence
, flags
);
8125 MYDB_END_ALLOW_THREADS
8127 self
->sequence
= NULL
;
8136 DBSequence_close(DBSequenceObject
* self
, PyObject
* args
)
8139 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
8142 return DBSequence_close_internal(self
,flags
,0);
8146 DBSequence_get(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
8151 PyObject
*txnobj
= NULL
;
8153 static char* kwnames
[] = {"delta", "txn", "flags", NULL
};
8154 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iOi:get", kwnames
, &delta
, &txnobj
, &flags
))
8156 CHECK_SEQUENCE_NOT_CLOSED(self
)
8158 if (!checkTxnObj(txnobj
, &txn
))
8161 MYDB_BEGIN_ALLOW_THREADS
8162 err
= self
->sequence
->get(self
->sequence
, txn
, delta
, &value
, flags
);
8163 MYDB_END_ALLOW_THREADS
8166 return PyLong_FromLongLong(value
);
8170 DBSequence_get_dbp(DBSequenceObject
* self
)
8172 CHECK_SEQUENCE_NOT_CLOSED(self
)
8173 Py_INCREF(self
->mydb
);
8174 return (PyObject
* )self
->mydb
;
8178 DBSequence_get_key(DBSequenceObject
* self
)
8182 PyObject
*retval
= NULL
;
8184 key
.flags
= DB_DBT_MALLOC
;
8185 CHECK_SEQUENCE_NOT_CLOSED(self
)
8186 MYDB_BEGIN_ALLOW_THREADS
8187 err
= self
->sequence
->get_key(self
->sequence
, &key
);
8188 MYDB_END_ALLOW_THREADS
8191 retval
= Build_PyString(key
.data
, key
.size
);
8200 DBSequence_initial_value(DBSequenceObject
* self
, PyObject
* args
)
8205 if (!PyArg_ParseTuple(args
,"L:initial_value", &value
))
8207 CHECK_SEQUENCE_NOT_CLOSED(self
)
8209 value2
=value
; /* If truncation, compiler should show a warning */
8210 MYDB_BEGIN_ALLOW_THREADS
8211 err
= self
->sequence
->initial_value(self
->sequence
, value2
);
8212 MYDB_END_ALLOW_THREADS
8220 DBSequence_open(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
8224 PyObject
*txnobj
= NULL
;
8228 static char* kwnames
[] = {"key", "txn", "flags", NULL
};
8229 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:open", kwnames
, &keyobj
, &txnobj
, &flags
))
8232 if (!checkTxnObj(txnobj
, &txn
))
8235 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
8238 MYDB_BEGIN_ALLOW_THREADS
8239 err
= self
->sequence
->open(self
->sequence
, txn
, &key
, flags
);
8240 MYDB_END_ALLOW_THREADS
8246 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject
*)txnobj
)->children_sequences
,self
);
8247 self
->txn
=(DBTxnObject
*)txnobj
;
8254 DBSequence_remove(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
8258 PyObject
*txnobj
= NULL
;
8261 static char* kwnames
[] = {"txn", "flags", NULL
};
8262 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:remove", kwnames
, &txnobj
, &flags
))
8265 if (!checkTxnObj(txnobj
, &txn
))
8268 CHECK_SEQUENCE_NOT_CLOSED(self
)
8270 MYDB_BEGIN_ALLOW_THREADS
8271 err
= self
->sequence
->remove(self
->sequence
, txn
, flags
);
8272 MYDB_END_ALLOW_THREADS
8274 dummy
=DBSequence_close_internal(self
,flags
,1);
8282 DBSequence_set_cachesize(DBSequenceObject
* self
, PyObject
* args
)
8285 if (!PyArg_ParseTuple(args
,"i:set_cachesize", &size
))
8287 CHECK_SEQUENCE_NOT_CLOSED(self
)
8289 MYDB_BEGIN_ALLOW_THREADS
8290 err
= self
->sequence
->set_cachesize(self
->sequence
, size
);
8291 MYDB_END_ALLOW_THREADS
8298 DBSequence_get_cachesize(DBSequenceObject
* self
)
8302 CHECK_SEQUENCE_NOT_CLOSED(self
)
8304 MYDB_BEGIN_ALLOW_THREADS
8305 err
= self
->sequence
->get_cachesize(self
->sequence
, &size
);
8306 MYDB_END_ALLOW_THREADS
8309 return NUMBER_FromLong(size
);
8313 DBSequence_set_flags(DBSequenceObject
* self
, PyObject
* args
)
8316 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
8318 CHECK_SEQUENCE_NOT_CLOSED(self
)
8320 MYDB_BEGIN_ALLOW_THREADS
8321 err
= self
->sequence
->set_flags(self
->sequence
, flags
);
8322 MYDB_END_ALLOW_THREADS
8329 DBSequence_get_flags(DBSequenceObject
* self
)
8334 CHECK_SEQUENCE_NOT_CLOSED(self
)
8336 MYDB_BEGIN_ALLOW_THREADS
8337 err
= self
->sequence
->get_flags(self
->sequence
, &flags
);
8338 MYDB_END_ALLOW_THREADS
8341 return NUMBER_FromLong((int)flags
);
8345 DBSequence_set_range(DBSequenceObject
* self
, PyObject
* args
)
8348 PY_LONG_LONG min
, max
;
8349 db_seq_t min2
, max2
;
8350 if (!PyArg_ParseTuple(args
,"(LL):set_range", &min
, &max
))
8352 CHECK_SEQUENCE_NOT_CLOSED(self
)
8354 min2
=min
; /* If truncation, compiler should show a warning */
8356 MYDB_BEGIN_ALLOW_THREADS
8357 err
= self
->sequence
->set_range(self
->sequence
, min2
, max2
);
8358 MYDB_END_ALLOW_THREADS
8365 DBSequence_get_range(DBSequenceObject
* self
)
8368 PY_LONG_LONG min
, max
;
8369 db_seq_t min2
, max2
;
8371 CHECK_SEQUENCE_NOT_CLOSED(self
)
8373 MYDB_BEGIN_ALLOW_THREADS
8374 err
= self
->sequence
->get_range(self
->sequence
, &min2
, &max2
);
8375 MYDB_END_ALLOW_THREADS
8378 min
=min2
; /* If truncation, compiler should show a warning */
8380 return Py_BuildValue("(LL)", min
, max
);
8385 DBSequence_stat_print(DBSequenceObject
* self
, PyObject
* args
, PyObject
*kwargs
)
8389 static char* kwnames
[] = { "flags", NULL
};
8391 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat_print",
8397 CHECK_SEQUENCE_NOT_CLOSED(self
);
8399 MYDB_BEGIN_ALLOW_THREADS
;
8400 err
= self
->sequence
->stat_print(self
->sequence
, flags
);
8401 MYDB_END_ALLOW_THREADS
;
8407 DBSequence_stat(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
8410 DB_SEQUENCE_STAT
* sp
= NULL
;
8411 PyObject
* dict_stat
;
8412 static char* kwnames
[] = {"flags", NULL
};
8413 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat", kwnames
, &flags
))
8415 CHECK_SEQUENCE_NOT_CLOSED(self
);
8417 MYDB_BEGIN_ALLOW_THREADS
;
8418 err
= self
->sequence
->stat(self
->sequence
, &sp
, flags
);
8419 MYDB_END_ALLOW_THREADS
;
8422 if ((dict_stat
= PyDict_New()) == NULL
) {
8428 #define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name)
8429 #define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
8431 MAKE_INT_ENTRY(wait
);
8432 MAKE_INT_ENTRY(nowait
);
8433 MAKE_LONG_LONG_ENTRY(current
);
8434 MAKE_LONG_LONG_ENTRY(value
);
8435 MAKE_LONG_LONG_ENTRY(last_value
);
8436 MAKE_LONG_LONG_ENTRY(min
);
8437 MAKE_LONG_LONG_ENTRY(max
);
8438 MAKE_INT_ENTRY(cache_size
);
8439 MAKE_INT_ENTRY(flags
);
8441 #undef MAKE_INT_ENTRY
8442 #undef MAKE_LONG_LONG_ENTRY
8450 /* --------------------------------------------------------------------- */
8451 /* Method definition tables and type objects */
8453 static PyMethodDef DB_methods
[] = {
8454 {"append", (PyCFunction
)DB_append
, METH_VARARGS
|METH_KEYWORDS
},
8455 {"associate", (PyCFunction
)DB_associate
, METH_VARARGS
|METH_KEYWORDS
},
8456 {"close", (PyCFunction
)DB_close
, METH_VARARGS
},
8458 {"compact", (PyCFunction
)DB_compact
, METH_VARARGS
|METH_KEYWORDS
},
8460 {"consume", (PyCFunction
)DB_consume
, METH_VARARGS
|METH_KEYWORDS
},
8461 {"consume_wait", (PyCFunction
)DB_consume_wait
, METH_VARARGS
|METH_KEYWORDS
},
8462 {"cursor", (PyCFunction
)DB_cursor
, METH_VARARGS
|METH_KEYWORDS
},
8463 {"delete", (PyCFunction
)DB_delete
, METH_VARARGS
|METH_KEYWORDS
},
8464 {"fd", (PyCFunction
)DB_fd
, METH_NOARGS
},
8466 {"exists", (PyCFunction
)DB_exists
,
8467 METH_VARARGS
|METH_KEYWORDS
},
8469 {"get", (PyCFunction
)DB_get
, METH_VARARGS
|METH_KEYWORDS
},
8470 {"pget", (PyCFunction
)DB_pget
, METH_VARARGS
|METH_KEYWORDS
},
8471 {"get_both", (PyCFunction
)DB_get_both
, METH_VARARGS
|METH_KEYWORDS
},
8472 {"get_byteswapped", (PyCFunction
)DB_get_byteswapped
,METH_NOARGS
},
8473 {"get_size", (PyCFunction
)DB_get_size
, METH_VARARGS
|METH_KEYWORDS
},
8474 {"get_type", (PyCFunction
)DB_get_type
, METH_NOARGS
},
8475 {"join", (PyCFunction
)DB_join
, METH_VARARGS
},
8476 {"key_range", (PyCFunction
)DB_key_range
, METH_VARARGS
|METH_KEYWORDS
},
8477 {"has_key", (PyCFunction
)DB_has_key
, METH_VARARGS
|METH_KEYWORDS
},
8478 {"items", (PyCFunction
)DB_items
, METH_VARARGS
},
8479 {"keys", (PyCFunction
)DB_keys
, METH_VARARGS
},
8480 {"open", (PyCFunction
)DB_open
, METH_VARARGS
|METH_KEYWORDS
},
8481 {"put", (PyCFunction
)DB_put
, METH_VARARGS
|METH_KEYWORDS
},
8482 {"remove", (PyCFunction
)DB_remove
, METH_VARARGS
|METH_KEYWORDS
},
8483 {"rename", (PyCFunction
)DB_rename
, METH_VARARGS
},
8484 {"set_bt_minkey", (PyCFunction
)DB_set_bt_minkey
, METH_VARARGS
},
8486 {"get_bt_minkey", (PyCFunction
)DB_get_bt_minkey
, METH_NOARGS
},
8488 {"set_bt_compare", (PyCFunction
)DB_set_bt_compare
, METH_O
},
8489 {"set_cachesize", (PyCFunction
)DB_set_cachesize
, METH_VARARGS
},
8491 {"get_cachesize", (PyCFunction
)DB_get_cachesize
, METH_NOARGS
},
8493 {"set_encrypt", (PyCFunction
)DB_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
8495 {"get_encrypt_flags", (PyCFunction
)DB_get_encrypt_flags
, METH_NOARGS
},
8498 {"set_flags", (PyCFunction
)DB_set_flags
, METH_VARARGS
},
8500 {"get_flags", (PyCFunction
)DB_get_flags
, METH_NOARGS
},
8502 {"set_h_ffactor", (PyCFunction
)DB_set_h_ffactor
, METH_VARARGS
},
8504 {"get_h_ffactor", (PyCFunction
)DB_get_h_ffactor
, METH_NOARGS
},
8506 {"set_h_nelem", (PyCFunction
)DB_set_h_nelem
, METH_VARARGS
},
8508 {"get_h_nelem", (PyCFunction
)DB_get_h_nelem
, METH_NOARGS
},
8510 {"set_lorder", (PyCFunction
)DB_set_lorder
, METH_VARARGS
},
8512 {"get_lorder", (PyCFunction
)DB_get_lorder
, METH_NOARGS
},
8514 {"set_pagesize", (PyCFunction
)DB_set_pagesize
, METH_VARARGS
},
8516 {"get_pagesize", (PyCFunction
)DB_get_pagesize
, METH_NOARGS
},
8518 {"set_re_delim", (PyCFunction
)DB_set_re_delim
, METH_VARARGS
},
8520 {"get_re_delim", (PyCFunction
)DB_get_re_delim
, METH_NOARGS
},
8522 {"set_re_len", (PyCFunction
)DB_set_re_len
, METH_VARARGS
},
8524 {"get_re_len", (PyCFunction
)DB_get_re_len
, METH_NOARGS
},
8526 {"set_re_pad", (PyCFunction
)DB_set_re_pad
, METH_VARARGS
},
8528 {"get_re_pad", (PyCFunction
)DB_get_re_pad
, METH_NOARGS
},
8530 {"set_re_source", (PyCFunction
)DB_set_re_source
, METH_VARARGS
},
8532 {"get_re_source", (PyCFunction
)DB_get_re_source
, METH_NOARGS
},
8534 {"set_q_extentsize",(PyCFunction
)DB_set_q_extentsize
, METH_VARARGS
},
8536 {"get_q_extentsize",(PyCFunction
)DB_get_q_extentsize
, METH_NOARGS
},
8538 {"set_private", (PyCFunction
)DB_set_private
, METH_O
},
8539 {"get_private", (PyCFunction
)DB_get_private
, METH_NOARGS
},
8541 {"set_priority", (PyCFunction
)DB_set_priority
, METH_VARARGS
},
8542 {"get_priority", (PyCFunction
)DB_get_priority
, METH_NOARGS
},
8544 {"stat", (PyCFunction
)DB_stat
, METH_VARARGS
|METH_KEYWORDS
},
8546 {"stat_print", (PyCFunction
)DB_stat_print
,
8547 METH_VARARGS
|METH_KEYWORDS
},
8549 {"sync", (PyCFunction
)DB_sync
, METH_VARARGS
},
8550 {"truncate", (PyCFunction
)DB_truncate
, METH_VARARGS
|METH_KEYWORDS
},
8551 {"type", (PyCFunction
)DB_get_type
, METH_NOARGS
},
8552 {"upgrade", (PyCFunction
)DB_upgrade
, METH_VARARGS
},
8553 {"values", (PyCFunction
)DB_values
, METH_VARARGS
},
8554 {"verify", (PyCFunction
)DB_verify
, METH_VARARGS
|METH_KEYWORDS
},
8555 {"set_get_returns_none",(PyCFunction
)DB_set_get_returns_none
, METH_VARARGS
},
8556 {NULL
, NULL
} /* sentinel */
8560 /* We need this to support __contains__() */
8561 static PySequenceMethods DB_sequence
= {
8562 0, /* sq_length, mapping wins here */
8567 0, /* sq_ass_item */
8568 0, /* sq_ass_slice */
8569 (objobjproc
)DB_contains
, /* sq_contains */
8570 0, /* sq_inplace_concat */
8571 0, /* sq_inplace_repeat */
8574 static PyMappingMethods DB_mapping
= {
8575 DB_length
, /*mp_length*/
8576 (binaryfunc
)DB_subscript
, /*mp_subscript*/
8577 (objobjargproc
)DB_ass_sub
, /*mp_ass_subscript*/
8581 static PyMethodDef DBCursor_methods
[] = {
8582 {"close", (PyCFunction
)DBC_close
, METH_NOARGS
},
8583 {"count", (PyCFunction
)DBC_count
, METH_VARARGS
},
8584 {"current", (PyCFunction
)DBC_current
, METH_VARARGS
|METH_KEYWORDS
},
8585 {"delete", (PyCFunction
)DBC_delete
, METH_VARARGS
},
8586 {"dup", (PyCFunction
)DBC_dup
, METH_VARARGS
},
8587 {"first", (PyCFunction
)DBC_first
, METH_VARARGS
|METH_KEYWORDS
},
8588 {"get", (PyCFunction
)DBC_get
, METH_VARARGS
|METH_KEYWORDS
},
8589 {"pget", (PyCFunction
)DBC_pget
, METH_VARARGS
|METH_KEYWORDS
},
8590 {"get_recno", (PyCFunction
)DBC_get_recno
, METH_NOARGS
},
8591 {"last", (PyCFunction
)DBC_last
, METH_VARARGS
|METH_KEYWORDS
},
8592 {"next", (PyCFunction
)DBC_next
, METH_VARARGS
|METH_KEYWORDS
},
8593 {"prev", (PyCFunction
)DBC_prev
, METH_VARARGS
|METH_KEYWORDS
},
8594 {"put", (PyCFunction
)DBC_put
, METH_VARARGS
|METH_KEYWORDS
},
8595 {"set", (PyCFunction
)DBC_set
, METH_VARARGS
|METH_KEYWORDS
},
8596 {"set_range", (PyCFunction
)DBC_set_range
, METH_VARARGS
|METH_KEYWORDS
},
8597 {"get_both", (PyCFunction
)DBC_get_both
, METH_VARARGS
},
8598 {"get_current_size",(PyCFunction
)DBC_get_current_size
, METH_NOARGS
},
8599 {"set_both", (PyCFunction
)DBC_set_both
, METH_VARARGS
},
8600 {"set_recno", (PyCFunction
)DBC_set_recno
, METH_VARARGS
|METH_KEYWORDS
},
8601 {"consume", (PyCFunction
)DBC_consume
, METH_VARARGS
|METH_KEYWORDS
},
8602 {"next_dup", (PyCFunction
)DBC_next_dup
, METH_VARARGS
|METH_KEYWORDS
},
8603 {"next_nodup", (PyCFunction
)DBC_next_nodup
, METH_VARARGS
|METH_KEYWORDS
},
8605 {"prev_dup", (PyCFunction
)DBC_prev_dup
,
8606 METH_VARARGS
|METH_KEYWORDS
},
8608 {"prev_nodup", (PyCFunction
)DBC_prev_nodup
, METH_VARARGS
|METH_KEYWORDS
},
8609 {"join_item", (PyCFunction
)DBC_join_item
, METH_VARARGS
},
8611 {"set_priority", (PyCFunction
)DBC_set_priority
,
8612 METH_VARARGS
|METH_KEYWORDS
},
8613 {"get_priority", (PyCFunction
)DBC_get_priority
, METH_NOARGS
},
8615 {NULL
, NULL
} /* sentinel */
8619 static PyMethodDef DBLogCursor_methods
[] = {
8620 {"close", (PyCFunction
)DBLogCursor_close
, METH_NOARGS
},
8621 {"current", (PyCFunction
)DBLogCursor_current
, METH_NOARGS
},
8622 {"first", (PyCFunction
)DBLogCursor_first
, METH_NOARGS
},
8623 {"last", (PyCFunction
)DBLogCursor_last
, METH_NOARGS
},
8624 {"next", (PyCFunction
)DBLogCursor_next
, METH_NOARGS
},
8625 {"prev", (PyCFunction
)DBLogCursor_prev
, METH_NOARGS
},
8626 {"set", (PyCFunction
)DBLogCursor_set
, METH_VARARGS
},
8627 {NULL
, NULL
} /* sentinel */
8631 static PyMethodDef DBEnv_methods
[] = {
8632 {"close", (PyCFunction
)DBEnv_close
, METH_VARARGS
},
8633 {"open", (PyCFunction
)DBEnv_open
, METH_VARARGS
},
8634 {"remove", (PyCFunction
)DBEnv_remove
, METH_VARARGS
},
8635 {"dbremove", (PyCFunction
)DBEnv_dbremove
, METH_VARARGS
|METH_KEYWORDS
},
8636 {"dbrename", (PyCFunction
)DBEnv_dbrename
, METH_VARARGS
|METH_KEYWORDS
},
8638 {"set_thread_count", (PyCFunction
)DBEnv_set_thread_count
, METH_VARARGS
},
8639 {"get_thread_count", (PyCFunction
)DBEnv_get_thread_count
, METH_NOARGS
},
8641 {"set_encrypt", (PyCFunction
)DBEnv_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
8643 {"get_encrypt_flags", (PyCFunction
)DBEnv_get_encrypt_flags
, METH_NOARGS
},
8644 {"get_timeout", (PyCFunction
)DBEnv_get_timeout
,
8645 METH_VARARGS
|METH_KEYWORDS
},
8647 {"set_timeout", (PyCFunction
)DBEnv_set_timeout
, METH_VARARGS
|METH_KEYWORDS
},
8648 {"set_shm_key", (PyCFunction
)DBEnv_set_shm_key
, METH_VARARGS
},
8650 {"get_shm_key", (PyCFunction
)DBEnv_get_shm_key
, METH_NOARGS
},
8653 {"set_cache_max", (PyCFunction
)DBEnv_set_cache_max
, METH_VARARGS
},
8654 {"get_cache_max", (PyCFunction
)DBEnv_get_cache_max
, METH_NOARGS
},
8656 {"set_cachesize", (PyCFunction
)DBEnv_set_cachesize
, METH_VARARGS
},
8658 {"get_cachesize", (PyCFunction
)DBEnv_get_cachesize
, METH_NOARGS
},
8660 {"memp_trickle", (PyCFunction
)DBEnv_memp_trickle
, METH_VARARGS
},
8661 {"memp_sync", (PyCFunction
)DBEnv_memp_sync
, METH_VARARGS
},
8662 {"memp_stat", (PyCFunction
)DBEnv_memp_stat
,
8663 METH_VARARGS
|METH_KEYWORDS
},
8665 {"memp_stat_print", (PyCFunction
)DBEnv_memp_stat_print
,
8666 METH_VARARGS
|METH_KEYWORDS
},
8669 {"mutex_set_max", (PyCFunction
)DBEnv_mutex_set_max
, METH_VARARGS
},
8670 {"mutex_get_max", (PyCFunction
)DBEnv_mutex_get_max
, METH_NOARGS
},
8671 {"mutex_set_align", (PyCFunction
)DBEnv_mutex_set_align
, METH_VARARGS
},
8672 {"mutex_get_align", (PyCFunction
)DBEnv_mutex_get_align
, METH_NOARGS
},
8673 {"mutex_set_increment", (PyCFunction
)DBEnv_mutex_set_increment
,
8675 {"mutex_get_increment", (PyCFunction
)DBEnv_mutex_get_increment
,
8677 {"mutex_set_tas_spins", (PyCFunction
)DBEnv_mutex_set_tas_spins
,
8679 {"mutex_get_tas_spins", (PyCFunction
)DBEnv_mutex_get_tas_spins
,
8681 {"mutex_stat", (PyCFunction
)DBEnv_mutex_stat
, METH_VARARGS
},
8683 {"mutex_stat_print", (PyCFunction
)DBEnv_mutex_stat_print
,
8684 METH_VARARGS
|METH_KEYWORDS
},
8687 {"set_data_dir", (PyCFunction
)DBEnv_set_data_dir
, METH_VARARGS
},
8689 {"get_data_dirs", (PyCFunction
)DBEnv_get_data_dirs
, METH_NOARGS
},
8692 {"get_flags", (PyCFunction
)DBEnv_get_flags
, METH_NOARGS
},
8694 {"set_flags", (PyCFunction
)DBEnv_set_flags
, METH_VARARGS
},
8696 {"log_set_config", (PyCFunction
)DBEnv_log_set_config
, METH_VARARGS
},
8697 {"log_get_config", (PyCFunction
)DBEnv_log_get_config
, METH_VARARGS
},
8699 {"set_lg_bsize", (PyCFunction
)DBEnv_set_lg_bsize
, METH_VARARGS
},
8701 {"get_lg_bsize", (PyCFunction
)DBEnv_get_lg_bsize
, METH_NOARGS
},
8703 {"set_lg_dir", (PyCFunction
)DBEnv_set_lg_dir
, METH_VARARGS
},
8705 {"get_lg_dir", (PyCFunction
)DBEnv_get_lg_dir
, METH_NOARGS
},
8707 {"set_lg_max", (PyCFunction
)DBEnv_set_lg_max
, METH_VARARGS
},
8709 {"get_lg_max", (PyCFunction
)DBEnv_get_lg_max
, METH_NOARGS
},
8711 {"set_lg_regionmax",(PyCFunction
)DBEnv_set_lg_regionmax
, METH_VARARGS
},
8713 {"get_lg_regionmax",(PyCFunction
)DBEnv_get_lg_regionmax
, METH_NOARGS
},
8716 {"set_lg_filemode", (PyCFunction
)DBEnv_set_lg_filemode
, METH_VARARGS
},
8717 {"get_lg_filemode", (PyCFunction
)DBEnv_get_lg_filemode
, METH_NOARGS
},
8720 {"set_lk_partitions", (PyCFunction
)DBEnv_set_lk_partitions
, METH_VARARGS
},
8721 {"get_lk_partitions", (PyCFunction
)DBEnv_get_lk_partitions
, METH_NOARGS
},
8723 {"set_lk_detect", (PyCFunction
)DBEnv_set_lk_detect
, METH_VARARGS
},
8725 {"get_lk_detect", (PyCFunction
)DBEnv_get_lk_detect
, METH_NOARGS
},
8728 {"set_lk_max", (PyCFunction
)DBEnv_set_lk_max
, METH_VARARGS
},
8730 {"set_lk_max_locks", (PyCFunction
)DBEnv_set_lk_max_locks
, METH_VARARGS
},
8732 {"get_lk_max_locks", (PyCFunction
)DBEnv_get_lk_max_locks
, METH_NOARGS
},
8734 {"set_lk_max_lockers", (PyCFunction
)DBEnv_set_lk_max_lockers
, METH_VARARGS
},
8736 {"get_lk_max_lockers", (PyCFunction
)DBEnv_get_lk_max_lockers
, METH_NOARGS
},
8738 {"set_lk_max_objects", (PyCFunction
)DBEnv_set_lk_max_objects
, METH_VARARGS
},
8740 {"get_lk_max_objects", (PyCFunction
)DBEnv_get_lk_max_objects
, METH_NOARGS
},
8743 {"stat_print", (PyCFunction
)DBEnv_stat_print
,
8744 METH_VARARGS
|METH_KEYWORDS
},
8746 {"set_mp_mmapsize", (PyCFunction
)DBEnv_set_mp_mmapsize
, METH_VARARGS
},
8748 {"get_mp_mmapsize", (PyCFunction
)DBEnv_get_mp_mmapsize
, METH_NOARGS
},
8750 {"set_tmp_dir", (PyCFunction
)DBEnv_set_tmp_dir
, METH_VARARGS
},
8752 {"get_tmp_dir", (PyCFunction
)DBEnv_get_tmp_dir
, METH_NOARGS
},
8754 {"txn_begin", (PyCFunction
)DBEnv_txn_begin
, METH_VARARGS
|METH_KEYWORDS
},
8755 {"txn_checkpoint", (PyCFunction
)DBEnv_txn_checkpoint
, METH_VARARGS
},
8756 {"txn_stat", (PyCFunction
)DBEnv_txn_stat
, METH_VARARGS
},
8758 {"txn_stat_print", (PyCFunction
)DBEnv_txn_stat_print
,
8759 METH_VARARGS
|METH_KEYWORDS
},
8762 {"get_tx_max", (PyCFunction
)DBEnv_get_tx_max
, METH_NOARGS
},
8763 {"get_tx_timestamp", (PyCFunction
)DBEnv_get_tx_timestamp
, METH_NOARGS
},
8765 {"set_tx_max", (PyCFunction
)DBEnv_set_tx_max
, METH_VARARGS
},
8766 {"set_tx_timestamp", (PyCFunction
)DBEnv_set_tx_timestamp
, METH_VARARGS
},
8767 {"lock_detect", (PyCFunction
)DBEnv_lock_detect
, METH_VARARGS
},
8768 {"lock_get", (PyCFunction
)DBEnv_lock_get
, METH_VARARGS
},
8769 {"lock_id", (PyCFunction
)DBEnv_lock_id
, METH_NOARGS
},
8770 {"lock_id_free", (PyCFunction
)DBEnv_lock_id_free
, METH_VARARGS
},
8771 {"lock_put", (PyCFunction
)DBEnv_lock_put
, METH_VARARGS
},
8772 {"lock_stat", (PyCFunction
)DBEnv_lock_stat
, METH_VARARGS
},
8774 {"lock_stat_print", (PyCFunction
)DBEnv_lock_stat_print
,
8775 METH_VARARGS
|METH_KEYWORDS
},
8777 {"log_cursor", (PyCFunction
)DBEnv_log_cursor
, METH_NOARGS
},
8778 {"log_file", (PyCFunction
)DBEnv_log_file
, METH_VARARGS
},
8780 {"log_printf", (PyCFunction
)DBEnv_log_printf
,
8781 METH_VARARGS
|METH_KEYWORDS
},
8783 {"log_archive", (PyCFunction
)DBEnv_log_archive
, METH_VARARGS
},
8784 {"log_flush", (PyCFunction
)DBEnv_log_flush
, METH_NOARGS
},
8785 {"log_stat", (PyCFunction
)DBEnv_log_stat
, METH_VARARGS
},
8787 {"log_stat_print", (PyCFunction
)DBEnv_log_stat_print
,
8788 METH_VARARGS
|METH_KEYWORDS
},
8791 {"fileid_reset", (PyCFunction
)DBEnv_fileid_reset
, METH_VARARGS
|METH_KEYWORDS
},
8792 {"lsn_reset", (PyCFunction
)DBEnv_lsn_reset
, METH_VARARGS
|METH_KEYWORDS
},
8794 {"set_get_returns_none",(PyCFunction
)DBEnv_set_get_returns_none
, METH_VARARGS
},
8795 {"txn_recover", (PyCFunction
)DBEnv_txn_recover
, METH_NOARGS
},
8797 {"set_rpc_server", (PyCFunction
)DBEnv_set_rpc_server
,
8798 METH_VARARGS
||METH_KEYWORDS
},
8801 {"set_mp_max_openfd", (PyCFunction
)DBEnv_set_mp_max_openfd
, METH_VARARGS
},
8802 {"get_mp_max_openfd", (PyCFunction
)DBEnv_get_mp_max_openfd
, METH_NOARGS
},
8803 {"set_mp_max_write", (PyCFunction
)DBEnv_set_mp_max_write
, METH_VARARGS
},
8804 {"get_mp_max_write", (PyCFunction
)DBEnv_get_mp_max_write
, METH_NOARGS
},
8806 {"set_verbose", (PyCFunction
)DBEnv_set_verbose
, METH_VARARGS
},
8808 {"get_verbose", (PyCFunction
)DBEnv_get_verbose
, METH_VARARGS
},
8810 {"set_private", (PyCFunction
)DBEnv_set_private
, METH_O
},
8811 {"get_private", (PyCFunction
)DBEnv_get_private
, METH_NOARGS
},
8812 {"rep_start", (PyCFunction
)DBEnv_rep_start
,
8813 METH_VARARGS
|METH_KEYWORDS
},
8814 {"rep_set_transport", (PyCFunction
)DBEnv_rep_set_transport
, METH_VARARGS
},
8815 {"rep_process_message", (PyCFunction
)DBEnv_rep_process_message
,
8818 {"rep_elect", (PyCFunction
)DBEnv_rep_elect
, METH_VARARGS
},
8821 {"rep_set_config", (PyCFunction
)DBEnv_rep_set_config
, METH_VARARGS
},
8822 {"rep_get_config", (PyCFunction
)DBEnv_rep_get_config
, METH_VARARGS
},
8823 {"rep_sync", (PyCFunction
)DBEnv_rep_sync
, METH_NOARGS
},
8826 {"rep_set_limit", (PyCFunction
)DBEnv_rep_set_limit
, METH_VARARGS
},
8827 {"rep_get_limit", (PyCFunction
)DBEnv_rep_get_limit
, METH_NOARGS
},
8830 {"rep_set_request", (PyCFunction
)DBEnv_rep_set_request
, METH_VARARGS
},
8831 {"rep_get_request", (PyCFunction
)DBEnv_rep_get_request
, METH_NOARGS
},
8834 {"set_event_notify", (PyCFunction
)DBEnv_set_event_notify
, METH_O
},
8837 {"rep_set_nsites", (PyCFunction
)DBEnv_rep_set_nsites
, METH_VARARGS
},
8838 {"rep_get_nsites", (PyCFunction
)DBEnv_rep_get_nsites
, METH_NOARGS
},
8839 {"rep_set_priority", (PyCFunction
)DBEnv_rep_set_priority
, METH_VARARGS
},
8840 {"rep_get_priority", (PyCFunction
)DBEnv_rep_get_priority
, METH_NOARGS
},
8841 {"rep_set_timeout", (PyCFunction
)DBEnv_rep_set_timeout
, METH_VARARGS
},
8842 {"rep_get_timeout", (PyCFunction
)DBEnv_rep_get_timeout
, METH_VARARGS
},
8845 {"rep_set_clockskew", (PyCFunction
)DBEnv_rep_set_clockskew
, METH_VARARGS
},
8846 {"rep_get_clockskew", (PyCFunction
)DBEnv_rep_get_clockskew
, METH_VARARGS
},
8848 {"rep_stat", (PyCFunction
)DBEnv_rep_stat
,
8849 METH_VARARGS
|METH_KEYWORDS
},
8851 {"rep_stat_print", (PyCFunction
)DBEnv_rep_stat_print
,
8852 METH_VARARGS
|METH_KEYWORDS
},
8856 {"repmgr_start", (PyCFunction
)DBEnv_repmgr_start
,
8857 METH_VARARGS
|METH_KEYWORDS
},
8858 {"repmgr_set_local_site", (PyCFunction
)DBEnv_repmgr_set_local_site
,
8859 METH_VARARGS
|METH_KEYWORDS
},
8860 {"repmgr_add_remote_site", (PyCFunction
)DBEnv_repmgr_add_remote_site
,
8861 METH_VARARGS
|METH_KEYWORDS
},
8862 {"repmgr_set_ack_policy", (PyCFunction
)DBEnv_repmgr_set_ack_policy
,
8864 {"repmgr_get_ack_policy", (PyCFunction
)DBEnv_repmgr_get_ack_policy
,
8866 {"repmgr_site_list", (PyCFunction
)DBEnv_repmgr_site_list
,
8870 {"repmgr_stat", (PyCFunction
)DBEnv_repmgr_stat
,
8871 METH_VARARGS
|METH_KEYWORDS
},
8872 {"repmgr_stat_print", (PyCFunction
)DBEnv_repmgr_stat_print
,
8873 METH_VARARGS
|METH_KEYWORDS
},
8875 {NULL
, NULL
} /* sentinel */
8879 static PyMethodDef DBTxn_methods
[] = {
8880 {"commit", (PyCFunction
)DBTxn_commit
, METH_VARARGS
},
8881 {"prepare", (PyCFunction
)DBTxn_prepare
, METH_VARARGS
},
8882 {"discard", (PyCFunction
)DBTxn_discard
, METH_NOARGS
},
8883 {"abort", (PyCFunction
)DBTxn_abort
, METH_NOARGS
},
8884 {"id", (PyCFunction
)DBTxn_id
, METH_NOARGS
},
8885 {"set_timeout", (PyCFunction
)DBTxn_set_timeout
,
8886 METH_VARARGS
|METH_KEYWORDS
},
8888 {"set_name", (PyCFunction
)DBTxn_set_name
, METH_VARARGS
},
8889 {"get_name", (PyCFunction
)DBTxn_get_name
, METH_NOARGS
},
8891 {NULL
, NULL
} /* sentinel */
8896 static PyMethodDef DBSequence_methods
[] = {
8897 {"close", (PyCFunction
)DBSequence_close
, METH_VARARGS
},
8898 {"get", (PyCFunction
)DBSequence_get
, METH_VARARGS
|METH_KEYWORDS
},
8899 {"get_dbp", (PyCFunction
)DBSequence_get_dbp
, METH_NOARGS
},
8900 {"get_key", (PyCFunction
)DBSequence_get_key
, METH_NOARGS
},
8901 {"initial_value", (PyCFunction
)DBSequence_initial_value
, METH_VARARGS
},
8902 {"open", (PyCFunction
)DBSequence_open
, METH_VARARGS
|METH_KEYWORDS
},
8903 {"remove", (PyCFunction
)DBSequence_remove
, METH_VARARGS
|METH_KEYWORDS
},
8904 {"set_cachesize", (PyCFunction
)DBSequence_set_cachesize
, METH_VARARGS
},
8905 {"get_cachesize", (PyCFunction
)DBSequence_get_cachesize
, METH_NOARGS
},
8906 {"set_flags", (PyCFunction
)DBSequence_set_flags
, METH_VARARGS
},
8907 {"get_flags", (PyCFunction
)DBSequence_get_flags
, METH_NOARGS
},
8908 {"set_range", (PyCFunction
)DBSequence_set_range
, METH_VARARGS
},
8909 {"get_range", (PyCFunction
)DBSequence_get_range
, METH_NOARGS
},
8910 {"stat", (PyCFunction
)DBSequence_stat
, METH_VARARGS
|METH_KEYWORDS
},
8911 {"stat_print", (PyCFunction
)DBSequence_stat_print
,
8912 METH_VARARGS
|METH_KEYWORDS
},
8913 {NULL
, NULL
} /* sentinel */
8919 DBEnv_db_home_get(DBEnvObject
* self
)
8921 const char *home
= NULL
;
8923 CHECK_ENV_NOT_CLOSED(self
);
8926 MYDB_BEGIN_ALLOW_THREADS
;
8927 self
->db_env
->get_home(self
->db_env
, &home
);
8928 MYDB_END_ALLOW_THREADS
;
8930 home
=self
->db_env
->db_home
;
8936 return PyBytes_FromString(home
);
8939 static PyGetSetDef DBEnv_getsets
[] = {
8940 {"db_home", (getter
)DBEnv_db_home_get
, NULL
,},
8945 statichere PyTypeObject DB_Type
= {
8946 #if (PY_VERSION_HEX < 0x03000000)
8947 PyObject_HEAD_INIT(NULL
)
8950 PyVarObject_HEAD_INIT(NULL
, 0)
8953 sizeof(DBObject
), /*tp_basicsize*/
8956 (destructor
)DB_dealloc
, /*tp_dealloc*/
8963 &DB_sequence
,/*tp_as_sequence*/
8964 &DB_mapping
,/*tp_as_mapping*/
8968 0, /* tp_getattro */
8969 0, /* tp_setattro */
8970 0, /* tp_as_buffer */
8971 #if (PY_VERSION_HEX < 0x03000000)
8972 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
8974 Py_TPFLAGS_DEFAULT
, /* tp_flags */
8977 0, /* tp_traverse */
8979 0, /* tp_richcompare */
8980 offsetof(DBObject
, in_weakreflist
), /* tp_weaklistoffset */
8983 DB_methods
, /*tp_methods*/
8988 statichere PyTypeObject DBCursor_Type
= {
8989 #if (PY_VERSION_HEX < 0x03000000)
8990 PyObject_HEAD_INIT(NULL
)
8993 PyVarObject_HEAD_INIT(NULL
, 0)
8995 "DBCursor", /*tp_name*/
8996 sizeof(DBCursorObject
), /*tp_basicsize*/
8999 (destructor
)DBCursor_dealloc
,/*tp_dealloc*/
9006 0, /*tp_as_sequence*/
9007 0, /*tp_as_mapping*/
9014 #if (PY_VERSION_HEX < 0x03000000)
9015 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
9017 Py_TPFLAGS_DEFAULT
, /* tp_flags */
9020 0, /* tp_traverse */
9022 0, /* tp_richcompare */
9023 offsetof(DBCursorObject
, in_weakreflist
), /* tp_weaklistoffset */
9026 DBCursor_methods
, /*tp_methods*/
9031 statichere PyTypeObject DBLogCursor_Type
= {
9032 #if (PY_VERSION_HEX < 0x03000000)
9033 PyObject_HEAD_INIT(NULL
)
9036 PyVarObject_HEAD_INIT(NULL
, 0)
9038 "DBLogCursor", /*tp_name*/
9039 sizeof(DBLogCursorObject
), /*tp_basicsize*/
9042 (destructor
)DBLogCursor_dealloc
,/*tp_dealloc*/
9049 0, /*tp_as_sequence*/
9050 0, /*tp_as_mapping*/
9057 #if (PY_VERSION_HEX < 0x03000000)
9058 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
9060 Py_TPFLAGS_DEFAULT
, /* tp_flags */
9063 0, /* tp_traverse */
9065 0, /* tp_richcompare */
9066 offsetof(DBLogCursorObject
, in_weakreflist
), /* tp_weaklistoffset */
9069 DBLogCursor_methods
, /*tp_methods*/
9074 statichere PyTypeObject DBEnv_Type
= {
9075 #if (PY_VERSION_HEX < 0x03000000)
9076 PyObject_HEAD_INIT(NULL
)
9079 PyVarObject_HEAD_INIT(NULL
, 0)
9081 "DBEnv", /*tp_name*/
9082 sizeof(DBEnvObject
), /*tp_basicsize*/
9085 (destructor
)DBEnv_dealloc
, /*tp_dealloc*/
9092 0, /*tp_as_sequence*/
9093 0, /*tp_as_mapping*/
9097 0, /* tp_getattro */
9098 0, /* tp_setattro */
9099 0, /* tp_as_buffer */
9100 #if (PY_VERSION_HEX < 0x03000000)
9101 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
9103 Py_TPFLAGS_DEFAULT
, /* tp_flags */
9106 0, /* tp_traverse */
9108 0, /* tp_richcompare */
9109 offsetof(DBEnvObject
, in_weakreflist
), /* tp_weaklistoffset */
9111 0, /* tp_iternext */
9112 DBEnv_methods
, /* tp_methods */
9114 DBEnv_getsets
, /* tp_getsets */
9117 statichere PyTypeObject DBTxn_Type
= {
9118 #if (PY_VERSION_HEX < 0x03000000)
9119 PyObject_HEAD_INIT(NULL
)
9122 PyVarObject_HEAD_INIT(NULL
, 0)
9124 "DBTxn", /*tp_name*/
9125 sizeof(DBTxnObject
), /*tp_basicsize*/
9128 (destructor
)DBTxn_dealloc
, /*tp_dealloc*/
9135 0, /*tp_as_sequence*/
9136 0, /*tp_as_mapping*/
9140 0, /* tp_getattro */
9141 0, /* tp_setattro */
9142 0, /* tp_as_buffer */
9143 #if (PY_VERSION_HEX < 0x03000000)
9144 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
9146 Py_TPFLAGS_DEFAULT
, /* tp_flags */
9149 0, /* tp_traverse */
9151 0, /* tp_richcompare */
9152 offsetof(DBTxnObject
, in_weakreflist
), /* tp_weaklistoffset */
9155 DBTxn_methods
, /*tp_methods*/
9160 statichere PyTypeObject DBLock_Type
= {
9161 #if (PY_VERSION_HEX < 0x03000000)
9162 PyObject_HEAD_INIT(NULL
)
9165 PyVarObject_HEAD_INIT(NULL
, 0)
9167 "DBLock", /*tp_name*/
9168 sizeof(DBLockObject
), /*tp_basicsize*/
9171 (destructor
)DBLock_dealloc
, /*tp_dealloc*/
9178 0, /*tp_as_sequence*/
9179 0, /*tp_as_mapping*/
9183 0, /* tp_getattro */
9184 0, /* tp_setattro */
9185 0, /* tp_as_buffer */
9186 #if (PY_VERSION_HEX < 0x03000000)
9187 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
9189 Py_TPFLAGS_DEFAULT
, /* tp_flags */
9192 0, /* tp_traverse */
9194 0, /* tp_richcompare */
9195 offsetof(DBLockObject
, in_weakreflist
), /* tp_weaklistoffset */
9199 statichere PyTypeObject DBSequence_Type
= {
9200 #if (PY_VERSION_HEX < 0x03000000)
9201 PyObject_HEAD_INIT(NULL
)
9204 PyVarObject_HEAD_INIT(NULL
, 0)
9206 "DBSequence", /*tp_name*/
9207 sizeof(DBSequenceObject
), /*tp_basicsize*/
9210 (destructor
)DBSequence_dealloc
, /*tp_dealloc*/
9217 0, /*tp_as_sequence*/
9218 0, /*tp_as_mapping*/
9222 0, /* tp_getattro */
9223 0, /* tp_setattro */
9224 0, /* tp_as_buffer */
9225 #if (PY_VERSION_HEX < 0x03000000)
9226 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
9228 Py_TPFLAGS_DEFAULT
, /* tp_flags */
9231 0, /* tp_traverse */
9233 0, /* tp_richcompare */
9234 offsetof(DBSequenceObject
, in_weakreflist
), /* tp_weaklistoffset */
9237 DBSequence_methods
, /*tp_methods*/
9242 /* --------------------------------------------------------------------- */
9243 /* Module-level functions */
9246 DB_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
9248 PyObject
* dbenvobj
= NULL
;
9250 static char* kwnames
[] = { "dbEnv", "flags", NULL
};
9252 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:DB", kwnames
,
9255 if (dbenvobj
== Py_None
)
9257 else if (dbenvobj
&& !DBEnvObject_Check(dbenvobj
)) {
9258 makeTypeError("DBEnv", dbenvobj
);
9262 return (PyObject
* )newDBObject((DBEnvObject
*)dbenvobj
, flags
);
9267 DBEnv_construct(PyObject
* self
, PyObject
* args
)
9270 if (!PyArg_ParseTuple(args
, "|i:DbEnv", &flags
)) return NULL
;
9271 return (PyObject
* )newDBEnvObject(flags
);
9276 DBSequence_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
9280 static char* kwnames
[] = { "db", "flags", NULL
};
9282 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|i:DBSequence", kwnames
, &dbobj
, &flags
))
9284 if (!DBObject_Check(dbobj
)) {
9285 makeTypeError("DB", dbobj
);
9288 return (PyObject
* )newDBSequenceObject((DBObject
*)dbobj
, flags
);
9292 static char bsddb_version_doc
[] =
9293 "Returns a tuple of major, minor, and patch release numbers of the\n\
9294 underlying DB library.";
9297 bsddb_version(PyObject
* self
)
9299 int major
, minor
, patch
;
9301 db_version(&major
, &minor
, &patch
);
9302 return Py_BuildValue("(iii)", major
, minor
, patch
);
9306 /* List of functions defined in the module */
9307 static PyMethodDef bsddb_methods
[] = {
9308 {"DB", (PyCFunction
)DB_construct
, METH_VARARGS
| METH_KEYWORDS
},
9309 {"DBEnv", (PyCFunction
)DBEnv_construct
, METH_VARARGS
},
9311 {"DBSequence", (PyCFunction
)DBSequence_construct
, METH_VARARGS
| METH_KEYWORDS
},
9313 {"version", (PyCFunction
)bsddb_version
, METH_NOARGS
, bsddb_version_doc
},
9314 {NULL
, NULL
} /* sentinel */
9319 static BSDDB_api bsddb_api
;
9322 /* --------------------------------------------------------------------- */
9323 /* Module initialization */
9326 /* Convenience routine to export an integer value.
9327 * Errors are silently ignored, for better or for worse...
9329 #define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
9331 #define MODULE_NAME_MAX_LEN 11
9332 static char _bsddbModuleName
[MODULE_NAME_MAX_LEN
+1] = "_bsddb";
9334 #if (PY_VERSION_HEX >= 0x03000000)
9335 static struct PyModuleDef bsddbmodule
= {
9336 PyModuleDef_HEAD_INIT
,
9337 _bsddbModuleName
, /* Name of module */
9338 NULL
, /* module documentation, may be NULL */
9339 -1, /* size of per-interpreter state of the module,
9340 or -1 if the module keeps state in global variables. */
9343 NULL
, /* Traverse */
9350 #if (PY_VERSION_HEX < 0x03000000)
9351 DL_EXPORT(void) init_bsddb(void)
9353 PyMODINIT_FUNC
PyInit__bsddb(void) /* Note the two underscores */
9359 PyObject
* pybsddb_version_s
;
9360 PyObject
* db_version_s
;
9363 #if (PY_VERSION_HEX < 0x03000000)
9364 pybsddb_version_s
= PyString_FromString(PY_BSDDB_VERSION
);
9365 db_version_s
= PyString_FromString(DB_VERSION_STRING
);
9366 cvsid_s
= PyString_FromString(rcs_id
);
9368 /* This data should be ascii, so UTF-8 conversion is fine */
9369 pybsddb_version_s
= PyUnicode_FromString(PY_BSDDB_VERSION
);
9370 db_version_s
= PyUnicode_FromString(DB_VERSION_STRING
);
9371 cvsid_s
= PyUnicode_FromString(rcs_id
);
9374 /* Initialize object types */
9375 if ((PyType_Ready(&DB_Type
) < 0)
9376 || (PyType_Ready(&DBCursor_Type
) < 0)
9377 || (PyType_Ready(&DBLogCursor_Type
) < 0)
9378 || (PyType_Ready(&DBEnv_Type
) < 0)
9379 || (PyType_Ready(&DBTxn_Type
) < 0)
9380 || (PyType_Ready(&DBLock_Type
) < 0)
9382 || (PyType_Ready(&DBSequence_Type
) < 0)
9385 #if (PY_VERSION_HEX < 0x03000000)
9392 #if defined(WITH_THREAD) && !defined(MYDB_USE_GILSTATE)
9393 /* Save the current interpreter, so callbacks can do the right thing. */
9394 _db_interpreterState
= PyThreadState_GET()->interp
;
9397 /* Create the module and add the functions */
9398 #if (PY_VERSION_HEX < 0x03000000)
9399 m
= Py_InitModule(_bsddbModuleName
, bsddb_methods
);
9401 m
=PyModule_Create(&bsddbmodule
);
9404 #if (PY_VERSION_HEX < 0x03000000)
9411 /* Add some symbolic constants to the module */
9412 d
= PyModule_GetDict(m
);
9413 PyDict_SetItemString(d
, "__version__", pybsddb_version_s
);
9414 PyDict_SetItemString(d
, "cvsid", cvsid_s
);
9415 PyDict_SetItemString(d
, "DB_VERSION_STRING", db_version_s
);
9416 Py_DECREF(pybsddb_version_s
);
9417 pybsddb_version_s
= NULL
;
9420 Py_DECREF(db_version_s
);
9421 db_version_s
= NULL
;
9423 ADD_INT(d
, DB_VERSION_MAJOR
);
9424 ADD_INT(d
, DB_VERSION_MINOR
);
9425 ADD_INT(d
, DB_VERSION_PATCH
);
9427 ADD_INT(d
, DB_MAX_PAGES
);
9428 ADD_INT(d
, DB_MAX_RECORDS
);
9432 ADD_INT(d
, DB_RPCCLIENT
);
9434 ADD_INT(d
, DB_CLIENT
);
9435 /* allow apps to be written using DB_RPCCLIENT on older Berkeley DB */
9436 _addIntToDict(d
, "DB_RPCCLIENT", DB_CLIENT
);
9441 ADD_INT(d
, DB_XA_CREATE
);
9444 ADD_INT(d
, DB_CREATE
);
9445 ADD_INT(d
, DB_NOMMAP
);
9446 ADD_INT(d
, DB_THREAD
);
9448 ADD_INT(d
, DB_MULTIVERSION
);
9451 ADD_INT(d
, DB_FORCE
);
9452 ADD_INT(d
, DB_INIT_CDB
);
9453 ADD_INT(d
, DB_INIT_LOCK
);
9454 ADD_INT(d
, DB_INIT_LOG
);
9455 ADD_INT(d
, DB_INIT_MPOOL
);
9456 ADD_INT(d
, DB_INIT_TXN
);
9457 ADD_INT(d
, DB_JOINENV
);
9460 ADD_INT(d
, DB_GID_SIZE
);
9462 ADD_INT(d
, DB_XIDDATASIZE
);
9463 /* Allow new code to work in old BDB releases */
9464 _addIntToDict(d
, "DB_GID_SIZE", DB_XIDDATASIZE
);
9467 ADD_INT(d
, DB_RECOVER
);
9468 ADD_INT(d
, DB_RECOVER_FATAL
);
9469 ADD_INT(d
, DB_TXN_NOSYNC
);
9470 ADD_INT(d
, DB_USE_ENVIRON
);
9471 ADD_INT(d
, DB_USE_ENVIRON_ROOT
);
9473 ADD_INT(d
, DB_LOCKDOWN
);
9474 ADD_INT(d
, DB_PRIVATE
);
9475 ADD_INT(d
, DB_SYSTEM_MEM
);
9477 ADD_INT(d
, DB_TXN_SYNC
);
9478 ADD_INT(d
, DB_TXN_NOWAIT
);
9481 ADD_INT(d
, DB_TXN_WAIT
);
9484 ADD_INT(d
, DB_EXCL
);
9485 ADD_INT(d
, DB_FCNTL_LOCKING
);
9486 ADD_INT(d
, DB_ODDFILESIZE
);
9487 ADD_INT(d
, DB_RDWRMASTER
);
9488 ADD_INT(d
, DB_RDONLY
);
9489 ADD_INT(d
, DB_TRUNCATE
);
9490 ADD_INT(d
, DB_EXTENT
);
9491 ADD_INT(d
, DB_CDB_ALLDB
);
9492 ADD_INT(d
, DB_VERIFY
);
9493 ADD_INT(d
, DB_UPGRADE
);
9495 ADD_INT(d
, DB_PRINTABLE
);
9496 ADD_INT(d
, DB_AGGRESSIVE
);
9497 ADD_INT(d
, DB_NOORDERCHK
);
9498 ADD_INT(d
, DB_ORDERCHKONLY
);
9499 ADD_INT(d
, DB_PR_PAGE
);
9501 ADD_INT(d
, DB_PR_RECOVERYTEST
);
9502 ADD_INT(d
, DB_SALVAGE
);
9504 ADD_INT(d
, DB_LOCK_NORUN
);
9505 ADD_INT(d
, DB_LOCK_DEFAULT
);
9506 ADD_INT(d
, DB_LOCK_OLDEST
);
9507 ADD_INT(d
, DB_LOCK_RANDOM
);
9508 ADD_INT(d
, DB_LOCK_YOUNGEST
);
9509 ADD_INT(d
, DB_LOCK_MAXLOCKS
);
9510 ADD_INT(d
, DB_LOCK_MINLOCKS
);
9511 ADD_INT(d
, DB_LOCK_MINWRITE
);
9513 ADD_INT(d
, DB_LOCK_EXPIRE
);
9515 ADD_INT(d
, DB_LOCK_MAXWRITE
);
9518 _addIntToDict(d
, "DB_LOCK_CONFLICT", 0);
9520 ADD_INT(d
, DB_LOCK_DUMP
);
9521 ADD_INT(d
, DB_LOCK_GET
);
9522 ADD_INT(d
, DB_LOCK_INHERIT
);
9523 ADD_INT(d
, DB_LOCK_PUT
);
9524 ADD_INT(d
, DB_LOCK_PUT_ALL
);
9525 ADD_INT(d
, DB_LOCK_PUT_OBJ
);
9527 ADD_INT(d
, DB_LOCK_NG
);
9528 ADD_INT(d
, DB_LOCK_READ
);
9529 ADD_INT(d
, DB_LOCK_WRITE
);
9530 ADD_INT(d
, DB_LOCK_NOWAIT
);
9531 ADD_INT(d
, DB_LOCK_WAIT
);
9532 ADD_INT(d
, DB_LOCK_IWRITE
);
9533 ADD_INT(d
, DB_LOCK_IREAD
);
9534 ADD_INT(d
, DB_LOCK_IWR
);
9536 ADD_INT(d
, DB_LOCK_DIRTY
);
9538 ADD_INT(d
, DB_LOCK_READ_UNCOMMITTED
); /* renamed in 4.4 */
9540 ADD_INT(d
, DB_LOCK_WWRITE
);
9542 ADD_INT(d
, DB_LOCK_RECORD
);
9543 ADD_INT(d
, DB_LOCK_UPGRADE
);
9544 ADD_INT(d
, DB_LOCK_SWITCH
);
9545 ADD_INT(d
, DB_LOCK_UPGRADE_WRITE
);
9547 ADD_INT(d
, DB_LOCK_NOWAIT
);
9548 ADD_INT(d
, DB_LOCK_RECORD
);
9549 ADD_INT(d
, DB_LOCK_UPGRADE
);
9551 ADD_INT(d
, DB_LSTAT_ABORTED
);
9553 ADD_INT(d
, DB_LSTAT_ERR
);
9555 ADD_INT(d
, DB_LSTAT_FREE
);
9556 ADD_INT(d
, DB_LSTAT_HELD
);
9558 ADD_INT(d
, DB_LSTAT_PENDING
);
9559 ADD_INT(d
, DB_LSTAT_WAITING
);
9561 ADD_INT(d
, DB_ARCH_ABS
);
9562 ADD_INT(d
, DB_ARCH_DATA
);
9563 ADD_INT(d
, DB_ARCH_LOG
);
9565 ADD_INT(d
, DB_ARCH_REMOVE
);
9568 ADD_INT(d
, DB_BTREE
);
9569 ADD_INT(d
, DB_HASH
);
9570 ADD_INT(d
, DB_RECNO
);
9571 ADD_INT(d
, DB_QUEUE
);
9572 ADD_INT(d
, DB_UNKNOWN
);
9575 ADD_INT(d
, DB_DUPSORT
);
9576 ADD_INT(d
, DB_RECNUM
);
9577 ADD_INT(d
, DB_RENUMBER
);
9578 ADD_INT(d
, DB_REVSPLITOFF
);
9579 ADD_INT(d
, DB_SNAPSHOT
);
9582 ADD_INT(d
, DB_INORDER
);
9585 ADD_INT(d
, DB_JOIN_NOSORT
);
9587 ADD_INT(d
, DB_AFTER
);
9588 ADD_INT(d
, DB_APPEND
);
9589 ADD_INT(d
, DB_BEFORE
);
9591 ADD_INT(d
, DB_CACHED_COUNTS
);
9595 ADD_INT(d
, DB_COMMIT
);
9597 ADD_INT(d
, DB_CONSUME
);
9598 ADD_INT(d
, DB_CONSUME_WAIT
);
9599 ADD_INT(d
, DB_CURRENT
);
9600 ADD_INT(d
, DB_FAST_STAT
);
9601 ADD_INT(d
, DB_FIRST
);
9602 ADD_INT(d
, DB_FLUSH
);
9603 ADD_INT(d
, DB_GET_BOTH
);
9604 ADD_INT(d
, DB_GET_BOTH_RANGE
);
9605 ADD_INT(d
, DB_GET_RECNO
);
9606 ADD_INT(d
, DB_JOIN_ITEM
);
9607 ADD_INT(d
, DB_KEYFIRST
);
9608 ADD_INT(d
, DB_KEYLAST
);
9609 ADD_INT(d
, DB_LAST
);
9610 ADD_INT(d
, DB_NEXT
);
9611 ADD_INT(d
, DB_NEXT_DUP
);
9612 ADD_INT(d
, DB_NEXT_NODUP
);
9613 ADD_INT(d
, DB_NODUPDATA
);
9614 ADD_INT(d
, DB_NOOVERWRITE
);
9615 ADD_INT(d
, DB_NOSYNC
);
9616 ADD_INT(d
, DB_POSITION
);
9617 ADD_INT(d
, DB_PREV
);
9618 ADD_INT(d
, DB_PREV_NODUP
);
9620 ADD_INT(d
, DB_PREV_DUP
);
9623 ADD_INT(d
, DB_RECORDCOUNT
);
9626 ADD_INT(d
, DB_SET_RANGE
);
9627 ADD_INT(d
, DB_SET_RECNO
);
9628 ADD_INT(d
, DB_WRITECURSOR
);
9630 ADD_INT(d
, DB_OPFLAGS_MASK
);
9632 ADD_INT(d
, DB_DIRTY_READ
);
9633 ADD_INT(d
, DB_MULTIPLE
);
9634 ADD_INT(d
, DB_MULTIPLE_KEY
);
9637 ADD_INT(d
, DB_IMMUTABLE_KEY
);
9638 ADD_INT(d
, DB_READ_UNCOMMITTED
); /* replaces DB_DIRTY_READ in 4.4 */
9639 ADD_INT(d
, DB_READ_COMMITTED
);
9643 ADD_INT(d
, DB_FREELIST_ONLY
);
9644 ADD_INT(d
, DB_FREE_SPACE
);
9647 ADD_INT(d
, DB_DONOTINDEX
);
9649 ADD_INT(d
, DB_KEYEMPTY
);
9650 ADD_INT(d
, DB_KEYEXIST
);
9651 ADD_INT(d
, DB_LOCK_DEADLOCK
);
9652 ADD_INT(d
, DB_LOCK_NOTGRANTED
);
9653 ADD_INT(d
, DB_NOSERVER
);
9654 ADD_INT(d
, DB_NOSERVER_HOME
);
9655 ADD_INT(d
, DB_NOSERVER_ID
);
9656 ADD_INT(d
, DB_NOTFOUND
);
9657 ADD_INT(d
, DB_OLD_VERSION
);
9658 ADD_INT(d
, DB_RUNRECOVERY
);
9659 ADD_INT(d
, DB_VERIFY_BAD
);
9660 ADD_INT(d
, DB_PAGE_NOTFOUND
);
9661 ADD_INT(d
, DB_SECONDARY_BAD
);
9662 ADD_INT(d
, DB_STAT_CLEAR
);
9663 ADD_INT(d
, DB_REGION_INIT
);
9664 ADD_INT(d
, DB_NOLOCKING
);
9665 ADD_INT(d
, DB_YIELDCPU
);
9666 ADD_INT(d
, DB_PANIC_ENVIRONMENT
);
9667 ADD_INT(d
, DB_NOPANIC
);
9669 ADD_INT(d
, DB_OVERWRITE
);
9672 ADD_INT(d
, DB_STAT_SUBSYSTEM
);
9673 ADD_INT(d
, DB_STAT_MEMP_HASH
);
9677 ADD_INT(d
, DB_OVERWRITE_DUP
);
9681 ADD_INT(d
, DB_FOREIGN_ABORT
);
9682 ADD_INT(d
, DB_FOREIGN_CASCADE
);
9683 ADD_INT(d
, DB_FOREIGN_NULLIFY
);
9687 ADD_INT(d
, DB_REGISTER
);
9690 ADD_INT(d
, DB_EID_INVALID
);
9691 ADD_INT(d
, DB_EID_BROADCAST
);
9694 ADD_INT(d
, DB_TIME_NOTGRANTED
);
9695 ADD_INT(d
, DB_TXN_NOT_DURABLE
);
9696 ADD_INT(d
, DB_TXN_WRITE_NOSYNC
);
9697 ADD_INT(d
, DB_DIRECT_DB
);
9698 ADD_INT(d
, DB_INIT_REP
);
9699 ADD_INT(d
, DB_ENCRYPT
);
9700 ADD_INT(d
, DB_CHKSUM
);
9703 #if (DBVER >= 42) && (DBVER < 47)
9704 ADD_INT(d
, DB_LOG_AUTOREMOVE
);
9705 ADD_INT(d
, DB_DIRECT_LOG
);
9709 ADD_INT(d
, DB_LOG_DIRECT
);
9710 ADD_INT(d
, DB_LOG_DSYNC
);
9711 ADD_INT(d
, DB_LOG_IN_MEMORY
);
9712 ADD_INT(d
, DB_LOG_AUTO_REMOVE
);
9713 ADD_INT(d
, DB_LOG_ZERO
);
9717 ADD_INT(d
, DB_DSYNC_DB
);
9721 ADD_INT(d
, DB_TXN_SNAPSHOT
);
9724 ADD_INT(d
, DB_VERB_DEADLOCK
);
9726 ADD_INT(d
, DB_VERB_FILEOPS
);
9727 ADD_INT(d
, DB_VERB_FILEOPS_ALL
);
9729 ADD_INT(d
, DB_VERB_RECOVERY
);
9731 ADD_INT(d
, DB_VERB_REGISTER
);
9733 ADD_INT(d
, DB_VERB_REPLICATION
);
9734 ADD_INT(d
, DB_VERB_WAITSFOR
);
9737 ADD_INT(d
, DB_EVENT_PANIC
);
9738 ADD_INT(d
, DB_EVENT_REP_CLIENT
);
9740 ADD_INT(d
, DB_EVENT_REP_ELECTED
);
9742 ADD_INT(d
, DB_EVENT_REP_MASTER
);
9743 ADD_INT(d
, DB_EVENT_REP_NEWMASTER
);
9745 ADD_INT(d
, DB_EVENT_REP_PERM_FAILED
);
9747 ADD_INT(d
, DB_EVENT_REP_STARTUPDONE
);
9748 ADD_INT(d
, DB_EVENT_WRITE_FAILED
);
9751 ADD_INT(d
, DB_REP_DUPMASTER
);
9752 ADD_INT(d
, DB_REP_HOLDELECTION
);
9754 ADD_INT(d
, DB_REP_IGNORE
);
9755 ADD_INT(d
, DB_REP_JOIN_FAILURE
);
9758 ADD_INT(d
, DB_REP_ISPERM
);
9759 ADD_INT(d
, DB_REP_NOTPERM
);
9761 ADD_INT(d
, DB_REP_NEWSITE
);
9763 ADD_INT(d
, DB_REP_MASTER
);
9764 ADD_INT(d
, DB_REP_CLIENT
);
9766 ADD_INT(d
, DB_REP_PERMANENT
);
9769 ADD_INT(d
, DB_REP_CONF_NOAUTOINIT
);
9770 ADD_INT(d
, DB_REP_CONF_DELAYCLIENT
);
9771 ADD_INT(d
, DB_REP_CONF_BULK
);
9772 ADD_INT(d
, DB_REP_CONF_NOWAIT
);
9773 ADD_INT(d
, DB_REP_ANYWHERE
);
9774 ADD_INT(d
, DB_REP_REREQUEST
);
9778 ADD_INT(d
, DB_REP_NOBUFFER
);
9782 ADD_INT(d
, DB_REP_LEASE_EXPIRED
);
9783 ADD_INT(d
, DB_IGNORE_LEASE
);
9787 ADD_INT(d
, DB_REP_CONF_LEASE
);
9788 ADD_INT(d
, DB_REPMGR_CONF_2SITE_STRICT
);
9792 ADD_INT(d
, DB_REP_ELECTION
);
9794 ADD_INT(d
, DB_REP_ACK_TIMEOUT
);
9795 ADD_INT(d
, DB_REP_CONNECTION_RETRY
);
9796 ADD_INT(d
, DB_REP_ELECTION_TIMEOUT
);
9797 ADD_INT(d
, DB_REP_ELECTION_RETRY
);
9800 ADD_INT(d
, DB_REP_CHECKPOINT_DELAY
);
9801 ADD_INT(d
, DB_REP_FULL_ELECTION_TIMEOUT
);
9802 ADD_INT(d
, DB_REP_LEASE_TIMEOUT
);
9805 ADD_INT(d
, DB_REP_HEARTBEAT_MONITOR
);
9806 ADD_INT(d
, DB_REP_HEARTBEAT_SEND
);
9810 ADD_INT(d
, DB_REPMGR_PEER
);
9811 ADD_INT(d
, DB_REPMGR_ACKS_ALL
);
9812 ADD_INT(d
, DB_REPMGR_ACKS_ALL_PEERS
);
9813 ADD_INT(d
, DB_REPMGR_ACKS_NONE
);
9814 ADD_INT(d
, DB_REPMGR_ACKS_ONE
);
9815 ADD_INT(d
, DB_REPMGR_ACKS_ONE_PEER
);
9816 ADD_INT(d
, DB_REPMGR_ACKS_QUORUM
);
9817 ADD_INT(d
, DB_REPMGR_CONNECTED
);
9818 ADD_INT(d
, DB_REPMGR_DISCONNECTED
);
9819 ADD_INT(d
, DB_STAT_ALL
);
9823 ADD_INT(d
, DB_BUFFER_SMALL
);
9824 ADD_INT(d
, DB_SEQ_DEC
);
9825 ADD_INT(d
, DB_SEQ_INC
);
9826 ADD_INT(d
, DB_SEQ_WRAP
);
9829 #if (DBVER >= 43) && (DBVER < 47)
9830 ADD_INT(d
, DB_LOG_INMEMORY
);
9831 ADD_INT(d
, DB_DSYNC_LOG
);
9834 ADD_INT(d
, DB_ENCRYPT_AES
);
9835 ADD_INT(d
, DB_AUTO_COMMIT
);
9836 ADD_INT(d
, DB_PRIORITY_VERY_LOW
);
9837 ADD_INT(d
, DB_PRIORITY_LOW
);
9838 ADD_INT(d
, DB_PRIORITY_DEFAULT
);
9839 ADD_INT(d
, DB_PRIORITY_HIGH
);
9840 ADD_INT(d
, DB_PRIORITY_VERY_HIGH
);
9843 ADD_INT(d
, DB_PRIORITY_UNCHANGED
);
9856 ADD_INT(d
, DB_SET_LOCK_TIMEOUT
);
9857 ADD_INT(d
, DB_SET_TXN_TIMEOUT
);
9859 /* The exception name must be correct for pickled exception *
9860 * objects to unpickle properly. */
9861 #ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
9862 #define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
9864 #define PYBSDDB_EXCEPTION_BASE "bsddb.db."
9867 /* All the rest of the exceptions derive only from DBError */
9868 #define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
9869 PyDict_SetItemString(d, #name, name)
9871 /* The base exception class is DBError */
9872 DBError
= NULL
; /* used in MAKE_EX so that it derives from nothing */
9875 #if (PY_VERSION_HEX < 0x03000000)
9876 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
9877 * from both DBError and KeyError, since the API only supports
9878 * using one base class. */
9879 PyDict_SetItemString(d
, "KeyError", PyExc_KeyError
);
9880 PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
9881 "class DBKeyEmptyError(DBError, KeyError): pass",
9882 Py_file_input
, d
, d
);
9883 DBNotFoundError
= PyDict_GetItemString(d
, "DBNotFoundError");
9884 DBKeyEmptyError
= PyDict_GetItemString(d
, "DBKeyEmptyError");
9885 PyDict_DelItemString(d
, "KeyError");
9887 /* Since Python 2.5, PyErr_NewException() accepts a tuple, to be able to
9888 ** derive from several classes. We use this new API only for Python 3.0,
9894 bases
= PyTuple_Pack(2, DBError
, PyExc_KeyError
);
9896 #define MAKE_EX2(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, bases, NULL); \
9897 PyDict_SetItemString(d, #name, name)
9898 MAKE_EX2(DBNotFoundError
);
9899 MAKE_EX2(DBKeyEmptyError
);
9907 MAKE_EX(DBCursorClosedError
);
9908 MAKE_EX(DBKeyExistError
);
9909 MAKE_EX(DBLockDeadlockError
);
9910 MAKE_EX(DBLockNotGrantedError
);
9911 MAKE_EX(DBOldVersionError
);
9912 MAKE_EX(DBRunRecoveryError
);
9913 MAKE_EX(DBVerifyBadError
);
9914 MAKE_EX(DBNoServerError
);
9915 MAKE_EX(DBNoServerHomeError
);
9916 MAKE_EX(DBNoServerIDError
);
9917 MAKE_EX(DBPageNotFoundError
);
9918 MAKE_EX(DBSecondaryBadError
);
9920 MAKE_EX(DBInvalidArgError
);
9921 MAKE_EX(DBAccessError
);
9922 MAKE_EX(DBNoSpaceError
);
9923 MAKE_EX(DBNoMemoryError
);
9924 MAKE_EX(DBAgainError
);
9925 MAKE_EX(DBBusyError
);
9926 MAKE_EX(DBFileExistsError
);
9927 MAKE_EX(DBNoSuchFileError
);
9928 MAKE_EX(DBPermissionsError
);
9931 MAKE_EX(DBRepHandleDeadError
);
9934 MAKE_EX(DBRepLockoutError
);
9937 MAKE_EX(DBRepUnavailError
);
9940 MAKE_EX(DBRepLeaseExpiredError
);
9944 MAKE_EX(DBForeignConflictError
);
9949 /* Initialise the C API structure and add it to the module */
9950 bsddb_api
.db_type
= &DB_Type
;
9951 bsddb_api
.dbcursor_type
= &DBCursor_Type
;
9952 bsddb_api
.dblogcursor_type
= &DBLogCursor_Type
;
9953 bsddb_api
.dbenv_type
= &DBEnv_Type
;
9954 bsddb_api
.dbtxn_type
= &DBTxn_Type
;
9955 bsddb_api
.dblock_type
= &DBLock_Type
;
9957 bsddb_api
.dbsequence_type
= &DBSequence_Type
;
9959 bsddb_api
.makeDBError
= makeDBError
;
9962 ** Capsules exist from Python 3.1, but I
9963 ** don't want to break the API compatibility
9964 ** for already published Python versions.
9966 #if (PY_VERSION_HEX < 0x03020000)
9967 py_api
= PyCObject_FromVoidPtr((void*)&bsddb_api
, NULL
);
9970 char py_api_name
[250];
9972 strcpy(py_api_name
, _bsddbModuleName
);
9973 strcat(py_api_name
, ".api");
9975 py_api
= PyCapsule_New((void*)&bsddb_api
, py_api_name
, NULL
);
9979 PyDict_SetItemString(d
, "api", py_api
);
9982 /* Check for errors */
9983 if (PyErr_Occurred()) {
9985 Py_FatalError("can't initialize module _bsddb/_pybsddb");
9989 #if (PY_VERSION_HEX < 0x03000000)
9996 /* allow this module to be named _pybsddb so that it can be installed
9997 * and imported on top of python >= 2.3 that includes its own older
9998 * copy of the library named _bsddb without importing the old version. */
9999 #if (PY_VERSION_HEX < 0x03000000)
10000 DL_EXPORT(void) init_pybsddb(void)
10002 PyMODINIT_FUNC
PyInit__pybsddb(void) /* Note the two underscores */
10005 strncpy(_bsddbModuleName
, "_pybsddb", MODULE_NAME_MAX_LEN
);
10006 #if (PY_VERSION_HEX < 0x03000000)
10009 return PyInit__bsddb(); /* Note the two underscores */