1 /*----------------------------------------------------------------------
2 Copyright (c) 1999-2001, Digital Creations, Fredericksburg, VA, USA
3 and Andrew Kuchling. All rights reserved.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
9 o Redistributions of source code must retain the above copyright
10 notice, this list of conditions, and the disclaimer that follows.
12 o Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions, and the following disclaimer in
14 the documentation and/or other materials provided with the
17 o Neither the name of Digital Creations nor the names of its
18 contributors may be used to endorse or promote products derived
19 from this software without specific prior written permission.
21 THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
22 IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
25 CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
33 ------------------------------------------------------------------------*/
37 * Handwritten code to wrap version 3.x of the Berkeley DB library,
38 * written to replace a SWIG-generated file. It has since been updated
39 * to compile with Berkeley DB versions 3.2 through 4.2.
41 * This module was started by Andrew Kuchling to remove the dependency
42 * on SWIG in a package by Gregory P. Smith who based his work on a
43 * similar package by Robin Dunn <robin@alldunn.com> which wrapped
46 * Development of this module then returned full circle back to Robin Dunn
47 * who worked on behalf of Digital Creations to complete the wrapping of
48 * the DB 3.x API and to build a solid unit test suite. Robin has
49 * since gone onto other projects (wxPython).
51 * Gregory P. Smith <greg@krypto.org> was once again the maintainer.
53 * Since January 2008, new maintainer is Jesus Cea <jcea@jcea.es>.
54 * Jesus Cea licenses this code to PSF under a Contributor Agreement.
56 * Use the pybsddb-users@lists.sf.net mailing list for all questions.
57 * Things can change faster than the header of this file is updated. This
58 * file is shared with the PyBSDDB project at SourceForge:
60 * http://pybsddb.sf.net
62 * This file should remain backward compatible with Python 2.1, but see PEP
63 * 291 for the most current backward compatibility requirements:
65 * http://www.python.org/peps/pep-0291.html
67 * This module contains 6 types:
70 * DBCursor (Database Cursor)
71 * DBEnv (database environment)
72 * DBTxn (An explicit database transaction)
73 * DBLock (A lock handle)
74 * DBSequence (Sequence)
78 /* --------------------------------------------------------------------- */
81 * Portions of this module, associated unit tests and build scripts are the
82 * result of a contract with The Written Word (http://thewrittenword.com/)
83 * Many thanks go out to them for causing me to raise the bar on quality and
84 * functionality, resulting in a better bsddb3 package for all of us to use.
89 /* --------------------------------------------------------------------- */
91 #include <stddef.h> /* for offsetof() */
94 #define COMPILING_BSDDB_C
96 #undef COMPILING_BSDDB_C
98 static char *rcs_id
= "$Id$";
100 /* --------------------------------------------------------------------- */
101 /* Various macro definitions */
103 #if (PY_VERSION_HEX < 0x02050000)
104 typedef int Py_ssize_t
;
107 #if (PY_VERSION_HEX < 0x02060000) /* really: before python trunk r63675 */
108 /* This code now uses PyBytes* API function names instead of PyString*.
109 * These #defines map to their equivalent on earlier python versions. */
110 #define PyBytes_FromStringAndSize PyString_FromStringAndSize
111 #define PyBytes_FromString PyString_FromString
112 #define PyBytes_AsStringAndSize PyString_AsStringAndSize
113 #define PyBytes_Check PyString_Check
114 #define PyBytes_GET_SIZE PyString_GET_SIZE
115 #define PyBytes_AS_STRING PyString_AS_STRING
118 #if (PY_VERSION_HEX >= 0x03000000)
119 #define NUMBER_Check PyLong_Check
120 #define NUMBER_AsLong PyLong_AsLong
121 #define NUMBER_FromLong PyLong_FromLong
123 #define NUMBER_Check PyInt_Check
124 #define NUMBER_AsLong PyInt_AsLong
125 #define NUMBER_FromLong PyInt_FromLong
130 /* These are for when calling Python --> C */
131 #define MYDB_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS;
132 #define MYDB_END_ALLOW_THREADS Py_END_ALLOW_THREADS;
134 /* For 2.3, use the PyGILState_ calls */
135 #if (PY_VERSION_HEX >= 0x02030000)
136 #define MYDB_USE_GILSTATE
139 /* and these are for calling C --> Python */
140 #if defined(MYDB_USE_GILSTATE)
141 #define MYDB_BEGIN_BLOCK_THREADS \
142 PyGILState_STATE __savestate = PyGILState_Ensure();
143 #define MYDB_END_BLOCK_THREADS \
144 PyGILState_Release(__savestate);
145 #else /* MYDB_USE_GILSTATE */
146 /* Pre GILState API - do it the long old way */
147 static PyInterpreterState
* _db_interpreterState
= NULL
;
148 #define MYDB_BEGIN_BLOCK_THREADS { \
149 PyThreadState* prevState; \
150 PyThreadState* newState; \
151 PyEval_AcquireLock(); \
152 newState = PyThreadState_New(_db_interpreterState); \
153 prevState = PyThreadState_Swap(newState);
155 #define MYDB_END_BLOCK_THREADS \
156 newState = PyThreadState_Swap(prevState); \
157 PyThreadState_Clear(newState); \
158 PyEval_ReleaseLock(); \
159 PyThreadState_Delete(newState); \
161 #endif /* MYDB_USE_GILSTATE */
164 /* Compiled without threads - avoid all this cruft */
165 #define MYDB_BEGIN_ALLOW_THREADS
166 #define MYDB_END_ALLOW_THREADS
167 #define MYDB_BEGIN_BLOCK_THREADS
168 #define MYDB_END_BLOCK_THREADS
172 /* Should DB_INCOMPLETE be turned into a warning or an exception? */
173 #define INCOMPLETE_IS_WARNING 1
175 /* --------------------------------------------------------------------- */
178 static PyObject
* DBError
; /* Base class, all others derive from this */
179 static PyObject
* DBCursorClosedError
; /* raised when trying to use a closed cursor object */
180 static PyObject
* DBKeyEmptyError
; /* DB_KEYEMPTY: also derives from KeyError */
181 static PyObject
* DBKeyExistError
; /* DB_KEYEXIST */
182 static PyObject
* DBLockDeadlockError
; /* DB_LOCK_DEADLOCK */
183 static PyObject
* DBLockNotGrantedError
; /* DB_LOCK_NOTGRANTED */
184 static PyObject
* DBNotFoundError
; /* DB_NOTFOUND: also derives from KeyError */
185 static PyObject
* DBOldVersionError
; /* DB_OLD_VERSION */
186 static PyObject
* DBRunRecoveryError
; /* DB_RUNRECOVERY */
187 static PyObject
* DBVerifyBadError
; /* DB_VERIFY_BAD */
188 static PyObject
* DBNoServerError
; /* DB_NOSERVER */
189 static PyObject
* DBNoServerHomeError
; /* DB_NOSERVER_HOME */
190 static PyObject
* DBNoServerIDError
; /* DB_NOSERVER_ID */
191 static PyObject
* DBPageNotFoundError
; /* DB_PAGE_NOTFOUND */
192 static PyObject
* DBSecondaryBadError
; /* DB_SECONDARY_BAD */
194 #if !INCOMPLETE_IS_WARNING
195 static PyObject
* DBIncompleteError
; /* DB_INCOMPLETE */
198 static PyObject
* DBInvalidArgError
; /* EINVAL */
199 static PyObject
* DBAccessError
; /* EACCES */
200 static PyObject
* DBNoSpaceError
; /* ENOSPC */
201 static PyObject
* DBNoMemoryError
; /* DB_BUFFER_SMALL (ENOMEM when < 4.3) */
202 static PyObject
* DBAgainError
; /* EAGAIN */
203 static PyObject
* DBBusyError
; /* EBUSY */
204 static PyObject
* DBFileExistsError
; /* EEXIST */
205 static PyObject
* DBNoSuchFileError
; /* ENOENT */
206 static PyObject
* DBPermissionsError
; /* EPERM */
209 static PyObject
* DBRepHandleDeadError
; /* DB_REP_HANDLE_DEAD */
212 static PyObject
* DBRepUnavailError
; /* DB_REP_UNAVAIL */
215 #define DB_BUFFER_SMALL ENOMEM
219 /* --------------------------------------------------------------------- */
220 /* Structure definitions */
222 #if PYTHON_API_VERSION < 1010
223 #error "Python 2.1 or later required"
227 /* Defaults for moduleFlags in DBEnvObject and DBObject. */
228 #define DEFAULT_GET_RETURNS_NONE 1
229 #define DEFAULT_CURSOR_SET_RETURNS_NONE 1 /* 0 in pybsddb < 4.2, python < 2.4 */
232 /* See comment in Python 2.6 "object.h" */
233 #ifndef staticforward
234 #define staticforward static
237 #define statichere static
240 staticforward PyTypeObject DB_Type
, DBCursor_Type
, DBEnv_Type
, DBTxn_Type
,
243 staticforward PyTypeObject DBSequence_Type
;
247 /* for compatibility with Python 2.5 and earlier */
248 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
251 #define DBObject_Check(v) (Py_TYPE(v) == &DB_Type)
252 #define DBCursorObject_Check(v) (Py_TYPE(v) == &DBCursor_Type)
253 #define DBEnvObject_Check(v) (Py_TYPE(v) == &DBEnv_Type)
254 #define DBTxnObject_Check(v) (Py_TYPE(v) == &DBTxn_Type)
255 #define DBLockObject_Check(v) (Py_TYPE(v) == &DBLock_Type)
257 #define DBSequenceObject_Check(v) (Py_TYPE(v) == &DBSequence_Type)
261 #define _DBC_close(dbc) dbc->c_close(dbc)
262 #define _DBC_count(dbc,a,b) dbc->c_count(dbc,a,b)
263 #define _DBC_del(dbc,a) dbc->c_del(dbc,a)
264 #define _DBC_dup(dbc,a,b) dbc->c_dup(dbc,a,b)
265 #define _DBC_get(dbc,a,b,c) dbc->c_get(dbc,a,b,c)
266 #define _DBC_pget(dbc,a,b,c,d) dbc->c_pget(dbc,a,b,c,d)
267 #define _DBC_put(dbc,a,b,c) dbc->c_put(dbc,a,b,c)
269 #define _DBC_close(dbc) dbc->close(dbc)
270 #define _DBC_count(dbc,a,b) dbc->count(dbc,a,b)
271 #define _DBC_del(dbc,a) dbc->del(dbc,a)
272 #define _DBC_dup(dbc,a,b) dbc->dup(dbc,a,b)
273 #define _DBC_get(dbc,a,b,c) dbc->get(dbc,a,b,c)
274 #define _DBC_pget(dbc,a,b,c,d) dbc->pget(dbc,a,b,c,d)
275 #define _DBC_put(dbc,a,b,c) dbc->put(dbc,a,b,c)
279 /* --------------------------------------------------------------------- */
280 /* Utility macros and functions */
282 #define INSERT_IN_DOUBLE_LINKED_LIST(backlink,object) \
284 object->sibling_next=backlink; \
285 object->sibling_prev_p=&(backlink); \
287 if (object->sibling_next) { \
288 object->sibling_next->sibling_prev_p=&(object->sibling_next); \
292 #define EXTRACT_FROM_DOUBLE_LINKED_LIST(object) \
294 if (object->sibling_next) { \
295 object->sibling_next->sibling_prev_p=object->sibling_prev_p; \
297 *(object->sibling_prev_p)=object->sibling_next; \
300 #define EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(object) \
302 if (object->sibling_next) { \
303 object->sibling_next->sibling_prev_p=object->sibling_prev_p; \
305 if (object->sibling_prev_p) { \
306 *(object->sibling_prev_p)=object->sibling_next; \
310 #define INSERT_IN_DOUBLE_LINKED_LIST_TXN(backlink,object) \
312 object->sibling_next_txn=backlink; \
313 object->sibling_prev_p_txn=&(backlink); \
315 if (object->sibling_next_txn) { \
316 object->sibling_next_txn->sibling_prev_p_txn= \
317 &(object->sibling_next_txn); \
321 #define EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(object) \
323 if (object->sibling_next_txn) { \
324 object->sibling_next_txn->sibling_prev_p_txn= \
325 object->sibling_prev_p_txn; \
327 *(object->sibling_prev_p_txn)=object->sibling_next_txn; \
331 #define RETURN_IF_ERR() \
332 if (makeDBError(err)) { \
336 #define RETURN_NONE() Py_INCREF(Py_None); return Py_None;
338 #define _CHECK_OBJECT_NOT_CLOSED(nonNull, pyErrObj, name) \
339 if ((nonNull) == NULL) { \
340 PyObject *errTuple = NULL; \
341 errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
343 PyErr_SetObject((pyErrObj), errTuple); \
344 Py_DECREF(errTuple); \
349 #define CHECK_DB_NOT_CLOSED(dbobj) \
350 _CHECK_OBJECT_NOT_CLOSED(dbobj->db, DBError, DB)
352 #define CHECK_ENV_NOT_CLOSED(env) \
353 _CHECK_OBJECT_NOT_CLOSED(env->db_env, DBError, DBEnv)
355 #define CHECK_CURSOR_NOT_CLOSED(curs) \
356 _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)
359 #define CHECK_SEQUENCE_NOT_CLOSED(curs) \
360 _CHECK_OBJECT_NOT_CLOSED(curs->sequence, DBError, DBSequence)
363 #define CHECK_DBFLAG(mydb, flag) (((mydb)->flags & (flag)) || \
364 (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))
366 #define CLEAR_DBT(dbt) (memset(&(dbt), 0, sizeof(dbt)))
368 #define FREE_DBT(dbt) if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
369 dbt.data != NULL) { free(dbt.data); dbt.data = NULL; }
372 static int makeDBError(int err
);
375 /* Return the access method type of the DBObject */
376 static int _DB_get_type(DBObject
* self
)
381 err
= self
->db
->get_type(self
->db
, &type
);
382 if (makeDBError(err
)) {
389 /* Create a DBT structure (containing key and data values) from Python
390 strings. Returns 1 on success, 0 on an error. */
391 static int make_dbt(PyObject
* obj
, DBT
* dbt
)
394 if (obj
== Py_None
) {
395 /* no need to do anything, the structure has already been zeroed */
397 else if (!PyArg_Parse(obj
, "s#", &dbt
->data
, &dbt
->size
)) {
398 PyErr_SetString(PyExc_TypeError
,
399 "Data values must be of type string or None.");
406 /* Recno and Queue DBs can have integer keys. This function figures out
407 what's been given, verifies that it's allowed, and then makes the DBT.
409 Caller MUST call FREE_DBT(key) when done. */
411 make_key_dbt(DBObject
* self
, PyObject
* keyobj
, DBT
* key
, int* pflags
)
417 if (keyobj
== Py_None
) {
418 type
= _DB_get_type(self
);
421 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
424 "None keys not allowed for Recno and Queue DB's");
427 /* no need to do anything, the structure has already been zeroed */
430 else if (PyBytes_Check(keyobj
)) {
431 /* verify access method type */
432 type
= _DB_get_type(self
);
435 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
438 "String keys not allowed for Recno and Queue DB's");
443 * NOTE(gps): I don't like doing a data copy here, it seems
444 * wasteful. But without a clean way to tell FREE_DBT if it
445 * should free key->data or not we have to. Other places in
446 * the code check for DB_THREAD and forceably set DBT_MALLOC
447 * when we otherwise would leave flags 0 to indicate that.
449 key
->data
= malloc(PyBytes_GET_SIZE(keyobj
));
450 if (key
->data
== NULL
) {
451 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
454 memcpy(key
->data
, PyBytes_AS_STRING(keyobj
),
455 PyBytes_GET_SIZE(keyobj
));
456 key
->flags
= DB_DBT_REALLOC
;
457 key
->size
= PyBytes_GET_SIZE(keyobj
);
460 else if (NUMBER_Check(keyobj
)) {
461 /* verify access method type */
462 type
= _DB_get_type(self
);
465 if (type
== DB_BTREE
&& pflags
!= NULL
) {
466 /* if BTREE then an Integer key is allowed with the
467 * DB_SET_RECNO flag */
468 *pflags
|= DB_SET_RECNO
;
470 else if (type
!= DB_RECNO
&& type
!= DB_QUEUE
) {
473 "Integer keys only allowed for Recno and Queue DB's");
477 /* Make a key out of the requested recno, use allocated space so DB
478 * will be able to realloc room for the real key if needed. */
479 recno
= NUMBER_AsLong(keyobj
);
480 key
->data
= malloc(sizeof(db_recno_t
));
481 if (key
->data
== NULL
) {
482 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
485 key
->ulen
= key
->size
= sizeof(db_recno_t
);
486 memcpy(key
->data
, &recno
, sizeof(db_recno_t
));
487 key
->flags
= DB_DBT_REALLOC
;
490 PyErr_Format(PyExc_TypeError
,
491 "String or Integer object expected for key, %s found",
492 Py_TYPE(keyobj
)->tp_name
);
500 /* Add partial record access to an existing DBT data struct.
501 If dlen and doff are set, then the DB_DBT_PARTIAL flag will be set
502 and the data storage/retrieval will be done using dlen and doff. */
503 static int add_partial_dbt(DBT
* d
, int dlen
, int doff
) {
504 /* if neither were set we do nothing (-1 is the default value) */
505 if ((dlen
== -1) && (doff
== -1)) {
509 if ((dlen
< 0) || (doff
< 0)) {
510 PyErr_SetString(PyExc_TypeError
, "dlen and doff must both be >= 0");
514 d
->flags
= d
->flags
| DB_DBT_PARTIAL
;
515 d
->dlen
= (unsigned int) dlen
;
516 d
->doff
= (unsigned int) doff
;
520 /* a safe strcpy() without the zeroing behaviour and semantics of strncpy. */
521 /* TODO: make this use the native libc strlcpy() when available (BSD) */
522 unsigned int our_strlcpy(char* dest
, const char* src
, unsigned int n
)
524 unsigned int srclen
, copylen
;
526 srclen
= strlen(src
);
529 copylen
= (srclen
> n
-1) ? n
-1 : srclen
;
530 /* populate dest[0] thru dest[copylen-1] */
531 memcpy(dest
, src
, copylen
);
532 /* guarantee null termination */
538 /* Callback used to save away more information about errors from the DB
540 static char _db_errmsg
[1024];
542 static void _db_errorCallback(const char* prefix
, char* msg
)
544 static void _db_errorCallback(const DB_ENV
*db_env
,
545 const char* prefix
, const char* msg
)
548 our_strlcpy(_db_errmsg
, msg
, sizeof(_db_errmsg
));
553 ** We need these functions because some results
554 ** are undefined if pointer is NULL. Some other
555 ** give None instead of "".
557 ** This functions are static and will be
560 static const char *DummyString
= "This string is a simple placeholder";
561 static PyObject
*Build_PyString(const char *p
,int s
)
567 return PyBytes_FromStringAndSize(p
,s
);
570 static PyObject
*BuildValue_S(const void *p
,int s
)
576 return Py_BuildValue("s#",p
,s
);
579 static PyObject
*BuildValue_SS(const void *p1
,int s1
,const void *p2
,int s2
)
589 return Py_BuildValue("s#s#",p1
,s1
,p2
,s2
);
592 static PyObject
*BuildValue_IS(int i
,const void *p
,int s
)
598 return Py_BuildValue("is#",i
,p
,s
);
601 static PyObject
*BuildValue_LS(long i
,const void *p
,int s
)
607 return Py_BuildValue("ls#",i
,p
,s
);
612 /* make a nice exception object to raise for errors. */
613 static int makeDBError(int err
)
615 char errTxt
[2048]; /* really big, just in case... */
616 PyObject
*errObj
= NULL
;
617 PyObject
*errTuple
= NULL
;
618 int exceptionRaised
= 0;
619 unsigned int bytes_left
;
622 case 0: /* successful, no error */ break;
626 #if INCOMPLETE_IS_WARNING
627 bytes_left
= our_strlcpy(errTxt
, db_strerror(err
), sizeof(errTxt
));
628 /* Ensure that bytes_left never goes negative */
629 if (_db_errmsg
[0] && bytes_left
< (sizeof(errTxt
) - 4)) {
630 bytes_left
= sizeof(errTxt
) - bytes_left
- 4 - 1;
631 assert(bytes_left
>= 0);
632 strcat(errTxt
, " -- ");
633 strncat(errTxt
, _db_errmsg
, bytes_left
);
636 exceptionRaised
= PyErr_Warn(PyExc_RuntimeWarning
, errTxt
);
638 #else /* do an exception instead */
639 errObj
= DBIncompleteError
;
642 #endif /* DBVER < 41 */
644 case DB_KEYEMPTY
: errObj
= DBKeyEmptyError
; break;
645 case DB_KEYEXIST
: errObj
= DBKeyExistError
; break;
646 case DB_LOCK_DEADLOCK
: errObj
= DBLockDeadlockError
; break;
647 case DB_LOCK_NOTGRANTED
: errObj
= DBLockNotGrantedError
; break;
648 case DB_NOTFOUND
: errObj
= DBNotFoundError
; break;
649 case DB_OLD_VERSION
: errObj
= DBOldVersionError
; break;
650 case DB_RUNRECOVERY
: errObj
= DBRunRecoveryError
; break;
651 case DB_VERIFY_BAD
: errObj
= DBVerifyBadError
; break;
652 case DB_NOSERVER
: errObj
= DBNoServerError
; break;
653 case DB_NOSERVER_HOME
: errObj
= DBNoServerHomeError
; break;
654 case DB_NOSERVER_ID
: errObj
= DBNoServerIDError
; break;
655 case DB_PAGE_NOTFOUND
: errObj
= DBPageNotFoundError
; break;
656 case DB_SECONDARY_BAD
: errObj
= DBSecondaryBadError
; break;
657 case DB_BUFFER_SMALL
: errObj
= DBNoMemoryError
; break;
660 /* ENOMEM and DB_BUFFER_SMALL were one and the same until 4.3 */
661 case ENOMEM
: errObj
= PyExc_MemoryError
; break;
663 case EINVAL
: errObj
= DBInvalidArgError
; break;
664 case EACCES
: errObj
= DBAccessError
; break;
665 case ENOSPC
: errObj
= DBNoSpaceError
; break;
666 case EAGAIN
: errObj
= DBAgainError
; break;
667 case EBUSY
: errObj
= DBBusyError
; break;
668 case EEXIST
: errObj
= DBFileExistsError
; break;
669 case ENOENT
: errObj
= DBNoSuchFileError
; break;
670 case EPERM
: errObj
= DBPermissionsError
; break;
673 case DB_REP_HANDLE_DEAD
: errObj
= DBRepHandleDeadError
; break;
676 case DB_REP_UNAVAIL
: errObj
= DBRepUnavailError
; break;
678 default: errObj
= DBError
; break;
681 if (errObj
!= NULL
) {
682 bytes_left
= our_strlcpy(errTxt
, db_strerror(err
), sizeof(errTxt
));
683 /* Ensure that bytes_left never goes negative */
684 if (_db_errmsg
[0] && bytes_left
< (sizeof(errTxt
) - 4)) {
685 bytes_left
= sizeof(errTxt
) - bytes_left
- 4 - 1;
686 assert(bytes_left
>= 0);
687 strcat(errTxt
, " -- ");
688 strncat(errTxt
, _db_errmsg
, bytes_left
);
692 errTuple
= Py_BuildValue("(is)", err
, errTxt
);
693 if (errTuple
== NULL
) {
697 PyErr_SetObject(errObj
, errTuple
);
701 return ((errObj
!= NULL
) || exceptionRaised
);
706 /* set a type exception */
707 static void makeTypeError(char* expected
, PyObject
* found
)
709 PyErr_Format(PyExc_TypeError
, "Expected %s argument, %s found.",
710 expected
, Py_TYPE(found
)->tp_name
);
714 /* verify that an obj is either None or a DBTxn, and set the txn pointer */
715 static int checkTxnObj(PyObject
* txnobj
, DB_TXN
** txn
)
717 if (txnobj
== Py_None
|| txnobj
== NULL
) {
721 if (DBTxnObject_Check(txnobj
)) {
722 *txn
= ((DBTxnObject
*)txnobj
)->txn
;
726 makeTypeError("DBTxn", txnobj
);
731 /* Delete a key from a database
732 Returns 0 on success, -1 on an error. */
733 static int _DB_delete(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, int flags
)
737 MYDB_BEGIN_ALLOW_THREADS
;
738 err
= self
->db
->del(self
->db
, txn
, key
, 0);
739 MYDB_END_ALLOW_THREADS
;
740 if (makeDBError(err
)) {
748 /* Store a key into a database
749 Returns 0 on success, -1 on an error. */
750 static int _DB_put(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, DBT
*data
, int flags
)
754 MYDB_BEGIN_ALLOW_THREADS
;
755 err
= self
->db
->put(self
->db
, txn
, key
, data
, flags
);
756 MYDB_END_ALLOW_THREADS
;
757 if (makeDBError(err
)) {
764 /* Get a key/data pair from a cursor */
765 static PyObject
* _DBCursor_get(DBCursorObject
* self
, int extra_flags
,
766 PyObject
*args
, PyObject
*kwargs
, char *format
)
769 PyObject
* retval
= NULL
;
774 static char* kwnames
[] = { "flags", "dlen", "doff", NULL
};
776 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, format
, kwnames
,
777 &flags
, &dlen
, &doff
))
780 CHECK_CURSOR_NOT_CLOSED(self
);
782 flags
|= extra_flags
;
785 if (!add_partial_dbt(&data
, dlen
, doff
))
788 MYDB_BEGIN_ALLOW_THREADS
;
789 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
);
790 MYDB_END_ALLOW_THREADS
;
792 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
793 && self
->mydb
->moduleFlags
.getReturnsNone
) {
797 else if (makeDBError(err
)) {
800 else { /* otherwise, success! */
802 /* if Recno or Queue, return the key as an Int */
803 switch (_DB_get_type(self
->mydb
)) {
810 retval
= BuildValue_IS(*((db_recno_t
*)key
.data
), data
.data
, data
.size
);
815 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
823 /* add an integer to a dictionary using the given name as a key */
824 static void _addIntToDict(PyObject
* dict
, char *name
, int value
)
826 PyObject
* v
= NUMBER_FromLong((long) value
);
827 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
833 /* The same, when the value is a time_t */
834 static void _addTimeTToDict(PyObject
* dict
, char *name
, time_t value
)
837 /* if the value fits in regular int, use that. */
839 if (sizeof(time_t) > sizeof(long))
840 v
= PyLong_FromLongLong((PY_LONG_LONG
) value
);
843 v
= NUMBER_FromLong((long) value
);
844 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
851 /* add an db_seq_t to a dictionary using the given name as a key */
852 static void _addDb_seq_tToDict(PyObject
* dict
, char *name
, db_seq_t value
)
854 PyObject
* v
= PyLong_FromLongLong(value
);
855 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
862 static void _addDB_lsnToDict(PyObject
* dict
, char *name
, DB_LSN value
)
864 PyObject
*v
= Py_BuildValue("(ll)",value
.file
,value
.offset
);
865 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
871 /* --------------------------------------------------------------------- */
872 /* Allocators and deallocators */
875 newDBObject(DBEnvObject
* arg
, int flags
)
878 DB_ENV
* db_env
= NULL
;
881 self
= PyObject_New(DBObject
, &DB_Type
);
888 self
->myenvobj
= NULL
;
890 self
->children_cursors
= NULL
;
892 self
->children_sequences
= NULL
;
894 self
->associateCallback
= NULL
;
895 self
->btCompareCallback
= NULL
;
896 self
->primaryDBType
= 0;
898 self
->private = Py_None
;
899 self
->in_weakreflist
= NULL
;
901 /* keep a reference to our python DBEnv object */
904 self
->myenvobj
= arg
;
905 db_env
= arg
->db_env
;
906 INSERT_IN_DOUBLE_LINKED_LIST(self
->myenvobj
->children_dbs
,self
);
908 self
->sibling_prev_p
=NULL
;
909 self
->sibling_next
=NULL
;
912 self
->sibling_prev_p_txn
=NULL
;
913 self
->sibling_next_txn
=NULL
;
916 self
->moduleFlags
= self
->myenvobj
->moduleFlags
;
918 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
919 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
921 MYDB_BEGIN_ALLOW_THREADS
;
922 err
= db_create(&self
->db
, db_env
, flags
);
923 if (self
->db
!= NULL
) {
924 self
->db
->set_errcall(self
->db
, _db_errorCallback
);
925 self
->db
->app_private
= (void*)self
;
927 MYDB_END_ALLOW_THREADS
;
928 /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
929 * list so that a DBEnv can refuse to close without aborting any open
930 * DBTxns and closing any open DBs first. */
931 if (makeDBError(err
)) {
932 if (self
->myenvobj
) {
933 Py_DECREF(self
->myenvobj
);
934 self
->myenvobj
= NULL
;
943 /* Forward declaration */
944 static PyObject
*DB_close_internal(DBObject
* self
, int flags
);
947 DB_dealloc(DBObject
* self
)
951 if (self
->db
!= NULL
) {
952 dummy
=DB_close_internal(self
,0);
955 if (self
->in_weakreflist
!= NULL
) {
956 PyObject_ClearWeakRefs((PyObject
*) self
);
958 if (self
->myenvobj
) {
959 Py_DECREF(self
->myenvobj
);
960 self
->myenvobj
= NULL
;
962 if (self
->associateCallback
!= NULL
) {
963 Py_DECREF(self
->associateCallback
);
964 self
->associateCallback
= NULL
;
966 if (self
->btCompareCallback
!= NULL
) {
967 Py_DECREF(self
->btCompareCallback
);
968 self
->btCompareCallback
= NULL
;
970 Py_DECREF(self
->private);
974 static DBCursorObject
*
975 newDBCursorObject(DBC
* dbc
, DBTxnObject
*txn
, DBObject
* db
)
977 DBCursorObject
* self
= PyObject_New(DBCursorObject
, &DBCursor_Type
);
984 INSERT_IN_DOUBLE_LINKED_LIST(self
->mydb
->children_cursors
,self
);
985 if (txn
&& ((PyObject
*)txn
!=Py_None
)) {
986 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn
->children_cursors
,self
);
992 self
->in_weakreflist
= NULL
;
993 Py_INCREF(self
->mydb
);
998 /* Forward declaration */
999 static PyObject
*DBC_close_internal(DBCursorObject
* self
);
1002 DBCursor_dealloc(DBCursorObject
* self
)
1006 if (self
->dbc
!= NULL
) {
1007 dummy
=DBC_close_internal(self
);
1010 if (self
->in_weakreflist
!= NULL
) {
1011 PyObject_ClearWeakRefs((PyObject
*) self
);
1013 Py_DECREF(self
->mydb
);
1019 newDBEnvObject(int flags
)
1022 DBEnvObject
* self
= PyObject_New(DBEnvObject
, &DBEnv_Type
);
1027 self
->flags
= flags
;
1028 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
1029 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
1030 self
->children_dbs
= NULL
;
1031 self
->children_txns
= NULL
;
1033 self
->private = Py_None
;
1035 self
->rep_transport
= Py_None
;
1036 self
->in_weakreflist
= NULL
;
1037 self
->event_notifyCallback
= NULL
;
1039 MYDB_BEGIN_ALLOW_THREADS
;
1040 err
= db_env_create(&self
->db_env
, flags
);
1041 MYDB_END_ALLOW_THREADS
;
1042 if (makeDBError(err
)) {
1047 self
->db_env
->set_errcall(self
->db_env
, _db_errorCallback
);
1048 self
->db_env
->app_private
=self
;
1053 /* Forward declaration */
1054 static PyObject
*DBEnv_close_internal(DBEnvObject
* self
, int flags
);
1057 DBEnv_dealloc(DBEnvObject
* self
)
1061 if (self
->db_env
&& !self
->closed
) {
1062 dummy
=DBEnv_close_internal(self
,0);
1066 Py_XDECREF(self
->event_notifyCallback
);
1067 self
->event_notifyCallback
= NULL
;
1069 if (self
->in_weakreflist
!= NULL
) {
1070 PyObject_ClearWeakRefs((PyObject
*) self
);
1072 Py_DECREF(self
->private);
1073 Py_DECREF(self
->rep_transport
);
1079 newDBTxnObject(DBEnvObject
* myenv
, DBTxnObject
*parent
, DB_TXN
*txn
, int flags
)
1082 DB_TXN
*parent_txn
= NULL
;
1084 DBTxnObject
* self
= PyObject_New(DBTxnObject
, &DBTxn_Type
);
1088 self
->in_weakreflist
= NULL
;
1089 self
->children_txns
= NULL
;
1090 self
->children_dbs
= NULL
;
1091 self
->children_cursors
= NULL
;
1092 self
->children_sequences
= NULL
;
1093 self
->flag_prepare
= 0;
1094 self
->parent_txn
= NULL
;
1097 if (parent
&& ((PyObject
*)parent
!=Py_None
)) {
1098 parent_txn
= parent
->txn
;
1104 MYDB_BEGIN_ALLOW_THREADS
;
1105 err
= myenv
->db_env
->txn_begin(myenv
->db_env
, parent_txn
, &(self
->txn
), flags
);
1106 MYDB_END_ALLOW_THREADS
;
1108 if (makeDBError(err
)) {
1114 /* Can't use 'parent' because could be 'parent==Py_None' */
1116 self
->parent_txn
= parent
;
1119 INSERT_IN_DOUBLE_LINKED_LIST(parent
->children_txns
, self
);
1121 self
->parent_txn
= NULL
;
1124 INSERT_IN_DOUBLE_LINKED_LIST(myenv
->children_txns
, self
);
1130 /* Forward declaration */
1132 DBTxn_abort_discard_internal(DBTxnObject
* self
, int discard
);
1135 DBTxn_dealloc(DBTxnObject
* self
)
1140 int flag_prepare
= self
->flag_prepare
;
1141 dummy
=DBTxn_abort_discard_internal(self
,0);
1143 if (!flag_prepare
) {
1144 PyErr_Warn(PyExc_RuntimeWarning
,
1145 "DBTxn aborted in destructor. No prior commit() or abort().");
1149 if (self
->in_weakreflist
!= NULL
) {
1150 PyObject_ClearWeakRefs((PyObject
*) self
);
1154 Py_DECREF(self
->env
);
1156 Py_DECREF(self
->parent_txn
);
1162 static DBLockObject
*
1163 newDBLockObject(DBEnvObject
* myenv
, u_int32_t locker
, DBT
* obj
,
1164 db_lockmode_t lock_mode
, int flags
)
1167 DBLockObject
* self
= PyObject_New(DBLockObject
, &DBLock_Type
);
1170 self
->in_weakreflist
= NULL
;
1172 MYDB_BEGIN_ALLOW_THREADS
;
1173 err
= myenv
->db_env
->lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
,
1175 MYDB_END_ALLOW_THREADS
;
1176 if (makeDBError(err
)) {
1186 DBLock_dealloc(DBLockObject
* self
)
1188 if (self
->in_weakreflist
!= NULL
) {
1189 PyObject_ClearWeakRefs((PyObject
*) self
);
1191 /* TODO: is this lock held? should we release it? */
1198 static DBSequenceObject
*
1199 newDBSequenceObject(DBObject
* mydb
, int flags
)
1202 DBSequenceObject
* self
= PyObject_New(DBSequenceObject
, &DBSequence_Type
);
1208 INSERT_IN_DOUBLE_LINKED_LIST(self
->mydb
->children_sequences
,self
);
1211 self
->in_weakreflist
= NULL
;
1213 MYDB_BEGIN_ALLOW_THREADS
;
1214 err
= db_sequence_create(&self
->sequence
, self
->mydb
->db
, flags
);
1215 MYDB_END_ALLOW_THREADS
;
1216 if (makeDBError(err
)) {
1224 /* Forward declaration */
1226 *DBSequence_close_internal(DBSequenceObject
* self
, int flags
, int do_not_close
);
1229 DBSequence_dealloc(DBSequenceObject
* self
)
1233 if (self
->sequence
!= NULL
) {
1234 dummy
=DBSequence_close_internal(self
,0,0);
1238 if (self
->in_weakreflist
!= NULL
) {
1239 PyObject_ClearWeakRefs((PyObject
*) self
);
1242 Py_DECREF(self
->mydb
);
1247 /* --------------------------------------------------------------------- */
1251 DB_append(DBObject
* self
, PyObject
* args
)
1253 PyObject
* txnobj
= NULL
;
1259 if (!PyArg_UnpackTuple(args
, "append", 1, 2, &dataobj
, &txnobj
))
1262 CHECK_DB_NOT_CLOSED(self
);
1264 /* make a dummy key out of a recno */
1268 key
.size
= sizeof(recno
);
1269 key
.ulen
= key
.size
;
1270 key
.flags
= DB_DBT_USERMEM
;
1272 if (!make_dbt(dataobj
, &data
)) return NULL
;
1273 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1275 if (-1 == _DB_put(self
, txn
, &key
, &data
, DB_APPEND
))
1278 return NUMBER_FromLong(recno
);
1283 _db_associateCallback(DB
* db
, const DBT
* priKey
, const DBT
* priData
,
1286 int retval
= DB_DONOTINDEX
;
1287 DBObject
* secondaryDB
= (DBObject
*)db
->app_private
;
1288 PyObject
* callback
= secondaryDB
->associateCallback
;
1289 int type
= secondaryDB
->primaryDBType
;
1291 PyObject
* result
= NULL
;
1294 if (callback
!= NULL
) {
1295 MYDB_BEGIN_BLOCK_THREADS
;
1297 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
1298 args
= BuildValue_LS(*((db_recno_t
*)priKey
->data
), priData
->data
, priData
->size
);
1300 args
= BuildValue_SS(priKey
->data
, priKey
->size
, priData
->data
, priData
->size
);
1302 result
= PyEval_CallObject(callback
, args
);
1304 if (args
== NULL
|| result
== NULL
) {
1307 else if (result
== Py_None
) {
1308 retval
= DB_DONOTINDEX
;
1310 else if (NUMBER_Check(result
)) {
1311 retval
= NUMBER_AsLong(result
);
1313 else if (PyBytes_Check(result
)) {
1318 PyBytes_AsStringAndSize(result
, &data
, &size
);
1319 secKey
->flags
= DB_DBT_APPMALLOC
; /* DB will free */
1320 secKey
->data
= malloc(size
); /* TODO, check this */
1322 memcpy(secKey
->data
, data
, size
);
1323 secKey
->size
= size
;
1327 PyErr_SetString(PyExc_MemoryError
,
1328 "malloc failed in _db_associateCallback");
1335 "DB associate callback should return DB_DONOTINDEX or string.");
1342 MYDB_END_BLOCK_THREADS
;
1349 DB_associate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1352 DBObject
* secondaryDB
;
1355 PyObject
*txnobj
= NULL
;
1357 static char* kwnames
[] = {"secondaryDB", "callback", "flags", "txn",
1360 static char* kwnames
[] = {"secondaryDB", "callback", "flags", NULL
};
1364 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iO:associate", kwnames
,
1365 &secondaryDB
, &callback
, &flags
,
1368 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|i:associate", kwnames
,
1369 &secondaryDB
, &callback
, &flags
)) {
1375 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1378 CHECK_DB_NOT_CLOSED(self
);
1379 if (!DBObject_Check(secondaryDB
)) {
1380 makeTypeError("DB", (PyObject
*)secondaryDB
);
1383 CHECK_DB_NOT_CLOSED(secondaryDB
);
1384 if (callback
== Py_None
) {
1387 else if (!PyCallable_Check(callback
)) {
1388 makeTypeError("Callable", callback
);
1392 /* Save a reference to the callback in the secondary DB. */
1393 Py_XDECREF(secondaryDB
->associateCallback
);
1394 Py_XINCREF(callback
);
1395 secondaryDB
->associateCallback
= callback
;
1396 secondaryDB
->primaryDBType
= _DB_get_type(self
);
1398 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1399 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1400 * The global interepreter lock is not initialized until the first
1401 * thread is created using thread.start_new_thread() or fork() is
1402 * called. that would cause the ALLOW_THREADS here to segfault due
1403 * to a null pointer reference if no threads or child processes
1404 * have been created. This works around that and is a no-op if
1405 * threads have already been initialized.
1406 * (see pybsddb-users mailing list post on 2002-08-07)
1409 PyEval_InitThreads();
1411 MYDB_BEGIN_ALLOW_THREADS
;
1413 err
= self
->db
->associate(self
->db
,
1416 _db_associateCallback
,
1419 err
= self
->db
->associate(self
->db
,
1421 _db_associateCallback
,
1424 MYDB_END_ALLOW_THREADS
;
1427 Py_XDECREF(secondaryDB
->associateCallback
);
1428 secondaryDB
->associateCallback
= NULL
;
1429 secondaryDB
->primaryDBType
= 0;
1438 DB_close_internal(DBObject
* self
, int flags
)
1443 if (self
->db
!= NULL
) {
1444 /* Can be NULL if db is not in an environment */
1445 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self
);
1447 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self
);
1451 while(self
->children_cursors
) {
1452 dummy
=DBC_close_internal(self
->children_cursors
);
1457 while(self
->children_sequences
) {
1458 dummy
=DBSequence_close_internal(self
->children_sequences
,0,0);
1463 MYDB_BEGIN_ALLOW_THREADS
;
1464 err
= self
->db
->close(self
->db
, flags
);
1465 MYDB_END_ALLOW_THREADS
;
1473 DB_close(DBObject
* self
, PyObject
* args
)
1476 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
1478 return DB_close_internal(self
,flags
);
1483 _DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1485 int err
, flags
=0, type
;
1486 PyObject
* txnobj
= NULL
;
1487 PyObject
* retval
= NULL
;
1490 static char* kwnames
[] = { "txn", "flags", NULL
};
1492 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:consume", kwnames
,
1496 CHECK_DB_NOT_CLOSED(self
);
1497 type
= _DB_get_type(self
);
1500 if (type
!= DB_QUEUE
) {
1501 PyErr_SetString(PyExc_TypeError
,
1502 "Consume methods only allowed for Queue DB's");
1505 if (!checkTxnObj(txnobj
, &txn
))
1510 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1511 /* Tell Berkeley DB to malloc the return value (thread safe) */
1512 data
.flags
= DB_DBT_MALLOC
;
1513 key
.flags
= DB_DBT_MALLOC
;
1516 MYDB_BEGIN_ALLOW_THREADS
;
1517 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
|consume_flag
);
1518 MYDB_END_ALLOW_THREADS
;
1520 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1521 && self
->moduleFlags
.getReturnsNone
) {
1527 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
1537 DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1539 return _DB_consume(self
, args
, kwargs
, DB_CONSUME
);
1543 DB_consume_wait(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
,
1546 return _DB_consume(self
, args
, kwargs
, DB_CONSUME_WAIT
);
1551 DB_cursor(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1555 PyObject
* txnobj
= NULL
;
1557 static char* kwnames
[] = { "txn", "flags", NULL
};
1559 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
1562 CHECK_DB_NOT_CLOSED(self
);
1563 if (!checkTxnObj(txnobj
, &txn
))
1566 MYDB_BEGIN_ALLOW_THREADS
;
1567 err
= self
->db
->cursor(self
->db
, txn
, &dbc
, flags
);
1568 MYDB_END_ALLOW_THREADS
;
1570 return (PyObject
*) newDBCursorObject(dbc
, (DBTxnObject
*)txnobj
, self
);
1575 DB_delete(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1577 PyObject
* txnobj
= NULL
;
1582 static char* kwnames
[] = { "key", "txn", "flags", NULL
};
1584 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:delete", kwnames
,
1585 &keyobj
, &txnobj
, &flags
))
1587 CHECK_DB_NOT_CLOSED(self
);
1588 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1590 if (!checkTxnObj(txnobj
, &txn
)) {
1595 if (-1 == _DB_delete(self
, txn
, &key
, 0)) {
1606 DB_fd(DBObject
* self
)
1610 CHECK_DB_NOT_CLOSED(self
);
1612 MYDB_BEGIN_ALLOW_THREADS
;
1613 err
= self
->db
->fd(self
->db
, &the_fd
);
1614 MYDB_END_ALLOW_THREADS
;
1616 return NUMBER_FromLong(the_fd
);
1621 DB_get(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1624 PyObject
* txnobj
= NULL
;
1626 PyObject
* dfltobj
= NULL
;
1627 PyObject
* retval
= NULL
;
1632 static char* kwnames
[] = {"key", "default", "txn", "flags", "dlen",
1635 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:get", kwnames
,
1636 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1640 CHECK_DB_NOT_CLOSED(self
);
1641 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1643 if (!checkTxnObj(txnobj
, &txn
)) {
1649 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1650 /* Tell Berkeley DB to malloc the return value (thread safe) */
1651 data
.flags
= DB_DBT_MALLOC
;
1653 if (!add_partial_dbt(&data
, dlen
, doff
)) {
1658 MYDB_BEGIN_ALLOW_THREADS
;
1659 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1660 MYDB_END_ALLOW_THREADS
;
1662 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && (dfltobj
!= NULL
)) {
1667 else if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1668 && self
->moduleFlags
.getReturnsNone
) {
1674 if (flags
& DB_SET_RECNO
) /* return both key and data */
1675 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
1676 else /* return just the data */
1677 retval
= Build_PyString(data
.data
, data
.size
);
1687 DB_pget(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1690 PyObject
* txnobj
= NULL
;
1692 PyObject
* dfltobj
= NULL
;
1693 PyObject
* retval
= NULL
;
1696 DBT key
, pkey
, data
;
1698 static char* kwnames
[] = {"key", "default", "txn", "flags", "dlen",
1701 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:pget", kwnames
,
1702 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1706 CHECK_DB_NOT_CLOSED(self
);
1707 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1709 if (!checkTxnObj(txnobj
, &txn
)) {
1715 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1716 /* Tell Berkeley DB to malloc the return value (thread safe) */
1717 data
.flags
= DB_DBT_MALLOC
;
1719 if (!add_partial_dbt(&data
, dlen
, doff
)) {
1725 pkey
.flags
= DB_DBT_MALLOC
;
1727 MYDB_BEGIN_ALLOW_THREADS
;
1728 err
= self
->db
->pget(self
->db
, txn
, &key
, &pkey
, &data
, flags
);
1729 MYDB_END_ALLOW_THREADS
;
1731 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && (dfltobj
!= NULL
)) {
1736 else if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1737 && self
->moduleFlags
.getReturnsNone
) {
1745 dataObj
= Build_PyString(data
.data
, data
.size
);
1747 if (self
->primaryDBType
== DB_RECNO
||
1748 self
->primaryDBType
== DB_QUEUE
)
1749 pkeyObj
= NUMBER_FromLong(*(int *)pkey
.data
);
1751 pkeyObj
= Build_PyString(pkey
.data
, pkey
.size
);
1753 if (flags
& DB_SET_RECNO
) /* return key , pkey and data */
1756 int type
= _DB_get_type(self
);
1757 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
1758 keyObj
= NUMBER_FromLong(*(int *)key
.data
);
1760 keyObj
= Build_PyString(key
.data
, key
.size
);
1761 #if (PY_VERSION_HEX >= 0x02040000)
1762 retval
= PyTuple_Pack(3, keyObj
, pkeyObj
, dataObj
);
1764 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
1768 else /* return just the pkey and data */
1770 #if (PY_VERSION_HEX >= 0x02040000)
1771 retval
= PyTuple_Pack(2, pkeyObj
, dataObj
);
1773 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
1788 /* Return size of entry */
1790 DB_get_size(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1793 PyObject
* txnobj
= NULL
;
1795 PyObject
* retval
= NULL
;
1798 static char* kwnames
[] = { "key", "txn", NULL
};
1800 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O:get_size", kwnames
,
1803 CHECK_DB_NOT_CLOSED(self
);
1804 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1806 if (!checkTxnObj(txnobj
, &txn
)) {
1812 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
1813 thus getting the record size. */
1814 data
.flags
= DB_DBT_USERMEM
;
1816 MYDB_BEGIN_ALLOW_THREADS
;
1817 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1818 MYDB_END_ALLOW_THREADS
;
1819 if (err
== DB_BUFFER_SMALL
) {
1820 retval
= NUMBER_FromLong((long)data
.size
);
1832 DB_get_both(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1835 PyObject
* txnobj
= NULL
;
1838 PyObject
* retval
= NULL
;
1842 static char* kwnames
[] = { "key", "data", "txn", "flags", NULL
};
1844 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oi:get_both", kwnames
,
1845 &keyobj
, &dataobj
, &txnobj
, &flags
))
1848 CHECK_DB_NOT_CLOSED(self
);
1849 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1851 if ( !make_dbt(dataobj
, &data
) ||
1852 !checkTxnObj(txnobj
, &txn
) )
1858 flags
|= DB_GET_BOTH
;
1859 orig_data
= data
.data
;
1861 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1862 /* Tell Berkeley DB to malloc the return value (thread safe) */
1863 /* XXX(nnorwitz): At least 4.4.20 and 4.5.20 require this flag. */
1864 data
.flags
= DB_DBT_MALLOC
;
1867 MYDB_BEGIN_ALLOW_THREADS
;
1868 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1869 MYDB_END_ALLOW_THREADS
;
1871 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1872 && self
->moduleFlags
.getReturnsNone
) {
1878 /* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */
1879 retval
= Build_PyString(data
.data
, data
.size
);
1881 /* Even though the flags require DB_DBT_MALLOC, data is not always
1882 allocated. 4.4: allocated, 4.5: *not* allocated. :-( */
1883 if (data
.data
!= orig_data
)
1894 DB_get_byteswapped(DBObject
* self
)
1899 CHECK_DB_NOT_CLOSED(self
);
1901 MYDB_BEGIN_ALLOW_THREADS
;
1902 err
= self
->db
->get_byteswapped(self
->db
, &retval
);
1903 MYDB_END_ALLOW_THREADS
;
1905 return NUMBER_FromLong(retval
);
1910 DB_get_type(DBObject
* self
)
1914 CHECK_DB_NOT_CLOSED(self
);
1916 type
= _DB_get_type(self
);
1919 return NUMBER_FromLong(type
);
1924 DB_join(DBObject
* self
, PyObject
* args
)
1928 PyObject
* cursorsObj
;
1932 if (!PyArg_ParseTuple(args
,"O|i:join", &cursorsObj
, &flags
))
1935 CHECK_DB_NOT_CLOSED(self
);
1937 if (!PySequence_Check(cursorsObj
)) {
1938 PyErr_SetString(PyExc_TypeError
,
1939 "Sequence of DBCursor objects expected");
1943 length
= PyObject_Length(cursorsObj
);
1944 cursors
= malloc((length
+1) * sizeof(DBC
*));
1950 cursors
[length
] = NULL
;
1951 for (x
=0; x
<length
; x
++) {
1952 PyObject
* item
= PySequence_GetItem(cursorsObj
, x
);
1957 if (!DBCursorObject_Check(item
)) {
1958 PyErr_SetString(PyExc_TypeError
,
1959 "Sequence of DBCursor objects expected");
1963 cursors
[x
] = ((DBCursorObject
*)item
)->dbc
;
1967 MYDB_BEGIN_ALLOW_THREADS
;
1968 err
= self
->db
->join(self
->db
, cursors
, &dbc
, flags
);
1969 MYDB_END_ALLOW_THREADS
;
1973 /* FIXME: this is a buggy interface. The returned cursor
1974 contains internal references to the passed in cursors
1975 but does not hold python references to them or prevent
1976 them from being closed prematurely. This can cause
1977 python to crash when things are done in the wrong order. */
1978 return (PyObject
*) newDBCursorObject(dbc
, NULL
, self
);
1983 DB_key_range(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1986 PyObject
* txnobj
= NULL
;
1991 static char* kwnames
[] = { "key", "txn", "flags", NULL
};
1993 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:key_range", kwnames
,
1994 &keyobj
, &txnobj
, &flags
))
1996 CHECK_DB_NOT_CLOSED(self
);
1997 if (!make_dbt(keyobj
, &key
))
1998 /* BTree only, don't need to allow for an int key */
2000 if (!checkTxnObj(txnobj
, &txn
))
2003 MYDB_BEGIN_ALLOW_THREADS
;
2004 err
= self
->db
->key_range(self
->db
, txn
, &key
, &range
, flags
);
2005 MYDB_END_ALLOW_THREADS
;
2008 return Py_BuildValue("ddd", range
.less
, range
.equal
, range
.greater
);
2013 DB_open(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2015 int err
, type
= DB_UNKNOWN
, flags
=0, mode
=0660;
2016 char* filename
= NULL
;
2017 char* dbname
= NULL
;
2019 PyObject
*txnobj
= NULL
;
2022 static char* kwnames
[] = {
2023 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL
};
2024 /* without dbname */
2025 static char* kwnames_basic
[] = {
2026 "filename", "dbtype", "flags", "mode", "txn", NULL
};
2029 static char* kwnames
[] = {
2030 "filename", "dbname", "dbtype", "flags", "mode", NULL
};
2031 /* without dbname */
2032 static char* kwnames_basic
[] = {
2033 "filename", "dbtype", "flags", "mode", NULL
};
2037 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziiiO:open", kwnames
,
2038 &filename
, &dbname
, &type
, &flags
, &mode
,
2041 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziii:open", kwnames
,
2042 &filename
, &dbname
, &type
, &flags
,
2047 type
= DB_UNKNOWN
; flags
= 0; mode
= 0660;
2048 filename
= NULL
; dbname
= NULL
;
2050 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iiiO:open",
2052 &filename
, &type
, &flags
, &mode
,
2056 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iii:open",
2058 &filename
, &type
, &flags
, &mode
))
2064 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
2067 if (NULL
== self
->db
) {
2068 PyObject
*t
= Py_BuildValue("(is)", 0,
2069 "Cannot call open() twice for DB object");
2071 PyErr_SetObject(DBError
, t
);
2078 if (txn
) { /* Can't use 'txnobj' because could be 'txnobj==Py_None' */
2079 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject
*)txnobj
)->children_dbs
,self
);
2080 self
->txn
=(DBTxnObject
*)txnobj
;
2088 MYDB_BEGIN_ALLOW_THREADS
;
2090 err
= self
->db
->open(self
->db
, txn
, filename
, dbname
, type
, flags
, mode
);
2092 err
= self
->db
->open(self
->db
, filename
, dbname
, type
, flags
, mode
);
2094 MYDB_END_ALLOW_THREADS
;
2095 if (makeDBError(err
)) {
2098 dummy
=DB_close_internal(self
,0);
2104 self
->db
->get_flags(self
->db
, &self
->setflags
);
2107 self
->flags
= flags
;
2114 DB_put(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2117 PyObject
* txnobj
= NULL
;
2120 PyObject
* keyobj
, *dataobj
, *retval
;
2123 static char* kwnames
[] = { "key", "data", "txn", "flags", "dlen",
2126 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oiii:put", kwnames
,
2127 &keyobj
, &dataobj
, &txnobj
, &flags
, &dlen
, &doff
))
2130 CHECK_DB_NOT_CLOSED(self
);
2131 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2133 if ( !make_dbt(dataobj
, &data
) ||
2134 !add_partial_dbt(&data
, dlen
, doff
) ||
2135 !checkTxnObj(txnobj
, &txn
) )
2141 if (-1 == _DB_put(self
, txn
, &key
, &data
, flags
)) {
2146 if (flags
& DB_APPEND
)
2147 retval
= NUMBER_FromLong(*((db_recno_t
*)key
.data
));
2159 DB_remove(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2162 char* database
= NULL
;
2164 static char* kwnames
[] = { "filename", "dbname", "flags", NULL
};
2166 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zi:remove", kwnames
,
2167 &filename
, &database
, &flags
))
2169 CHECK_DB_NOT_CLOSED(self
);
2171 err
= self
->db
->remove(self
->db
, filename
, database
, flags
);
2180 DB_rename(DBObject
* self
, PyObject
* args
)
2187 if (!PyArg_ParseTuple(args
, "sss|i:rename", &filename
, &database
, &newname
,
2190 CHECK_DB_NOT_CLOSED(self
);
2192 MYDB_BEGIN_ALLOW_THREADS
;
2193 err
= self
->db
->rename(self
->db
, filename
, database
, newname
, flags
);
2194 MYDB_END_ALLOW_THREADS
;
2201 DB_get_private(DBObject
* self
)
2203 /* We can give out the private field even if db is closed */
2204 Py_INCREF(self
->private);
2205 return self
->private;
2209 DB_set_private(DBObject
* self
, PyObject
* private)
2211 /* We can set the private field even if db is closed */
2212 Py_DECREF(self
->private);
2214 self
->private = private;
2220 DB_set_bt_minkey(DBObject
* self
, PyObject
* args
)
2224 if (!PyArg_ParseTuple(args
,"i:set_bt_minkey", &minkey
))
2226 CHECK_DB_NOT_CLOSED(self
);
2228 MYDB_BEGIN_ALLOW_THREADS
;
2229 err
= self
->db
->set_bt_minkey(self
->db
, minkey
);
2230 MYDB_END_ALLOW_THREADS
;
2236 _default_cmp(const DBT
*leftKey
,
2237 const DBT
*rightKey
)
2240 int lsize
= leftKey
->size
, rsize
= rightKey
->size
;
2242 res
= memcmp(leftKey
->data
, rightKey
->data
,
2243 lsize
< rsize
? lsize
: rsize
);
2246 if (lsize
< rsize
) {
2249 else if (lsize
> rsize
) {
2257 _db_compareCallback(DB
* db
,
2259 const DBT
*rightKey
)
2263 PyObject
*result
= NULL
;
2264 DBObject
*self
= (DBObject
*)db
->app_private
;
2266 if (self
== NULL
|| self
->btCompareCallback
== NULL
) {
2267 MYDB_BEGIN_BLOCK_THREADS
;
2268 PyErr_SetString(PyExc_TypeError
,
2270 ? "DB_bt_compare db is NULL."
2271 : "DB_bt_compare callback is NULL."));
2272 /* we're in a callback within the DB code, we can't raise */
2274 res
= _default_cmp(leftKey
, rightKey
);
2275 MYDB_END_BLOCK_THREADS
;
2277 MYDB_BEGIN_BLOCK_THREADS
;
2279 args
= BuildValue_SS(leftKey
->data
, leftKey
->size
, rightKey
->data
, rightKey
->size
);
2281 /* XXX(twouters) I highly doubt this INCREF is correct */
2283 result
= PyEval_CallObject(self
->btCompareCallback
, args
);
2285 if (args
== NULL
|| result
== NULL
) {
2286 /* we're in a callback within the DB code, we can't raise */
2288 res
= _default_cmp(leftKey
, rightKey
);
2289 } else if (NUMBER_Check(result
)) {
2290 res
= NUMBER_AsLong(result
);
2292 PyErr_SetString(PyExc_TypeError
,
2293 "DB_bt_compare callback MUST return an int.");
2294 /* we're in a callback within the DB code, we can't raise */
2296 res
= _default_cmp(leftKey
, rightKey
);
2302 MYDB_END_BLOCK_THREADS
;
2308 DB_set_bt_compare(DBObject
* self
, PyObject
* comparator
)
2311 PyObject
*tuple
, *result
;
2313 CHECK_DB_NOT_CLOSED(self
);
2315 if (!PyCallable_Check(comparator
)) {
2316 makeTypeError("Callable", comparator
);
2321 * Perform a test call of the comparator function with two empty
2322 * string objects here. verify that it returns an int (0).
2325 tuple
= Py_BuildValue("(ss)", "", "");
2326 result
= PyEval_CallObject(comparator
, tuple
);
2330 if (!NUMBER_Check(result
)) {
2331 PyErr_SetString(PyExc_TypeError
,
2332 "callback MUST return an int");
2334 } else if (NUMBER_AsLong(result
) != 0) {
2335 PyErr_SetString(PyExc_TypeError
,
2336 "callback failed to return 0 on two empty strings");
2341 /* We don't accept multiple set_bt_compare operations, in order to
2342 * simplify the code. This would have no real use, as one cannot
2343 * change the function once the db is opened anyway */
2344 if (self
->btCompareCallback
!= NULL
) {
2345 PyErr_SetString(PyExc_RuntimeError
, "set_bt_compare() cannot be called more than once");
2349 Py_INCREF(comparator
);
2350 self
->btCompareCallback
= comparator
;
2352 /* This is to workaround a problem with un-initialized threads (see
2353 comment in DB_associate) */
2355 PyEval_InitThreads();
2358 err
= self
->db
->set_bt_compare(self
->db
, _db_compareCallback
);
2361 /* restore the old state in case of error */
2362 Py_DECREF(comparator
);
2363 self
->btCompareCallback
= NULL
;
2372 DB_set_cachesize(DBObject
* self
, PyObject
* args
)
2375 int gbytes
= 0, bytes
= 0, ncache
= 0;
2377 if (!PyArg_ParseTuple(args
,"ii|i:set_cachesize",
2378 &gbytes
,&bytes
,&ncache
))
2380 CHECK_DB_NOT_CLOSED(self
);
2382 MYDB_BEGIN_ALLOW_THREADS
;
2383 err
= self
->db
->set_cachesize(self
->db
, gbytes
, bytes
, ncache
);
2384 MYDB_END_ALLOW_THREADS
;
2391 DB_set_flags(DBObject
* self
, PyObject
* args
)
2395 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
2397 CHECK_DB_NOT_CLOSED(self
);
2399 MYDB_BEGIN_ALLOW_THREADS
;
2400 err
= self
->db
->set_flags(self
->db
, flags
);
2401 MYDB_END_ALLOW_THREADS
;
2404 self
->setflags
|= flags
;
2410 DB_set_h_ffactor(DBObject
* self
, PyObject
* args
)
2414 if (!PyArg_ParseTuple(args
,"i:set_h_ffactor", &ffactor
))
2416 CHECK_DB_NOT_CLOSED(self
);
2418 MYDB_BEGIN_ALLOW_THREADS
;
2419 err
= self
->db
->set_h_ffactor(self
->db
, ffactor
);
2420 MYDB_END_ALLOW_THREADS
;
2427 DB_set_h_nelem(DBObject
* self
, PyObject
* args
)
2431 if (!PyArg_ParseTuple(args
,"i:set_h_nelem", &nelem
))
2433 CHECK_DB_NOT_CLOSED(self
);
2435 MYDB_BEGIN_ALLOW_THREADS
;
2436 err
= self
->db
->set_h_nelem(self
->db
, nelem
);
2437 MYDB_END_ALLOW_THREADS
;
2444 DB_set_lorder(DBObject
* self
, PyObject
* args
)
2448 if (!PyArg_ParseTuple(args
,"i:set_lorder", &lorder
))
2450 CHECK_DB_NOT_CLOSED(self
);
2452 MYDB_BEGIN_ALLOW_THREADS
;
2453 err
= self
->db
->set_lorder(self
->db
, lorder
);
2454 MYDB_END_ALLOW_THREADS
;
2461 DB_set_pagesize(DBObject
* self
, PyObject
* args
)
2465 if (!PyArg_ParseTuple(args
,"i:set_pagesize", &pagesize
))
2467 CHECK_DB_NOT_CLOSED(self
);
2469 MYDB_BEGIN_ALLOW_THREADS
;
2470 err
= self
->db
->set_pagesize(self
->db
, pagesize
);
2471 MYDB_END_ALLOW_THREADS
;
2478 DB_set_re_delim(DBObject
* self
, PyObject
* args
)
2483 if (!PyArg_ParseTuple(args
,"b:set_re_delim", &delim
)) {
2485 if (!PyArg_ParseTuple(args
,"c:set_re_delim", &delim
))
2489 CHECK_DB_NOT_CLOSED(self
);
2491 MYDB_BEGIN_ALLOW_THREADS
;
2492 err
= self
->db
->set_re_delim(self
->db
, delim
);
2493 MYDB_END_ALLOW_THREADS
;
2499 DB_set_re_len(DBObject
* self
, PyObject
* args
)
2503 if (!PyArg_ParseTuple(args
,"i:set_re_len", &len
))
2505 CHECK_DB_NOT_CLOSED(self
);
2507 MYDB_BEGIN_ALLOW_THREADS
;
2508 err
= self
->db
->set_re_len(self
->db
, len
);
2509 MYDB_END_ALLOW_THREADS
;
2516 DB_set_re_pad(DBObject
* self
, PyObject
* args
)
2521 if (!PyArg_ParseTuple(args
,"b:set_re_pad", &pad
)) {
2523 if (!PyArg_ParseTuple(args
,"c:set_re_pad", &pad
))
2526 CHECK_DB_NOT_CLOSED(self
);
2528 MYDB_BEGIN_ALLOW_THREADS
;
2529 err
= self
->db
->set_re_pad(self
->db
, pad
);
2530 MYDB_END_ALLOW_THREADS
;
2537 DB_set_re_source(DBObject
* self
, PyObject
* args
)
2542 if (!PyArg_ParseTuple(args
,"s:set_re_source", &re_source
))
2544 CHECK_DB_NOT_CLOSED(self
);
2546 MYDB_BEGIN_ALLOW_THREADS
;
2547 err
= self
->db
->set_re_source(self
->db
, re_source
);
2548 MYDB_END_ALLOW_THREADS
;
2555 DB_set_q_extentsize(DBObject
* self
, PyObject
* args
)
2560 if (!PyArg_ParseTuple(args
,"i:set_q_extentsize", &extentsize
))
2562 CHECK_DB_NOT_CLOSED(self
);
2564 MYDB_BEGIN_ALLOW_THREADS
;
2565 err
= self
->db
->set_q_extentsize(self
->db
, extentsize
);
2566 MYDB_END_ALLOW_THREADS
;
2572 DB_stat(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2574 int err
, flags
= 0, type
;
2578 PyObject
* txnobj
= NULL
;
2580 static char* kwnames
[] = { "flags", "txn", NULL
};
2582 static char* kwnames
[] = { "flags", NULL
};
2586 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iO:stat", kwnames
,
2589 if (!checkTxnObj(txnobj
, &txn
))
2592 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat", kwnames
, &flags
))
2595 CHECK_DB_NOT_CLOSED(self
);
2597 MYDB_BEGIN_ALLOW_THREADS
;
2599 err
= self
->db
->stat(self
->db
, txn
, &sp
, flags
);
2601 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2603 MYDB_END_ALLOW_THREADS
;
2608 /* Turn the stat structure into a dictionary */
2609 type
= _DB_get_type(self
);
2610 if ((type
== -1) || ((d
= PyDict_New()) == NULL
)) {
2615 #define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
2616 #define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
2617 #define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
2621 MAKE_HASH_ENTRY(magic
);
2622 MAKE_HASH_ENTRY(version
);
2623 MAKE_HASH_ENTRY(nkeys
);
2624 MAKE_HASH_ENTRY(ndata
);
2626 MAKE_HASH_ENTRY(pagecnt
);
2628 MAKE_HASH_ENTRY(pagesize
);
2630 MAKE_HASH_ENTRY(nelem
);
2632 MAKE_HASH_ENTRY(ffactor
);
2633 MAKE_HASH_ENTRY(buckets
);
2634 MAKE_HASH_ENTRY(free
);
2635 MAKE_HASH_ENTRY(bfree
);
2636 MAKE_HASH_ENTRY(bigpages
);
2637 MAKE_HASH_ENTRY(big_bfree
);
2638 MAKE_HASH_ENTRY(overflows
);
2639 MAKE_HASH_ENTRY(ovfl_free
);
2640 MAKE_HASH_ENTRY(dup
);
2641 MAKE_HASH_ENTRY(dup_free
);
2646 MAKE_BT_ENTRY(magic
);
2647 MAKE_BT_ENTRY(version
);
2648 MAKE_BT_ENTRY(nkeys
);
2649 MAKE_BT_ENTRY(ndata
);
2651 MAKE_BT_ENTRY(pagecnt
);
2653 MAKE_BT_ENTRY(pagesize
);
2654 MAKE_BT_ENTRY(minkey
);
2655 MAKE_BT_ENTRY(re_len
);
2656 MAKE_BT_ENTRY(re_pad
);
2657 MAKE_BT_ENTRY(levels
);
2658 MAKE_BT_ENTRY(int_pg
);
2659 MAKE_BT_ENTRY(leaf_pg
);
2660 MAKE_BT_ENTRY(dup_pg
);
2661 MAKE_BT_ENTRY(over_pg
);
2663 MAKE_BT_ENTRY(empty_pg
);
2665 MAKE_BT_ENTRY(free
);
2666 MAKE_BT_ENTRY(int_pgfree
);
2667 MAKE_BT_ENTRY(leaf_pgfree
);
2668 MAKE_BT_ENTRY(dup_pgfree
);
2669 MAKE_BT_ENTRY(over_pgfree
);
2673 MAKE_QUEUE_ENTRY(magic
);
2674 MAKE_QUEUE_ENTRY(version
);
2675 MAKE_QUEUE_ENTRY(nkeys
);
2676 MAKE_QUEUE_ENTRY(ndata
);
2677 MAKE_QUEUE_ENTRY(pagesize
);
2679 MAKE_QUEUE_ENTRY(extentsize
);
2681 MAKE_QUEUE_ENTRY(pages
);
2682 MAKE_QUEUE_ENTRY(re_len
);
2683 MAKE_QUEUE_ENTRY(re_pad
);
2684 MAKE_QUEUE_ENTRY(pgfree
);
2686 MAKE_QUEUE_ENTRY(start
);
2688 MAKE_QUEUE_ENTRY(first_recno
);
2689 MAKE_QUEUE_ENTRY(cur_recno
);
2693 PyErr_SetString(PyExc_TypeError
, "Unknown DB type, unable to stat");
2698 #undef MAKE_HASH_ENTRY
2699 #undef MAKE_BT_ENTRY
2700 #undef MAKE_QUEUE_ENTRY
2707 DB_sync(DBObject
* self
, PyObject
* args
)
2712 if (!PyArg_ParseTuple(args
,"|i:sync", &flags
))
2714 CHECK_DB_NOT_CLOSED(self
);
2716 MYDB_BEGIN_ALLOW_THREADS
;
2717 err
= self
->db
->sync(self
->db
, flags
);
2718 MYDB_END_ALLOW_THREADS
;
2725 DB_truncate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2729 PyObject
* txnobj
= NULL
;
2731 static char* kwnames
[] = { "txn", "flags", NULL
};
2733 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
2736 CHECK_DB_NOT_CLOSED(self
);
2737 if (!checkTxnObj(txnobj
, &txn
))
2740 MYDB_BEGIN_ALLOW_THREADS
;
2741 err
= self
->db
->truncate(self
->db
, txn
, &count
, flags
);
2742 MYDB_END_ALLOW_THREADS
;
2744 return NUMBER_FromLong(count
);
2749 DB_upgrade(DBObject
* self
, PyObject
* args
)
2754 if (!PyArg_ParseTuple(args
,"s|i:upgrade", &filename
, &flags
))
2756 CHECK_DB_NOT_CLOSED(self
);
2758 MYDB_BEGIN_ALLOW_THREADS
;
2759 err
= self
->db
->upgrade(self
->db
, filename
, flags
);
2760 MYDB_END_ALLOW_THREADS
;
2767 DB_verify(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2772 char* outFileName
=NULL
;
2774 static char* kwnames
[] = { "filename", "dbname", "outfile", "flags",
2777 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zzi:verify", kwnames
,
2778 &fileName
, &dbName
, &outFileName
, &flags
))
2781 CHECK_DB_NOT_CLOSED(self
);
2783 outFile
= fopen(outFileName
, "w");
2784 /* XXX(nnorwitz): it should probably be an exception if outFile
2787 MYDB_BEGIN_ALLOW_THREADS
;
2788 err
= self
->db
->verify(self
->db
, fileName
, dbName
, outFile
, flags
);
2789 MYDB_END_ALLOW_THREADS
;
2793 { /* DB.verify acts as a DB handle destructor (like close) */
2796 error
=DB_close_internal(self
,0);
2808 DB_set_get_returns_none(DBObject
* self
, PyObject
* args
)
2813 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
2815 CHECK_DB_NOT_CLOSED(self
);
2817 if (self
->moduleFlags
.getReturnsNone
)
2819 if (self
->moduleFlags
.cursorSetReturnsNone
)
2821 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
2822 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
2823 return NUMBER_FromLong(oldValue
);
2828 DB_set_encrypt(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2832 char *passwd
= NULL
;
2833 static char* kwnames
[] = { "passwd", "flags", NULL
};
2835 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
2840 MYDB_BEGIN_ALLOW_THREADS
;
2841 err
= self
->db
->set_encrypt(self
->db
, passwd
, flags
);
2842 MYDB_END_ALLOW_THREADS
;
2847 #endif /* DBVER >= 41 */
2850 /*-------------------------------------------------------------- */
2851 /* Mapping and Dictionary-like access routines */
2853 Py_ssize_t
DB_length(PyObject
* _self
)
2856 Py_ssize_t size
= 0;
2859 DBObject
* self
= (DBObject
*)_self
;
2861 if (self
->db
== NULL
) {
2862 PyObject
*t
= Py_BuildValue("(is)", 0, "DB object has been closed");
2864 PyErr_SetObject(DBError
, t
);
2870 if (self
->haveStat
) { /* Has the stat function been called recently? If
2871 so, we can use the cached value. */
2872 flags
= DB_FAST_STAT
;
2875 MYDB_BEGIN_ALLOW_THREADS
;
2876 redo_stat_for_length
:
2878 err
= self
->db
->stat(self
->db
, /*txnid*/ NULL
, &sp
, flags
);
2880 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2883 /* All the stat structures have matching fields upto the ndata field,
2884 so we can use any of them for the type cast */
2885 size
= ((DB_BTREE_STAT
*)sp
)->bt_ndata
;
2887 /* A size of 0 could mean that Berkeley DB no longer had the stat values cached.
2888 * redo a full stat to make sure.
2889 * Fixes SF python bug 1493322, pybsddb bug 1184012
2891 if (size
== 0 && (flags
& DB_FAST_STAT
)) {
2895 goto redo_stat_for_length
;
2898 MYDB_END_ALLOW_THREADS
;
2910 PyObject
* DB_subscript(DBObject
* self
, PyObject
* keyobj
)
2917 CHECK_DB_NOT_CLOSED(self
);
2918 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2922 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2923 /* Tell Berkeley DB to malloc the return value (thread safe) */
2924 data
.flags
= DB_DBT_MALLOC
;
2926 MYDB_BEGIN_ALLOW_THREADS
;
2927 err
= self
->db
->get(self
->db
, NULL
, &key
, &data
, 0);
2928 MYDB_END_ALLOW_THREADS
;
2929 if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
2930 PyErr_SetObject(PyExc_KeyError
, keyobj
);
2933 else if (makeDBError(err
)) {
2937 retval
= Build_PyString(data
.data
, data
.size
);
2947 DB_ass_sub(DBObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
)
2953 if (self
->db
== NULL
) {
2954 PyObject
*t
= Py_BuildValue("(is)", 0, "DB object has been closed");
2956 PyErr_SetObject(DBError
, t
);
2962 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2965 if (dataobj
!= NULL
) {
2966 if (!make_dbt(dataobj
, &data
))
2969 if (self
->setflags
& (DB_DUP
|DB_DUPSORT
))
2970 /* dictionaries shouldn't have duplicate keys */
2971 flags
= DB_NOOVERWRITE
;
2972 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2974 if ((retval
== -1) && (self
->setflags
& (DB_DUP
|DB_DUPSORT
))) {
2975 /* try deleting any old record that matches and then PUT it
2977 _DB_delete(self
, NULL
, &key
, 0);
2979 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2984 /* dataobj == NULL, so delete the key */
2985 retval
= _DB_delete(self
, NULL
, &key
, 0);
2993 DB_has_key(DBObject
* self
, PyObject
* args
)
2998 PyObject
* txnobj
= NULL
;
3001 if (!PyArg_UnpackTuple(args
,"has_key", 1, 2, &keyobj
, &txnobj
))
3003 CHECK_DB_NOT_CLOSED(self
);
3004 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
3006 if (!checkTxnObj(txnobj
, &txn
)) {
3011 /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
3012 it has a record but can't allocate a buffer for the data. This saves
3013 having to deal with data we won't be using.
3016 data
.flags
= DB_DBT_USERMEM
;
3018 MYDB_BEGIN_ALLOW_THREADS
;
3019 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, 0);
3020 MYDB_END_ALLOW_THREADS
;
3023 if (err
== DB_BUFFER_SMALL
|| err
== 0) {
3024 return NUMBER_FromLong(1);
3025 } else if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
3026 return NUMBER_FromLong(0);
3034 #define _KEYS_LIST 1
3035 #define _VALUES_LIST 2
3036 #define _ITEMS_LIST 3
3039 _DB_make_list(DBObject
* self
, DB_TXN
* txn
, int type
)
3046 PyObject
* item
= NULL
;
3048 CHECK_DB_NOT_CLOSED(self
);
3052 dbtype
= _DB_get_type(self
);
3056 list
= PyList_New(0);
3061 MYDB_BEGIN_ALLOW_THREADS
;
3062 err
= self
->db
->cursor(self
->db
, txn
, &cursor
, 0);
3063 MYDB_END_ALLOW_THREADS
;
3064 if (makeDBError(err
)) {
3069 while (1) { /* use the cursor to traverse the DB, collecting items */
3070 MYDB_BEGIN_ALLOW_THREADS
;
3071 err
= _DBC_get(cursor
, &key
, &data
, DB_NEXT
);
3072 MYDB_END_ALLOW_THREADS
;
3075 /* for any error, break out of the loop */
3085 item
= Build_PyString(key
.data
, key
.size
);
3089 item
= NUMBER_FromLong(*((db_recno_t
*)key
.data
));
3095 item
= Build_PyString(data
.data
, data
.size
);
3103 item
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
3107 item
= BuildValue_IS(*((db_recno_t
*)key
.data
), data
.data
, data
.size
);
3112 PyErr_Format(PyExc_ValueError
, "Unknown key type 0x%x", type
);
3121 if (PyList_Append(list
, item
)) {
3130 /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
3131 if (err
!= DB_NOTFOUND
&& err
!= DB_KEYEMPTY
&& makeDBError(err
)) {
3137 MYDB_BEGIN_ALLOW_THREADS
;
3139 MYDB_END_ALLOW_THREADS
;
3145 DB_keys(DBObject
* self
, PyObject
* args
)
3147 PyObject
* txnobj
= NULL
;
3150 if (!PyArg_UnpackTuple(args
, "keys", 0, 1, &txnobj
))
3152 if (!checkTxnObj(txnobj
, &txn
))
3154 return _DB_make_list(self
, txn
, _KEYS_LIST
);
3159 DB_items(DBObject
* self
, PyObject
* args
)
3161 PyObject
* txnobj
= NULL
;
3164 if (!PyArg_UnpackTuple(args
, "items", 0, 1, &txnobj
))
3166 if (!checkTxnObj(txnobj
, &txn
))
3168 return _DB_make_list(self
, txn
, _ITEMS_LIST
);
3173 DB_values(DBObject
* self
, PyObject
* args
)
3175 PyObject
* txnobj
= NULL
;
3178 if (!PyArg_UnpackTuple(args
, "values", 0, 1, &txnobj
))
3180 if (!checkTxnObj(txnobj
, &txn
))
3182 return _DB_make_list(self
, txn
, _VALUES_LIST
);
3185 /* --------------------------------------------------------------------- */
3186 /* DBCursor methods */
3190 DBC_close_internal(DBCursorObject
* self
)
3194 if (self
->dbc
!= NULL
) {
3195 EXTRACT_FROM_DOUBLE_LINKED_LIST(self
);
3197 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self
);
3201 MYDB_BEGIN_ALLOW_THREADS
;
3202 err
= _DBC_close(self
->dbc
);
3203 MYDB_END_ALLOW_THREADS
;
3211 DBC_close(DBCursorObject
* self
)
3213 return DBC_close_internal(self
);
3218 DBC_count(DBCursorObject
* self
, PyObject
* args
)
3224 if (!PyArg_ParseTuple(args
, "|i:count", &flags
))
3227 CHECK_CURSOR_NOT_CLOSED(self
);
3229 MYDB_BEGIN_ALLOW_THREADS
;
3230 err
= _DBC_count(self
->dbc
, &count
, flags
);
3231 MYDB_END_ALLOW_THREADS
;
3234 return NUMBER_FromLong(count
);
3239 DBC_current(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3241 return _DBCursor_get(self
,DB_CURRENT
,args
,kwargs
,"|iii:current");
3246 DBC_delete(DBCursorObject
* self
, PyObject
* args
)
3250 if (!PyArg_ParseTuple(args
, "|i:delete", &flags
))
3253 CHECK_CURSOR_NOT_CLOSED(self
);
3255 MYDB_BEGIN_ALLOW_THREADS
;
3256 err
= _DBC_del(self
->dbc
, flags
);
3257 MYDB_END_ALLOW_THREADS
;
3260 self
->mydb
->haveStat
= 0;
3266 DBC_dup(DBCursorObject
* self
, PyObject
* args
)
3271 if (!PyArg_ParseTuple(args
, "|i:dup", &flags
))
3274 CHECK_CURSOR_NOT_CLOSED(self
);
3276 MYDB_BEGIN_ALLOW_THREADS
;
3277 err
= _DBC_dup(self
->dbc
, &dbc
, flags
);
3278 MYDB_END_ALLOW_THREADS
;
3281 return (PyObject
*) newDBCursorObject(dbc
, self
->txn
, self
->mydb
);
3285 DBC_first(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3287 return _DBCursor_get(self
,DB_FIRST
,args
,kwargs
,"|iii:first");
3292 DBC_get(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3295 PyObject
* keyobj
= NULL
;
3296 PyObject
* dataobj
= NULL
;
3297 PyObject
* retval
= NULL
;
3301 static char* kwnames
[] = { "key","data", "flags", "dlen", "doff",
3306 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:get", &kwnames
[2],
3307 &flags
, &dlen
, &doff
))
3310 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:get",
3312 &keyobj
, &flags
, &dlen
, &doff
))
3315 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:get",
3316 kwnames
, &keyobj
, &dataobj
,
3317 &flags
, &dlen
, &doff
))
3324 CHECK_CURSOR_NOT_CLOSED(self
);
3326 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3328 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
3329 (!add_partial_dbt(&data
, dlen
, doff
)) )
3331 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3335 MYDB_BEGIN_ALLOW_THREADS
;
3336 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
);
3337 MYDB_END_ALLOW_THREADS
;
3339 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3340 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3344 else if (makeDBError(err
)) {
3348 switch (_DB_get_type(self
->mydb
)) {
3355 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
3359 retval
= BuildValue_IS(*((db_recno_t
*)key
.data
), data
.data
, data
.size
);
3363 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3368 DBC_pget(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3371 PyObject
* keyobj
= NULL
;
3372 PyObject
* dataobj
= NULL
;
3373 PyObject
* retval
= NULL
;
3376 DBT key
, pkey
, data
;
3377 static char* kwnames_keyOnly
[] = { "key", "flags", "dlen", "doff", NULL
};
3378 static char* kwnames
[] = { "key", "data", "flags", "dlen", "doff", NULL
};
3382 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:pget", &kwnames
[2],
3383 &flags
, &dlen
, &doff
))
3386 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:pget",
3388 &keyobj
, &flags
, &dlen
, &doff
))
3391 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:pget",
3392 kwnames
, &keyobj
, &dataobj
,
3393 &flags
, &dlen
, &doff
))
3400 CHECK_CURSOR_NOT_CLOSED(self
);
3402 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3404 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
3405 (!add_partial_dbt(&data
, dlen
, doff
)) ) {
3406 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3411 pkey
.flags
= DB_DBT_MALLOC
;
3413 MYDB_BEGIN_ALLOW_THREADS
;
3414 err
= _DBC_pget(self
->dbc
, &key
, &pkey
, &data
, flags
);
3415 MYDB_END_ALLOW_THREADS
;
3417 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3418 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3422 else if (makeDBError(err
)) {
3428 dataObj
= Build_PyString(data
.data
, data
.size
);
3430 if (self
->mydb
->primaryDBType
== DB_RECNO
||
3431 self
->mydb
->primaryDBType
== DB_QUEUE
)
3432 pkeyObj
= NUMBER_FromLong(*(int *)pkey
.data
);
3434 pkeyObj
= Build_PyString(pkey
.data
, pkey
.size
);
3436 if (key
.data
&& key
.size
) /* return key, pkey and data */
3439 int type
= _DB_get_type(self
->mydb
);
3440 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
3441 keyObj
= NUMBER_FromLong(*(int *)key
.data
);
3443 keyObj
= Build_PyString(key
.data
, key
.size
);
3444 #if (PY_VERSION_HEX >= 0x02040000)
3445 retval
= PyTuple_Pack(3, keyObj
, pkeyObj
, dataObj
);
3447 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
3450 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3452 else /* return just the pkey and data */
3454 #if (PY_VERSION_HEX >= 0x02040000)
3455 retval
= PyTuple_Pack(2, pkeyObj
, dataObj
);
3457 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
3464 /* the only time REALLOC should be set is if we used an integer
3465 * key that make_key_dbt malloc'd for us. always free these. */
3466 if (key
.flags
& DB_DBT_REALLOC
) { /* 'make_key_dbt' could do a 'malloc' */
3474 DBC_get_recno(DBCursorObject
* self
)
3481 CHECK_CURSOR_NOT_CLOSED(self
);
3486 MYDB_BEGIN_ALLOW_THREADS
;
3487 err
= _DBC_get(self
->dbc
, &key
, &data
, DB_GET_RECNO
);
3488 MYDB_END_ALLOW_THREADS
;
3491 recno
= *((db_recno_t
*)data
.data
);
3492 return NUMBER_FromLong(recno
);
3497 DBC_last(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3499 return _DBCursor_get(self
,DB_LAST
,args
,kwargs
,"|iii:last");
3504 DBC_next(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3506 return _DBCursor_get(self
,DB_NEXT
,args
,kwargs
,"|iii:next");
3511 DBC_prev(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3513 return _DBCursor_get(self
,DB_PREV
,args
,kwargs
,"|iii:prev");
3518 DBC_put(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3521 PyObject
* keyobj
, *dataobj
;
3523 static char* kwnames
[] = { "key", "data", "flags", "dlen", "doff",
3528 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iii:put", kwnames
,
3529 &keyobj
, &dataobj
, &flags
, &dlen
, &doff
))
3532 CHECK_CURSOR_NOT_CLOSED(self
);
3534 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3536 if (!make_dbt(dataobj
, &data
) ||
3537 !add_partial_dbt(&data
, dlen
, doff
) )
3539 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3543 MYDB_BEGIN_ALLOW_THREADS
;
3544 err
= _DBC_put(self
->dbc
, &key
, &data
, flags
);
3545 MYDB_END_ALLOW_THREADS
;
3546 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3548 self
->mydb
->haveStat
= 0;
3554 DBC_set(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3558 PyObject
* retval
, *keyobj
;
3559 static char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
3563 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set", kwnames
,
3564 &keyobj
, &flags
, &dlen
, &doff
))
3567 CHECK_CURSOR_NOT_CLOSED(self
);
3569 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3573 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3574 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3578 MYDB_BEGIN_ALLOW_THREADS
;
3579 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
|DB_SET
);
3580 MYDB_END_ALLOW_THREADS
;
3581 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3582 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3586 else if (makeDBError(err
)) {
3590 switch (_DB_get_type(self
->mydb
)) {
3597 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
3601 retval
= BuildValue_IS(*((db_recno_t
*)key
.data
), data
.data
, data
.size
);
3604 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3606 /* the only time REALLOC should be set is if we used an integer
3607 * key that make_key_dbt malloc'd for us. always free these. */
3608 if (key
.flags
& DB_DBT_REALLOC
) {
3609 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3617 DBC_set_range(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3621 PyObject
* retval
, *keyobj
;
3622 static char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
3626 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set_range", kwnames
,
3627 &keyobj
, &flags
, &dlen
, &doff
))
3630 CHECK_CURSOR_NOT_CLOSED(self
);
3632 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3636 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3637 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3640 MYDB_BEGIN_ALLOW_THREADS
;
3641 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RANGE
);
3642 MYDB_END_ALLOW_THREADS
;
3643 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3644 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3648 else if (makeDBError(err
)) {
3652 switch (_DB_get_type(self
->mydb
)) {
3659 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
3663 retval
= BuildValue_IS(*((db_recno_t
*)key
.data
), data
.data
, data
.size
);
3666 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3668 /* the only time REALLOC should be set is if we used an integer
3669 * key that make_key_dbt malloc'd for us. always free these. */
3670 if (key
.flags
& DB_DBT_REALLOC
) {
3671 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3678 _DBC_get_set_both(DBCursorObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
,
3679 int flags
, unsigned int returnsNone
)
3685 /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
3686 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3688 if (!make_dbt(dataobj
, &data
)) {
3689 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3693 MYDB_BEGIN_ALLOW_THREADS
;
3694 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
|DB_GET_BOTH
);
3695 MYDB_END_ALLOW_THREADS
;
3696 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && returnsNone
) {
3700 else if (makeDBError(err
)) {
3704 switch (_DB_get_type(self
->mydb
)) {
3711 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
3715 retval
= BuildValue_IS(*((db_recno_t
*)key
.data
), data
.data
, data
.size
);
3720 FREE_DBT(key
); /* 'make_key_dbt' could do a 'malloc' */
3725 DBC_get_both(DBCursorObject
* self
, PyObject
* args
)
3728 PyObject
*keyobj
, *dataobj
;
3730 if (!PyArg_ParseTuple(args
, "OO|i:get_both", &keyobj
, &dataobj
, &flags
))
3733 /* if the cursor is closed, self->mydb may be invalid */
3734 CHECK_CURSOR_NOT_CLOSED(self
);
3736 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3737 self
->mydb
->moduleFlags
.getReturnsNone
);
3740 /* Return size of entry */
3742 DBC_get_current_size(DBCursorObject
* self
)
3744 int err
, flags
=DB_CURRENT
;
3745 PyObject
* retval
= NULL
;
3748 CHECK_CURSOR_NOT_CLOSED(self
);
3752 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
3753 getting the record size. */
3754 data
.flags
= DB_DBT_USERMEM
;
3756 MYDB_BEGIN_ALLOW_THREADS
;
3757 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
);
3758 MYDB_END_ALLOW_THREADS
;
3759 if (err
== DB_BUFFER_SMALL
|| !err
) {
3760 /* DB_BUFFER_SMALL means positive size, !err means zero length value */
3761 retval
= NUMBER_FromLong((long)data
.size
);
3770 DBC_set_both(DBCursorObject
* self
, PyObject
* args
)
3773 PyObject
*keyobj
, *dataobj
;
3775 if (!PyArg_ParseTuple(args
, "OO|i:set_both", &keyobj
, &dataobj
, &flags
))
3778 /* if the cursor is closed, self->mydb may be invalid */
3779 CHECK_CURSOR_NOT_CLOSED(self
);
3781 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3782 self
->mydb
->moduleFlags
.cursorSetReturnsNone
);
3787 DBC_set_recno(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3789 int err
, irecno
, flags
=0;
3795 static char* kwnames
[] = { "recno","flags", "dlen", "doff", NULL
};
3797 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|iii:set_recno", kwnames
,
3798 &irecno
, &flags
, &dlen
, &doff
))
3801 CHECK_CURSOR_NOT_CLOSED(self
);
3804 recno
= (db_recno_t
) irecno
;
3805 /* use allocated space so DB will be able to realloc room for the real
3807 key
.data
= malloc(sizeof(db_recno_t
));
3808 if (key
.data
== NULL
) {
3809 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
3812 key
.size
= sizeof(db_recno_t
);
3813 key
.ulen
= key
.size
;
3814 memcpy(key
.data
, &recno
, sizeof(db_recno_t
));
3815 key
.flags
= DB_DBT_REALLOC
;
3818 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3823 MYDB_BEGIN_ALLOW_THREADS
;
3824 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RECNO
);
3825 MYDB_END_ALLOW_THREADS
;
3826 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3827 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3831 else if (makeDBError(err
)) {
3834 else { /* Can only be used for BTrees, so no need to return int key */
3835 retval
= BuildValue_SS(key
.data
, key
.size
, data
.data
, data
.size
);
3844 DBC_consume(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3846 return _DBCursor_get(self
,DB_CONSUME
,args
,kwargs
,"|iii:consume");
3851 DBC_next_dup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3853 return _DBCursor_get(self
,DB_NEXT_DUP
,args
,kwargs
,"|iii:next_dup");
3858 DBC_next_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3860 return _DBCursor_get(self
,DB_NEXT_NODUP
,args
,kwargs
,"|iii:next_nodup");
3865 DBC_prev_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3867 return _DBCursor_get(self
,DB_PREV_NODUP
,args
,kwargs
,"|iii:prev_nodup");
3872 DBC_join_item(DBCursorObject
* self
, PyObject
* args
)
3878 if (!PyArg_ParseTuple(args
, "|i:join_item", &flags
))
3881 CHECK_CURSOR_NOT_CLOSED(self
);
3886 MYDB_BEGIN_ALLOW_THREADS
;
3887 err
= _DBC_get(self
->dbc
, &key
, &data
, flags
| DB_JOIN_ITEM
);
3888 MYDB_END_ALLOW_THREADS
;
3889 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3890 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3894 else if (makeDBError(err
)) {
3898 retval
= BuildValue_S(key
.data
, key
.size
);
3906 /* --------------------------------------------------------------------- */
3911 DBEnv_close_internal(DBEnvObject
* self
, int flags
)
3916 if (!self
->closed
) { /* Don't close more than once */
3917 while(self
->children_txns
) {
3918 dummy
=DBTxn_abort_discard_internal(self
->children_txns
,0);
3921 while(self
->children_dbs
) {
3922 dummy
=DB_close_internal(self
->children_dbs
,0);
3926 MYDB_BEGIN_ALLOW_THREADS
;
3927 err
= self
->db_env
->close(self
->db_env
, flags
);
3928 MYDB_END_ALLOW_THREADS
;
3929 /* after calling DBEnv->close, regardless of error, this DBEnv
3930 * may not be accessed again (Berkeley DB docs). */
3932 self
->db_env
= NULL
;
3939 DBEnv_close(DBEnvObject
* self
, PyObject
* args
)
3943 if (!PyArg_ParseTuple(args
, "|i:close", &flags
))
3945 return DBEnv_close_internal(self
,flags
);
3950 DBEnv_open(DBEnvObject
* self
, PyObject
* args
)
3952 int err
, flags
=0, mode
=0660;
3955 if (!PyArg_ParseTuple(args
, "z|ii:open", &db_home
, &flags
, &mode
))
3958 CHECK_ENV_NOT_CLOSED(self
);
3960 MYDB_BEGIN_ALLOW_THREADS
;
3961 err
= self
->db_env
->open(self
->db_env
, db_home
, flags
, mode
);
3962 MYDB_END_ALLOW_THREADS
;
3965 self
->flags
= flags
;
3971 DBEnv_remove(DBEnvObject
* self
, PyObject
* args
)
3976 if (!PyArg_ParseTuple(args
, "s|i:remove", &db_home
, &flags
))
3978 CHECK_ENV_NOT_CLOSED(self
);
3979 MYDB_BEGIN_ALLOW_THREADS
;
3980 err
= self
->db_env
->remove(self
->db_env
, db_home
, flags
);
3981 MYDB_END_ALLOW_THREADS
;
3988 DBEnv_dbremove(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3993 char *database
= NULL
;
3994 PyObject
*txnobj
= NULL
;
3996 static char* kwnames
[] = { "file", "database", "txn", "flags",
3999 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zOi:dbremove", kwnames
,
4000 &file
, &database
, &txnobj
, &flags
)) {
4003 if (!checkTxnObj(txnobj
, &txn
)) {
4006 CHECK_ENV_NOT_CLOSED(self
);
4007 MYDB_BEGIN_ALLOW_THREADS
;
4008 err
= self
->db_env
->dbremove(self
->db_env
, txn
, file
, database
, flags
);
4009 MYDB_END_ALLOW_THREADS
;
4015 DBEnv_dbrename(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4020 char *database
= NULL
;
4021 char *newname
= NULL
;
4022 PyObject
*txnobj
= NULL
;
4024 static char* kwnames
[] = { "file", "database", "newname", "txn",
4027 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "szs|Oi:dbrename", kwnames
,
4028 &file
, &database
, &newname
, &txnobj
, &flags
)) {
4031 if (!checkTxnObj(txnobj
, &txn
)) {
4034 CHECK_ENV_NOT_CLOSED(self
);
4035 MYDB_BEGIN_ALLOW_THREADS
;
4036 err
= self
->db_env
->dbrename(self
->db_env
, txn
, file
, database
, newname
,
4038 MYDB_END_ALLOW_THREADS
;
4044 DBEnv_set_encrypt(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4048 char *passwd
= NULL
;
4049 static char* kwnames
[] = { "passwd", "flags", NULL
};
4051 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
4056 MYDB_BEGIN_ALLOW_THREADS
;
4057 err
= self
->db_env
->set_encrypt(self
->db_env
, passwd
, flags
);
4058 MYDB_END_ALLOW_THREADS
;
4063 #endif /* DBVER >= 41 */
4066 DBEnv_set_timeout(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4070 u_int32_t timeout
= 0;
4071 static char* kwnames
[] = { "timeout", "flags", NULL
};
4073 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ii:set_timeout", kwnames
,
4074 &timeout
, &flags
)) {
4078 MYDB_BEGIN_ALLOW_THREADS
;
4079 err
= self
->db_env
->set_timeout(self
->db_env
, (db_timeout_t
)timeout
, flags
);
4080 MYDB_END_ALLOW_THREADS
;
4087 DBEnv_set_shm_key(DBEnvObject
* self
, PyObject
* args
)
4092 if (!PyArg_ParseTuple(args
, "l:set_shm_key", &shm_key
))
4094 CHECK_ENV_NOT_CLOSED(self
);
4096 err
= self
->db_env
->set_shm_key(self
->db_env
, shm_key
);
4102 DBEnv_set_cachesize(DBEnvObject
* self
, PyObject
* args
)
4104 int err
, gbytes
=0, bytes
=0, ncache
=0;
4106 if (!PyArg_ParseTuple(args
, "ii|i:set_cachesize",
4107 &gbytes
, &bytes
, &ncache
))
4109 CHECK_ENV_NOT_CLOSED(self
);
4111 MYDB_BEGIN_ALLOW_THREADS
;
4112 err
= self
->db_env
->set_cachesize(self
->db_env
, gbytes
, bytes
, ncache
);
4113 MYDB_END_ALLOW_THREADS
;
4120 DBEnv_set_flags(DBEnvObject
* self
, PyObject
* args
)
4122 int err
, flags
=0, onoff
=0;
4124 if (!PyArg_ParseTuple(args
, "ii:set_flags",
4127 CHECK_ENV_NOT_CLOSED(self
);
4129 MYDB_BEGIN_ALLOW_THREADS
;
4130 err
= self
->db_env
->set_flags(self
->db_env
, flags
, onoff
);
4131 MYDB_END_ALLOW_THREADS
;
4139 DBEnv_log_set_config(DBEnvObject
* self
, PyObject
* args
)
4141 int err
, flags
, onoff
;
4143 if (!PyArg_ParseTuple(args
, "ii:log_set_config",
4146 CHECK_ENV_NOT_CLOSED(self
);
4148 MYDB_BEGIN_ALLOW_THREADS
;
4149 err
= self
->db_env
->log_set_config(self
->db_env
, flags
, onoff
);
4150 MYDB_END_ALLOW_THREADS
;
4154 #endif /* DBVER >= 47 */
4158 DBEnv_set_data_dir(DBEnvObject
* self
, PyObject
* args
)
4163 if (!PyArg_ParseTuple(args
, "s:set_data_dir", &dir
))
4165 CHECK_ENV_NOT_CLOSED(self
);
4167 MYDB_BEGIN_ALLOW_THREADS
;
4168 err
= self
->db_env
->set_data_dir(self
->db_env
, dir
);
4169 MYDB_END_ALLOW_THREADS
;
4176 DBEnv_set_lg_bsize(DBEnvObject
* self
, PyObject
* args
)
4180 if (!PyArg_ParseTuple(args
, "i:set_lg_bsize", &lg_bsize
))
4182 CHECK_ENV_NOT_CLOSED(self
);
4184 MYDB_BEGIN_ALLOW_THREADS
;
4185 err
= self
->db_env
->set_lg_bsize(self
->db_env
, lg_bsize
);
4186 MYDB_END_ALLOW_THREADS
;
4193 DBEnv_set_lg_dir(DBEnvObject
* self
, PyObject
* args
)
4198 if (!PyArg_ParseTuple(args
, "s:set_lg_dir", &dir
))
4200 CHECK_ENV_NOT_CLOSED(self
);
4202 MYDB_BEGIN_ALLOW_THREADS
;
4203 err
= self
->db_env
->set_lg_dir(self
->db_env
, dir
);
4204 MYDB_END_ALLOW_THREADS
;
4210 DBEnv_set_lg_max(DBEnvObject
* self
, PyObject
* args
)
4214 if (!PyArg_ParseTuple(args
, "i:set_lg_max", &lg_max
))
4216 CHECK_ENV_NOT_CLOSED(self
);
4218 MYDB_BEGIN_ALLOW_THREADS
;
4219 err
= self
->db_env
->set_lg_max(self
->db_env
, lg_max
);
4220 MYDB_END_ALLOW_THREADS
;
4227 DBEnv_get_lg_max(DBEnvObject
* self
)
4232 CHECK_ENV_NOT_CLOSED(self
);
4234 MYDB_BEGIN_ALLOW_THREADS
;
4235 err
= self
->db_env
->get_lg_max(self
->db_env
, &lg_max
);
4236 MYDB_END_ALLOW_THREADS
;
4238 return NUMBER_FromLong(lg_max
);
4244 DBEnv_set_lg_regionmax(DBEnvObject
* self
, PyObject
* args
)
4248 if (!PyArg_ParseTuple(args
, "i:set_lg_regionmax", &lg_max
))
4250 CHECK_ENV_NOT_CLOSED(self
);
4252 MYDB_BEGIN_ALLOW_THREADS
;
4253 err
= self
->db_env
->set_lg_regionmax(self
->db_env
, lg_max
);
4254 MYDB_END_ALLOW_THREADS
;
4261 DBEnv_set_lk_detect(DBEnvObject
* self
, PyObject
* args
)
4265 if (!PyArg_ParseTuple(args
, "i:set_lk_detect", &lk_detect
))
4267 CHECK_ENV_NOT_CLOSED(self
);
4269 MYDB_BEGIN_ALLOW_THREADS
;
4270 err
= self
->db_env
->set_lk_detect(self
->db_env
, lk_detect
);
4271 MYDB_END_ALLOW_THREADS
;
4279 DBEnv_set_lk_max(DBEnvObject
* self
, PyObject
* args
)
4283 if (!PyArg_ParseTuple(args
, "i:set_lk_max", &max
))
4285 CHECK_ENV_NOT_CLOSED(self
);
4287 MYDB_BEGIN_ALLOW_THREADS
;
4288 err
= self
->db_env
->set_lk_max(self
->db_env
, max
);
4289 MYDB_END_ALLOW_THREADS
;
4298 DBEnv_set_lk_max_locks(DBEnvObject
* self
, PyObject
* args
)
4302 if (!PyArg_ParseTuple(args
, "i:set_lk_max_locks", &max
))
4304 CHECK_ENV_NOT_CLOSED(self
);
4306 MYDB_BEGIN_ALLOW_THREADS
;
4307 err
= self
->db_env
->set_lk_max_locks(self
->db_env
, max
);
4308 MYDB_END_ALLOW_THREADS
;
4315 DBEnv_set_lk_max_lockers(DBEnvObject
* self
, PyObject
* args
)
4319 if (!PyArg_ParseTuple(args
, "i:set_lk_max_lockers", &max
))
4321 CHECK_ENV_NOT_CLOSED(self
);
4323 MYDB_BEGIN_ALLOW_THREADS
;
4324 err
= self
->db_env
->set_lk_max_lockers(self
->db_env
, max
);
4325 MYDB_END_ALLOW_THREADS
;
4332 DBEnv_set_lk_max_objects(DBEnvObject
* self
, PyObject
* args
)
4336 if (!PyArg_ParseTuple(args
, "i:set_lk_max_objects", &max
))
4338 CHECK_ENV_NOT_CLOSED(self
);
4340 MYDB_BEGIN_ALLOW_THREADS
;
4341 err
= self
->db_env
->set_lk_max_objects(self
->db_env
, max
);
4342 MYDB_END_ALLOW_THREADS
;
4349 DBEnv_set_mp_mmapsize(DBEnvObject
* self
, PyObject
* args
)
4351 int err
, mp_mmapsize
;
4353 if (!PyArg_ParseTuple(args
, "i:set_mp_mmapsize", &mp_mmapsize
))
4355 CHECK_ENV_NOT_CLOSED(self
);
4357 MYDB_BEGIN_ALLOW_THREADS
;
4358 err
= self
->db_env
->set_mp_mmapsize(self
->db_env
, mp_mmapsize
);
4359 MYDB_END_ALLOW_THREADS
;
4366 DBEnv_set_tmp_dir(DBEnvObject
* self
, PyObject
* args
)
4371 if (!PyArg_ParseTuple(args
, "s:set_tmp_dir", &dir
))
4373 CHECK_ENV_NOT_CLOSED(self
);
4375 MYDB_BEGIN_ALLOW_THREADS
;
4376 err
= self
->db_env
->set_tmp_dir(self
->db_env
, dir
);
4377 MYDB_END_ALLOW_THREADS
;
4384 DBEnv_txn_recover(DBEnvObject
* self
)
4386 int flags
= DB_FIRST
;
4388 PyObject
*list
, *tuple
, *gid
;
4390 #define PREPLIST_LEN 16
4391 DB_PREPLIST preplist
[PREPLIST_LEN
];
4394 CHECK_ENV_NOT_CLOSED(self
);
4400 MYDB_BEGIN_ALLOW_THREADS
4401 err
=self
->db_env
->txn_recover(self
->db_env
,
4402 preplist
, PREPLIST_LEN
, &retp
, flags
);
4404 MYDB_END_ALLOW_THREADS
4410 flags
=DB_NEXT
; /* Prepare for next loop pass */
4411 for (i
=0; i
<retp
; i
++) {
4412 gid
=PyBytes_FromStringAndSize((char *)(preplist
[i
].gid
),
4418 txn
=newDBTxnObject(self
, NULL
, preplist
[i
].txn
, flags
);
4424 txn
->flag_prepare
=1; /* Recover state */
4425 tuple
=PyTuple_New(2);
4432 if (PyTuple_SetItem(tuple
, 0, gid
)) {
4439 if (PyTuple_SetItem(tuple
, 1, (PyObject
*)txn
)) {
4442 Py_DECREF(tuple
); /* This delete the "gid" also */
4445 if (PyList_Append(list
, tuple
)) {
4447 Py_DECREF(tuple
);/* This delete the "gid" and the "txn" also */
4457 DBEnv_txn_begin(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4460 PyObject
* txnobj
= NULL
;
4462 static char* kwnames
[] = { "parent", "flags", NULL
};
4464 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:txn_begin", kwnames
,
4468 if (!checkTxnObj(txnobj
, &txn
))
4470 CHECK_ENV_NOT_CLOSED(self
);
4472 return (PyObject
*)newDBTxnObject(self
, (DBTxnObject
*)txnobj
, NULL
, flags
);
4477 DBEnv_txn_checkpoint(DBEnvObject
* self
, PyObject
* args
)
4479 int err
, kbyte
=0, min
=0, flags
=0;
4481 if (!PyArg_ParseTuple(args
, "|iii:txn_checkpoint", &kbyte
, &min
, &flags
))
4483 CHECK_ENV_NOT_CLOSED(self
);
4485 MYDB_BEGIN_ALLOW_THREADS
;
4486 err
= self
->db_env
->txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
4487 MYDB_END_ALLOW_THREADS
;
4494 DBEnv_set_tx_max(DBEnvObject
* self
, PyObject
* args
)
4498 if (!PyArg_ParseTuple(args
, "i:set_tx_max", &max
))
4500 CHECK_ENV_NOT_CLOSED(self
);
4502 err
= self
->db_env
->set_tx_max(self
->db_env
, max
);
4509 DBEnv_set_tx_timestamp(DBEnvObject
* self
, PyObject
* args
)
4515 if (!PyArg_ParseTuple(args
, "l:set_tx_timestamp", &stamp
))
4517 CHECK_ENV_NOT_CLOSED(self
);
4518 timestamp
= (time_t)stamp
;
4519 err
= self
->db_env
->set_tx_timestamp(self
->db_env
, ×tamp
);
4526 DBEnv_lock_detect(DBEnvObject
* self
, PyObject
* args
)
4528 int err
, atype
, flags
=0;
4531 if (!PyArg_ParseTuple(args
, "i|i:lock_detect", &atype
, &flags
))
4533 CHECK_ENV_NOT_CLOSED(self
);
4535 MYDB_BEGIN_ALLOW_THREADS
;
4536 err
= self
->db_env
->lock_detect(self
->db_env
, flags
, atype
, &aborted
);
4537 MYDB_END_ALLOW_THREADS
;
4539 return NUMBER_FromLong(aborted
);
4544 DBEnv_lock_get(DBEnvObject
* self
, PyObject
* args
)
4547 int locker
, lock_mode
;
4551 if (!PyArg_ParseTuple(args
, "iOi|i:lock_get", &locker
, &objobj
, &lock_mode
, &flags
))
4555 if (!make_dbt(objobj
, &obj
))
4558 return (PyObject
*)newDBLockObject(self
, locker
, &obj
, lock_mode
, flags
);
4563 DBEnv_lock_id(DBEnvObject
* self
)
4568 CHECK_ENV_NOT_CLOSED(self
);
4569 MYDB_BEGIN_ALLOW_THREADS
;
4570 err
= self
->db_env
->lock_id(self
->db_env
, &theID
);
4571 MYDB_END_ALLOW_THREADS
;
4574 return NUMBER_FromLong((long)theID
);
4578 DBEnv_lock_id_free(DBEnvObject
* self
, PyObject
* args
)
4583 if (!PyArg_ParseTuple(args
, "I:lock_id_free", &theID
))
4586 CHECK_ENV_NOT_CLOSED(self
);
4587 MYDB_BEGIN_ALLOW_THREADS
;
4588 err
= self
->db_env
->lock_id_free(self
->db_env
, theID
);
4589 MYDB_END_ALLOW_THREADS
;
4595 DBEnv_lock_put(DBEnvObject
* self
, PyObject
* args
)
4598 DBLockObject
* dblockobj
;
4600 if (!PyArg_ParseTuple(args
, "O!:lock_put", &DBLock_Type
, &dblockobj
))
4603 CHECK_ENV_NOT_CLOSED(self
);
4604 MYDB_BEGIN_ALLOW_THREADS
;
4605 err
= self
->db_env
->lock_put(self
->db_env
, &dblockobj
->lock
);
4606 MYDB_END_ALLOW_THREADS
;
4613 DBEnv_lsn_reset(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4617 u_int32_t flags
= 0;
4618 static char* kwnames
[] = { "file", "flags", NULL
};
4620 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|i:lsn_reset", kwnames
,
4623 CHECK_ENV_NOT_CLOSED(self
);
4625 MYDB_BEGIN_ALLOW_THREADS
;
4626 err
= self
->db_env
->lsn_reset(self
->db_env
, file
, flags
);
4627 MYDB_END_ALLOW_THREADS
;
4631 #endif /* DBVER >= 4.4 */
4634 DBEnv_log_stat(DBEnvObject
* self
, PyObject
* args
)
4637 DB_LOG_STAT
* statp
= NULL
;
4639 u_int32_t flags
= 0;
4641 if (!PyArg_ParseTuple(args
, "|i:log_stat", &flags
))
4643 CHECK_ENV_NOT_CLOSED(self
);
4645 MYDB_BEGIN_ALLOW_THREADS
;
4646 err
= self
->db_env
->log_stat(self
->db_env
, &statp
, flags
);
4647 MYDB_END_ALLOW_THREADS
;
4650 /* Turn the stat structure into a dictionary */
4658 #define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
4661 MAKE_ENTRY(version
);
4663 MAKE_ENTRY(lg_bsize
);
4665 MAKE_ENTRY(lg_size
);
4671 MAKE_ENTRY(w_mbytes
);
4672 MAKE_ENTRY(w_bytes
);
4673 MAKE_ENTRY(wc_mbytes
);
4674 MAKE_ENTRY(wc_bytes
);
4676 MAKE_ENTRY(wcount_fill
);
4681 MAKE_ENTRY(cur_file
);
4682 MAKE_ENTRY(cur_offset
);
4683 MAKE_ENTRY(disk_file
);
4684 MAKE_ENTRY(disk_offset
);
4685 MAKE_ENTRY(maxcommitperflush
);
4686 MAKE_ENTRY(mincommitperflush
);
4687 MAKE_ENTRY(regsize
);
4688 MAKE_ENTRY(region_wait
);
4689 MAKE_ENTRY(region_nowait
);
4694 } /* DBEnv_log_stat */
4698 DBEnv_lock_stat(DBEnvObject
* self
, PyObject
* args
)
4703 u_int32_t flags
= 0;
4705 if (!PyArg_ParseTuple(args
, "|i:lock_stat", &flags
))
4707 CHECK_ENV_NOT_CLOSED(self
);
4709 MYDB_BEGIN_ALLOW_THREADS
;
4710 err
= self
->db_env
->lock_stat(self
->db_env
, &sp
, flags
);
4711 MYDB_END_ALLOW_THREADS
;
4714 /* Turn the stat structure into a dictionary */
4721 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4728 MAKE_ENTRY(cur_maxid
);
4731 MAKE_ENTRY(maxlocks
);
4732 MAKE_ENTRY(maxlockers
);
4733 MAKE_ENTRY(maxobjects
);
4735 MAKE_ENTRY(maxnlocks
);
4736 MAKE_ENTRY(nlockers
);
4737 MAKE_ENTRY(maxnlockers
);
4738 MAKE_ENTRY(nobjects
);
4739 MAKE_ENTRY(maxnobjects
);
4740 MAKE_ENTRY(nrequests
);
4741 MAKE_ENTRY(nreleases
);
4743 MAKE_ENTRY(nupgrade
);
4744 MAKE_ENTRY(ndowngrade
);
4747 MAKE_ENTRY(nnowaits
); /* these were renamed in 4.4 */
4748 MAKE_ENTRY(nconflicts
);
4750 MAKE_ENTRY(lock_nowait
);
4751 MAKE_ENTRY(lock_wait
);
4753 MAKE_ENTRY(ndeadlocks
);
4755 MAKE_ENTRY(locktimeout
);
4756 MAKE_ENTRY(txntimeout
);
4758 MAKE_ENTRY(nlocktimeouts
);
4759 MAKE_ENTRY(ntxntimeouts
);
4761 MAKE_ENTRY(objs_wait
);
4762 MAKE_ENTRY(objs_nowait
);
4763 MAKE_ENTRY(lockers_wait
);
4764 MAKE_ENTRY(lockers_nowait
);
4766 MAKE_ENTRY(lock_wait
);
4767 MAKE_ENTRY(lock_nowait
);
4769 MAKE_ENTRY(locks_wait
);
4770 MAKE_ENTRY(locks_nowait
);
4772 MAKE_ENTRY(hash_len
);
4774 MAKE_ENTRY(regsize
);
4775 MAKE_ENTRY(region_wait
);
4776 MAKE_ENTRY(region_nowait
);
4784 DBEnv_log_flush(DBEnvObject
* self
)
4788 CHECK_ENV_NOT_CLOSED(self
);
4790 MYDB_BEGIN_ALLOW_THREADS
4791 err
= self
->db_env
->log_flush(self
->db_env
, NULL
);
4792 MYDB_END_ALLOW_THREADS
4799 DBEnv_log_archive(DBEnvObject
* self
, PyObject
* args
)
4803 char **log_list
= NULL
;
4805 PyObject
* item
= NULL
;
4807 if (!PyArg_ParseTuple(args
, "|i:log_archive", &flags
))
4810 CHECK_ENV_NOT_CLOSED(self
);
4811 MYDB_BEGIN_ALLOW_THREADS
;
4812 err
= self
->db_env
->log_archive(self
->db_env
, &log_list
, flags
);
4813 MYDB_END_ALLOW_THREADS
;
4816 list
= PyList_New(0);
4824 char **log_list_start
;
4825 for (log_list_start
= log_list
; *log_list
!= NULL
; ++log_list
) {
4826 item
= PyBytes_FromString (*log_list
);
4832 if (PyList_Append(list
, item
)) {
4840 free(log_list_start
);
4847 DBEnv_txn_stat(DBEnvObject
* self
, PyObject
* args
)
4854 if (!PyArg_ParseTuple(args
, "|i:txn_stat", &flags
))
4856 CHECK_ENV_NOT_CLOSED(self
);
4858 MYDB_BEGIN_ALLOW_THREADS
;
4859 err
= self
->db_env
->txn_stat(self
->db_env
, &sp
, flags
);
4860 MYDB_END_ALLOW_THREADS
;
4863 /* Turn the stat structure into a dictionary */
4870 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4871 #define MAKE_TIME_T_ENTRY(name) _addTimeTToDict(d, #name, sp->st_##name)
4872 #define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(d, #name, sp->st_##name)
4874 MAKE_DB_LSN_ENTRY(last_ckp
);
4875 MAKE_TIME_T_ENTRY(time_ckp
);
4876 MAKE_ENTRY(last_txnid
);
4877 MAKE_ENTRY(maxtxns
);
4878 MAKE_ENTRY(nactive
);
4879 MAKE_ENTRY(maxnactive
);
4881 MAKE_ENTRY(nsnapshot
);
4882 MAKE_ENTRY(maxnsnapshot
);
4884 MAKE_ENTRY(nbegins
);
4885 MAKE_ENTRY(naborts
);
4886 MAKE_ENTRY(ncommits
);
4887 MAKE_ENTRY(nrestores
);
4888 MAKE_ENTRY(regsize
);
4889 MAKE_ENTRY(region_wait
);
4890 MAKE_ENTRY(region_nowait
);
4892 #undef MAKE_DB_LSN_ENTRY
4894 #undef MAKE_TIME_T_ENTRY
4901 DBEnv_set_get_returns_none(DBEnvObject
* self
, PyObject
* args
)
4906 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
4908 CHECK_ENV_NOT_CLOSED(self
);
4910 if (self
->moduleFlags
.getReturnsNone
)
4912 if (self
->moduleFlags
.cursorSetReturnsNone
)
4914 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
4915 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
4916 return NUMBER_FromLong(oldValue
);
4920 DBEnv_get_private(DBEnvObject
* self
)
4922 /* We can give out the private field even if dbenv is closed */
4923 Py_INCREF(self
->private);
4924 return self
->private;
4928 DBEnv_set_private(DBEnvObject
* self
, PyObject
* private)
4930 /* We can set the private field even if dbenv is closed */
4931 Py_DECREF(self
->private);
4933 self
->private = private;
4939 DBEnv_set_rpc_server(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4943 long cl_timeout
=0, sv_timeout
=0;
4945 static char* kwnames
[] = { "host", "cl_timeout", "sv_timeout", NULL
};
4947 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|ll:set_rpc_server", kwnames
,
4948 &host
, &cl_timeout
, &sv_timeout
))
4950 CHECK_ENV_NOT_CLOSED(self
);
4952 MYDB_BEGIN_ALLOW_THREADS
;
4953 err
= self
->db_env
->set_rpc_server(self
->db_env
, NULL
, host
, cl_timeout
,
4955 MYDB_END_ALLOW_THREADS
;
4961 DBEnv_set_verbose(DBEnvObject
* self
, PyObject
* args
)
4966 if (!PyArg_ParseTuple(args
, "ii:set_verbose", &which
, &onoff
)) {
4969 CHECK_ENV_NOT_CLOSED(self
);
4970 MYDB_BEGIN_ALLOW_THREADS
;
4971 err
= self
->db_env
->set_verbose(self
->db_env
, which
, onoff
);
4972 MYDB_END_ALLOW_THREADS
;
4979 DBEnv_get_verbose(DBEnvObject
* self
, PyObject
* args
)
4985 if (!PyArg_ParseTuple(args
, "i:get_verbose", &which
)) {
4988 CHECK_ENV_NOT_CLOSED(self
);
4989 MYDB_BEGIN_ALLOW_THREADS
;
4990 err
= self
->db_env
->get_verbose(self
->db_env
, which
, &verbose
);
4991 MYDB_END_ALLOW_THREADS
;
4993 return PyBool_FromLong(verbose
);
4999 _dbenv_event_notifyCallback(DB_ENV
* db_env
, u_int32_t event
, void *event_info
)
5004 PyObject
* result
= NULL
;
5006 MYDB_BEGIN_BLOCK_THREADS
;
5007 dbenv
= (DBEnvObject
*)db_env
->app_private
;
5008 callback
= dbenv
->event_notifyCallback
;
5010 if (event
== DB_EVENT_REP_NEWMASTER
) {
5011 args
= Py_BuildValue("(Oii)", dbenv
, event
, *((int *)event_info
));
5013 args
= Py_BuildValue("(OiO)", dbenv
, event
, Py_None
);
5016 result
= PyEval_CallObject(callback
, args
);
5018 if ((!args
) || (!result
)) {
5024 MYDB_END_BLOCK_THREADS
;
5030 DBEnv_set_event_notify(DBEnvObject
* self
, PyObject
* notifyFunc
)
5034 CHECK_ENV_NOT_CLOSED(self
);
5036 if (!PyCallable_Check(notifyFunc
)) {
5037 makeTypeError("Callable", notifyFunc
);
5041 Py_XDECREF(self
->event_notifyCallback
);
5042 Py_INCREF(notifyFunc
);
5043 self
->event_notifyCallback
= notifyFunc
;
5045 /* This is to workaround a problem with un-initialized threads (see
5046 comment in DB_associate) */
5048 PyEval_InitThreads();
5051 MYDB_BEGIN_ALLOW_THREADS
;
5052 err
= self
->db_env
->set_event_notify(self
->db_env
, _dbenv_event_notifyCallback
);
5053 MYDB_END_ALLOW_THREADS
;
5056 Py_DECREF(notifyFunc
);
5057 self
->event_notifyCallback
= NULL
;
5066 /* --------------------------------------------------------------------- */
5067 /* REPLICATION METHODS: Base Replication */
5071 DBEnv_rep_process_message(DBEnvObject
* self
, PyObject
* args
)
5074 PyObject
*control_py
, *rec_py
;
5081 if (!PyArg_ParseTuple(args
, "OOi:rep_process_message", &control_py
,
5084 CHECK_ENV_NOT_CLOSED(self
);
5086 if (!make_dbt(control_py
, &control
))
5088 if (!make_dbt(rec_py
, &rec
))
5091 MYDB_BEGIN_ALLOW_THREADS
;
5093 err
= self
->db_env
->rep_process_message(self
->db_env
, &control
, &rec
,
5097 err
= self
->db_env
->rep_process_message(self
->db_env
, &control
, &rec
,
5100 err
= self
->db_env
->rep_process_message(self
->db_env
, &control
, &rec
,
5104 MYDB_END_ALLOW_THREADS
;
5106 case DB_REP_NEWMASTER
:
5107 return Py_BuildValue("(iO)", envid
, Py_None
);
5110 case DB_REP_DUPMASTER
:
5111 case DB_REP_HOLDELECTION
:
5113 case DB_REP_IGNORE
:
5114 case DB_REP_JOIN_FAILURE
:
5116 return Py_BuildValue("(iO)", err
, Py_None
);
5118 case DB_REP_NEWSITE
:
5119 return Py_BuildValue("(is#)", err
, rec
.data
, rec
.size
);
5122 case DB_REP_NOTPERM
:
5123 case DB_REP_ISPERM
:
5124 return Py_BuildValue("(i(ll))", err
, lsn
.file
, lsn
.offset
);
5129 return Py_BuildValue("(OO)", Py_None
, Py_None
);
5133 _DBEnv_rep_transportCallback(DB_ENV
* db_env
, const DBT
* control
, const DBT
* rec
,
5134 const DB_LSN
*lsn
, int envid
, u_int32_t flags
)
5137 PyObject
* rep_transport
;
5139 PyObject
* result
= NULL
;
5142 MYDB_BEGIN_BLOCK_THREADS
;
5143 dbenv
= (DBEnvObject
*)db_env
->app_private
;
5144 rep_transport
= dbenv
->rep_transport
;
5146 args
= Py_BuildValue(
5147 #if (PY_VERSION_HEX >= 0x02040000)
5153 control
->data
, control
->size
,
5154 rec
->data
, rec
->size
, lsn
->file
, lsn
->offset
, envid
, flags
);
5156 result
= PyEval_CallObject(rep_transport
, args
);
5159 if ((!args
) || (!result
)) {
5165 MYDB_END_BLOCK_THREADS
;
5171 _DBEnv_rep_transportCallbackOLD(DB_ENV
* db_env
, const DBT
* control
, const DBT
* rec
,
5172 int envid
, u_int32_t flags
)
5176 lsn
.file
= -1; /* Dummy values */
5178 return _DBEnv_rep_transportCallback(db_env
, control
, rec
, &lsn
, envid
,
5184 DBEnv_rep_set_transport(DBEnvObject
* self
, PyObject
* args
)
5188 PyObject
*rep_transport
;
5190 if (!PyArg_ParseTuple(args
, "iO:rep_set_transport", &envid
, &rep_transport
))
5192 CHECK_ENV_NOT_CLOSED(self
);
5193 if (!PyCallable_Check(rep_transport
)) {
5194 makeTypeError("Callable", rep_transport
);
5198 MYDB_BEGIN_ALLOW_THREADS
;
5200 err
= self
->db_env
->rep_set_transport(self
->db_env
, envid
,
5201 &_DBEnv_rep_transportCallback
);
5204 err
= self
->db_env
->set_rep_transport(self
->db_env
, envid
,
5205 &_DBEnv_rep_transportCallback
);
5207 err
= self
->db_env
->set_rep_transport(self
->db_env
, envid
,
5208 &_DBEnv_rep_transportCallbackOLD
);
5211 MYDB_END_ALLOW_THREADS
;
5214 Py_DECREF(self
->rep_transport
);
5215 Py_INCREF(rep_transport
);
5216 self
->rep_transport
= rep_transport
;
5222 DBEnv_rep_set_request(DBEnvObject
* self
, PyObject
* args
)
5225 unsigned int minimum
, maximum
;
5227 if (!PyArg_ParseTuple(args
,"II:rep_set_request", &minimum
, &maximum
))
5229 CHECK_ENV_NOT_CLOSED(self
);
5231 MYDB_BEGIN_ALLOW_THREADS
;
5232 err
= self
->db_env
->rep_set_request(self
->db_env
, minimum
, maximum
);
5233 MYDB_END_ALLOW_THREADS
;
5239 DBEnv_rep_get_request(DBEnvObject
* self
)
5242 u_int32_t minimum
, maximum
;
5244 CHECK_ENV_NOT_CLOSED(self
);
5245 MYDB_BEGIN_ALLOW_THREADS
;
5246 err
= self
->db_env
->rep_get_request(self
->db_env
, &minimum
, &maximum
);
5247 MYDB_END_ALLOW_THREADS
;
5249 #if (PY_VERSION_HEX >= 0x02040000)
5250 return Py_BuildValue("II", minimum
, maximum
);
5252 return Py_BuildValue("ii", minimum
, maximum
);
5259 DBEnv_rep_set_limit(DBEnvObject
* self
, PyObject
* args
)
5264 if (!PyArg_ParseTuple(args
,"i:rep_set_limit", &limit
))
5266 CHECK_ENV_NOT_CLOSED(self
);
5268 MYDB_BEGIN_ALLOW_THREADS
;
5269 err
= self
->db_env
->rep_set_limit(self
->db_env
, 0, limit
);
5270 MYDB_END_ALLOW_THREADS
;
5276 DBEnv_rep_get_limit(DBEnvObject
* self
)
5279 u_int32_t gbytes
, bytes
;
5281 CHECK_ENV_NOT_CLOSED(self
);
5282 MYDB_BEGIN_ALLOW_THREADS
;
5283 err
= self
->db_env
->rep_get_limit(self
->db_env
, &gbytes
, &bytes
);
5284 MYDB_END_ALLOW_THREADS
;
5286 return NUMBER_FromLong(bytes
);
5292 DBEnv_rep_set_config(DBEnvObject
* self
, PyObject
* args
)
5298 if (!PyArg_ParseTuple(args
,"ii:rep_set_config", &which
, &onoff
))
5300 CHECK_ENV_NOT_CLOSED(self
);
5302 MYDB_BEGIN_ALLOW_THREADS
;
5303 err
= self
->db_env
->rep_set_config(self
->db_env
, which
, onoff
);
5304 MYDB_END_ALLOW_THREADS
;
5310 DBEnv_rep_get_config(DBEnvObject
* self
, PyObject
* args
)
5316 if (!PyArg_ParseTuple(args
, "i:rep_get_config", &which
)) {
5319 CHECK_ENV_NOT_CLOSED(self
);
5320 MYDB_BEGIN_ALLOW_THREADS
;
5321 err
= self
->db_env
->rep_get_config(self
->db_env
, which
, &onoff
);
5322 MYDB_END_ALLOW_THREADS
;
5324 return PyBool_FromLong(onoff
);
5330 DBEnv_rep_elect(DBEnvObject
* self
, PyObject
* args
)
5333 u_int32_t nsites
, nvotes
;
5335 if (!PyArg_ParseTuple(args
, "II:rep_elect", &nsites
, &nvotes
)) {
5338 CHECK_ENV_NOT_CLOSED(self
);
5339 MYDB_BEGIN_ALLOW_THREADS
;
5340 err
= self
->db_env
->rep_elect(self
->db_env
, nvotes
, nvotes
, 0);
5341 MYDB_END_ALLOW_THREADS
;
5348 DBEnv_rep_start(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5351 PyObject
*cdata_py
= Py_None
;
5354 static char* kwnames
[] = {"flags","cdata", NULL
};
5356 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,
5357 "i|O:rep_start", kwnames
, &flags
, &cdata_py
))
5361 CHECK_ENV_NOT_CLOSED(self
);
5363 if (!make_dbt(cdata_py
, &cdata
))
5366 MYDB_BEGIN_ALLOW_THREADS
;
5367 err
= self
->db_env
->rep_start(self
->db_env
, cdata
.size
? &cdata
: NULL
,
5369 MYDB_END_ALLOW_THREADS
;
5376 DBEnv_rep_sync(DBEnvObject
* self
)
5380 CHECK_ENV_NOT_CLOSED(self
);
5381 MYDB_BEGIN_ALLOW_THREADS
;
5382 err
= self
->db_env
->rep_sync(self
->db_env
, 0);
5383 MYDB_END_ALLOW_THREADS
;
5392 DBEnv_rep_set_nsites(DBEnvObject
* self
, PyObject
* args
)
5397 if (!PyArg_ParseTuple(args
, "i:rep_set_nsites", &nsites
)) {
5400 CHECK_ENV_NOT_CLOSED(self
);
5401 MYDB_BEGIN_ALLOW_THREADS
;
5402 err
= self
->db_env
->rep_set_nsites(self
->db_env
, nsites
);
5403 MYDB_END_ALLOW_THREADS
;
5409 DBEnv_rep_get_nsites(DBEnvObject
* self
)
5418 CHECK_ENV_NOT_CLOSED(self
);
5419 MYDB_BEGIN_ALLOW_THREADS
;
5420 err
= self
->db_env
->rep_get_nsites(self
->db_env
, &nsites
);
5421 MYDB_END_ALLOW_THREADS
;
5423 return NUMBER_FromLong(nsites
);
5427 DBEnv_rep_set_priority(DBEnvObject
* self
, PyObject
* args
)
5432 if (!PyArg_ParseTuple(args
, "i:rep_set_priority", &priority
)) {
5435 CHECK_ENV_NOT_CLOSED(self
);
5436 MYDB_BEGIN_ALLOW_THREADS
;
5437 err
= self
->db_env
->rep_set_priority(self
->db_env
, priority
);
5438 MYDB_END_ALLOW_THREADS
;
5444 DBEnv_rep_get_priority(DBEnvObject
* self
)
5453 CHECK_ENV_NOT_CLOSED(self
);
5454 MYDB_BEGIN_ALLOW_THREADS
;
5455 err
= self
->db_env
->rep_get_priority(self
->db_env
, &priority
);
5456 MYDB_END_ALLOW_THREADS
;
5458 return NUMBER_FromLong(priority
);
5462 DBEnv_rep_set_timeout(DBEnvObject
* self
, PyObject
* args
)
5467 if (!PyArg_ParseTuple(args
, "ii:rep_set_timeout", &which
, &timeout
)) {
5470 CHECK_ENV_NOT_CLOSED(self
);
5471 MYDB_BEGIN_ALLOW_THREADS
;
5472 err
= self
->db_env
->rep_set_timeout(self
->db_env
, which
, timeout
);
5473 MYDB_END_ALLOW_THREADS
;
5479 DBEnv_rep_get_timeout(DBEnvObject
* self
, PyObject
* args
)
5485 if (!PyArg_ParseTuple(args
, "i:rep_get_timeout", &which
)) {
5488 CHECK_ENV_NOT_CLOSED(self
);
5489 MYDB_BEGIN_ALLOW_THREADS
;
5490 err
= self
->db_env
->rep_get_timeout(self
->db_env
, which
, &timeout
);
5491 MYDB_END_ALLOW_THREADS
;
5493 return NUMBER_FromLong(timeout
);
5497 /* --------------------------------------------------------------------- */
5498 /* REPLICATION METHODS: Replication Manager */
5502 DBEnv_repmgr_start(DBEnvObject
* self
, PyObject
* args
, PyObject
*
5506 int nthreads
, flags
;
5507 static char* kwnames
[] = {"nthreads","flags", NULL
};
5509 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,
5510 "ii:repmgr_start", kwnames
, &nthreads
, &flags
))
5514 CHECK_ENV_NOT_CLOSED(self
);
5515 MYDB_BEGIN_ALLOW_THREADS
;
5516 err
= self
->db_env
->repmgr_start(self
->db_env
, nthreads
, flags
);
5517 MYDB_END_ALLOW_THREADS
;
5523 DBEnv_repmgr_set_local_site(DBEnvObject
* self
, PyObject
* args
, PyObject
*
5530 static char* kwnames
[] = {"host", "port", "flags", NULL
};
5532 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,
5533 "si|i:repmgr_set_local_site", kwnames
, &host
, &port
, &flags
))
5537 CHECK_ENV_NOT_CLOSED(self
);
5538 MYDB_BEGIN_ALLOW_THREADS
;
5539 err
= self
->db_env
->repmgr_set_local_site(self
->db_env
, host
, port
, flags
);
5540 MYDB_END_ALLOW_THREADS
;
5546 DBEnv_repmgr_add_remote_site(DBEnvObject
* self
, PyObject
* args
, PyObject
*
5554 static char* kwnames
[] = {"host", "port", "flags", NULL
};
5556 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,
5557 "si|i:repmgr_add_remote_site", kwnames
, &host
, &port
, &flags
))
5561 CHECK_ENV_NOT_CLOSED(self
);
5562 MYDB_BEGIN_ALLOW_THREADS
;
5563 err
= self
->db_env
->repmgr_add_remote_site(self
->db_env
, host
, port
, &eidp
, flags
);
5564 MYDB_END_ALLOW_THREADS
;
5566 return NUMBER_FromLong(eidp
);
5570 DBEnv_repmgr_set_ack_policy(DBEnvObject
* self
, PyObject
* args
)
5575 if (!PyArg_ParseTuple(args
, "i:repmgr_set_ack_policy", &ack_policy
))
5579 CHECK_ENV_NOT_CLOSED(self
);
5580 MYDB_BEGIN_ALLOW_THREADS
;
5581 err
= self
->db_env
->repmgr_set_ack_policy(self
->db_env
, ack_policy
);
5582 MYDB_END_ALLOW_THREADS
;
5588 DBEnv_repmgr_get_ack_policy(DBEnvObject
* self
)
5593 CHECK_ENV_NOT_CLOSED(self
);
5594 MYDB_BEGIN_ALLOW_THREADS
;
5595 err
= self
->db_env
->repmgr_get_ack_policy(self
->db_env
, &ack_policy
);
5596 MYDB_END_ALLOW_THREADS
;
5598 return NUMBER_FromLong(ack_policy
);
5602 DBEnv_repmgr_site_list(DBEnvObject
* self
)
5605 unsigned int countp
;
5606 DB_REPMGR_SITE
*listp
;
5607 PyObject
*stats
, *key
, *tuple
;
5609 CHECK_ENV_NOT_CLOSED(self
);
5610 MYDB_BEGIN_ALLOW_THREADS
;
5611 err
= self
->db_env
->repmgr_site_list(self
->db_env
, &countp
, &listp
);
5612 MYDB_END_ALLOW_THREADS
;
5616 if (stats
== NULL
) {
5622 key
=NUMBER_FromLong(listp
[countp
].eid
);
5628 #if (PY_VERSION_HEX >= 0x02040000)
5629 tuple
=Py_BuildValue("(sII)", listp
[countp
].host
,
5630 listp
[countp
].port
, listp
[countp
].status
);
5632 tuple
=Py_BuildValue("(sii)", listp
[countp
].host
,
5633 listp
[countp
].port
, listp
[countp
].status
);
5641 if(PyDict_SetItem(stats
, key
, tuple
)) {
5656 DBEnv_repmgr_stat_print(DBEnvObject
* self
, PyObject
* args
, PyObject
*kwargs
)
5660 static char* kwnames
[] = { "flags", NULL
};
5662 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:repmgr_stat_print",
5667 CHECK_ENV_NOT_CLOSED(self
);
5668 MYDB_BEGIN_ALLOW_THREADS
;
5669 err
= self
->db_env
->repmgr_stat_print(self
->db_env
, flags
);
5670 MYDB_END_ALLOW_THREADS
;
5676 DBEnv_repmgr_stat(DBEnvObject
* self
, PyObject
* args
, PyObject
*kwargs
)
5680 DB_REPMGR_STAT
*statp
;
5682 static char* kwnames
[] = { "flags", NULL
};
5684 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:repmgr_stat",
5689 CHECK_ENV_NOT_CLOSED(self
);
5690 MYDB_BEGIN_ALLOW_THREADS
;
5691 err
= self
->db_env
->repmgr_stat(self
->db_env
, &statp
, flags
);
5692 MYDB_END_ALLOW_THREADS
;
5696 if (stats
== NULL
) {
5701 #define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
5703 MAKE_ENTRY(perm_failed
);
5704 MAKE_ENTRY(msgs_queued
);
5705 MAKE_ENTRY(msgs_dropped
);
5706 MAKE_ENTRY(connection_drop
);
5707 MAKE_ENTRY(connect_fail
);
5717 /* --------------------------------------------------------------------- */
5721 static void _close_transaction_cursors(DBTxnObject
* txn
)
5725 while(txn
->children_cursors
) {
5726 PyErr_Warn(PyExc_RuntimeWarning
,
5727 "Must close cursors before resolving a transaction.");
5728 dummy
=DBC_close_internal(txn
->children_cursors
);
5733 static void _promote_transaction_dbs_and_sequences(DBTxnObject
*txn
)
5737 DBSequenceObject
*dbs
;
5740 while (txn
->children_dbs
) {
5741 db
=txn
->children_dbs
;
5742 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(db
);
5743 if (txn
->parent_txn
) {
5744 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn
->parent_txn
->children_dbs
,db
);
5745 db
->txn
=txn
->parent_txn
;
5747 /* The db is already linked to its environment,
5748 ** so nothing to do.
5755 while (txn
->children_sequences
) {
5756 dbs
=txn
->children_sequences
;
5757 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(dbs
);
5758 if (txn
->parent_txn
) {
5759 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn
->parent_txn
->children_sequences
,dbs
);
5760 dbs
->txn
=txn
->parent_txn
;
5762 /* The sequence is already linked to its
5763 ** parent db. Nothing to do.
5773 DBTxn_commit(DBTxnObject
* self
, PyObject
* args
)
5778 if (!PyArg_ParseTuple(args
, "|i:commit", &flags
))
5781 _close_transaction_cursors(self
);
5784 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
5785 "after txn_commit, txn_abort "
5788 PyErr_SetObject(DBError
, t
);
5793 self
->flag_prepare
=0;
5795 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
5797 EXTRACT_FROM_DOUBLE_LINKED_LIST(self
);
5799 MYDB_BEGIN_ALLOW_THREADS
;
5800 err
= txn
->commit(txn
, flags
);
5801 MYDB_END_ALLOW_THREADS
;
5803 _promote_transaction_dbs_and_sequences(self
);
5810 DBTxn_prepare(DBTxnObject
* self
, PyObject
* args
)
5816 if (!PyArg_ParseTuple(args
, "s#:prepare", &gid
, &gid_size
))
5819 if (gid_size
!= DB_XIDDATASIZE
) {
5820 PyErr_SetString(PyExc_TypeError
,
5821 "gid must be DB_XIDDATASIZE bytes long");
5826 PyObject
*t
= Py_BuildValue("(is)", 0,"DBTxn must not be used "
5827 "after txn_commit, txn_abort "
5830 PyErr_SetObject(DBError
, t
);
5835 self
->flag_prepare
=1; /* Prepare state */
5836 MYDB_BEGIN_ALLOW_THREADS
;
5837 err
= self
->txn
->prepare(self
->txn
, (u_int8_t
*)gid
);
5838 MYDB_END_ALLOW_THREADS
;
5845 DBTxn_abort_discard_internal(DBTxnObject
* self
, int discard
)
5852 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
5853 "after txn_commit, txn_abort "
5856 PyErr_SetObject(DBError
, t
);
5862 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
5864 _close_transaction_cursors(self
);
5866 while (self
->children_sequences
) {
5867 dummy
=DBSequence_close_internal(self
->children_sequences
,0,0);
5871 while (self
->children_dbs
) {
5872 dummy
=DB_close_internal(self
->children_dbs
,0);
5876 EXTRACT_FROM_DOUBLE_LINKED_LIST(self
);
5878 MYDB_BEGIN_ALLOW_THREADS
;
5880 assert(!self
->flag_prepare
);
5881 err
= txn
->discard(txn
,0);
5884 ** If the transaction is in the "prepare" or "recover" state,
5885 ** we better do not implicitly abort it.
5887 if (!self
->flag_prepare
) {
5888 err
= txn
->abort(txn
);
5891 MYDB_END_ALLOW_THREADS
;
5897 DBTxn_abort(DBTxnObject
* self
)
5899 self
->flag_prepare
=0;
5900 _close_transaction_cursors(self
);
5902 return DBTxn_abort_discard_internal(self
,0);
5906 DBTxn_discard(DBTxnObject
* self
)
5908 self
->flag_prepare
=0;
5909 _close_transaction_cursors(self
);
5911 return DBTxn_abort_discard_internal(self
,1);
5916 DBTxn_id(DBTxnObject
* self
)
5921 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
5922 "after txn_commit, txn_abort "
5925 PyErr_SetObject(DBError
, t
);
5930 MYDB_BEGIN_ALLOW_THREADS
;
5931 id
= self
->txn
->id(self
->txn
);
5932 MYDB_END_ALLOW_THREADS
;
5933 return NUMBER_FromLong(id
);
5937 /* --------------------------------------------------------------------- */
5938 /* DBSequence methods */
5942 DBSequence_close_internal(DBSequenceObject
* self
, int flags
, int do_not_close
)
5946 if (self
->sequence
!=NULL
) {
5947 EXTRACT_FROM_DOUBLE_LINKED_LIST(self
);
5949 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self
);
5953 if (!do_not_close
) {
5954 MYDB_BEGIN_ALLOW_THREADS
5955 err
= self
->sequence
->close(self
->sequence
, flags
);
5956 MYDB_END_ALLOW_THREADS
5958 self
->sequence
= NULL
;
5967 DBSequence_close(DBSequenceObject
* self
, PyObject
* args
)
5970 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
5973 return DBSequence_close_internal(self
,flags
,0);
5977 DBSequence_get(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5982 PyObject
*txnobj
= NULL
;
5984 static char* kwnames
[] = {"delta", "txn", "flags", NULL
};
5985 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iOi:get", kwnames
, &delta
, &txnobj
, &flags
))
5987 CHECK_SEQUENCE_NOT_CLOSED(self
)
5989 if (!checkTxnObj(txnobj
, &txn
))
5992 MYDB_BEGIN_ALLOW_THREADS
5993 err
= self
->sequence
->get(self
->sequence
, txn
, delta
, &value
, flags
);
5994 MYDB_END_ALLOW_THREADS
5997 return PyLong_FromLongLong(value
);
6001 DBSequence_get_dbp(DBSequenceObject
* self
)
6003 CHECK_SEQUENCE_NOT_CLOSED(self
)
6004 Py_INCREF(self
->mydb
);
6005 return (PyObject
* )self
->mydb
;
6009 DBSequence_get_key(DBSequenceObject
* self
)
6013 PyObject
*retval
= NULL
;
6015 key
.flags
= DB_DBT_MALLOC
;
6016 CHECK_SEQUENCE_NOT_CLOSED(self
)
6017 MYDB_BEGIN_ALLOW_THREADS
6018 err
= self
->sequence
->get_key(self
->sequence
, &key
);
6019 MYDB_END_ALLOW_THREADS
6022 retval
= Build_PyString(key
.data
, key
.size
);
6031 DBSequence_init_value(DBSequenceObject
* self
, PyObject
* args
)
6036 if (!PyArg_ParseTuple(args
,"L:init_value", &value
))
6038 CHECK_SEQUENCE_NOT_CLOSED(self
)
6040 value2
=value
; /* If truncation, compiler should show a warning */
6041 MYDB_BEGIN_ALLOW_THREADS
6042 err
= self
->sequence
->initial_value(self
->sequence
, value2
);
6043 MYDB_END_ALLOW_THREADS
6051 DBSequence_open(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
6055 PyObject
*txnobj
= NULL
;
6059 static char* kwnames
[] = {"key", "txn", "flags", NULL
};
6060 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:open", kwnames
, &keyobj
, &txnobj
, &flags
))
6063 if (!checkTxnObj(txnobj
, &txn
))
6066 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
6069 MYDB_BEGIN_ALLOW_THREADS
6070 err
= self
->sequence
->open(self
->sequence
, txn
, &key
, flags
);
6071 MYDB_END_ALLOW_THREADS
6077 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject
*)txnobj
)->children_sequences
,self
);
6078 self
->txn
=(DBTxnObject
*)txnobj
;
6085 DBSequence_remove(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
6089 PyObject
*txnobj
= NULL
;
6092 static char* kwnames
[] = {"txn", "flags", NULL
};
6093 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:remove", kwnames
, &txnobj
, &flags
))
6096 if (!checkTxnObj(txnobj
, &txn
))
6099 CHECK_SEQUENCE_NOT_CLOSED(self
)
6101 MYDB_BEGIN_ALLOW_THREADS
6102 err
= self
->sequence
->remove(self
->sequence
, txn
, flags
);
6103 MYDB_END_ALLOW_THREADS
6105 dummy
=DBSequence_close_internal(self
,flags
,1);
6113 DBSequence_set_cachesize(DBSequenceObject
* self
, PyObject
* args
)
6116 if (!PyArg_ParseTuple(args
,"i:set_cachesize", &size
))
6118 CHECK_SEQUENCE_NOT_CLOSED(self
)
6120 MYDB_BEGIN_ALLOW_THREADS
6121 err
= self
->sequence
->set_cachesize(self
->sequence
, size
);
6122 MYDB_END_ALLOW_THREADS
6129 DBSequence_get_cachesize(DBSequenceObject
* self
)
6133 CHECK_SEQUENCE_NOT_CLOSED(self
)
6135 MYDB_BEGIN_ALLOW_THREADS
6136 err
= self
->sequence
->get_cachesize(self
->sequence
, &size
);
6137 MYDB_END_ALLOW_THREADS
6140 return NUMBER_FromLong(size
);
6144 DBSequence_set_flags(DBSequenceObject
* self
, PyObject
* args
)
6147 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
6149 CHECK_SEQUENCE_NOT_CLOSED(self
)
6151 MYDB_BEGIN_ALLOW_THREADS
6152 err
= self
->sequence
->set_flags(self
->sequence
, flags
);
6153 MYDB_END_ALLOW_THREADS
6160 DBSequence_get_flags(DBSequenceObject
* self
)
6165 CHECK_SEQUENCE_NOT_CLOSED(self
)
6167 MYDB_BEGIN_ALLOW_THREADS
6168 err
= self
->sequence
->get_flags(self
->sequence
, &flags
);
6169 MYDB_END_ALLOW_THREADS
6172 return NUMBER_FromLong((int)flags
);
6176 DBSequence_set_range(DBSequenceObject
* self
, PyObject
* args
)
6179 PY_LONG_LONG min
, max
;
6180 db_seq_t min2
, max2
;
6181 if (!PyArg_ParseTuple(args
,"(LL):set_range", &min
, &max
))
6183 CHECK_SEQUENCE_NOT_CLOSED(self
)
6185 min2
=min
; /* If truncation, compiler should show a warning */
6187 MYDB_BEGIN_ALLOW_THREADS
6188 err
= self
->sequence
->set_range(self
->sequence
, min2
, max2
);
6189 MYDB_END_ALLOW_THREADS
6196 DBSequence_get_range(DBSequenceObject
* self
)
6199 PY_LONG_LONG min
, max
;
6200 db_seq_t min2
, max2
;
6202 CHECK_SEQUENCE_NOT_CLOSED(self
)
6204 MYDB_BEGIN_ALLOW_THREADS
6205 err
= self
->sequence
->get_range(self
->sequence
, &min2
, &max2
);
6206 MYDB_END_ALLOW_THREADS
6209 min
=min2
; /* If truncation, compiler should show a warning */
6211 return Py_BuildValue("(LL)", min
, max
);
6215 DBSequence_stat(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
6218 DB_SEQUENCE_STAT
* sp
= NULL
;
6219 PyObject
* dict_stat
;
6220 static char* kwnames
[] = {"flags", NULL
};
6221 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat", kwnames
, &flags
))
6223 CHECK_SEQUENCE_NOT_CLOSED(self
);
6225 MYDB_BEGIN_ALLOW_THREADS
;
6226 err
= self
->sequence
->stat(self
->sequence
, &sp
, flags
);
6227 MYDB_END_ALLOW_THREADS
;
6230 if ((dict_stat
= PyDict_New()) == NULL
) {
6236 #define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name)
6237 #define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
6239 MAKE_INT_ENTRY(wait
);
6240 MAKE_INT_ENTRY(nowait
);
6241 MAKE_LONG_LONG_ENTRY(current
);
6242 MAKE_LONG_LONG_ENTRY(value
);
6243 MAKE_LONG_LONG_ENTRY(last_value
);
6244 MAKE_LONG_LONG_ENTRY(min
);
6245 MAKE_LONG_LONG_ENTRY(max
);
6246 MAKE_INT_ENTRY(cache_size
);
6247 MAKE_INT_ENTRY(flags
);
6249 #undef MAKE_INT_ENTRY
6250 #undef MAKE_LONG_LONG_ENTRY
6258 /* --------------------------------------------------------------------- */
6259 /* Method definition tables and type objects */
6261 static PyMethodDef DB_methods
[] = {
6262 {"append", (PyCFunction
)DB_append
, METH_VARARGS
},
6263 {"associate", (PyCFunction
)DB_associate
, METH_VARARGS
|METH_KEYWORDS
},
6264 {"close", (PyCFunction
)DB_close
, METH_VARARGS
},
6265 {"consume", (PyCFunction
)DB_consume
, METH_VARARGS
|METH_KEYWORDS
},
6266 {"consume_wait", (PyCFunction
)DB_consume_wait
, METH_VARARGS
|METH_KEYWORDS
},
6267 {"cursor", (PyCFunction
)DB_cursor
, METH_VARARGS
|METH_KEYWORDS
},
6268 {"delete", (PyCFunction
)DB_delete
, METH_VARARGS
|METH_KEYWORDS
},
6269 {"fd", (PyCFunction
)DB_fd
, METH_NOARGS
},
6270 {"get", (PyCFunction
)DB_get
, METH_VARARGS
|METH_KEYWORDS
},
6271 {"pget", (PyCFunction
)DB_pget
, METH_VARARGS
|METH_KEYWORDS
},
6272 {"get_both", (PyCFunction
)DB_get_both
, METH_VARARGS
|METH_KEYWORDS
},
6273 {"get_byteswapped", (PyCFunction
)DB_get_byteswapped
,METH_NOARGS
},
6274 {"get_size", (PyCFunction
)DB_get_size
, METH_VARARGS
|METH_KEYWORDS
},
6275 {"get_type", (PyCFunction
)DB_get_type
, METH_NOARGS
},
6276 {"join", (PyCFunction
)DB_join
, METH_VARARGS
},
6277 {"key_range", (PyCFunction
)DB_key_range
, METH_VARARGS
|METH_KEYWORDS
},
6278 {"has_key", (PyCFunction
)DB_has_key
, METH_VARARGS
},
6279 {"items", (PyCFunction
)DB_items
, METH_VARARGS
},
6280 {"keys", (PyCFunction
)DB_keys
, METH_VARARGS
},
6281 {"open", (PyCFunction
)DB_open
, METH_VARARGS
|METH_KEYWORDS
},
6282 {"put", (PyCFunction
)DB_put
, METH_VARARGS
|METH_KEYWORDS
},
6283 {"remove", (PyCFunction
)DB_remove
, METH_VARARGS
|METH_KEYWORDS
},
6284 {"rename", (PyCFunction
)DB_rename
, METH_VARARGS
},
6285 {"set_bt_minkey", (PyCFunction
)DB_set_bt_minkey
, METH_VARARGS
},
6286 {"set_bt_compare", (PyCFunction
)DB_set_bt_compare
, METH_O
},
6287 {"set_cachesize", (PyCFunction
)DB_set_cachesize
, METH_VARARGS
},
6289 {"set_encrypt", (PyCFunction
)DB_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
6291 {"set_flags", (PyCFunction
)DB_set_flags
, METH_VARARGS
},
6292 {"set_h_ffactor", (PyCFunction
)DB_set_h_ffactor
, METH_VARARGS
},
6293 {"set_h_nelem", (PyCFunction
)DB_set_h_nelem
, METH_VARARGS
},
6294 {"set_lorder", (PyCFunction
)DB_set_lorder
, METH_VARARGS
},
6295 {"set_pagesize", (PyCFunction
)DB_set_pagesize
, METH_VARARGS
},
6296 {"set_re_delim", (PyCFunction
)DB_set_re_delim
, METH_VARARGS
},
6297 {"set_re_len", (PyCFunction
)DB_set_re_len
, METH_VARARGS
},
6298 {"set_re_pad", (PyCFunction
)DB_set_re_pad
, METH_VARARGS
},
6299 {"set_re_source", (PyCFunction
)DB_set_re_source
, METH_VARARGS
},
6300 {"set_q_extentsize",(PyCFunction
)DB_set_q_extentsize
, METH_VARARGS
},
6301 {"set_private", (PyCFunction
)DB_set_private
, METH_O
},
6302 {"get_private", (PyCFunction
)DB_get_private
, METH_NOARGS
},
6303 {"stat", (PyCFunction
)DB_stat
, METH_VARARGS
|METH_KEYWORDS
},
6304 {"sync", (PyCFunction
)DB_sync
, METH_VARARGS
},
6305 {"truncate", (PyCFunction
)DB_truncate
, METH_VARARGS
|METH_KEYWORDS
},
6306 {"type", (PyCFunction
)DB_get_type
, METH_NOARGS
},
6307 {"upgrade", (PyCFunction
)DB_upgrade
, METH_VARARGS
},
6308 {"values", (PyCFunction
)DB_values
, METH_VARARGS
},
6309 {"verify", (PyCFunction
)DB_verify
, METH_VARARGS
|METH_KEYWORDS
},
6310 {"set_get_returns_none",(PyCFunction
)DB_set_get_returns_none
, METH_VARARGS
},
6311 {NULL
, NULL
} /* sentinel */
6315 static PyMappingMethods DB_mapping
= {
6316 DB_length
, /*mp_length*/
6317 (binaryfunc
)DB_subscript
, /*mp_subscript*/
6318 (objobjargproc
)DB_ass_sub
, /*mp_ass_subscript*/
6322 static PyMethodDef DBCursor_methods
[] = {
6323 {"close", (PyCFunction
)DBC_close
, METH_NOARGS
},
6324 {"count", (PyCFunction
)DBC_count
, METH_VARARGS
},
6325 {"current", (PyCFunction
)DBC_current
, METH_VARARGS
|METH_KEYWORDS
},
6326 {"delete", (PyCFunction
)DBC_delete
, METH_VARARGS
},
6327 {"dup", (PyCFunction
)DBC_dup
, METH_VARARGS
},
6328 {"first", (PyCFunction
)DBC_first
, METH_VARARGS
|METH_KEYWORDS
},
6329 {"get", (PyCFunction
)DBC_get
, METH_VARARGS
|METH_KEYWORDS
},
6330 {"pget", (PyCFunction
)DBC_pget
, METH_VARARGS
|METH_KEYWORDS
},
6331 {"get_recno", (PyCFunction
)DBC_get_recno
, METH_NOARGS
},
6332 {"last", (PyCFunction
)DBC_last
, METH_VARARGS
|METH_KEYWORDS
},
6333 {"next", (PyCFunction
)DBC_next
, METH_VARARGS
|METH_KEYWORDS
},
6334 {"prev", (PyCFunction
)DBC_prev
, METH_VARARGS
|METH_KEYWORDS
},
6335 {"put", (PyCFunction
)DBC_put
, METH_VARARGS
|METH_KEYWORDS
},
6336 {"set", (PyCFunction
)DBC_set
, METH_VARARGS
|METH_KEYWORDS
},
6337 {"set_range", (PyCFunction
)DBC_set_range
, METH_VARARGS
|METH_KEYWORDS
},
6338 {"get_both", (PyCFunction
)DBC_get_both
, METH_VARARGS
},
6339 {"get_current_size",(PyCFunction
)DBC_get_current_size
, METH_NOARGS
},
6340 {"set_both", (PyCFunction
)DBC_set_both
, METH_VARARGS
},
6341 {"set_recno", (PyCFunction
)DBC_set_recno
, METH_VARARGS
|METH_KEYWORDS
},
6342 {"consume", (PyCFunction
)DBC_consume
, METH_VARARGS
|METH_KEYWORDS
},
6343 {"next_dup", (PyCFunction
)DBC_next_dup
, METH_VARARGS
|METH_KEYWORDS
},
6344 {"next_nodup", (PyCFunction
)DBC_next_nodup
, METH_VARARGS
|METH_KEYWORDS
},
6345 {"prev_nodup", (PyCFunction
)DBC_prev_nodup
, METH_VARARGS
|METH_KEYWORDS
},
6346 {"join_item", (PyCFunction
)DBC_join_item
, METH_VARARGS
},
6347 {NULL
, NULL
} /* sentinel */
6351 static PyMethodDef DBEnv_methods
[] = {
6352 {"close", (PyCFunction
)DBEnv_close
, METH_VARARGS
},
6353 {"open", (PyCFunction
)DBEnv_open
, METH_VARARGS
},
6354 {"remove", (PyCFunction
)DBEnv_remove
, METH_VARARGS
},
6356 {"dbremove", (PyCFunction
)DBEnv_dbremove
, METH_VARARGS
|METH_KEYWORDS
},
6357 {"dbrename", (PyCFunction
)DBEnv_dbrename
, METH_VARARGS
|METH_KEYWORDS
},
6358 {"set_encrypt", (PyCFunction
)DBEnv_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
6360 {"set_timeout", (PyCFunction
)DBEnv_set_timeout
, METH_VARARGS
|METH_KEYWORDS
},
6361 {"set_shm_key", (PyCFunction
)DBEnv_set_shm_key
, METH_VARARGS
},
6362 {"set_cachesize", (PyCFunction
)DBEnv_set_cachesize
, METH_VARARGS
},
6363 {"set_data_dir", (PyCFunction
)DBEnv_set_data_dir
, METH_VARARGS
},
6364 {"set_flags", (PyCFunction
)DBEnv_set_flags
, METH_VARARGS
},
6366 {"log_set_config", (PyCFunction
)DBEnv_log_set_config
, METH_VARARGS
},
6368 {"set_lg_bsize", (PyCFunction
)DBEnv_set_lg_bsize
, METH_VARARGS
},
6369 {"set_lg_dir", (PyCFunction
)DBEnv_set_lg_dir
, METH_VARARGS
},
6370 {"set_lg_max", (PyCFunction
)DBEnv_set_lg_max
, METH_VARARGS
},
6372 {"get_lg_max", (PyCFunction
)DBEnv_get_lg_max
, METH_NOARGS
},
6374 {"set_lg_regionmax",(PyCFunction
)DBEnv_set_lg_regionmax
, METH_VARARGS
},
6375 {"set_lk_detect", (PyCFunction
)DBEnv_set_lk_detect
, METH_VARARGS
},
6377 {"set_lk_max", (PyCFunction
)DBEnv_set_lk_max
, METH_VARARGS
},
6379 {"set_lk_max_locks", (PyCFunction
)DBEnv_set_lk_max_locks
, METH_VARARGS
},
6380 {"set_lk_max_lockers", (PyCFunction
)DBEnv_set_lk_max_lockers
, METH_VARARGS
},
6381 {"set_lk_max_objects", (PyCFunction
)DBEnv_set_lk_max_objects
, METH_VARARGS
},
6382 {"set_mp_mmapsize", (PyCFunction
)DBEnv_set_mp_mmapsize
, METH_VARARGS
},
6383 {"set_tmp_dir", (PyCFunction
)DBEnv_set_tmp_dir
, METH_VARARGS
},
6384 {"txn_begin", (PyCFunction
)DBEnv_txn_begin
, METH_VARARGS
|METH_KEYWORDS
},
6385 {"txn_checkpoint", (PyCFunction
)DBEnv_txn_checkpoint
, METH_VARARGS
},
6386 {"txn_stat", (PyCFunction
)DBEnv_txn_stat
, METH_VARARGS
},
6387 {"set_tx_max", (PyCFunction
)DBEnv_set_tx_max
, METH_VARARGS
},
6388 {"set_tx_timestamp", (PyCFunction
)DBEnv_set_tx_timestamp
, METH_VARARGS
},
6389 {"lock_detect", (PyCFunction
)DBEnv_lock_detect
, METH_VARARGS
},
6390 {"lock_get", (PyCFunction
)DBEnv_lock_get
, METH_VARARGS
},
6391 {"lock_id", (PyCFunction
)DBEnv_lock_id
, METH_NOARGS
},
6392 {"lock_id_free", (PyCFunction
)DBEnv_lock_id_free
, METH_VARARGS
},
6393 {"lock_put", (PyCFunction
)DBEnv_lock_put
, METH_VARARGS
},
6394 {"lock_stat", (PyCFunction
)DBEnv_lock_stat
, METH_VARARGS
},
6395 {"log_archive", (PyCFunction
)DBEnv_log_archive
, METH_VARARGS
},
6396 {"log_flush", (PyCFunction
)DBEnv_log_flush
, METH_NOARGS
},
6397 {"log_stat", (PyCFunction
)DBEnv_log_stat
, METH_VARARGS
},
6399 {"lsn_reset", (PyCFunction
)DBEnv_lsn_reset
, METH_VARARGS
|METH_KEYWORDS
},
6401 {"set_get_returns_none",(PyCFunction
)DBEnv_set_get_returns_none
, METH_VARARGS
},
6402 {"txn_recover", (PyCFunction
)DBEnv_txn_recover
, METH_NOARGS
},
6403 {"set_rpc_server", (PyCFunction
)DBEnv_set_rpc_server
,
6404 METH_VARARGS
||METH_KEYWORDS
},
6405 {"set_verbose", (PyCFunction
)DBEnv_set_verbose
, METH_VARARGS
},
6407 {"get_verbose", (PyCFunction
)DBEnv_get_verbose
, METH_VARARGS
},
6409 {"set_private", (PyCFunction
)DBEnv_set_private
, METH_O
},
6410 {"get_private", (PyCFunction
)DBEnv_get_private
, METH_NOARGS
},
6411 {"rep_start", (PyCFunction
)DBEnv_rep_start
,
6412 METH_VARARGS
|METH_KEYWORDS
},
6413 {"rep_set_transport", (PyCFunction
)DBEnv_rep_set_transport
, METH_VARARGS
},
6414 {"rep_process_message", (PyCFunction
)DBEnv_rep_process_message
,
6417 {"rep_elect", (PyCFunction
)DBEnv_rep_elect
, METH_VARARGS
},
6420 {"rep_set_config", (PyCFunction
)DBEnv_rep_set_config
, METH_VARARGS
},
6421 {"rep_get_config", (PyCFunction
)DBEnv_rep_get_config
, METH_VARARGS
},
6422 {"rep_sync", (PyCFunction
)DBEnv_rep_sync
, METH_NOARGS
},
6425 {"rep_set_limit", (PyCFunction
)DBEnv_rep_set_limit
, METH_VARARGS
},
6426 {"rep_get_limit", (PyCFunction
)DBEnv_rep_get_limit
, METH_NOARGS
},
6429 {"rep_set_request", (PyCFunction
)DBEnv_rep_set_request
, METH_VARARGS
},
6430 {"rep_get_request", (PyCFunction
)DBEnv_rep_get_request
, METH_NOARGS
},
6433 {"set_event_notify", (PyCFunction
)DBEnv_set_event_notify
, METH_O
},
6436 {"rep_set_nsites", (PyCFunction
)DBEnv_rep_set_nsites
, METH_VARARGS
},
6437 {"rep_get_nsites", (PyCFunction
)DBEnv_rep_get_nsites
, METH_NOARGS
},
6438 {"rep_set_priority", (PyCFunction
)DBEnv_rep_set_priority
, METH_VARARGS
},
6439 {"rep_get_priority", (PyCFunction
)DBEnv_rep_get_priority
, METH_NOARGS
},
6440 {"rep_set_timeout", (PyCFunction
)DBEnv_rep_set_timeout
, METH_VARARGS
},
6441 {"rep_get_timeout", (PyCFunction
)DBEnv_rep_get_timeout
, METH_VARARGS
},
6444 {"repmgr_start", (PyCFunction
)DBEnv_repmgr_start
,
6445 METH_VARARGS
|METH_KEYWORDS
},
6446 {"repmgr_set_local_site", (PyCFunction
)DBEnv_repmgr_set_local_site
,
6447 METH_VARARGS
|METH_KEYWORDS
},
6448 {"repmgr_add_remote_site", (PyCFunction
)DBEnv_repmgr_add_remote_site
,
6449 METH_VARARGS
|METH_KEYWORDS
},
6450 {"repmgr_set_ack_policy", (PyCFunction
)DBEnv_repmgr_set_ack_policy
,
6452 {"repmgr_get_ack_policy", (PyCFunction
)DBEnv_repmgr_get_ack_policy
,
6454 {"repmgr_site_list", (PyCFunction
)DBEnv_repmgr_site_list
,
6458 {"repmgr_stat", (PyCFunction
)DBEnv_repmgr_stat
,
6459 METH_VARARGS
|METH_KEYWORDS
},
6460 {"repmgr_stat_print", (PyCFunction
)DBEnv_repmgr_stat_print
,
6461 METH_VARARGS
|METH_KEYWORDS
},
6463 {NULL
, NULL
} /* sentinel */
6467 static PyMethodDef DBTxn_methods
[] = {
6468 {"commit", (PyCFunction
)DBTxn_commit
, METH_VARARGS
},
6469 {"prepare", (PyCFunction
)DBTxn_prepare
, METH_VARARGS
},
6470 {"discard", (PyCFunction
)DBTxn_discard
, METH_NOARGS
},
6471 {"abort", (PyCFunction
)DBTxn_abort
, METH_NOARGS
},
6472 {"id", (PyCFunction
)DBTxn_id
, METH_NOARGS
},
6473 {NULL
, NULL
} /* sentinel */
6478 static PyMethodDef DBSequence_methods
[] = {
6479 {"close", (PyCFunction
)DBSequence_close
, METH_VARARGS
},
6480 {"get", (PyCFunction
)DBSequence_get
, METH_VARARGS
|METH_KEYWORDS
},
6481 {"get_dbp", (PyCFunction
)DBSequence_get_dbp
, METH_NOARGS
},
6482 {"get_key", (PyCFunction
)DBSequence_get_key
, METH_NOARGS
},
6483 {"init_value", (PyCFunction
)DBSequence_init_value
, METH_VARARGS
},
6484 {"open", (PyCFunction
)DBSequence_open
, METH_VARARGS
|METH_KEYWORDS
},
6485 {"remove", (PyCFunction
)DBSequence_remove
, METH_VARARGS
|METH_KEYWORDS
},
6486 {"set_cachesize", (PyCFunction
)DBSequence_set_cachesize
, METH_VARARGS
},
6487 {"get_cachesize", (PyCFunction
)DBSequence_get_cachesize
, METH_NOARGS
},
6488 {"set_flags", (PyCFunction
)DBSequence_set_flags
, METH_VARARGS
},
6489 {"get_flags", (PyCFunction
)DBSequence_get_flags
, METH_NOARGS
},
6490 {"set_range", (PyCFunction
)DBSequence_set_range
, METH_VARARGS
},
6491 {"get_range", (PyCFunction
)DBSequence_get_range
, METH_NOARGS
},
6492 {"stat", (PyCFunction
)DBSequence_stat
, METH_VARARGS
|METH_KEYWORDS
},
6493 {NULL
, NULL
} /* sentinel */
6499 DBEnv_db_home_get(DBEnvObject
* self
)
6501 const char *home
= NULL
;
6503 CHECK_ENV_NOT_CLOSED(self
);
6506 self
->db_env
->get_home(self
->db_env
, &home
);
6508 home
=self
->db_env
->db_home
;
6514 return PyBytes_FromString(home
);
6517 static PyGetSetDef DBEnv_getsets
[] = {
6518 {"db_home", (getter
)DBEnv_db_home_get
, NULL
,},
6523 statichere PyTypeObject DB_Type
= {
6524 #if (PY_VERSION_HEX < 0x03000000)
6525 PyObject_HEAD_INIT(NULL
)
6528 PyVarObject_HEAD_INIT(NULL
, 0)
6531 sizeof(DBObject
), /*tp_basicsize*/
6534 (destructor
)DB_dealloc
, /*tp_dealloc*/
6541 0, /*tp_as_sequence*/
6542 &DB_mapping
,/*tp_as_mapping*/
6546 0, /* tp_getattro */
6547 0, /* tp_setattro */
6548 0, /* tp_as_buffer */
6549 #if (PY_VERSION_HEX < 0x03000000)
6550 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
6552 Py_TPFLAGS_DEFAULT
, /* tp_flags */
6555 0, /* tp_traverse */
6557 0, /* tp_richcompare */
6558 offsetof(DBObject
, in_weakreflist
), /* tp_weaklistoffset */
6561 DB_methods
, /*tp_methods*/
6566 statichere PyTypeObject DBCursor_Type
= {
6567 #if (PY_VERSION_HEX < 0x03000000)
6568 PyObject_HEAD_INIT(NULL
)
6571 PyVarObject_HEAD_INIT(NULL
, 0)
6573 "DBCursor", /*tp_name*/
6574 sizeof(DBCursorObject
), /*tp_basicsize*/
6577 (destructor
)DBCursor_dealloc
,/*tp_dealloc*/
6584 0, /*tp_as_sequence*/
6585 0, /*tp_as_mapping*/
6592 #if (PY_VERSION_HEX < 0x03000000)
6593 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
6595 Py_TPFLAGS_DEFAULT
, /* tp_flags */
6598 0, /* tp_traverse */
6600 0, /* tp_richcompare */
6601 offsetof(DBCursorObject
, in_weakreflist
), /* tp_weaklistoffset */
6604 DBCursor_methods
, /*tp_methods*/
6609 statichere PyTypeObject DBEnv_Type
= {
6610 #if (PY_VERSION_HEX < 0x03000000)
6611 PyObject_HEAD_INIT(NULL
)
6614 PyVarObject_HEAD_INIT(NULL
, 0)
6616 "DBEnv", /*tp_name*/
6617 sizeof(DBEnvObject
), /*tp_basicsize*/
6620 (destructor
)DBEnv_dealloc
, /*tp_dealloc*/
6627 0, /*tp_as_sequence*/
6628 0, /*tp_as_mapping*/
6632 0, /* tp_getattro */
6633 0, /* tp_setattro */
6634 0, /* tp_as_buffer */
6635 #if (PY_VERSION_HEX < 0x03000000)
6636 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
6638 Py_TPFLAGS_DEFAULT
, /* tp_flags */
6641 0, /* tp_traverse */
6643 0, /* tp_richcompare */
6644 offsetof(DBEnvObject
, in_weakreflist
), /* tp_weaklistoffset */
6646 0, /* tp_iternext */
6647 DBEnv_methods
, /* tp_methods */
6649 DBEnv_getsets
, /* tp_getsets */
6652 statichere PyTypeObject DBTxn_Type
= {
6653 #if (PY_VERSION_HEX < 0x03000000)
6654 PyObject_HEAD_INIT(NULL
)
6657 PyVarObject_HEAD_INIT(NULL
, 0)
6659 "DBTxn", /*tp_name*/
6660 sizeof(DBTxnObject
), /*tp_basicsize*/
6663 (destructor
)DBTxn_dealloc
, /*tp_dealloc*/
6670 0, /*tp_as_sequence*/
6671 0, /*tp_as_mapping*/
6675 0, /* tp_getattro */
6676 0, /* tp_setattro */
6677 0, /* tp_as_buffer */
6678 #if (PY_VERSION_HEX < 0x03000000)
6679 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
6681 Py_TPFLAGS_DEFAULT
, /* tp_flags */
6684 0, /* tp_traverse */
6686 0, /* tp_richcompare */
6687 offsetof(DBTxnObject
, in_weakreflist
), /* tp_weaklistoffset */
6690 DBTxn_methods
, /*tp_methods*/
6695 statichere PyTypeObject DBLock_Type
= {
6696 #if (PY_VERSION_HEX < 0x03000000)
6697 PyObject_HEAD_INIT(NULL
)
6700 PyVarObject_HEAD_INIT(NULL
, 0)
6702 "DBLock", /*tp_name*/
6703 sizeof(DBLockObject
), /*tp_basicsize*/
6706 (destructor
)DBLock_dealloc
, /*tp_dealloc*/
6713 0, /*tp_as_sequence*/
6714 0, /*tp_as_mapping*/
6718 0, /* tp_getattro */
6719 0, /* tp_setattro */
6720 0, /* tp_as_buffer */
6721 #if (PY_VERSION_HEX < 0x03000000)
6722 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
6724 Py_TPFLAGS_DEFAULT
, /* tp_flags */
6727 0, /* tp_traverse */
6729 0, /* tp_richcompare */
6730 offsetof(DBLockObject
, in_weakreflist
), /* tp_weaklistoffset */
6734 statichere PyTypeObject DBSequence_Type
= {
6735 #if (PY_VERSION_HEX < 0x03000000)
6736 PyObject_HEAD_INIT(NULL
)
6739 PyVarObject_HEAD_INIT(NULL
, 0)
6741 "DBSequence", /*tp_name*/
6742 sizeof(DBSequenceObject
), /*tp_basicsize*/
6745 (destructor
)DBSequence_dealloc
, /*tp_dealloc*/
6752 0, /*tp_as_sequence*/
6753 0, /*tp_as_mapping*/
6757 0, /* tp_getattro */
6758 0, /* tp_setattro */
6759 0, /* tp_as_buffer */
6760 #if (PY_VERSION_HEX < 0x03000000)
6761 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
6763 Py_TPFLAGS_DEFAULT
, /* tp_flags */
6766 0, /* tp_traverse */
6768 0, /* tp_richcompare */
6769 offsetof(DBSequenceObject
, in_weakreflist
), /* tp_weaklistoffset */
6772 DBSequence_methods
, /*tp_methods*/
6777 /* --------------------------------------------------------------------- */
6778 /* Module-level functions */
6781 DB_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
6783 PyObject
* dbenvobj
= NULL
;
6785 static char* kwnames
[] = { "dbEnv", "flags", NULL
};
6787 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:DB", kwnames
,
6790 if (dbenvobj
== Py_None
)
6792 else if (dbenvobj
&& !DBEnvObject_Check(dbenvobj
)) {
6793 makeTypeError("DBEnv", dbenvobj
);
6797 return (PyObject
* )newDBObject((DBEnvObject
*)dbenvobj
, flags
);
6802 DBEnv_construct(PyObject
* self
, PyObject
* args
)
6805 if (!PyArg_ParseTuple(args
, "|i:DbEnv", &flags
)) return NULL
;
6806 return (PyObject
* )newDBEnvObject(flags
);
6811 DBSequence_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
6815 static char* kwnames
[] = { "db", "flags", NULL
};
6817 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|i:DBSequence", kwnames
, &dbobj
, &flags
))
6819 if (!DBObject_Check(dbobj
)) {
6820 makeTypeError("DB", dbobj
);
6823 return (PyObject
* )newDBSequenceObject((DBObject
*)dbobj
, flags
);
6827 static char bsddb_version_doc
[] =
6828 "Returns a tuple of major, minor, and patch release numbers of the\n\
6829 underlying DB library.";
6832 bsddb_version(PyObject
* self
)
6834 int major
, minor
, patch
;
6836 db_version(&major
, &minor
, &patch
);
6837 return Py_BuildValue("(iii)", major
, minor
, patch
);
6841 /* List of functions defined in the module */
6842 static PyMethodDef bsddb_methods
[] = {
6843 {"DB", (PyCFunction
)DB_construct
, METH_VARARGS
| METH_KEYWORDS
},
6844 {"DBEnv", (PyCFunction
)DBEnv_construct
, METH_VARARGS
},
6846 {"DBSequence", (PyCFunction
)DBSequence_construct
, METH_VARARGS
| METH_KEYWORDS
},
6848 {"version", (PyCFunction
)bsddb_version
, METH_NOARGS
, bsddb_version_doc
},
6849 {NULL
, NULL
} /* sentinel */
6854 static BSDDB_api bsddb_api
;
6857 /* --------------------------------------------------------------------- */
6858 /* Module initialization */
6861 /* Convenience routine to export an integer value.
6862 * Errors are silently ignored, for better or for worse...
6864 #define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
6866 #define MODULE_NAME_MAX_LEN 11
6867 static char _bsddbModuleName
[MODULE_NAME_MAX_LEN
+1] = "_bsddb";
6869 #if (PY_VERSION_HEX >= 0x03000000)
6870 static struct PyModuleDef bsddbmodule
= {
6871 PyModuleDef_HEAD_INIT
,
6872 _bsddbModuleName
, /* Name of module */
6873 NULL
, /* module documentation, may be NULL */
6874 -1, /* size of per-interpreter state of the module,
6875 or -1 if the module keeps state in global variables. */
6878 NULL
, /* Traverse */
6885 #if (PY_VERSION_HEX < 0x03000000)
6886 DL_EXPORT(void) init_bsddb(void)
6888 PyMODINIT_FUNC
PyInit__bsddb(void) /* Note the two underscores */
6893 PyObject
* pybsddb_version_s
= PyBytes_FromString( PY_BSDDB_VERSION
);
6894 PyObject
* db_version_s
= PyBytes_FromString( DB_VERSION_STRING
);
6895 PyObject
* cvsid_s
= PyBytes_FromString( rcs_id
);
6898 /* Initialize object types */
6899 if ((PyType_Ready(&DB_Type
) < 0)
6900 || (PyType_Ready(&DBCursor_Type
) < 0)
6901 || (PyType_Ready(&DBEnv_Type
) < 0)
6902 || (PyType_Ready(&DBTxn_Type
) < 0)
6903 || (PyType_Ready(&DBLock_Type
) < 0)
6905 || (PyType_Ready(&DBSequence_Type
) < 0)
6908 #if (PY_VERSION_HEX < 0x03000000)
6915 #if defined(WITH_THREAD) && !defined(MYDB_USE_GILSTATE)
6916 /* Save the current interpreter, so callbacks can do the right thing. */
6917 _db_interpreterState
= PyThreadState_GET()->interp
;
6920 /* Create the module and add the functions */
6921 #if (PY_VERSION_HEX < 0x03000000)
6922 m
= Py_InitModule(_bsddbModuleName
, bsddb_methods
);
6924 m
=PyModule_Create(&bsddbmodule
);
6927 #if (PY_VERSION_HEX < 0x03000000)
6934 /* Add some symbolic constants to the module */
6935 d
= PyModule_GetDict(m
);
6936 PyDict_SetItemString(d
, "__version__", pybsddb_version_s
);
6937 PyDict_SetItemString(d
, "cvsid", cvsid_s
);
6938 PyDict_SetItemString(d
, "DB_VERSION_STRING", db_version_s
);
6939 Py_DECREF(pybsddb_version_s
);
6940 pybsddb_version_s
= NULL
;
6943 Py_DECREF(db_version_s
);
6944 db_version_s
= NULL
;
6946 ADD_INT(d
, DB_VERSION_MAJOR
);
6947 ADD_INT(d
, DB_VERSION_MINOR
);
6948 ADD_INT(d
, DB_VERSION_PATCH
);
6950 ADD_INT(d
, DB_MAX_PAGES
);
6951 ADD_INT(d
, DB_MAX_RECORDS
);
6954 ADD_INT(d
, DB_RPCCLIENT
);
6956 ADD_INT(d
, DB_CLIENT
);
6957 /* allow apps to be written using DB_RPCCLIENT on older Berkeley DB */
6958 _addIntToDict(d
, "DB_RPCCLIENT", DB_CLIENT
);
6960 ADD_INT(d
, DB_XA_CREATE
);
6962 ADD_INT(d
, DB_CREATE
);
6963 ADD_INT(d
, DB_NOMMAP
);
6964 ADD_INT(d
, DB_THREAD
);
6966 ADD_INT(d
, DB_MULTIVERSION
);
6969 ADD_INT(d
, DB_FORCE
);
6970 ADD_INT(d
, DB_INIT_CDB
);
6971 ADD_INT(d
, DB_INIT_LOCK
);
6972 ADD_INT(d
, DB_INIT_LOG
);
6973 ADD_INT(d
, DB_INIT_MPOOL
);
6974 ADD_INT(d
, DB_INIT_TXN
);
6975 ADD_INT(d
, DB_JOINENV
);
6977 ADD_INT(d
, DB_XIDDATASIZE
);
6979 ADD_INT(d
, DB_RECOVER
);
6980 ADD_INT(d
, DB_RECOVER_FATAL
);
6981 ADD_INT(d
, DB_TXN_NOSYNC
);
6982 ADD_INT(d
, DB_USE_ENVIRON
);
6983 ADD_INT(d
, DB_USE_ENVIRON_ROOT
);
6985 ADD_INT(d
, DB_LOCKDOWN
);
6986 ADD_INT(d
, DB_PRIVATE
);
6987 ADD_INT(d
, DB_SYSTEM_MEM
);
6989 ADD_INT(d
, DB_TXN_SYNC
);
6990 ADD_INT(d
, DB_TXN_NOWAIT
);
6992 ADD_INT(d
, DB_EXCL
);
6993 ADD_INT(d
, DB_FCNTL_LOCKING
);
6994 ADD_INT(d
, DB_ODDFILESIZE
);
6995 ADD_INT(d
, DB_RDWRMASTER
);
6996 ADD_INT(d
, DB_RDONLY
);
6997 ADD_INT(d
, DB_TRUNCATE
);
6998 ADD_INT(d
, DB_EXTENT
);
6999 ADD_INT(d
, DB_CDB_ALLDB
);
7000 ADD_INT(d
, DB_VERIFY
);
7001 ADD_INT(d
, DB_UPGRADE
);
7003 ADD_INT(d
, DB_AGGRESSIVE
);
7004 ADD_INT(d
, DB_NOORDERCHK
);
7005 ADD_INT(d
, DB_ORDERCHKONLY
);
7006 ADD_INT(d
, DB_PR_PAGE
);
7008 ADD_INT(d
, DB_PR_RECOVERYTEST
);
7009 ADD_INT(d
, DB_SALVAGE
);
7011 ADD_INT(d
, DB_LOCK_NORUN
);
7012 ADD_INT(d
, DB_LOCK_DEFAULT
);
7013 ADD_INT(d
, DB_LOCK_OLDEST
);
7014 ADD_INT(d
, DB_LOCK_RANDOM
);
7015 ADD_INT(d
, DB_LOCK_YOUNGEST
);
7016 ADD_INT(d
, DB_LOCK_MAXLOCKS
);
7017 ADD_INT(d
, DB_LOCK_MINLOCKS
);
7018 ADD_INT(d
, DB_LOCK_MINWRITE
);
7020 ADD_INT(d
, DB_LOCK_EXPIRE
);
7022 ADD_INT(d
, DB_LOCK_MAXWRITE
);
7025 _addIntToDict(d
, "DB_LOCK_CONFLICT", 0);
7027 ADD_INT(d
, DB_LOCK_DUMP
);
7028 ADD_INT(d
, DB_LOCK_GET
);
7029 ADD_INT(d
, DB_LOCK_INHERIT
);
7030 ADD_INT(d
, DB_LOCK_PUT
);
7031 ADD_INT(d
, DB_LOCK_PUT_ALL
);
7032 ADD_INT(d
, DB_LOCK_PUT_OBJ
);
7034 ADD_INT(d
, DB_LOCK_NG
);
7035 ADD_INT(d
, DB_LOCK_READ
);
7036 ADD_INT(d
, DB_LOCK_WRITE
);
7037 ADD_INT(d
, DB_LOCK_NOWAIT
);
7038 ADD_INT(d
, DB_LOCK_WAIT
);
7039 ADD_INT(d
, DB_LOCK_IWRITE
);
7040 ADD_INT(d
, DB_LOCK_IREAD
);
7041 ADD_INT(d
, DB_LOCK_IWR
);
7043 ADD_INT(d
, DB_LOCK_DIRTY
);
7045 ADD_INT(d
, DB_LOCK_READ_UNCOMMITTED
); /* renamed in 4.4 */
7047 ADD_INT(d
, DB_LOCK_WWRITE
);
7049 ADD_INT(d
, DB_LOCK_RECORD
);
7050 ADD_INT(d
, DB_LOCK_UPGRADE
);
7051 ADD_INT(d
, DB_LOCK_SWITCH
);
7052 ADD_INT(d
, DB_LOCK_UPGRADE_WRITE
);
7054 ADD_INT(d
, DB_LOCK_NOWAIT
);
7055 ADD_INT(d
, DB_LOCK_RECORD
);
7056 ADD_INT(d
, DB_LOCK_UPGRADE
);
7058 ADD_INT(d
, DB_LSTAT_ABORTED
);
7060 ADD_INT(d
, DB_LSTAT_ERR
);
7062 ADD_INT(d
, DB_LSTAT_FREE
);
7063 ADD_INT(d
, DB_LSTAT_HELD
);
7065 ADD_INT(d
, DB_LSTAT_PENDING
);
7066 ADD_INT(d
, DB_LSTAT_WAITING
);
7068 ADD_INT(d
, DB_ARCH_ABS
);
7069 ADD_INT(d
, DB_ARCH_DATA
);
7070 ADD_INT(d
, DB_ARCH_LOG
);
7072 ADD_INT(d
, DB_ARCH_REMOVE
);
7075 ADD_INT(d
, DB_BTREE
);
7076 ADD_INT(d
, DB_HASH
);
7077 ADD_INT(d
, DB_RECNO
);
7078 ADD_INT(d
, DB_QUEUE
);
7079 ADD_INT(d
, DB_UNKNOWN
);
7082 ADD_INT(d
, DB_DUPSORT
);
7083 ADD_INT(d
, DB_RECNUM
);
7084 ADD_INT(d
, DB_RENUMBER
);
7085 ADD_INT(d
, DB_REVSPLITOFF
);
7086 ADD_INT(d
, DB_SNAPSHOT
);
7088 ADD_INT(d
, DB_JOIN_NOSORT
);
7090 ADD_INT(d
, DB_AFTER
);
7091 ADD_INT(d
, DB_APPEND
);
7092 ADD_INT(d
, DB_BEFORE
);
7094 ADD_INT(d
, DB_CACHED_COUNTS
);
7098 _addIntToDict(d
, "DB_CHECKPOINT", 0);
7100 ADD_INT(d
, DB_CHECKPOINT
);
7101 ADD_INT(d
, DB_CURLSN
);
7104 ADD_INT(d
, DB_COMMIT
);
7106 ADD_INT(d
, DB_CONSUME
);
7107 ADD_INT(d
, DB_CONSUME_WAIT
);
7108 ADD_INT(d
, DB_CURRENT
);
7109 ADD_INT(d
, DB_FAST_STAT
);
7110 ADD_INT(d
, DB_FIRST
);
7111 ADD_INT(d
, DB_FLUSH
);
7112 ADD_INT(d
, DB_GET_BOTH
);
7113 ADD_INT(d
, DB_GET_RECNO
);
7114 ADD_INT(d
, DB_JOIN_ITEM
);
7115 ADD_INT(d
, DB_KEYFIRST
);
7116 ADD_INT(d
, DB_KEYLAST
);
7117 ADD_INT(d
, DB_LAST
);
7118 ADD_INT(d
, DB_NEXT
);
7119 ADD_INT(d
, DB_NEXT_DUP
);
7120 ADD_INT(d
, DB_NEXT_NODUP
);
7121 ADD_INT(d
, DB_NODUPDATA
);
7122 ADD_INT(d
, DB_NOOVERWRITE
);
7123 ADD_INT(d
, DB_NOSYNC
);
7124 ADD_INT(d
, DB_POSITION
);
7125 ADD_INT(d
, DB_PREV
);
7126 ADD_INT(d
, DB_PREV_NODUP
);
7128 ADD_INT(d
, DB_RECORDCOUNT
);
7131 ADD_INT(d
, DB_SET_RANGE
);
7132 ADD_INT(d
, DB_SET_RECNO
);
7133 ADD_INT(d
, DB_WRITECURSOR
);
7135 ADD_INT(d
, DB_OPFLAGS_MASK
);
7137 ADD_INT(d
, DB_DIRTY_READ
);
7138 ADD_INT(d
, DB_MULTIPLE
);
7139 ADD_INT(d
, DB_MULTIPLE_KEY
);
7142 ADD_INT(d
, DB_READ_UNCOMMITTED
); /* replaces DB_DIRTY_READ in 4.4 */
7143 ADD_INT(d
, DB_READ_COMMITTED
);
7146 ADD_INT(d
, DB_DONOTINDEX
);
7149 _addIntToDict(d
, "DB_INCOMPLETE", 0);
7151 ADD_INT(d
, DB_INCOMPLETE
);
7153 ADD_INT(d
, DB_KEYEMPTY
);
7154 ADD_INT(d
, DB_KEYEXIST
);
7155 ADD_INT(d
, DB_LOCK_DEADLOCK
);
7156 ADD_INT(d
, DB_LOCK_NOTGRANTED
);
7157 ADD_INT(d
, DB_NOSERVER
);
7158 ADD_INT(d
, DB_NOSERVER_HOME
);
7159 ADD_INT(d
, DB_NOSERVER_ID
);
7160 ADD_INT(d
, DB_NOTFOUND
);
7161 ADD_INT(d
, DB_OLD_VERSION
);
7162 ADD_INT(d
, DB_RUNRECOVERY
);
7163 ADD_INT(d
, DB_VERIFY_BAD
);
7164 ADD_INT(d
, DB_PAGE_NOTFOUND
);
7165 ADD_INT(d
, DB_SECONDARY_BAD
);
7166 ADD_INT(d
, DB_STAT_CLEAR
);
7167 ADD_INT(d
, DB_REGION_INIT
);
7168 ADD_INT(d
, DB_NOLOCKING
);
7169 ADD_INT(d
, DB_YIELDCPU
);
7170 ADD_INT(d
, DB_PANIC_ENVIRONMENT
);
7171 ADD_INT(d
, DB_NOPANIC
);
7174 ADD_INT(d
, DB_OVERWRITE
);
7178 ADD_INT(d
, DB_REGISTER
);
7182 ADD_INT(d
, DB_TIME_NOTGRANTED
);
7183 ADD_INT(d
, DB_TXN_NOT_DURABLE
);
7184 ADD_INT(d
, DB_TXN_WRITE_NOSYNC
);
7185 ADD_INT(d
, DB_DIRECT_DB
);
7186 ADD_INT(d
, DB_INIT_REP
);
7187 ADD_INT(d
, DB_ENCRYPT
);
7188 ADD_INT(d
, DB_CHKSUM
);
7191 #if (DBVER >= 42) && (DBVER < 47)
7192 ADD_INT(d
, DB_LOG_AUTOREMOVE
);
7193 ADD_INT(d
, DB_DIRECT_LOG
);
7197 ADD_INT(d
, DB_LOG_DIRECT
);
7198 ADD_INT(d
, DB_LOG_DSYNC
);
7199 ADD_INT(d
, DB_LOG_IN_MEMORY
);
7200 ADD_INT(d
, DB_LOG_AUTO_REMOVE
);
7201 ADD_INT(d
, DB_LOG_ZERO
);
7205 ADD_INT(d
, DB_DSYNC_DB
);
7209 ADD_INT(d
, DB_TXN_SNAPSHOT
);
7212 ADD_INT(d
, DB_VERB_DEADLOCK
);
7214 ADD_INT(d
, DB_VERB_FILEOPS
);
7215 ADD_INT(d
, DB_VERB_FILEOPS_ALL
);
7217 ADD_INT(d
, DB_VERB_RECOVERY
);
7219 ADD_INT(d
, DB_VERB_REGISTER
);
7221 ADD_INT(d
, DB_VERB_REPLICATION
);
7222 ADD_INT(d
, DB_VERB_WAITSFOR
);
7225 ADD_INT(d
, DB_EVENT_PANIC
);
7226 ADD_INT(d
, DB_EVENT_REP_CLIENT
);
7228 ADD_INT(d
, DB_EVENT_REP_ELECTED
);
7230 ADD_INT(d
, DB_EVENT_REP_MASTER
);
7231 ADD_INT(d
, DB_EVENT_REP_NEWMASTER
);
7233 ADD_INT(d
, DB_EVENT_REP_PERM_FAILED
);
7235 ADD_INT(d
, DB_EVENT_REP_STARTUPDONE
);
7236 ADD_INT(d
, DB_EVENT_WRITE_FAILED
);
7239 ADD_INT(d
, DB_REP_DUPMASTER
);
7240 ADD_INT(d
, DB_REP_HOLDELECTION
);
7242 ADD_INT(d
, DB_REP_IGNORE
);
7243 ADD_INT(d
, DB_REP_JOIN_FAILURE
);
7246 ADD_INT(d
, DB_REP_ISPERM
);
7247 ADD_INT(d
, DB_REP_NOTPERM
);
7249 ADD_INT(d
, DB_REP_NEWSITE
);
7251 ADD_INT(d
, DB_REP_MASTER
);
7252 ADD_INT(d
, DB_REP_CLIENT
);
7254 ADD_INT(d
, DB_REP_ELECTION
);
7256 ADD_INT(d
, DB_REP_ACK_TIMEOUT
);
7257 ADD_INT(d
, DB_REP_CONNECTION_RETRY
);
7258 ADD_INT(d
, DB_REP_ELECTION_TIMEOUT
);
7259 ADD_INT(d
, DB_REP_ELECTION_RETRY
);
7262 ADD_INT(d
, DB_REP_CHECKPOINT_DELAY
);
7263 ADD_INT(d
, DB_REP_FULL_ELECTION_TIMEOUT
);
7267 ADD_INT(d
, DB_REPMGR_PEER
);
7268 ADD_INT(d
, DB_REPMGR_ACKS_ALL
);
7269 ADD_INT(d
, DB_REPMGR_ACKS_ALL_PEERS
);
7270 ADD_INT(d
, DB_REPMGR_ACKS_NONE
);
7271 ADD_INT(d
, DB_REPMGR_ACKS_ONE
);
7272 ADD_INT(d
, DB_REPMGR_ACKS_ONE_PEER
);
7273 ADD_INT(d
, DB_REPMGR_ACKS_QUORUM
);
7274 ADD_INT(d
, DB_REPMGR_CONNECTED
);
7275 ADD_INT(d
, DB_REPMGR_DISCONNECTED
);
7276 ADD_INT(d
, DB_STAT_CLEAR
);
7277 ADD_INT(d
, DB_STAT_ALL
);
7281 ADD_INT(d
, DB_BUFFER_SMALL
);
7282 ADD_INT(d
, DB_SEQ_DEC
);
7283 ADD_INT(d
, DB_SEQ_INC
);
7284 ADD_INT(d
, DB_SEQ_WRAP
);
7287 #if (DBVER >= 43) && (DBVER < 47)
7288 ADD_INT(d
, DB_LOG_INMEMORY
);
7289 ADD_INT(d
, DB_DSYNC_LOG
);
7293 ADD_INT(d
, DB_ENCRYPT_AES
);
7294 ADD_INT(d
, DB_AUTO_COMMIT
);
7296 /* allow Berkeley DB 4.1 aware apps to run on older versions */
7297 _addIntToDict(d
, "DB_AUTO_COMMIT", 0);
7310 ADD_INT(d
, DB_SET_LOCK_TIMEOUT
);
7311 ADD_INT(d
, DB_SET_TXN_TIMEOUT
);
7313 /* The exception name must be correct for pickled exception *
7314 * objects to unpickle properly. */
7315 #ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
7316 #define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
7318 #define PYBSDDB_EXCEPTION_BASE "bsddb.db."
7321 /* All the rest of the exceptions derive only from DBError */
7322 #define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
7323 PyDict_SetItemString(d, #name, name)
7325 /* The base exception class is DBError */
7326 DBError
= NULL
; /* used in MAKE_EX so that it derives from nothing */
7329 #if (PY_VERSION_HEX < 0x03000000)
7330 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
7331 * from both DBError and KeyError, since the API only supports
7332 * using one base class. */
7333 PyDict_SetItemString(d
, "KeyError", PyExc_KeyError
);
7334 PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
7335 "class DBKeyEmptyError(DBError, KeyError): pass",
7336 Py_file_input
, d
, d
);
7337 DBNotFoundError
= PyDict_GetItemString(d
, "DBNotFoundError");
7338 DBKeyEmptyError
= PyDict_GetItemString(d
, "DBKeyEmptyError");
7339 PyDict_DelItemString(d
, "KeyError");
7341 /* Since Python 2.5, PyErr_NewException() accepts a tuple, to be able to
7342 ** derive from several classes. We use this new API only for Python 3.0,
7348 bases
= PyTuple_Pack(2, DBError
, PyExc_KeyError
);
7350 #define MAKE_EX2(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, bases, NULL); \
7351 PyDict_SetItemString(d, #name, name)
7352 MAKE_EX2(DBNotFoundError
);
7353 MAKE_EX2(DBKeyEmptyError
);
7362 #if !INCOMPLETE_IS_WARNING
7363 MAKE_EX(DBIncompleteError
);
7365 MAKE_EX(DBCursorClosedError
);
7366 MAKE_EX(DBKeyEmptyError
);
7367 MAKE_EX(DBKeyExistError
);
7368 MAKE_EX(DBLockDeadlockError
);
7369 MAKE_EX(DBLockNotGrantedError
);
7370 MAKE_EX(DBOldVersionError
);
7371 MAKE_EX(DBRunRecoveryError
);
7372 MAKE_EX(DBVerifyBadError
);
7373 MAKE_EX(DBNoServerError
);
7374 MAKE_EX(DBNoServerHomeError
);
7375 MAKE_EX(DBNoServerIDError
);
7376 MAKE_EX(DBPageNotFoundError
);
7377 MAKE_EX(DBSecondaryBadError
);
7379 MAKE_EX(DBInvalidArgError
);
7380 MAKE_EX(DBAccessError
);
7381 MAKE_EX(DBNoSpaceError
);
7382 MAKE_EX(DBNoMemoryError
);
7383 MAKE_EX(DBAgainError
);
7384 MAKE_EX(DBBusyError
);
7385 MAKE_EX(DBFileExistsError
);
7386 MAKE_EX(DBNoSuchFileError
);
7387 MAKE_EX(DBPermissionsError
);
7390 MAKE_EX(DBRepHandleDeadError
);
7393 MAKE_EX(DBRepUnavailError
);
7397 /* Initiliase the C API structure and add it to the module */
7398 bsddb_api
.db_type
= &DB_Type
;
7399 bsddb_api
.dbcursor_type
= &DBCursor_Type
;
7400 bsddb_api
.dbenv_type
= &DBEnv_Type
;
7401 bsddb_api
.dbtxn_type
= &DBTxn_Type
;
7402 bsddb_api
.dblock_type
= &DBLock_Type
;
7404 bsddb_api
.dbsequence_type
= &DBSequence_Type
;
7406 bsddb_api
.makeDBError
= makeDBError
;
7408 py_api
= PyCObject_FromVoidPtr((void*)&bsddb_api
, NULL
);
7409 PyDict_SetItemString(d
, "api", py_api
);
7412 /* Check for errors */
7413 if (PyErr_Occurred()) {
7415 Py_FatalError("can't initialize module _bsddb/_pybsddb");
7419 #if (PY_VERSION_HEX < 0x03000000)
7426 /* allow this module to be named _pybsddb so that it can be installed
7427 * and imported on top of python >= 2.3 that includes its own older
7428 * copy of the library named _bsddb without importing the old version. */
7429 #if (PY_VERSION_HEX < 0x03000000)
7430 DL_EXPORT(void) init_pybsddb(void)
7432 PyMODINIT_FUNC
PyInit__pybsddb(void) /* Note the two underscores */
7435 strncpy(_bsddbModuleName
, "_pybsddb", MODULE_NAME_MAX_LEN
);
7436 #if (PY_VERSION_HEX < 0x03000000)
7439 return PyInit__bsddb(); /* Note the two underscores */