1 /*----------------------------------------------------------------------
2 Copyright (c) 1999-2001, Digital Creations, Fredericksburg, VA, USA
3 and Andrew Kuchling. All rights reserved.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
9 o Redistributions of source code must retain the above copyright
10 notice, this list of conditions, and the disclaimer that follows.
12 o Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions, and the following disclaimer in
14 the documentation and/or other materials provided with the
17 o Neither the name of Digital Creations nor the names of its
18 contributors may be used to endorse or promote products derived
19 from this software without specific prior written permission.
21 THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
22 IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
25 CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
33 ------------------------------------------------------------------------*/
37 * Handwritten code to wrap version 3.x of the Berkeley DB library,
38 * written to replace a SWIG-generated file. It has since been updated
39 * to compile with BerkeleyDB versions 3.2 through 4.2.
41 * This module was started by Andrew Kuchling to remove the dependency
42 * on SWIG in a package by Gregory P. Smith <greg@electricrain.com> who
43 * based his work on a similar package by Robin Dunn <robin@alldunn.com>
44 * which wrapped Berkeley DB 2.7.x.
46 * Development of this module then returned full circle back to Robin Dunn
47 * who worked on behalf of Digital Creations to complete the wrapping of
48 * the DB 3.x API and to build a solid unit test suite. Robin has
49 * since gone onto other projects (wxPython).
51 * Gregory P. Smith <greg@electricrain.com> is once again the maintainer.
53 * Use the pybsddb-users@lists.sf.net mailing list for all questions.
54 * Things can change faster than the header of this file is updated. This
55 * file is shared with the PyBSDDB project at SourceForge:
57 * http://pybsddb.sf.net
59 * This file should remain backward compatible with Python 2.1, but see PEP
60 * 291 for the most current backward compatibility requirements:
62 * http://www.python.org/peps/pep-0291.html
64 * This module contains 6 types:
67 * DBCursor (Database Cursor)
68 * DBEnv (database environment)
69 * DBTxn (An explicit database transaction)
70 * DBLock (A lock handle)
71 * DBSequence (Sequence)
75 /* --------------------------------------------------------------------- */
78 * Portions of this module, associated unit tests and build scripts are the
79 * result of a contract with The Written Word (http://thewrittenword.com/)
80 * Many thanks go out to them for causing me to raise the bar on quality and
81 * functionality, resulting in a better bsddb3 package for all of us to use.
86 /* --------------------------------------------------------------------- */
88 #include <stddef.h> /* for offsetof() */
92 /* --------------------------------------------------------------------- */
93 /* Various macro definitions */
95 /* 40 = 4.0, 33 = 3.3; this will break if the second number is > 9 */
96 #define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
97 #if DB_VERSION_MINOR > 9
98 #error "eek! DBVER can't handle minor versions > 9"
101 #define PY_BSDDB_VERSION "4.5.0"
102 static char *rcs_id
= "$Id$";
105 #if (PY_VERSION_HEX < 0x02050000)
106 typedef int Py_ssize_t
;
111 /* These are for when calling Python --> C */
112 #define MYDB_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS;
113 #define MYDB_END_ALLOW_THREADS Py_END_ALLOW_THREADS;
115 /* For 2.3, use the PyGILState_ calls */
116 #if (PY_VERSION_HEX >= 0x02030000)
117 #define MYDB_USE_GILSTATE
120 /* and these are for calling C --> Python */
121 #if defined(MYDB_USE_GILSTATE)
122 #define MYDB_BEGIN_BLOCK_THREADS \
123 PyGILState_STATE __savestate = PyGILState_Ensure();
124 #define MYDB_END_BLOCK_THREADS \
125 PyGILState_Release(__savestate);
126 #else /* MYDB_USE_GILSTATE */
127 /* Pre GILState API - do it the long old way */
128 static PyInterpreterState
* _db_interpreterState
= NULL
;
129 #define MYDB_BEGIN_BLOCK_THREADS { \
130 PyThreadState* prevState; \
131 PyThreadState* newState; \
132 PyEval_AcquireLock(); \
133 newState = PyThreadState_New(_db_interpreterState); \
134 prevState = PyThreadState_Swap(newState);
136 #define MYDB_END_BLOCK_THREADS \
137 newState = PyThreadState_Swap(prevState); \
138 PyThreadState_Clear(newState); \
139 PyEval_ReleaseLock(); \
140 PyThreadState_Delete(newState); \
142 #endif /* MYDB_USE_GILSTATE */
145 /* Compiled without threads - avoid all this cruft */
146 #define MYDB_BEGIN_ALLOW_THREADS
147 #define MYDB_END_ALLOW_THREADS
148 #define MYDB_BEGIN_BLOCK_THREADS
149 #define MYDB_END_BLOCK_THREADS
153 /* Should DB_INCOMPLETE be turned into a warning or an exception? */
154 #define INCOMPLETE_IS_WARNING 1
156 /* --------------------------------------------------------------------- */
159 static PyObject
* DBError
; /* Base class, all others derive from this */
160 static PyObject
* DBCursorClosedError
; /* raised when trying to use a closed cursor object */
161 static PyObject
* DBKeyEmptyError
; /* DB_KEYEMPTY: also derives from KeyError */
162 static PyObject
* DBKeyExistError
; /* DB_KEYEXIST */
163 static PyObject
* DBLockDeadlockError
; /* DB_LOCK_DEADLOCK */
164 static PyObject
* DBLockNotGrantedError
; /* DB_LOCK_NOTGRANTED */
165 static PyObject
* DBNotFoundError
; /* DB_NOTFOUND: also derives from KeyError */
166 static PyObject
* DBOldVersionError
; /* DB_OLD_VERSION */
167 static PyObject
* DBRunRecoveryError
; /* DB_RUNRECOVERY */
168 static PyObject
* DBVerifyBadError
; /* DB_VERIFY_BAD */
169 static PyObject
* DBNoServerError
; /* DB_NOSERVER */
170 static PyObject
* DBNoServerHomeError
; /* DB_NOSERVER_HOME */
171 static PyObject
* DBNoServerIDError
; /* DB_NOSERVER_ID */
173 static PyObject
* DBPageNotFoundError
; /* DB_PAGE_NOTFOUND */
174 static PyObject
* DBSecondaryBadError
; /* DB_SECONDARY_BAD */
177 #if !INCOMPLETE_IS_WARNING
178 static PyObject
* DBIncompleteError
; /* DB_INCOMPLETE */
181 static PyObject
* DBInvalidArgError
; /* EINVAL */
182 static PyObject
* DBAccessError
; /* EACCES */
183 static PyObject
* DBNoSpaceError
; /* ENOSPC */
184 static PyObject
* DBNoMemoryError
; /* DB_BUFFER_SMALL (ENOMEM when < 4.3) */
185 static PyObject
* DBAgainError
; /* EAGAIN */
186 static PyObject
* DBBusyError
; /* EBUSY */
187 static PyObject
* DBFileExistsError
; /* EEXIST */
188 static PyObject
* DBNoSuchFileError
; /* ENOENT */
189 static PyObject
* DBPermissionsError
; /* EPERM */
192 #define DB_BUFFER_SMALL ENOMEM
196 /* --------------------------------------------------------------------- */
197 /* Structure definitions */
199 #if PYTHON_API_VERSION >= 1010 /* python >= 2.1 support weak references */
205 /* if Python >= 2.1 better support warnings */
206 #if PYTHON_API_VERSION >= 1010
207 #define HAVE_WARNINGS
212 #if PYTHON_API_VERSION <= 1007
213 /* 1.5 compatibility */
214 #define PyObject_New PyObject_NEW
215 #define PyObject_Del PyMem_DEL
218 struct behaviourFlags
{
219 /* What is the default behaviour when DB->get or DBCursor->get returns a
220 DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise an exception? */
221 unsigned int getReturnsNone
: 1;
222 /* What is the default behaviour for DBCursor.set* methods when DBCursor->get
223 * returns a DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise? */
224 unsigned int cursorSetReturnsNone
: 1;
227 #define DEFAULT_GET_RETURNS_NONE 1
228 #define DEFAULT_CURSOR_SET_RETURNS_NONE 1 /* 0 in pybsddb < 4.2, python < 2.4 */
233 u_int32_t flags
; /* saved flags from open() */
235 struct behaviourFlags moduleFlags
;
237 PyObject
*in_weakreflist
; /* List of weak references */
245 DBEnvObject
* myenvobj
; /* PyObject containing the DB_ENV */
246 u_int32_t flags
; /* saved flags from open() */
247 u_int32_t setflags
; /* saved flags from set_flags() */
249 struct behaviourFlags moduleFlags
;
251 PyObject
* associateCallback
;
252 PyObject
* btCompareCallback
;
256 PyObject
*in_weakreflist
; /* List of weak references */
266 PyObject
*in_weakreflist
; /* List of weak references */
276 PyObject
*in_weakreflist
; /* List of weak references */
285 PyObject
*in_weakreflist
; /* List of weak references */
292 DB_SEQUENCE
* sequence
;
295 PyObject
*in_weakreflist
; /* List of weak references */
298 staticforward PyTypeObject DBSequence_Type
;
301 staticforward PyTypeObject DB_Type
, DBCursor_Type
, DBEnv_Type
, DBTxn_Type
, DBLock_Type
;
303 #define DBObject_Check(v) ((v)->ob_type == &DB_Type)
304 #define DBCursorObject_Check(v) ((v)->ob_type == &DBCursor_Type)
305 #define DBEnvObject_Check(v) ((v)->ob_type == &DBEnv_Type)
306 #define DBTxnObject_Check(v) ((v)->ob_type == &DBTxn_Type)
307 #define DBLockObject_Check(v) ((v)->ob_type == &DBLock_Type)
309 #define DBSequenceObject_Check(v) ((v)->ob_type == &DBSequence_Type)
313 /* --------------------------------------------------------------------- */
314 /* Utility macros and functions */
316 #define RETURN_IF_ERR() \
317 if (makeDBError(err)) { \
321 #define RETURN_NONE() Py_INCREF(Py_None); return Py_None;
323 #define _CHECK_OBJECT_NOT_CLOSED(nonNull, pyErrObj, name) \
324 if ((nonNull) == NULL) { \
325 PyObject *errTuple = NULL; \
326 errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
327 PyErr_SetObject((pyErrObj), errTuple); \
328 Py_DECREF(errTuple); \
332 #define CHECK_DB_NOT_CLOSED(dbobj) \
333 _CHECK_OBJECT_NOT_CLOSED(dbobj->db, DBError, DB)
335 #define CHECK_ENV_NOT_CLOSED(env) \
336 _CHECK_OBJECT_NOT_CLOSED(env->db_env, DBError, DBEnv)
338 #define CHECK_CURSOR_NOT_CLOSED(curs) \
339 _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)
342 #define CHECK_SEQUENCE_NOT_CLOSED(curs) \
343 _CHECK_OBJECT_NOT_CLOSED(curs->sequence, DBError, DBSequence)
346 #define CHECK_DBFLAG(mydb, flag) (((mydb)->flags & (flag)) || \
347 (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))
349 #define CLEAR_DBT(dbt) (memset(&(dbt), 0, sizeof(dbt)))
351 #define FREE_DBT(dbt) if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
352 dbt.data != NULL) { free(dbt.data); dbt.data = NULL; }
355 static int makeDBError(int err
);
358 /* Return the access method type of the DBObject */
359 static int _DB_get_type(DBObject
* self
)
364 err
= self
->db
->get_type(self
->db
, &type
);
365 if (makeDBError(err
)) {
370 return self
->db
->get_type(self
->db
);
375 /* Create a DBT structure (containing key and data values) from Python
376 strings. Returns 1 on success, 0 on an error. */
377 static int make_dbt(PyObject
* obj
, DBT
* dbt
)
380 if (obj
== Py_None
) {
381 /* no need to do anything, the structure has already been zeroed */
383 else if (!PyArg_Parse(obj
, "s#", &dbt
->data
, &dbt
->size
)) {
384 PyErr_SetString(PyExc_TypeError
,
385 "Data values must be of type string or None.");
392 /* Recno and Queue DBs can have integer keys. This function figures out
393 what's been given, verifies that it's allowed, and then makes the DBT.
395 Caller MUST call FREE_DBT(key) when done. */
397 make_key_dbt(DBObject
* self
, PyObject
* keyobj
, DBT
* key
, int* pflags
)
403 if (keyobj
== Py_None
) {
404 type
= _DB_get_type(self
);
407 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
410 "None keys not allowed for Recno and Queue DB's");
413 /* no need to do anything, the structure has already been zeroed */
416 else if (PyString_Check(keyobj
)) {
417 /* verify access method type */
418 type
= _DB_get_type(self
);
421 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
424 "String keys not allowed for Recno and Queue DB's");
428 key
->data
= PyString_AS_STRING(keyobj
);
429 key
->size
= PyString_GET_SIZE(keyobj
);
432 else if (PyInt_Check(keyobj
)) {
433 /* verify access method type */
434 type
= _DB_get_type(self
);
437 if (type
== DB_BTREE
&& pflags
!= NULL
) {
438 /* if BTREE then an Integer key is allowed with the
439 * DB_SET_RECNO flag */
440 *pflags
|= DB_SET_RECNO
;
442 else if (type
!= DB_RECNO
&& type
!= DB_QUEUE
) {
445 "Integer keys only allowed for Recno and Queue DB's");
449 /* Make a key out of the requested recno, use allocated space so DB
450 * will be able to realloc room for the real key if needed. */
451 recno
= PyInt_AS_LONG(keyobj
);
452 key
->data
= malloc(sizeof(db_recno_t
));
453 if (key
->data
== NULL
) {
454 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
457 key
->ulen
= key
->size
= sizeof(db_recno_t
);
458 memcpy(key
->data
, &recno
, sizeof(db_recno_t
));
459 key
->flags
= DB_DBT_REALLOC
;
462 PyErr_Format(PyExc_TypeError
,
463 "String or Integer object expected for key, %s found",
464 keyobj
->ob_type
->tp_name
);
472 /* Add partial record access to an existing DBT data struct.
473 If dlen and doff are set, then the DB_DBT_PARTIAL flag will be set
474 and the data storage/retrieval will be done using dlen and doff. */
475 static int add_partial_dbt(DBT
* d
, int dlen
, int doff
) {
476 /* if neither were set we do nothing (-1 is the default value) */
477 if ((dlen
== -1) && (doff
== -1)) {
481 if ((dlen
< 0) || (doff
< 0)) {
482 PyErr_SetString(PyExc_TypeError
, "dlen and doff must both be >= 0");
486 d
->flags
= d
->flags
| DB_DBT_PARTIAL
;
487 d
->dlen
= (unsigned int) dlen
;
488 d
->doff
= (unsigned int) doff
;
492 /* a safe strcpy() without the zeroing behaviour and semantics of strncpy. */
493 /* TODO: make this use the native libc strlcpy() when available (BSD) */
494 unsigned int our_strlcpy(char* dest
, const char* src
, unsigned int n
)
496 unsigned int srclen
, copylen
;
498 srclen
= strlen(src
);
501 copylen
= (srclen
> n
-1) ? n
-1 : srclen
;
502 /* populate dest[0] thru dest[copylen-1] */
503 memcpy(dest
, src
, copylen
);
504 /* guarantee null termination */
510 /* Callback used to save away more information about errors from the DB
512 static char _db_errmsg
[1024];
514 static void _db_errorCallback(const char* prefix
, char* msg
)
516 static void _db_errorCallback(const DB_ENV
*db_env
,
517 const char* prefix
, const char* msg
)
520 our_strlcpy(_db_errmsg
, msg
, sizeof(_db_errmsg
));
524 /* make a nice exception object to raise for errors. */
525 static int makeDBError(int err
)
527 char errTxt
[2048]; /* really big, just in case... */
528 PyObject
*errObj
= NULL
;
529 PyObject
*errTuple
= NULL
;
530 int exceptionRaised
= 0;
531 unsigned int bytes_left
;
534 case 0: /* successful, no error */ break;
538 #if INCOMPLETE_IS_WARNING
539 bytes_left
= our_strlcpy(errTxt
, db_strerror(err
), sizeof(errTxt
));
540 /* Ensure that bytes_left never goes negative */
541 if (_db_errmsg
[0] && bytes_left
< (sizeof(errTxt
) - 4)) {
542 bytes_left
= sizeof(errTxt
) - bytes_left
- 4 - 1;
543 assert(bytes_left
>= 0);
544 strcat(errTxt
, " -- ");
545 strncat(errTxt
, _db_errmsg
, bytes_left
);
549 exceptionRaised
= PyErr_Warn(PyExc_RuntimeWarning
, errTxt
);
551 fprintf(stderr
, errTxt
);
552 fprintf(stderr
, "\n");
555 #else /* do an exception instead */
556 errObj
= DBIncompleteError
;
559 #endif /* DBVER < 41 */
561 case DB_KEYEMPTY
: errObj
= DBKeyEmptyError
; break;
562 case DB_KEYEXIST
: errObj
= DBKeyExistError
; break;
563 case DB_LOCK_DEADLOCK
: errObj
= DBLockDeadlockError
; break;
564 case DB_LOCK_NOTGRANTED
: errObj
= DBLockNotGrantedError
; break;
565 case DB_NOTFOUND
: errObj
= DBNotFoundError
; break;
566 case DB_OLD_VERSION
: errObj
= DBOldVersionError
; break;
567 case DB_RUNRECOVERY
: errObj
= DBRunRecoveryError
; break;
568 case DB_VERIFY_BAD
: errObj
= DBVerifyBadError
; break;
569 case DB_NOSERVER
: errObj
= DBNoServerError
; break;
570 case DB_NOSERVER_HOME
: errObj
= DBNoServerHomeError
; break;
571 case DB_NOSERVER_ID
: errObj
= DBNoServerIDError
; break;
573 case DB_PAGE_NOTFOUND
: errObj
= DBPageNotFoundError
; break;
574 case DB_SECONDARY_BAD
: errObj
= DBSecondaryBadError
; break;
576 case DB_BUFFER_SMALL
: errObj
= DBNoMemoryError
; break;
579 /* ENOMEM and DB_BUFFER_SMALL were one and the same until 4.3 */
580 case ENOMEM
: errObj
= PyExc_MemoryError
; break;
582 case EINVAL
: errObj
= DBInvalidArgError
; break;
583 case EACCES
: errObj
= DBAccessError
; break;
584 case ENOSPC
: errObj
= DBNoSpaceError
; break;
585 case EAGAIN
: errObj
= DBAgainError
; break;
586 case EBUSY
: errObj
= DBBusyError
; break;
587 case EEXIST
: errObj
= DBFileExistsError
; break;
588 case ENOENT
: errObj
= DBNoSuchFileError
; break;
589 case EPERM
: errObj
= DBPermissionsError
; break;
591 default: errObj
= DBError
; break;
594 if (errObj
!= NULL
) {
595 bytes_left
= our_strlcpy(errTxt
, db_strerror(err
), sizeof(errTxt
));
596 /* Ensure that bytes_left never goes negative */
597 if (_db_errmsg
[0] && bytes_left
< (sizeof(errTxt
) - 4)) {
598 bytes_left
= sizeof(errTxt
) - bytes_left
- 4 - 1;
599 assert(bytes_left
>= 0);
600 strcat(errTxt
, " -- ");
601 strncat(errTxt
, _db_errmsg
, bytes_left
);
605 errTuple
= Py_BuildValue("(is)", err
, errTxt
);
606 PyErr_SetObject(errObj
, errTuple
);
610 return ((errObj
!= NULL
) || exceptionRaised
);
615 /* set a type exception */
616 static void makeTypeError(char* expected
, PyObject
* found
)
618 PyErr_Format(PyExc_TypeError
, "Expected %s argument, %s found.",
619 expected
, found
->ob_type
->tp_name
);
623 /* verify that an obj is either None or a DBTxn, and set the txn pointer */
624 static int checkTxnObj(PyObject
* txnobj
, DB_TXN
** txn
)
626 if (txnobj
== Py_None
|| txnobj
== NULL
) {
630 if (DBTxnObject_Check(txnobj
)) {
631 *txn
= ((DBTxnObject
*)txnobj
)->txn
;
635 makeTypeError("DBTxn", txnobj
);
640 /* Delete a key from a database
641 Returns 0 on success, -1 on an error. */
642 static int _DB_delete(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, int flags
)
646 MYDB_BEGIN_ALLOW_THREADS
;
647 err
= self
->db
->del(self
->db
, txn
, key
, 0);
648 MYDB_END_ALLOW_THREADS
;
649 if (makeDBError(err
)) {
657 /* Store a key into a database
658 Returns 0 on success, -1 on an error. */
659 static int _DB_put(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, DBT
*data
, int flags
)
663 MYDB_BEGIN_ALLOW_THREADS
;
664 err
= self
->db
->put(self
->db
, txn
, key
, data
, flags
);
665 MYDB_END_ALLOW_THREADS
;
666 if (makeDBError(err
)) {
673 /* Get a key/data pair from a cursor */
674 static PyObject
* _DBCursor_get(DBCursorObject
* self
, int extra_flags
,
675 PyObject
*args
, PyObject
*kwargs
, char *format
)
678 PyObject
* retval
= NULL
;
683 static char* kwnames
[] = { "flags", "dlen", "doff", NULL
};
685 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, format
, kwnames
,
686 &flags
, &dlen
, &doff
))
689 CHECK_CURSOR_NOT_CLOSED(self
);
691 flags
|= extra_flags
;
694 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
695 /* Tell BerkeleyDB to malloc the return value (thread safe) */
696 data
.flags
= DB_DBT_MALLOC
;
697 key
.flags
= DB_DBT_MALLOC
;
699 if (!add_partial_dbt(&data
, dlen
, doff
))
702 MYDB_BEGIN_ALLOW_THREADS
;
703 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
704 MYDB_END_ALLOW_THREADS
;
706 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
707 && self
->mydb
->moduleFlags
.getReturnsNone
) {
711 else if (makeDBError(err
)) {
714 else { /* otherwise, success! */
716 /* if Recno or Queue, return the key as an Int */
717 switch (_DB_get_type(self
->mydb
)) {
724 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
725 data
.data
, data
.size
);
730 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
731 data
.data
, data
.size
);
743 /* add an integer to a dictionary using the given name as a key */
744 static void _addIntToDict(PyObject
* dict
, char *name
, int value
)
746 PyObject
* v
= PyInt_FromLong((long) value
);
747 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
753 /* The same, when the value is a time_t */
754 static void _addTimeTToDict(PyObject
* dict
, char *name
, time_t value
)
757 /* if the value fits in regular int, use that. */
758 #ifdef HAVE_LONG_LONG
759 if (sizeof(time_t) > sizeof(long))
760 v
= PyLong_FromLongLong((PY_LONG_LONG
) value
);
763 v
= PyInt_FromLong((long) value
);
764 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
771 /* add an db_seq_t to a dictionary using the given name as a key */
772 static void _addDb_seq_tToDict(PyObject
* dict
, char *name
, db_seq_t value
)
774 PyObject
* v
= PyLong_FromLongLong(value
);
775 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
784 /* --------------------------------------------------------------------- */
785 /* Allocators and deallocators */
788 newDBObject(DBEnvObject
* arg
, int flags
)
791 DB_ENV
* db_env
= NULL
;
794 self
= PyObject_New(DBObject
, &DB_Type
);
801 self
->myenvobj
= NULL
;
803 self
->associateCallback
= NULL
;
804 self
->btCompareCallback
= NULL
;
805 self
->primaryDBType
= 0;
808 self
->in_weakreflist
= NULL
;
811 /* keep a reference to our python DBEnv object */
814 self
->myenvobj
= arg
;
815 db_env
= arg
->db_env
;
819 self
->moduleFlags
= self
->myenvobj
->moduleFlags
;
821 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
822 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
824 MYDB_BEGIN_ALLOW_THREADS
;
825 err
= db_create(&self
->db
, db_env
, flags
);
826 if (self
->db
!= NULL
) {
827 self
->db
->set_errcall(self
->db
, _db_errorCallback
);
829 self
->db
->app_private
= (void*)self
;
832 MYDB_END_ALLOW_THREADS
;
833 /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
834 * list so that a DBEnv can refuse to close without aborting any open
835 * DBTxns and closing any open DBs first. */
836 if (makeDBError(err
)) {
837 if (self
->myenvobj
) {
838 Py_DECREF(self
->myenvobj
);
839 self
->myenvobj
= NULL
;
849 DB_dealloc(DBObject
* self
)
851 if (self
->db
!= NULL
) {
852 /* avoid closing a DB when its DBEnv has been closed out from under
854 if (!self
->myenvobj
||
855 (self
->myenvobj
&& self
->myenvobj
->db_env
))
857 MYDB_BEGIN_ALLOW_THREADS
;
858 self
->db
->close(self
->db
, 0);
859 MYDB_END_ALLOW_THREADS
;
862 PyErr_Warn(PyExc_RuntimeWarning
,
863 "DB could not be closed in destructor: DBEnv already closed");
869 if (self
->in_weakreflist
!= NULL
) {
870 PyObject_ClearWeakRefs((PyObject
*) self
);
873 if (self
->myenvobj
) {
874 Py_DECREF(self
->myenvobj
);
875 self
->myenvobj
= NULL
;
878 if (self
->associateCallback
!= NULL
) {
879 Py_DECREF(self
->associateCallback
);
880 self
->associateCallback
= NULL
;
882 if (self
->btCompareCallback
!= NULL
) {
883 Py_DECREF(self
->btCompareCallback
);
884 self
->btCompareCallback
= NULL
;
891 static DBCursorObject
*
892 newDBCursorObject(DBC
* dbc
, DBObject
* db
)
894 DBCursorObject
* self
= PyObject_New(DBCursorObject
, &DBCursor_Type
);
901 self
->in_weakreflist
= NULL
;
903 Py_INCREF(self
->mydb
);
909 DBCursor_dealloc(DBCursorObject
* self
)
914 if (self
->in_weakreflist
!= NULL
) {
915 PyObject_ClearWeakRefs((PyObject
*) self
);
919 if (self
->dbc
!= NULL
) {
920 MYDB_BEGIN_ALLOW_THREADS
;
921 /* If the underlying database has been closed, we don't
922 need to do anything. If the environment has been closed
923 we need to leak, as BerkeleyDB will crash trying to access
924 the environment. There was an exception when the
925 user closed the environment even though there still was
927 if (self
->mydb
->db
&& self
->mydb
->myenvobj
&&
928 !self
->mydb
->myenvobj
->closed
)
929 err
= self
->dbc
->c_close(self
->dbc
);
931 MYDB_END_ALLOW_THREADS
;
933 Py_XDECREF( self
->mydb
);
939 newDBEnvObject(int flags
)
942 DBEnvObject
* self
= PyObject_New(DBEnvObject
, &DBEnv_Type
);
948 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
949 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
951 self
->in_weakreflist
= NULL
;
954 MYDB_BEGIN_ALLOW_THREADS
;
955 err
= db_env_create(&self
->db_env
, flags
);
956 MYDB_END_ALLOW_THREADS
;
957 if (makeDBError(err
)) {
962 self
->db_env
->set_errcall(self
->db_env
, _db_errorCallback
);
969 DBEnv_dealloc(DBEnvObject
* self
)
972 if (self
->in_weakreflist
!= NULL
) {
973 PyObject_ClearWeakRefs((PyObject
*) self
);
977 if (self
->db_env
&& !self
->closed
) {
978 MYDB_BEGIN_ALLOW_THREADS
;
979 self
->db_env
->close(self
->db_env
, 0);
980 MYDB_END_ALLOW_THREADS
;
987 newDBTxnObject(DBEnvObject
* myenv
, DB_TXN
*parent
, int flags
)
990 DBTxnObject
* self
= PyObject_New(DBTxnObject
, &DBTxn_Type
);
994 self
->env
= (PyObject
*)myenv
;
996 self
->in_weakreflist
= NULL
;
999 MYDB_BEGIN_ALLOW_THREADS
;
1001 err
= myenv
->db_env
->txn_begin(myenv
->db_env
, parent
, &(self
->txn
), flags
);
1003 err
= txn_begin(myenv
->db_env
, parent
, &(self
->txn
), flags
);
1005 MYDB_END_ALLOW_THREADS
;
1006 if (makeDBError(err
)) {
1007 Py_DECREF(self
->env
);
1016 DBTxn_dealloc(DBTxnObject
* self
)
1019 if (self
->in_weakreflist
!= NULL
) {
1020 PyObject_ClearWeakRefs((PyObject
*) self
);
1024 #ifdef HAVE_WARNINGS
1026 /* it hasn't been finalized, abort it! */
1027 MYDB_BEGIN_ALLOW_THREADS
;
1029 self
->txn
->abort(self
->txn
);
1031 txn_abort(self
->txn
);
1033 MYDB_END_ALLOW_THREADS
;
1034 PyErr_Warn(PyExc_RuntimeWarning
,
1035 "DBTxn aborted in destructor. No prior commit() or abort().");
1039 Py_DECREF(self
->env
);
1044 static DBLockObject
*
1045 newDBLockObject(DBEnvObject
* myenv
, u_int32_t locker
, DBT
* obj
,
1046 db_lockmode_t lock_mode
, int flags
)
1049 DBLockObject
* self
= PyObject_New(DBLockObject
, &DBLock_Type
);
1053 self
->in_weakreflist
= NULL
;
1056 MYDB_BEGIN_ALLOW_THREADS
;
1058 err
= myenv
->db_env
->lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
,
1061 err
= lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
, &self
->lock
);
1063 MYDB_END_ALLOW_THREADS
;
1064 if (makeDBError(err
)) {
1074 DBLock_dealloc(DBLockObject
* self
)
1077 if (self
->in_weakreflist
!= NULL
) {
1078 PyObject_ClearWeakRefs((PyObject
*) self
);
1081 /* TODO: is this lock held? should we release it? */
1088 static DBSequenceObject
*
1089 newDBSequenceObject(DBObject
* mydb
, int flags
)
1092 DBSequenceObject
* self
= PyObject_New(DBSequenceObject
, &DBSequence_Type
);
1098 self
->in_weakreflist
= NULL
;
1102 MYDB_BEGIN_ALLOW_THREADS
;
1103 err
= db_sequence_create(&self
->sequence
, self
->mydb
->db
, flags
);
1104 MYDB_END_ALLOW_THREADS
;
1105 if (makeDBError(err
)) {
1106 Py_DECREF(self
->mydb
);
1116 DBSequence_dealloc(DBSequenceObject
* self
)
1119 if (self
->in_weakreflist
!= NULL
) {
1120 PyObject_ClearWeakRefs((PyObject
*) self
);
1124 Py_DECREF(self
->mydb
);
1129 /* --------------------------------------------------------------------- */
1133 DB_append(DBObject
* self
, PyObject
* args
)
1135 PyObject
* txnobj
= NULL
;
1141 if (!PyArg_UnpackTuple(args
, "append", 1, 2, &dataobj
, &txnobj
))
1144 CHECK_DB_NOT_CLOSED(self
);
1146 /* make a dummy key out of a recno */
1150 key
.size
= sizeof(recno
);
1151 key
.ulen
= key
.size
;
1152 key
.flags
= DB_DBT_USERMEM
;
1154 if (!make_dbt(dataobj
, &data
)) return NULL
;
1155 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1157 if (-1 == _DB_put(self
, txn
, &key
, &data
, DB_APPEND
))
1160 return PyInt_FromLong(recno
);
1167 _db_associateCallback(DB
* db
, const DBT
* priKey
, const DBT
* priData
,
1170 int retval
= DB_DONOTINDEX
;
1171 DBObject
* secondaryDB
= (DBObject
*)db
->app_private
;
1172 PyObject
* callback
= secondaryDB
->associateCallback
;
1173 int type
= secondaryDB
->primaryDBType
;
1175 PyObject
* result
= NULL
;
1178 if (callback
!= NULL
) {
1179 MYDB_BEGIN_BLOCK_THREADS
;
1181 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
1182 args
= Py_BuildValue("(ls#)", *((db_recno_t
*)priKey
->data
),
1183 priData
->data
, priData
->size
);
1185 args
= Py_BuildValue("(s#s#)", priKey
->data
, priKey
->size
,
1186 priData
->data
, priData
->size
);
1188 result
= PyEval_CallObject(callback
, args
);
1190 if (args
== NULL
|| result
== NULL
) {
1193 else if (result
== Py_None
) {
1194 retval
= DB_DONOTINDEX
;
1196 else if (PyInt_Check(result
)) {
1197 retval
= PyInt_AsLong(result
);
1199 else if (PyString_Check(result
)) {
1204 #if PYTHON_API_VERSION <= 1007
1205 /* 1.5 compatibility */
1206 size
= PyString_Size(result
);
1207 data
= PyString_AsString(result
);
1209 PyString_AsStringAndSize(result
, &data
, &size
);
1211 secKey
->flags
= DB_DBT_APPMALLOC
; /* DB will free */
1212 secKey
->data
= malloc(size
); /* TODO, check this */
1214 memcpy(secKey
->data
, data
, size
);
1215 secKey
->size
= size
;
1219 PyErr_SetString(PyExc_MemoryError
,
1220 "malloc failed in _db_associateCallback");
1227 "DB associate callback should return DB_DONOTINDEX or string.");
1234 MYDB_END_BLOCK_THREADS
;
1241 DB_associate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1244 DBObject
* secondaryDB
;
1247 PyObject
*txnobj
= NULL
;
1249 static char* kwnames
[] = {"secondaryDB", "callback", "flags", "txn",
1252 static char* kwnames
[] = {"secondaryDB", "callback", "flags", NULL
};
1256 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iO:associate", kwnames
,
1257 &secondaryDB
, &callback
, &flags
,
1260 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|i:associate", kwnames
,
1261 &secondaryDB
, &callback
, &flags
)) {
1267 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1270 CHECK_DB_NOT_CLOSED(self
);
1271 if (!DBObject_Check(secondaryDB
)) {
1272 makeTypeError("DB", (PyObject
*)secondaryDB
);
1275 CHECK_DB_NOT_CLOSED(secondaryDB
);
1276 if (callback
== Py_None
) {
1279 else if (!PyCallable_Check(callback
)) {
1280 makeTypeError("Callable", callback
);
1284 /* Save a reference to the callback in the secondary DB. */
1285 Py_XDECREF(secondaryDB
->associateCallback
);
1286 Py_XINCREF(callback
);
1287 secondaryDB
->associateCallback
= callback
;
1288 secondaryDB
->primaryDBType
= _DB_get_type(self
);
1290 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1291 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1292 * The global interepreter lock is not initialized until the first
1293 * thread is created using thread.start_new_thread() or fork() is
1294 * called. that would cause the ALLOW_THREADS here to segfault due
1295 * to a null pointer reference if no threads or child processes
1296 * have been created. This works around that and is a no-op if
1297 * threads have already been initialized.
1298 * (see pybsddb-users mailing list post on 2002-08-07)
1301 PyEval_InitThreads();
1303 MYDB_BEGIN_ALLOW_THREADS
;
1305 err
= self
->db
->associate(self
->db
,
1308 _db_associateCallback
,
1311 err
= self
->db
->associate(self
->db
,
1313 _db_associateCallback
,
1316 MYDB_END_ALLOW_THREADS
;
1319 Py_XDECREF(secondaryDB
->associateCallback
);
1320 secondaryDB
->associateCallback
= NULL
;
1321 secondaryDB
->primaryDBType
= 0;
1333 DB_close(DBObject
* self
, PyObject
* args
)
1336 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
1338 if (self
->db
!= NULL
) {
1340 CHECK_ENV_NOT_CLOSED(self
->myenvobj
);
1341 err
= self
->db
->close(self
->db
, flags
);
1351 _DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1353 int err
, flags
=0, type
;
1354 PyObject
* txnobj
= NULL
;
1355 PyObject
* retval
= NULL
;
1358 static char* kwnames
[] = { "txn", "flags", NULL
};
1360 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:consume", kwnames
,
1364 CHECK_DB_NOT_CLOSED(self
);
1365 type
= _DB_get_type(self
);
1368 if (type
!= DB_QUEUE
) {
1369 PyErr_SetString(PyExc_TypeError
,
1370 "Consume methods only allowed for Queue DB's");
1373 if (!checkTxnObj(txnobj
, &txn
))
1378 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1379 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1380 data
.flags
= DB_DBT_MALLOC
;
1381 key
.flags
= DB_DBT_MALLOC
;
1384 MYDB_BEGIN_ALLOW_THREADS
;
1385 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
|consume_flag
);
1386 MYDB_END_ALLOW_THREADS
;
1388 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1389 && self
->moduleFlags
.getReturnsNone
) {
1395 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
1406 DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1408 return _DB_consume(self
, args
, kwargs
, DB_CONSUME
);
1412 DB_consume_wait(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
,
1415 return _DB_consume(self
, args
, kwargs
, DB_CONSUME_WAIT
);
1422 DB_cursor(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1426 PyObject
* txnobj
= NULL
;
1428 static char* kwnames
[] = { "txn", "flags", NULL
};
1430 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
1433 CHECK_DB_NOT_CLOSED(self
);
1434 if (!checkTxnObj(txnobj
, &txn
))
1437 MYDB_BEGIN_ALLOW_THREADS
;
1438 err
= self
->db
->cursor(self
->db
, txn
, &dbc
, flags
);
1439 MYDB_END_ALLOW_THREADS
;
1441 return (PyObject
*) newDBCursorObject(dbc
, self
);
1446 DB_delete(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1448 PyObject
* txnobj
= NULL
;
1453 static char* kwnames
[] = { "key", "txn", "flags", NULL
};
1455 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:delete", kwnames
,
1456 &keyobj
, &txnobj
, &flags
))
1458 CHECK_DB_NOT_CLOSED(self
);
1459 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1461 if (!checkTxnObj(txnobj
, &txn
)) {
1466 if (-1 == _DB_delete(self
, txn
, &key
, 0)) {
1477 DB_fd(DBObject
* self
, PyObject
* args
)
1481 if (!PyArg_ParseTuple(args
,":fd"))
1483 CHECK_DB_NOT_CLOSED(self
);
1485 MYDB_BEGIN_ALLOW_THREADS
;
1486 err
= self
->db
->fd(self
->db
, &the_fd
);
1487 MYDB_END_ALLOW_THREADS
;
1489 return PyInt_FromLong(the_fd
);
1494 DB_get(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1497 PyObject
* txnobj
= NULL
;
1499 PyObject
* dfltobj
= NULL
;
1500 PyObject
* retval
= NULL
;
1505 static char* kwnames
[] = {"key", "default", "txn", "flags", "dlen",
1508 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:get", kwnames
,
1509 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1513 CHECK_DB_NOT_CLOSED(self
);
1514 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1516 if (!checkTxnObj(txnobj
, &txn
)) {
1522 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1523 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1524 data
.flags
= DB_DBT_MALLOC
;
1526 if (!add_partial_dbt(&data
, dlen
, doff
)) {
1531 MYDB_BEGIN_ALLOW_THREADS
;
1532 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1533 MYDB_END_ALLOW_THREADS
;
1535 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && (dfltobj
!= NULL
)) {
1540 else if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1541 && self
->moduleFlags
.getReturnsNone
) {
1547 if (flags
& DB_SET_RECNO
) /* return both key and data */
1548 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
1550 else /* return just the data */
1551 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
1562 DB_pget(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1565 PyObject
* txnobj
= NULL
;
1567 PyObject
* dfltobj
= NULL
;
1568 PyObject
* retval
= NULL
;
1571 DBT key
, pkey
, data
;
1573 static char* kwnames
[] = {"key", "default", "txn", "flags", "dlen",
1576 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:pget", kwnames
,
1577 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1581 CHECK_DB_NOT_CLOSED(self
);
1582 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1584 if (!checkTxnObj(txnobj
, &txn
)) {
1590 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1591 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1592 data
.flags
= DB_DBT_MALLOC
;
1594 if (!add_partial_dbt(&data
, dlen
, doff
)) {
1600 pkey
.flags
= DB_DBT_MALLOC
;
1602 MYDB_BEGIN_ALLOW_THREADS
;
1603 err
= self
->db
->pget(self
->db
, txn
, &key
, &pkey
, &data
, flags
);
1604 MYDB_END_ALLOW_THREADS
;
1606 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && (dfltobj
!= NULL
)) {
1611 else if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1612 && self
->moduleFlags
.getReturnsNone
) {
1620 dataObj
= PyString_FromStringAndSize(data
.data
, data
.size
);
1622 if (self
->primaryDBType
== DB_RECNO
||
1623 self
->primaryDBType
== DB_QUEUE
)
1624 pkeyObj
= PyInt_FromLong(*(int *)pkey
.data
);
1626 pkeyObj
= PyString_FromStringAndSize(pkey
.data
, pkey
.size
);
1628 if (flags
& DB_SET_RECNO
) /* return key , pkey and data */
1631 int type
= _DB_get_type(self
);
1632 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
1633 keyObj
= PyInt_FromLong(*(int *)key
.data
);
1635 keyObj
= PyString_FromStringAndSize(key
.data
, key
.size
);
1636 #if (PY_VERSION_HEX >= 0x02040000)
1637 retval
= PyTuple_Pack(3, keyObj
, pkeyObj
, dataObj
);
1639 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
1643 else /* return just the pkey and data */
1645 #if (PY_VERSION_HEX >= 0x02040000)
1646 retval
= PyTuple_Pack(2, pkeyObj
, dataObj
);
1648 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
1664 /* Return size of entry */
1666 DB_get_size(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1669 PyObject
* txnobj
= NULL
;
1671 PyObject
* retval
= NULL
;
1674 static char* kwnames
[] = { "key", "txn", NULL
};
1676 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O:get_size", kwnames
,
1679 CHECK_DB_NOT_CLOSED(self
);
1680 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1682 if (!checkTxnObj(txnobj
, &txn
)) {
1688 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
1689 thus getting the record size. */
1690 data
.flags
= DB_DBT_USERMEM
;
1692 MYDB_BEGIN_ALLOW_THREADS
;
1693 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1694 MYDB_END_ALLOW_THREADS
;
1695 if (err
== DB_BUFFER_SMALL
) {
1696 retval
= PyInt_FromLong((long)data
.size
);
1708 DB_get_both(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1711 PyObject
* txnobj
= NULL
;
1714 PyObject
* retval
= NULL
;
1717 static char* kwnames
[] = { "key", "data", "txn", "flags", NULL
};
1720 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oi:get_both", kwnames
,
1721 &keyobj
, &dataobj
, &txnobj
, &flags
))
1724 CHECK_DB_NOT_CLOSED(self
);
1725 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1727 if ( !make_dbt(dataobj
, &data
) ||
1728 !checkTxnObj(txnobj
, &txn
) )
1734 flags
|= DB_GET_BOTH
;
1736 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1737 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1738 data
.flags
= DB_DBT_MALLOC
;
1739 /* TODO: Is this flag needed? We're passing a data object that should
1740 match what's in the DB, so there should be no need to malloc.
1741 We run the risk of freeing something twice! Check this. */
1744 MYDB_BEGIN_ALLOW_THREADS
;
1745 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1746 MYDB_END_ALLOW_THREADS
;
1748 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
1749 && self
->moduleFlags
.getReturnsNone
) {
1755 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
1756 FREE_DBT(data
); /* Only if retrieval was successful */
1766 DB_get_byteswapped(DBObject
* self
, PyObject
* args
)
1773 if (!PyArg_ParseTuple(args
,":get_byteswapped"))
1775 CHECK_DB_NOT_CLOSED(self
);
1778 MYDB_BEGIN_ALLOW_THREADS
;
1779 err
= self
->db
->get_byteswapped(self
->db
, &retval
);
1780 MYDB_END_ALLOW_THREADS
;
1783 MYDB_BEGIN_ALLOW_THREADS
;
1784 retval
= self
->db
->get_byteswapped(self
->db
);
1785 MYDB_END_ALLOW_THREADS
;
1787 return PyInt_FromLong(retval
);
1792 DB_get_type(DBObject
* self
, PyObject
* args
)
1796 if (!PyArg_ParseTuple(args
,":get_type"))
1798 CHECK_DB_NOT_CLOSED(self
);
1800 type
= _DB_get_type(self
);
1803 return PyInt_FromLong(type
);
1808 DB_join(DBObject
* self
, PyObject
* args
)
1812 PyObject
* cursorsObj
;
1816 if (!PyArg_ParseTuple(args
,"O|i:join", &cursorsObj
, &flags
))
1819 CHECK_DB_NOT_CLOSED(self
);
1821 if (!PySequence_Check(cursorsObj
)) {
1822 PyErr_SetString(PyExc_TypeError
,
1823 "Sequence of DBCursor objects expected");
1827 length
= PyObject_Length(cursorsObj
);
1828 cursors
= malloc((length
+1) * sizeof(DBC
*));
1834 cursors
[length
] = NULL
;
1835 for (x
=0; x
<length
; x
++) {
1836 PyObject
* item
= PySequence_GetItem(cursorsObj
, x
);
1841 if (!DBCursorObject_Check(item
)) {
1842 PyErr_SetString(PyExc_TypeError
,
1843 "Sequence of DBCursor objects expected");
1847 cursors
[x
] = ((DBCursorObject
*)item
)->dbc
;
1851 MYDB_BEGIN_ALLOW_THREADS
;
1852 err
= self
->db
->join(self
->db
, cursors
, &dbc
, flags
);
1853 MYDB_END_ALLOW_THREADS
;
1857 /* FIXME: this is a buggy interface. The returned cursor
1858 contains internal references to the passed in cursors
1859 but does not hold python references to them or prevent
1860 them from being closed prematurely. This can cause
1861 python to crash when things are done in the wrong order. */
1862 return (PyObject
*) newDBCursorObject(dbc
, self
);
1867 DB_key_range(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1870 PyObject
* txnobj
= NULL
;
1875 static char* kwnames
[] = { "key", "txn", "flags", NULL
};
1877 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:key_range", kwnames
,
1878 &keyobj
, &txnobj
, &flags
))
1880 CHECK_DB_NOT_CLOSED(self
);
1881 if (!make_dbt(keyobj
, &key
))
1882 /* BTree only, don't need to allow for an int key */
1884 if (!checkTxnObj(txnobj
, &txn
))
1887 MYDB_BEGIN_ALLOW_THREADS
;
1888 err
= self
->db
->key_range(self
->db
, txn
, &key
, &range
, flags
);
1889 MYDB_END_ALLOW_THREADS
;
1892 return Py_BuildValue("ddd", range
.less
, range
.equal
, range
.greater
);
1897 DB_open(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1899 int err
, type
= DB_UNKNOWN
, flags
=0, mode
=0660;
1900 char* filename
= NULL
;
1901 char* dbname
= NULL
;
1903 PyObject
*txnobj
= NULL
;
1906 static char* kwnames
[] = {
1907 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL
};
1908 /* without dbname */
1909 static char* kwnames_basic
[] = {
1910 "filename", "dbtype", "flags", "mode", "txn", NULL
};
1913 static char* kwnames
[] = {
1914 "filename", "dbname", "dbtype", "flags", "mode", NULL
};
1915 /* without dbname */
1916 static char* kwnames_basic
[] = {
1917 "filename", "dbtype", "flags", "mode", NULL
};
1921 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziiiO:open", kwnames
,
1922 &filename
, &dbname
, &type
, &flags
, &mode
,
1925 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziii:open", kwnames
,
1926 &filename
, &dbname
, &type
, &flags
,
1931 type
= DB_UNKNOWN
; flags
= 0; mode
= 0660;
1932 filename
= NULL
; dbname
= NULL
;
1934 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iiiO:open",
1936 &filename
, &type
, &flags
, &mode
,
1940 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iii:open",
1942 &filename
, &type
, &flags
, &mode
))
1948 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1951 if (NULL
== self
->db
) {
1952 PyObject
*t
= Py_BuildValue("(is)", 0,
1953 "Cannot call open() twice for DB object");
1954 PyErr_SetObject(DBError
, t
);
1959 #if 0 && (DBVER >= 41)
1960 if ((!txn
) && (txnobj
!= Py_None
) && self
->myenvobj
1961 && (self
->myenvobj
->flags
& DB_INIT_TXN
))
1963 /* If no 'txn' parameter was supplied (no DbTxn object and None was not
1964 * explicitly passed) but we are in a transaction ready environment:
1965 * add DB_AUTO_COMMIT to allow for older pybsddb apps using transactions
1966 * to work on BerkeleyDB 4.1 without needing to modify their
1967 * DBEnv or DB open calls.
1968 * TODO make this behaviour of the library configurable.
1970 flags
|= DB_AUTO_COMMIT
;
1974 MYDB_BEGIN_ALLOW_THREADS
;
1976 err
= self
->db
->open(self
->db
, txn
, filename
, dbname
, type
, flags
, mode
);
1978 err
= self
->db
->open(self
->db
, filename
, dbname
, type
, flags
, mode
);
1980 MYDB_END_ALLOW_THREADS
;
1981 if (makeDBError(err
)) {
1982 self
->db
->close(self
->db
, 0);
1987 self
->flags
= flags
;
1993 DB_put(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1996 PyObject
* txnobj
= NULL
;
1999 PyObject
* keyobj
, *dataobj
, *retval
;
2002 static char* kwnames
[] = { "key", "data", "txn", "flags", "dlen",
2005 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oiii:put", kwnames
,
2006 &keyobj
, &dataobj
, &txnobj
, &flags
, &dlen
, &doff
))
2009 CHECK_DB_NOT_CLOSED(self
);
2010 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2012 if ( !make_dbt(dataobj
, &data
) ||
2013 !add_partial_dbt(&data
, dlen
, doff
) ||
2014 !checkTxnObj(txnobj
, &txn
) )
2020 if (-1 == _DB_put(self
, txn
, &key
, &data
, flags
)) {
2025 if (flags
& DB_APPEND
)
2026 retval
= PyInt_FromLong(*((db_recno_t
*)key
.data
));
2038 DB_remove(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2041 char* database
= NULL
;
2043 static char* kwnames
[] = { "filename", "dbname", "flags", NULL
};
2045 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zi:remove", kwnames
,
2046 &filename
, &database
, &flags
))
2048 CHECK_DB_NOT_CLOSED(self
);
2050 err
= self
->db
->remove(self
->db
, filename
, database
, flags
);
2059 DB_rename(DBObject
* self
, PyObject
* args
)
2066 if (!PyArg_ParseTuple(args
, "sss|i:rename", &filename
, &database
, &newname
,
2069 CHECK_DB_NOT_CLOSED(self
);
2071 MYDB_BEGIN_ALLOW_THREADS
;
2072 err
= self
->db
->rename(self
->db
, filename
, database
, newname
, flags
);
2073 MYDB_END_ALLOW_THREADS
;
2080 DB_set_bt_minkey(DBObject
* self
, PyObject
* args
)
2084 if (!PyArg_ParseTuple(args
,"i:set_bt_minkey", &minkey
))
2086 CHECK_DB_NOT_CLOSED(self
);
2088 MYDB_BEGIN_ALLOW_THREADS
;
2089 err
= self
->db
->set_bt_minkey(self
->db
, minkey
);
2090 MYDB_END_ALLOW_THREADS
;
2097 _default_cmp(const DBT
*leftKey
,
2098 const DBT
*rightKey
)
2101 int lsize
= leftKey
->size
, rsize
= rightKey
->size
;
2103 res
= memcmp(leftKey
->data
, rightKey
->data
,
2104 lsize
< rsize
? lsize
: rsize
);
2107 if (lsize
< rsize
) {
2110 else if (lsize
> rsize
) {
2118 _db_compareCallback(DB
* db
,
2120 const DBT
*rightKey
)
2124 PyObject
*result
= NULL
;
2125 DBObject
*self
= (DBObject
*)db
->app_private
;
2127 if (self
== NULL
|| self
->btCompareCallback
== NULL
) {
2128 MYDB_BEGIN_BLOCK_THREADS
;
2129 PyErr_SetString(PyExc_TypeError
,
2131 ? "DB_bt_compare db is NULL."
2132 : "DB_bt_compare callback is NULL."));
2133 /* we're in a callback within the DB code, we can't raise */
2135 res
= _default_cmp(leftKey
, rightKey
);
2136 MYDB_END_BLOCK_THREADS
;
2138 MYDB_BEGIN_BLOCK_THREADS
;
2140 args
= Py_BuildValue("s#s#", leftKey
->data
, leftKey
->size
,
2141 rightKey
->data
, rightKey
->size
);
2143 /* XXX(twouters) I highly doubt this INCREF is correct */
2145 result
= PyEval_CallObject(self
->btCompareCallback
, args
);
2147 if (args
== NULL
|| result
== NULL
) {
2148 /* we're in a callback within the DB code, we can't raise */
2150 res
= _default_cmp(leftKey
, rightKey
);
2151 } else if (PyInt_Check(result
)) {
2152 res
= PyInt_AsLong(result
);
2154 PyErr_SetString(PyExc_TypeError
,
2155 "DB_bt_compare callback MUST return an int.");
2156 /* we're in a callback within the DB code, we can't raise */
2158 res
= _default_cmp(leftKey
, rightKey
);
2164 MYDB_END_BLOCK_THREADS
;
2170 DB_set_bt_compare(DBObject
* self
, PyObject
* args
)
2173 PyObject
*comparator
;
2174 PyObject
*tuple
, *result
;
2176 if (!PyArg_ParseTuple(args
, "O:set_bt_compare", &comparator
))
2179 CHECK_DB_NOT_CLOSED(self
);
2181 if (!PyCallable_Check(comparator
)) {
2182 makeTypeError("Callable", comparator
);
2187 * Perform a test call of the comparator function with two empty
2188 * string objects here. verify that it returns an int (0).
2191 tuple
= Py_BuildValue("(ss)", "", "");
2192 result
= PyEval_CallObject(comparator
, tuple
);
2196 if (!PyInt_Check(result
)) {
2197 PyErr_SetString(PyExc_TypeError
,
2198 "callback MUST return an int");
2200 } else if (PyInt_AsLong(result
) != 0) {
2201 PyErr_SetString(PyExc_TypeError
,
2202 "callback failed to return 0 on two empty strings");
2207 /* We don't accept multiple set_bt_compare operations, in order to
2208 * simplify the code. This would have no real use, as one cannot
2209 * change the function once the db is opened anyway */
2210 if (self
->btCompareCallback
!= NULL
) {
2211 PyErr_SetString(PyExc_RuntimeError
, "set_bt_compare() cannot be called more than once");
2215 Py_INCREF(comparator
);
2216 self
->btCompareCallback
= comparator
;
2218 /* This is to workaround a problem with un-initialized threads (see
2219 comment in DB_associate) */
2221 PyEval_InitThreads();
2224 err
= self
->db
->set_bt_compare(self
->db
, _db_compareCallback
);
2227 /* restore the old state in case of error */
2228 Py_DECREF(comparator
);
2229 self
->btCompareCallback
= NULL
;
2235 #endif /* DBVER >= 33 */
2239 DB_set_cachesize(DBObject
* self
, PyObject
* args
)
2242 int gbytes
= 0, bytes
= 0, ncache
= 0;
2244 if (!PyArg_ParseTuple(args
,"ii|i:set_cachesize",
2245 &gbytes
,&bytes
,&ncache
))
2247 CHECK_DB_NOT_CLOSED(self
);
2249 MYDB_BEGIN_ALLOW_THREADS
;
2250 err
= self
->db
->set_cachesize(self
->db
, gbytes
, bytes
, ncache
);
2251 MYDB_END_ALLOW_THREADS
;
2258 DB_set_flags(DBObject
* self
, PyObject
* args
)
2262 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
2264 CHECK_DB_NOT_CLOSED(self
);
2266 MYDB_BEGIN_ALLOW_THREADS
;
2267 err
= self
->db
->set_flags(self
->db
, flags
);
2268 MYDB_END_ALLOW_THREADS
;
2271 self
->setflags
|= flags
;
2277 DB_set_h_ffactor(DBObject
* self
, PyObject
* args
)
2281 if (!PyArg_ParseTuple(args
,"i:set_h_ffactor", &ffactor
))
2283 CHECK_DB_NOT_CLOSED(self
);
2285 MYDB_BEGIN_ALLOW_THREADS
;
2286 err
= self
->db
->set_h_ffactor(self
->db
, ffactor
);
2287 MYDB_END_ALLOW_THREADS
;
2294 DB_set_h_nelem(DBObject
* self
, PyObject
* args
)
2298 if (!PyArg_ParseTuple(args
,"i:set_h_nelem", &nelem
))
2300 CHECK_DB_NOT_CLOSED(self
);
2302 MYDB_BEGIN_ALLOW_THREADS
;
2303 err
= self
->db
->set_h_nelem(self
->db
, nelem
);
2304 MYDB_END_ALLOW_THREADS
;
2311 DB_set_lorder(DBObject
* self
, PyObject
* args
)
2315 if (!PyArg_ParseTuple(args
,"i:set_lorder", &lorder
))
2317 CHECK_DB_NOT_CLOSED(self
);
2319 MYDB_BEGIN_ALLOW_THREADS
;
2320 err
= self
->db
->set_lorder(self
->db
, lorder
);
2321 MYDB_END_ALLOW_THREADS
;
2328 DB_set_pagesize(DBObject
* self
, PyObject
* args
)
2332 if (!PyArg_ParseTuple(args
,"i:set_pagesize", &pagesize
))
2334 CHECK_DB_NOT_CLOSED(self
);
2336 MYDB_BEGIN_ALLOW_THREADS
;
2337 err
= self
->db
->set_pagesize(self
->db
, pagesize
);
2338 MYDB_END_ALLOW_THREADS
;
2345 DB_set_re_delim(DBObject
* self
, PyObject
* args
)
2350 if (!PyArg_ParseTuple(args
,"b:set_re_delim", &delim
)) {
2352 if (!PyArg_ParseTuple(args
,"c:set_re_delim", &delim
))
2356 CHECK_DB_NOT_CLOSED(self
);
2358 MYDB_BEGIN_ALLOW_THREADS
;
2359 err
= self
->db
->set_re_delim(self
->db
, delim
);
2360 MYDB_END_ALLOW_THREADS
;
2366 DB_set_re_len(DBObject
* self
, PyObject
* args
)
2370 if (!PyArg_ParseTuple(args
,"i:set_re_len", &len
))
2372 CHECK_DB_NOT_CLOSED(self
);
2374 MYDB_BEGIN_ALLOW_THREADS
;
2375 err
= self
->db
->set_re_len(self
->db
, len
);
2376 MYDB_END_ALLOW_THREADS
;
2383 DB_set_re_pad(DBObject
* self
, PyObject
* args
)
2388 if (!PyArg_ParseTuple(args
,"b:set_re_pad", &pad
)) {
2390 if (!PyArg_ParseTuple(args
,"c:set_re_pad", &pad
))
2393 CHECK_DB_NOT_CLOSED(self
);
2395 MYDB_BEGIN_ALLOW_THREADS
;
2396 err
= self
->db
->set_re_pad(self
->db
, pad
);
2397 MYDB_END_ALLOW_THREADS
;
2404 DB_set_re_source(DBObject
* self
, PyObject
* args
)
2409 if (!PyArg_ParseTuple(args
,"s:set_re_source", &re_source
))
2411 CHECK_DB_NOT_CLOSED(self
);
2413 MYDB_BEGIN_ALLOW_THREADS
;
2414 err
= self
->db
->set_re_source(self
->db
, re_source
);
2415 MYDB_END_ALLOW_THREADS
;
2423 DB_set_q_extentsize(DBObject
* self
, PyObject
* args
)
2428 if (!PyArg_ParseTuple(args
,"i:set_q_extentsize", &extentsize
))
2430 CHECK_DB_NOT_CLOSED(self
);
2432 MYDB_BEGIN_ALLOW_THREADS
;
2433 err
= self
->db
->set_q_extentsize(self
->db
, extentsize
);
2434 MYDB_END_ALLOW_THREADS
;
2441 DB_stat(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2443 int err
, flags
= 0, type
;
2447 PyObject
* txnobj
= NULL
;
2449 static char* kwnames
[] = { "flags", "txn", NULL
};
2451 static char* kwnames
[] = { "flags", NULL
};
2455 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iO:stat", kwnames
,
2458 if (!checkTxnObj(txnobj
, &txn
))
2461 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat", kwnames
, &flags
))
2464 CHECK_DB_NOT_CLOSED(self
);
2466 MYDB_BEGIN_ALLOW_THREADS
;
2468 err
= self
->db
->stat(self
->db
, txn
, &sp
, flags
);
2470 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2472 err
= self
->db
->stat(self
->db
, &sp
, NULL
, flags
);
2474 MYDB_END_ALLOW_THREADS
;
2479 /* Turn the stat structure into a dictionary */
2480 type
= _DB_get_type(self
);
2481 if ((type
== -1) || ((d
= PyDict_New()) == NULL
)) {
2486 #define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
2487 #define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
2488 #define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
2492 MAKE_HASH_ENTRY(magic
);
2493 MAKE_HASH_ENTRY(version
);
2494 MAKE_HASH_ENTRY(nkeys
);
2495 MAKE_HASH_ENTRY(ndata
);
2496 MAKE_HASH_ENTRY(pagesize
);
2498 MAKE_HASH_ENTRY(nelem
);
2500 MAKE_HASH_ENTRY(ffactor
);
2501 MAKE_HASH_ENTRY(buckets
);
2502 MAKE_HASH_ENTRY(free
);
2503 MAKE_HASH_ENTRY(bfree
);
2504 MAKE_HASH_ENTRY(bigpages
);
2505 MAKE_HASH_ENTRY(big_bfree
);
2506 MAKE_HASH_ENTRY(overflows
);
2507 MAKE_HASH_ENTRY(ovfl_free
);
2508 MAKE_HASH_ENTRY(dup
);
2509 MAKE_HASH_ENTRY(dup_free
);
2514 MAKE_BT_ENTRY(magic
);
2515 MAKE_BT_ENTRY(version
);
2516 MAKE_BT_ENTRY(nkeys
);
2517 MAKE_BT_ENTRY(ndata
);
2518 MAKE_BT_ENTRY(pagesize
);
2519 MAKE_BT_ENTRY(minkey
);
2520 MAKE_BT_ENTRY(re_len
);
2521 MAKE_BT_ENTRY(re_pad
);
2522 MAKE_BT_ENTRY(levels
);
2523 MAKE_BT_ENTRY(int_pg
);
2524 MAKE_BT_ENTRY(leaf_pg
);
2525 MAKE_BT_ENTRY(dup_pg
);
2526 MAKE_BT_ENTRY(over_pg
);
2527 MAKE_BT_ENTRY(free
);
2528 MAKE_BT_ENTRY(int_pgfree
);
2529 MAKE_BT_ENTRY(leaf_pgfree
);
2530 MAKE_BT_ENTRY(dup_pgfree
);
2531 MAKE_BT_ENTRY(over_pgfree
);
2535 MAKE_QUEUE_ENTRY(magic
);
2536 MAKE_QUEUE_ENTRY(version
);
2537 MAKE_QUEUE_ENTRY(nkeys
);
2538 MAKE_QUEUE_ENTRY(ndata
);
2539 MAKE_QUEUE_ENTRY(pagesize
);
2540 MAKE_QUEUE_ENTRY(pages
);
2541 MAKE_QUEUE_ENTRY(re_len
);
2542 MAKE_QUEUE_ENTRY(re_pad
);
2543 MAKE_QUEUE_ENTRY(pgfree
);
2545 MAKE_QUEUE_ENTRY(start
);
2547 MAKE_QUEUE_ENTRY(first_recno
);
2548 MAKE_QUEUE_ENTRY(cur_recno
);
2552 PyErr_SetString(PyExc_TypeError
, "Unknown DB type, unable to stat");
2557 #undef MAKE_HASH_ENTRY
2558 #undef MAKE_BT_ENTRY
2559 #undef MAKE_QUEUE_ENTRY
2566 DB_sync(DBObject
* self
, PyObject
* args
)
2571 if (!PyArg_ParseTuple(args
,"|i:sync", &flags
))
2573 CHECK_DB_NOT_CLOSED(self
);
2575 MYDB_BEGIN_ALLOW_THREADS
;
2576 err
= self
->db
->sync(self
->db
, flags
);
2577 MYDB_END_ALLOW_THREADS
;
2585 DB_truncate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2589 PyObject
* txnobj
= NULL
;
2591 static char* kwnames
[] = { "txn", "flags", NULL
};
2593 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
2596 CHECK_DB_NOT_CLOSED(self
);
2597 if (!checkTxnObj(txnobj
, &txn
))
2600 MYDB_BEGIN_ALLOW_THREADS
;
2601 err
= self
->db
->truncate(self
->db
, txn
, &count
, flags
);
2602 MYDB_END_ALLOW_THREADS
;
2604 return PyInt_FromLong(count
);
2610 DB_upgrade(DBObject
* self
, PyObject
* args
)
2615 if (!PyArg_ParseTuple(args
,"s|i:upgrade", &filename
, &flags
))
2617 CHECK_DB_NOT_CLOSED(self
);
2619 MYDB_BEGIN_ALLOW_THREADS
;
2620 err
= self
->db
->upgrade(self
->db
, filename
, flags
);
2621 MYDB_END_ALLOW_THREADS
;
2628 DB_verify(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2633 char* outFileName
=NULL
;
2635 static char* kwnames
[] = { "filename", "dbname", "outfile", "flags",
2638 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zzi:verify", kwnames
,
2639 &fileName
, &dbName
, &outFileName
, &flags
))
2642 CHECK_DB_NOT_CLOSED(self
);
2644 outFile
= fopen(outFileName
, "w");
2645 /* XXX(nnorwitz): it should probably be an exception if outFile
2648 MYDB_BEGIN_ALLOW_THREADS
;
2649 err
= self
->db
->verify(self
->db
, fileName
, dbName
, outFile
, flags
);
2650 MYDB_END_ALLOW_THREADS
;
2654 /* DB.verify acts as a DB handle destructor (like close); this was
2655 * documented in BerkeleyDB 4.2 but had the undocumented effect
2656 * of not being safe in prior versions while still requiring an explicit
2657 * DB.close call afterwards. Lets call close for the user to emulate
2658 * the safe 4.2 behaviour. */
2660 self
->db
->close(self
->db
, 0);
2670 DB_set_get_returns_none(DBObject
* self
, PyObject
* args
)
2675 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
2677 CHECK_DB_NOT_CLOSED(self
);
2679 if (self
->moduleFlags
.getReturnsNone
)
2681 if (self
->moduleFlags
.cursorSetReturnsNone
)
2683 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
2684 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
2685 return PyInt_FromLong(oldValue
);
2690 DB_set_encrypt(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2694 char *passwd
= NULL
;
2695 static char* kwnames
[] = { "passwd", "flags", NULL
};
2697 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
2702 MYDB_BEGIN_ALLOW_THREADS
;
2703 err
= self
->db
->set_encrypt(self
->db
, passwd
, flags
);
2704 MYDB_END_ALLOW_THREADS
;
2709 #endif /* DBVER >= 41 */
2712 /*-------------------------------------------------------------- */
2713 /* Mapping and Dictionary-like access routines */
2715 Py_ssize_t
DB_length(PyObject
* _self
)
2718 Py_ssize_t size
= 0;
2721 DBObject
* self
= (DBObject
*)_self
;
2723 if (self
->db
== NULL
) {
2724 PyObject
*t
= Py_BuildValue("(is)", 0, "DB object has been closed");
2725 PyErr_SetObject(DBError
, t
);
2730 if (self
->haveStat
) { /* Has the stat function been called recently? If
2731 so, we can use the cached value. */
2732 flags
= DB_FAST_STAT
;
2735 MYDB_BEGIN_ALLOW_THREADS
;
2736 redo_stat_for_length
:
2738 err
= self
->db
->stat(self
->db
, /*txnid*/ NULL
, &sp
, flags
);
2740 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2742 err
= self
->db
->stat(self
->db
, &sp
, NULL
, flags
);
2745 /* All the stat structures have matching fields upto the ndata field,
2746 so we can use any of them for the type cast */
2747 size
= ((DB_BTREE_STAT
*)sp
)->bt_ndata
;
2749 /* A size of 0 could mean that BerkeleyDB no longer had the stat values cached.
2750 * redo a full stat to make sure.
2751 * Fixes SF python bug 1493322, pybsddb bug 1184012
2753 if (size
== 0 && (flags
& DB_FAST_STAT
)) {
2757 goto redo_stat_for_length
;
2760 MYDB_END_ALLOW_THREADS
;
2772 PyObject
* DB_subscript(DBObject
* self
, PyObject
* keyobj
)
2779 CHECK_DB_NOT_CLOSED(self
);
2780 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2784 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2785 /* Tell BerkeleyDB to malloc the return value (thread safe) */
2786 data
.flags
= DB_DBT_MALLOC
;
2788 MYDB_BEGIN_ALLOW_THREADS
;
2789 err
= self
->db
->get(self
->db
, NULL
, &key
, &data
, 0);
2790 MYDB_END_ALLOW_THREADS
;
2791 if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
2792 PyErr_SetObject(PyExc_KeyError
, keyobj
);
2795 else if (makeDBError(err
)) {
2799 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
2809 DB_ass_sub(DBObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
)
2815 if (self
->db
== NULL
) {
2816 PyObject
*t
= Py_BuildValue("(is)", 0, "DB object has been closed");
2817 PyErr_SetObject(DBError
, t
);
2822 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2825 if (dataobj
!= NULL
) {
2826 if (!make_dbt(dataobj
, &data
))
2829 if (self
->setflags
& (DB_DUP
|DB_DUPSORT
))
2830 /* dictionaries shouldn't have duplicate keys */
2831 flags
= DB_NOOVERWRITE
;
2832 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2834 if ((retval
== -1) && (self
->setflags
& (DB_DUP
|DB_DUPSORT
))) {
2835 /* try deleting any old record that matches and then PUT it
2837 _DB_delete(self
, NULL
, &key
, 0);
2839 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2844 /* dataobj == NULL, so delete the key */
2845 retval
= _DB_delete(self
, NULL
, &key
, 0);
2853 DB_has_key(DBObject
* self
, PyObject
* args
)
2858 PyObject
* txnobj
= NULL
;
2861 if (!PyArg_ParseTuple(args
,"O|O:has_key", &keyobj
, &txnobj
))
2863 CHECK_DB_NOT_CLOSED(self
);
2864 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2866 if (!checkTxnObj(txnobj
, &txn
)) {
2871 /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
2872 it has a record but can't allocate a buffer for the data. This saves
2873 having to deal with data we won't be using.
2876 data
.flags
= DB_DBT_USERMEM
;
2878 MYDB_BEGIN_ALLOW_THREADS
;
2879 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, 0);
2880 MYDB_END_ALLOW_THREADS
;
2883 if (err
== DB_BUFFER_SMALL
|| err
== 0) {
2884 return PyInt_FromLong(1);
2885 } else if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
2886 return PyInt_FromLong(0);
2894 #define _KEYS_LIST 1
2895 #define _VALUES_LIST 2
2896 #define _ITEMS_LIST 3
2899 _DB_make_list(DBObject
* self
, DB_TXN
* txn
, int type
)
2906 PyObject
* item
= NULL
;
2908 CHECK_DB_NOT_CLOSED(self
);
2912 dbtype
= _DB_get_type(self
);
2916 list
= PyList_New(0);
2921 MYDB_BEGIN_ALLOW_THREADS
;
2922 err
= self
->db
->cursor(self
->db
, txn
, &cursor
, 0);
2923 MYDB_END_ALLOW_THREADS
;
2924 if (makeDBError(err
)) {
2929 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2930 key
.flags
= DB_DBT_REALLOC
;
2931 data
.flags
= DB_DBT_REALLOC
;
2934 while (1) { /* use the cursor to traverse the DB, collecting items */
2935 MYDB_BEGIN_ALLOW_THREADS
;
2936 err
= cursor
->c_get(cursor
, &key
, &data
, DB_NEXT
);
2937 MYDB_END_ALLOW_THREADS
;
2940 /* for any error, break out of the loop */
2950 item
= PyString_FromStringAndSize((char*)key
.data
, key
.size
);
2954 item
= PyInt_FromLong(*((db_recno_t
*)key
.data
));
2960 item
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
2968 item
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
2973 item
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
2974 data
.data
, data
.size
);
2979 PyErr_Format(PyExc_ValueError
, "Unknown key type 0x%x", type
);
2988 PyList_Append(list
, item
);
2992 /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
2993 if (err
!= DB_NOTFOUND
&& err
!= DB_KEYEMPTY
&& makeDBError(err
)) {
3001 MYDB_BEGIN_ALLOW_THREADS
;
3002 cursor
->c_close(cursor
);
3003 MYDB_END_ALLOW_THREADS
;
3009 DB_keys(DBObject
* self
, PyObject
* args
)
3011 PyObject
* txnobj
= NULL
;
3014 if (!PyArg_UnpackTuple(args
, "keys", 0, 1, &txnobj
))
3016 if (!checkTxnObj(txnobj
, &txn
))
3018 return _DB_make_list(self
, txn
, _KEYS_LIST
);
3023 DB_items(DBObject
* self
, PyObject
* args
)
3025 PyObject
* txnobj
= NULL
;
3028 if (!PyArg_UnpackTuple(args
, "items", 0, 1, &txnobj
))
3030 if (!checkTxnObj(txnobj
, &txn
))
3032 return _DB_make_list(self
, txn
, _ITEMS_LIST
);
3037 DB_values(DBObject
* self
, PyObject
* args
)
3039 PyObject
* txnobj
= NULL
;
3042 if (!PyArg_UnpackTuple(args
, "values", 0, 1, &txnobj
))
3044 if (!checkTxnObj(txnobj
, &txn
))
3046 return _DB_make_list(self
, txn
, _VALUES_LIST
);
3049 /* --------------------------------------------------------------------- */
3050 /* DBCursor methods */
3054 DBC_close(DBCursorObject
* self
, PyObject
* args
)
3058 if (!PyArg_ParseTuple(args
, ":close"))
3061 if (self
->dbc
!= NULL
) {
3062 MYDB_BEGIN_ALLOW_THREADS
;
3063 err
= self
->dbc
->c_close(self
->dbc
);
3065 MYDB_END_ALLOW_THREADS
;
3073 DBC_count(DBCursorObject
* self
, PyObject
* args
)
3079 if (!PyArg_ParseTuple(args
, "|i:count", &flags
))
3082 CHECK_CURSOR_NOT_CLOSED(self
);
3084 MYDB_BEGIN_ALLOW_THREADS
;
3085 err
= self
->dbc
->c_count(self
->dbc
, &count
, flags
);
3086 MYDB_END_ALLOW_THREADS
;
3089 return PyInt_FromLong(count
);
3094 DBC_current(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3096 return _DBCursor_get(self
,DB_CURRENT
,args
,kwargs
,"|iii:current");
3101 DBC_delete(DBCursorObject
* self
, PyObject
* args
)
3105 if (!PyArg_ParseTuple(args
, "|i:delete", &flags
))
3108 CHECK_CURSOR_NOT_CLOSED(self
);
3110 MYDB_BEGIN_ALLOW_THREADS
;
3111 err
= self
->dbc
->c_del(self
->dbc
, flags
);
3112 MYDB_END_ALLOW_THREADS
;
3115 self
->mydb
->haveStat
= 0;
3121 DBC_dup(DBCursorObject
* self
, PyObject
* args
)
3126 if (!PyArg_ParseTuple(args
, "|i:dup", &flags
))
3129 CHECK_CURSOR_NOT_CLOSED(self
);
3131 MYDB_BEGIN_ALLOW_THREADS
;
3132 err
= self
->dbc
->c_dup(self
->dbc
, &dbc
, flags
);
3133 MYDB_END_ALLOW_THREADS
;
3136 return (PyObject
*) newDBCursorObject(dbc
, self
->mydb
);
3140 DBC_first(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3142 return _DBCursor_get(self
,DB_FIRST
,args
,kwargs
,"|iii:first");
3147 DBC_get(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3150 PyObject
* keyobj
= NULL
;
3151 PyObject
* dataobj
= NULL
;
3152 PyObject
* retval
= NULL
;
3156 static char* kwnames
[] = { "key","data", "flags", "dlen", "doff",
3161 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:get", &kwnames
[2],
3162 &flags
, &dlen
, &doff
))
3165 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:get",
3167 &keyobj
, &flags
, &dlen
, &doff
))
3170 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:get",
3171 kwnames
, &keyobj
, &dataobj
,
3172 &flags
, &dlen
, &doff
))
3179 CHECK_CURSOR_NOT_CLOSED(self
);
3181 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3183 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
3184 (!add_partial_dbt(&data
, dlen
, doff
)) )
3190 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3191 data
.flags
= DB_DBT_MALLOC
;
3192 if (!(key
.flags
& DB_DBT_REALLOC
)) {
3193 key
.flags
|= DB_DBT_MALLOC
;
3197 MYDB_BEGIN_ALLOW_THREADS
;
3198 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
3199 MYDB_END_ALLOW_THREADS
;
3201 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3202 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3206 else if (makeDBError(err
)) {
3210 switch (_DB_get_type(self
->mydb
)) {
3217 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3218 data
.data
, data
.size
);
3222 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3223 data
.data
, data
.size
);
3234 DBC_pget(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3237 PyObject
* keyobj
= NULL
;
3238 PyObject
* dataobj
= NULL
;
3239 PyObject
* retval
= NULL
;
3242 DBT key
, pkey
, data
;
3243 static char* kwnames_keyOnly
[] = { "key", "flags", "dlen", "doff", NULL
};
3244 static char* kwnames
[] = { "key", "data", "flags", "dlen", "doff", NULL
};
3248 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:pget", &kwnames
[2],
3249 &flags
, &dlen
, &doff
))
3252 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:pget",
3254 &keyobj
, &flags
, &dlen
, &doff
))
3257 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:pget",
3258 kwnames
, &keyobj
, &dataobj
,
3259 &flags
, &dlen
, &doff
))
3266 CHECK_CURSOR_NOT_CLOSED(self
);
3268 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3270 if ( (dataobj
&& !make_dbt(dataobj
, &data
)) ||
3271 (!add_partial_dbt(&data
, dlen
, doff
)) ) {
3276 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3277 data
.flags
= DB_DBT_MALLOC
;
3278 if (!(key
.flags
& DB_DBT_REALLOC
)) {
3279 key
.flags
|= DB_DBT_MALLOC
;
3284 pkey
.flags
= DB_DBT_MALLOC
;
3286 MYDB_BEGIN_ALLOW_THREADS
;
3287 err
= self
->dbc
->c_pget(self
->dbc
, &key
, &pkey
, &data
, flags
);
3288 MYDB_END_ALLOW_THREADS
;
3290 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3291 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3295 else if (makeDBError(err
)) {
3301 dataObj
= PyString_FromStringAndSize(data
.data
, data
.size
);
3303 if (self
->mydb
->primaryDBType
== DB_RECNO
||
3304 self
->mydb
->primaryDBType
== DB_QUEUE
)
3305 pkeyObj
= PyInt_FromLong(*(int *)pkey
.data
);
3307 pkeyObj
= PyString_FromStringAndSize(pkey
.data
, pkey
.size
);
3309 if (key
.data
&& key
.size
) /* return key, pkey and data */
3312 int type
= _DB_get_type(self
->mydb
);
3313 if (type
== DB_RECNO
|| type
== DB_QUEUE
)
3314 keyObj
= PyInt_FromLong(*(int *)key
.data
);
3316 keyObj
= PyString_FromStringAndSize(key
.data
, key
.size
);
3317 #if (PY_VERSION_HEX >= 0x02040000)
3318 retval
= PyTuple_Pack(3, keyObj
, pkeyObj
, dataObj
);
3320 retval
= Py_BuildValue("OOO", keyObj
, pkeyObj
, dataObj
);
3325 else /* return just the pkey and data */
3327 #if (PY_VERSION_HEX >= 0x02040000)
3328 retval
= PyTuple_Pack(2, pkeyObj
, dataObj
);
3330 retval
= Py_BuildValue("OO", pkeyObj
, dataObj
);
3338 /* the only time REALLOC should be set is if we used an integer
3339 * key that make_key_dbt malloc'd for us. always free these. */
3340 if (key
.flags
& DB_DBT_REALLOC
) {
3349 DBC_get_recno(DBCursorObject
* self
, PyObject
* args
)
3356 if (!PyArg_ParseTuple(args
, ":get_recno"))
3359 CHECK_CURSOR_NOT_CLOSED(self
);
3363 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3364 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3365 data
.flags
= DB_DBT_MALLOC
;
3366 key
.flags
= DB_DBT_MALLOC
;
3369 MYDB_BEGIN_ALLOW_THREADS
;
3370 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, DB_GET_RECNO
);
3371 MYDB_END_ALLOW_THREADS
;
3374 recno
= *((db_recno_t
*)data
.data
);
3377 return PyInt_FromLong(recno
);
3382 DBC_last(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3384 return _DBCursor_get(self
,DB_LAST
,args
,kwargs
,"|iii:last");
3389 DBC_next(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3391 return _DBCursor_get(self
,DB_NEXT
,args
,kwargs
,"|iii:next");
3396 DBC_prev(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3398 return _DBCursor_get(self
,DB_PREV
,args
,kwargs
,"|iii:prev");
3403 DBC_put(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3406 PyObject
* keyobj
, *dataobj
;
3408 static char* kwnames
[] = { "key", "data", "flags", "dlen", "doff",
3413 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iii:put", kwnames
,
3414 &keyobj
, &dataobj
, &flags
, &dlen
, &doff
))
3417 CHECK_CURSOR_NOT_CLOSED(self
);
3419 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3421 if (!make_dbt(dataobj
, &data
) ||
3422 !add_partial_dbt(&data
, dlen
, doff
) )
3428 MYDB_BEGIN_ALLOW_THREADS
;
3429 err
= self
->dbc
->c_put(self
->dbc
, &key
, &data
, flags
);
3430 MYDB_END_ALLOW_THREADS
;
3433 self
->mydb
->haveStat
= 0;
3439 DBC_set(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3443 PyObject
* retval
, *keyobj
;
3444 static char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
3448 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set", kwnames
,
3449 &keyobj
, &flags
, &dlen
, &doff
))
3452 CHECK_CURSOR_NOT_CLOSED(self
);
3454 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3458 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3459 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3460 data
.flags
= DB_DBT_MALLOC
;
3462 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3467 MYDB_BEGIN_ALLOW_THREADS
;
3468 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET
);
3469 MYDB_END_ALLOW_THREADS
;
3470 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3471 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3475 else if (makeDBError(err
)) {
3479 switch (_DB_get_type(self
->mydb
)) {
3486 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3487 data
.data
, data
.size
);
3491 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3492 data
.data
, data
.size
);
3498 /* the only time REALLOC should be set is if we used an integer
3499 * key that make_key_dbt malloc'd for us. always free these. */
3500 if (key
.flags
& DB_DBT_REALLOC
) {
3509 DBC_set_range(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3513 PyObject
* retval
, *keyobj
;
3514 static char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
3518 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set_range", kwnames
,
3519 &keyobj
, &flags
, &dlen
, &doff
))
3522 CHECK_CURSOR_NOT_CLOSED(self
);
3524 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3528 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3532 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3533 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3534 data
.flags
|= DB_DBT_MALLOC
;
3535 /* only BTREE databases will return anything in the key */
3536 if (!(key
.flags
& DB_DBT_REALLOC
) && _DB_get_type(self
->mydb
) == DB_BTREE
) {
3537 key
.flags
|= DB_DBT_MALLOC
;
3540 MYDB_BEGIN_ALLOW_THREADS
;
3541 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RANGE
);
3542 MYDB_END_ALLOW_THREADS
;
3543 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3544 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3548 else if (makeDBError(err
)) {
3552 switch (_DB_get_type(self
->mydb
)) {
3559 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3560 data
.data
, data
.size
);
3564 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3565 data
.data
, data
.size
);
3571 /* the only time REALLOC should be set is if we used an integer
3572 * key that make_key_dbt malloc'd for us. always free these. */
3573 if (key
.flags
& DB_DBT_REALLOC
) {
3581 _DBC_get_set_both(DBCursorObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
,
3582 int flags
, unsigned int returnsNone
)
3588 /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
3589 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
3591 if (!make_dbt(dataobj
, &data
)) {
3596 MYDB_BEGIN_ALLOW_THREADS
;
3597 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_GET_BOTH
);
3598 MYDB_END_ALLOW_THREADS
;
3599 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) && returnsNone
) {
3603 else if (makeDBError(err
)) {
3607 switch (_DB_get_type(self
->mydb
)) {
3614 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3615 data
.data
, data
.size
);
3619 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
3620 data
.data
, data
.size
);
3630 DBC_get_both(DBCursorObject
* self
, PyObject
* args
)
3633 PyObject
*keyobj
, *dataobj
;
3635 if (!PyArg_ParseTuple(args
, "OO|i:get_both", &keyobj
, &dataobj
, &flags
))
3638 /* if the cursor is closed, self->mydb may be invalid */
3639 CHECK_CURSOR_NOT_CLOSED(self
);
3641 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3642 self
->mydb
->moduleFlags
.getReturnsNone
);
3645 /* Return size of entry */
3647 DBC_get_current_size(DBCursorObject
* self
, PyObject
* args
)
3649 int err
, flags
=DB_CURRENT
;
3650 PyObject
* retval
= NULL
;
3653 if (!PyArg_ParseTuple(args
, ":get_current_size"))
3655 CHECK_CURSOR_NOT_CLOSED(self
);
3659 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
3660 getting the record size. */
3661 data
.flags
= DB_DBT_USERMEM
;
3663 MYDB_BEGIN_ALLOW_THREADS
;
3664 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
3665 MYDB_END_ALLOW_THREADS
;
3666 if (err
== DB_BUFFER_SMALL
|| !err
) {
3667 /* DB_BUFFER_SMALL means positive size, !err means zero length value */
3668 retval
= PyInt_FromLong((long)data
.size
);
3679 DBC_set_both(DBCursorObject
* self
, PyObject
* args
)
3682 PyObject
*keyobj
, *dataobj
;
3684 if (!PyArg_ParseTuple(args
, "OO|i:set_both", &keyobj
, &dataobj
, &flags
))
3687 /* if the cursor is closed, self->mydb may be invalid */
3688 CHECK_CURSOR_NOT_CLOSED(self
);
3690 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3691 self
->mydb
->moduleFlags
.cursorSetReturnsNone
);
3696 DBC_set_recno(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3698 int err
, irecno
, flags
=0;
3704 static char* kwnames
[] = { "recno","flags", "dlen", "doff", NULL
};
3706 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|iii:set_recno", kwnames
,
3707 &irecno
, &flags
, &dlen
, &doff
))
3710 CHECK_CURSOR_NOT_CLOSED(self
);
3713 recno
= (db_recno_t
) irecno
;
3714 /* use allocated space so DB will be able to realloc room for the real
3716 key
.data
= malloc(sizeof(db_recno_t
));
3717 if (key
.data
== NULL
) {
3718 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
3721 key
.size
= sizeof(db_recno_t
);
3722 key
.ulen
= key
.size
;
3723 memcpy(key
.data
, &recno
, sizeof(db_recno_t
));
3724 key
.flags
= DB_DBT_REALLOC
;
3727 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3728 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3729 data
.flags
= DB_DBT_MALLOC
;
3731 if (!add_partial_dbt(&data
, dlen
, doff
)) {
3736 MYDB_BEGIN_ALLOW_THREADS
;
3737 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RECNO
);
3738 MYDB_END_ALLOW_THREADS
;
3739 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3740 && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3744 else if (makeDBError(err
)) {
3747 else { /* Can only be used for BTrees, so no need to return int key */
3748 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3749 data
.data
, data
.size
);
3759 DBC_consume(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3761 return _DBCursor_get(self
,DB_CONSUME
,args
,kwargs
,"|iii:consume");
3766 DBC_next_dup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3768 return _DBCursor_get(self
,DB_NEXT_DUP
,args
,kwargs
,"|iii:next_dup");
3773 DBC_next_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3775 return _DBCursor_get(self
,DB_NEXT_NODUP
,args
,kwargs
,"|iii:next_nodup");
3780 DBC_prev_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3782 return _DBCursor_get(self
,DB_PREV_NODUP
,args
,kwargs
,"|iii:prev_nodup");
3787 DBC_join_item(DBCursorObject
* self
, PyObject
* args
)
3793 if (!PyArg_ParseTuple(args
, "|i:join_item", &flags
))
3796 CHECK_CURSOR_NOT_CLOSED(self
);
3800 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3801 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3802 key
.flags
= DB_DBT_MALLOC
;
3805 MYDB_BEGIN_ALLOW_THREADS
;
3806 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
| DB_JOIN_ITEM
);
3807 MYDB_END_ALLOW_THREADS
;
3808 if ((err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
)
3809 && self
->mydb
->moduleFlags
.getReturnsNone
) {
3813 else if (makeDBError(err
)) {
3817 retval
= Py_BuildValue("s#", key
.data
, key
.size
);
3826 /* --------------------------------------------------------------------- */
3831 DBEnv_close(DBEnvObject
* self
, PyObject
* args
)
3835 if (!PyArg_ParseTuple(args
, "|i:close", &flags
))
3837 if (!self
->closed
) { /* Don't close more than once */
3838 MYDB_BEGIN_ALLOW_THREADS
;
3839 err
= self
->db_env
->close(self
->db_env
, flags
);
3840 MYDB_END_ALLOW_THREADS
;
3841 /* after calling DBEnv->close, regardless of error, this DBEnv
3842 * may not be accessed again (BerkeleyDB docs). */
3844 self
->db_env
= NULL
;
3852 DBEnv_open(DBEnvObject
* self
, PyObject
* args
)
3854 int err
, flags
=0, mode
=0660;
3857 if (!PyArg_ParseTuple(args
, "z|ii:open", &db_home
, &flags
, &mode
))
3860 CHECK_ENV_NOT_CLOSED(self
);
3862 MYDB_BEGIN_ALLOW_THREADS
;
3863 err
= self
->db_env
->open(self
->db_env
, db_home
, flags
, mode
);
3864 MYDB_END_ALLOW_THREADS
;
3867 self
->flags
= flags
;
3873 DBEnv_remove(DBEnvObject
* self
, PyObject
* args
)
3878 if (!PyArg_ParseTuple(args
, "s|i:remove", &db_home
, &flags
))
3880 CHECK_ENV_NOT_CLOSED(self
);
3881 MYDB_BEGIN_ALLOW_THREADS
;
3882 err
= self
->db_env
->remove(self
->db_env
, db_home
, flags
);
3883 MYDB_END_ALLOW_THREADS
;
3890 DBEnv_dbremove(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3895 char *database
= NULL
;
3896 PyObject
*txnobj
= NULL
;
3898 static char* kwnames
[] = { "file", "database", "txn", "flags",
3901 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zOi:dbremove", kwnames
,
3902 &file
, &database
, &txnobj
, &flags
)) {
3905 if (!checkTxnObj(txnobj
, &txn
)) {
3908 CHECK_ENV_NOT_CLOSED(self
);
3909 MYDB_BEGIN_ALLOW_THREADS
;
3910 err
= self
->db_env
->dbremove(self
->db_env
, txn
, file
, database
, flags
);
3911 MYDB_END_ALLOW_THREADS
;
3917 DBEnv_dbrename(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3922 char *database
= NULL
;
3923 char *newname
= NULL
;
3924 PyObject
*txnobj
= NULL
;
3926 static char* kwnames
[] = { "file", "database", "newname", "txn",
3929 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "szs|Oi:dbrename", kwnames
,
3930 &file
, &database
, &newname
, &txnobj
, &flags
)) {
3933 if (!checkTxnObj(txnobj
, &txn
)) {
3936 CHECK_ENV_NOT_CLOSED(self
);
3937 MYDB_BEGIN_ALLOW_THREADS
;
3938 err
= self
->db_env
->dbrename(self
->db_env
, txn
, file
, database
, newname
,
3940 MYDB_END_ALLOW_THREADS
;
3946 DBEnv_set_encrypt(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3950 char *passwd
= NULL
;
3951 static char* kwnames
[] = { "passwd", "flags", NULL
};
3953 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
3958 MYDB_BEGIN_ALLOW_THREADS
;
3959 err
= self
->db_env
->set_encrypt(self
->db_env
, passwd
, flags
);
3960 MYDB_END_ALLOW_THREADS
;
3965 #endif /* DBVER >= 41 */
3969 DBEnv_set_timeout(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3973 u_int32_t timeout
= 0;
3974 static char* kwnames
[] = { "timeout", "flags", NULL
};
3976 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ii:set_timeout", kwnames
,
3977 &timeout
, &flags
)) {
3981 MYDB_BEGIN_ALLOW_THREADS
;
3982 err
= self
->db_env
->set_timeout(self
->db_env
, (db_timeout_t
)timeout
, flags
);
3983 MYDB_END_ALLOW_THREADS
;
3988 #endif /* DBVER >= 40 */
3991 DBEnv_set_shm_key(DBEnvObject
* self
, PyObject
* args
)
3996 if (!PyArg_ParseTuple(args
, "l:set_shm_key", &shm_key
))
3998 CHECK_ENV_NOT_CLOSED(self
);
4000 err
= self
->db_env
->set_shm_key(self
->db_env
, shm_key
);
4006 DBEnv_set_cachesize(DBEnvObject
* self
, PyObject
* args
)
4008 int err
, gbytes
=0, bytes
=0, ncache
=0;
4010 if (!PyArg_ParseTuple(args
, "ii|i:set_cachesize",
4011 &gbytes
, &bytes
, &ncache
))
4013 CHECK_ENV_NOT_CLOSED(self
);
4015 MYDB_BEGIN_ALLOW_THREADS
;
4016 err
= self
->db_env
->set_cachesize(self
->db_env
, gbytes
, bytes
, ncache
);
4017 MYDB_END_ALLOW_THREADS
;
4025 DBEnv_set_flags(DBEnvObject
* self
, PyObject
* args
)
4027 int err
, flags
=0, onoff
=0;
4029 if (!PyArg_ParseTuple(args
, "ii:set_flags",
4032 CHECK_ENV_NOT_CLOSED(self
);
4034 MYDB_BEGIN_ALLOW_THREADS
;
4035 err
= self
->db_env
->set_flags(self
->db_env
, flags
, onoff
);
4036 MYDB_END_ALLOW_THREADS
;
4044 DBEnv_set_data_dir(DBEnvObject
* self
, PyObject
* args
)
4049 if (!PyArg_ParseTuple(args
, "s:set_data_dir", &dir
))
4051 CHECK_ENV_NOT_CLOSED(self
);
4053 MYDB_BEGIN_ALLOW_THREADS
;
4054 err
= self
->db_env
->set_data_dir(self
->db_env
, dir
);
4055 MYDB_END_ALLOW_THREADS
;
4062 DBEnv_set_lg_bsize(DBEnvObject
* self
, PyObject
* args
)
4066 if (!PyArg_ParseTuple(args
, "i:set_lg_bsize", &lg_bsize
))
4068 CHECK_ENV_NOT_CLOSED(self
);
4070 MYDB_BEGIN_ALLOW_THREADS
;
4071 err
= self
->db_env
->set_lg_bsize(self
->db_env
, lg_bsize
);
4072 MYDB_END_ALLOW_THREADS
;
4079 DBEnv_set_lg_dir(DBEnvObject
* self
, PyObject
* args
)
4084 if (!PyArg_ParseTuple(args
, "s:set_lg_dir", &dir
))
4086 CHECK_ENV_NOT_CLOSED(self
);
4088 MYDB_BEGIN_ALLOW_THREADS
;
4089 err
= self
->db_env
->set_lg_dir(self
->db_env
, dir
);
4090 MYDB_END_ALLOW_THREADS
;
4096 DBEnv_set_lg_max(DBEnvObject
* self
, PyObject
* args
)
4100 if (!PyArg_ParseTuple(args
, "i:set_lg_max", &lg_max
))
4102 CHECK_ENV_NOT_CLOSED(self
);
4104 MYDB_BEGIN_ALLOW_THREADS
;
4105 err
= self
->db_env
->set_lg_max(self
->db_env
, lg_max
);
4106 MYDB_END_ALLOW_THREADS
;
4114 DBEnv_set_lg_regionmax(DBEnvObject
* self
, PyObject
* args
)
4118 if (!PyArg_ParseTuple(args
, "i:set_lg_regionmax", &lg_max
))
4120 CHECK_ENV_NOT_CLOSED(self
);
4122 MYDB_BEGIN_ALLOW_THREADS
;
4123 err
= self
->db_env
->set_lg_regionmax(self
->db_env
, lg_max
);
4124 MYDB_END_ALLOW_THREADS
;
4132 DBEnv_set_lk_detect(DBEnvObject
* self
, PyObject
* args
)
4136 if (!PyArg_ParseTuple(args
, "i:set_lk_detect", &lk_detect
))
4138 CHECK_ENV_NOT_CLOSED(self
);
4140 MYDB_BEGIN_ALLOW_THREADS
;
4141 err
= self
->db_env
->set_lk_detect(self
->db_env
, lk_detect
);
4142 MYDB_END_ALLOW_THREADS
;
4150 DBEnv_set_lk_max(DBEnvObject
* self
, PyObject
* args
)
4154 if (!PyArg_ParseTuple(args
, "i:set_lk_max", &max
))
4156 CHECK_ENV_NOT_CLOSED(self
);
4158 MYDB_BEGIN_ALLOW_THREADS
;
4159 err
= self
->db_env
->set_lk_max(self
->db_env
, max
);
4160 MYDB_END_ALLOW_THREADS
;
4170 DBEnv_set_lk_max_locks(DBEnvObject
* self
, PyObject
* args
)
4174 if (!PyArg_ParseTuple(args
, "i:set_lk_max_locks", &max
))
4176 CHECK_ENV_NOT_CLOSED(self
);
4178 MYDB_BEGIN_ALLOW_THREADS
;
4179 err
= self
->db_env
->set_lk_max_locks(self
->db_env
, max
);
4180 MYDB_END_ALLOW_THREADS
;
4187 DBEnv_set_lk_max_lockers(DBEnvObject
* self
, PyObject
* args
)
4191 if (!PyArg_ParseTuple(args
, "i:set_lk_max_lockers", &max
))
4193 CHECK_ENV_NOT_CLOSED(self
);
4195 MYDB_BEGIN_ALLOW_THREADS
;
4196 err
= self
->db_env
->set_lk_max_lockers(self
->db_env
, max
);
4197 MYDB_END_ALLOW_THREADS
;
4204 DBEnv_set_lk_max_objects(DBEnvObject
* self
, PyObject
* args
)
4208 if (!PyArg_ParseTuple(args
, "i:set_lk_max_objects", &max
))
4210 CHECK_ENV_NOT_CLOSED(self
);
4212 MYDB_BEGIN_ALLOW_THREADS
;
4213 err
= self
->db_env
->set_lk_max_objects(self
->db_env
, max
);
4214 MYDB_END_ALLOW_THREADS
;
4223 DBEnv_set_mp_mmapsize(DBEnvObject
* self
, PyObject
* args
)
4225 int err
, mp_mmapsize
;
4227 if (!PyArg_ParseTuple(args
, "i:set_mp_mmapsize", &mp_mmapsize
))
4229 CHECK_ENV_NOT_CLOSED(self
);
4231 MYDB_BEGIN_ALLOW_THREADS
;
4232 err
= self
->db_env
->set_mp_mmapsize(self
->db_env
, mp_mmapsize
);
4233 MYDB_END_ALLOW_THREADS
;
4240 DBEnv_set_tmp_dir(DBEnvObject
* self
, PyObject
* args
)
4245 if (!PyArg_ParseTuple(args
, "s:set_tmp_dir", &dir
))
4247 CHECK_ENV_NOT_CLOSED(self
);
4249 MYDB_BEGIN_ALLOW_THREADS
;
4250 err
= self
->db_env
->set_tmp_dir(self
->db_env
, dir
);
4251 MYDB_END_ALLOW_THREADS
;
4258 DBEnv_txn_begin(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4261 PyObject
* txnobj
= NULL
;
4263 static char* kwnames
[] = { "parent", "flags", NULL
};
4265 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:txn_begin", kwnames
,
4269 if (!checkTxnObj(txnobj
, &txn
))
4271 CHECK_ENV_NOT_CLOSED(self
);
4273 return (PyObject
*)newDBTxnObject(self
, txn
, flags
);
4278 DBEnv_txn_checkpoint(DBEnvObject
* self
, PyObject
* args
)
4280 int err
, kbyte
=0, min
=0, flags
=0;
4282 if (!PyArg_ParseTuple(args
, "|iii:txn_checkpoint", &kbyte
, &min
, &flags
))
4284 CHECK_ENV_NOT_CLOSED(self
);
4286 MYDB_BEGIN_ALLOW_THREADS
;
4288 err
= self
->db_env
->txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
4290 err
= txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
4292 MYDB_END_ALLOW_THREADS
;
4299 DBEnv_set_tx_max(DBEnvObject
* self
, PyObject
* args
)
4303 if (!PyArg_ParseTuple(args
, "i:set_tx_max", &max
))
4305 CHECK_ENV_NOT_CLOSED(self
);
4307 err
= self
->db_env
->set_tx_max(self
->db_env
, max
);
4314 DBEnv_set_tx_timestamp(DBEnvObject
* self
, PyObject
* args
)
4320 if (!PyArg_ParseTuple(args
, "l:set_tx_timestamp", &stamp
))
4322 CHECK_ENV_NOT_CLOSED(self
);
4323 timestamp
= (time_t)stamp
;
4324 err
= self
->db_env
->set_tx_timestamp(self
->db_env
, ×tamp
);
4331 DBEnv_lock_detect(DBEnvObject
* self
, PyObject
* args
)
4333 int err
, atype
, flags
=0;
4336 if (!PyArg_ParseTuple(args
, "i|i:lock_detect", &atype
, &flags
))
4338 CHECK_ENV_NOT_CLOSED(self
);
4340 MYDB_BEGIN_ALLOW_THREADS
;
4342 err
= self
->db_env
->lock_detect(self
->db_env
, flags
, atype
, &aborted
);
4344 err
= lock_detect(self
->db_env
, flags
, atype
, &aborted
);
4346 MYDB_END_ALLOW_THREADS
;
4348 return PyInt_FromLong(aborted
);
4353 DBEnv_lock_get(DBEnvObject
* self
, PyObject
* args
)
4356 int locker
, lock_mode
;
4360 if (!PyArg_ParseTuple(args
, "iOi|i:lock_get", &locker
, &objobj
, &lock_mode
, &flags
))
4364 if (!make_dbt(objobj
, &obj
))
4367 return (PyObject
*)newDBLockObject(self
, locker
, &obj
, lock_mode
, flags
);
4372 DBEnv_lock_id(DBEnvObject
* self
, PyObject
* args
)
4377 if (!PyArg_ParseTuple(args
, ":lock_id"))
4380 CHECK_ENV_NOT_CLOSED(self
);
4381 MYDB_BEGIN_ALLOW_THREADS
;
4383 err
= self
->db_env
->lock_id(self
->db_env
, &theID
);
4385 err
= lock_id(self
->db_env
, &theID
);
4387 MYDB_END_ALLOW_THREADS
;
4390 return PyInt_FromLong((long)theID
);
4395 DBEnv_lock_put(DBEnvObject
* self
, PyObject
* args
)
4398 DBLockObject
* dblockobj
;
4400 if (!PyArg_ParseTuple(args
, "O!:lock_put", &DBLock_Type
, &dblockobj
))
4403 CHECK_ENV_NOT_CLOSED(self
);
4404 MYDB_BEGIN_ALLOW_THREADS
;
4406 err
= self
->db_env
->lock_put(self
->db_env
, &dblockobj
->lock
);
4408 err
= lock_put(self
->db_env
, &dblockobj
->lock
);
4410 MYDB_END_ALLOW_THREADS
;
4417 DBEnv_lsn_reset(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4421 u_int32_t flags
= 0;
4422 static char* kwnames
[] = { "file", "flags", NULL
};
4424 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|i:lsn_reset", kwnames
,
4427 CHECK_ENV_NOT_CLOSED(self
);
4429 MYDB_BEGIN_ALLOW_THREADS
;
4430 err
= self
->db_env
->lsn_reset(self
->db_env
, file
, flags
);
4431 MYDB_END_ALLOW_THREADS
;
4435 #endif /* DBVER >= 4.4 */
4439 DBEnv_log_stat(DBEnvObject
* self
, PyObject
* args
)
4442 DB_LOG_STAT
* statp
= NULL
;
4444 u_int32_t flags
= 0;
4446 if (!PyArg_ParseTuple(args
, "|i:log_stat", &flags
))
4448 CHECK_ENV_NOT_CLOSED(self
);
4450 MYDB_BEGIN_ALLOW_THREADS
;
4451 err
= self
->db_env
->log_stat(self
->db_env
, &statp
, flags
);
4452 MYDB_END_ALLOW_THREADS
;
4455 /* Turn the stat structure into a dictionary */
4463 #define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
4466 MAKE_ENTRY(version
);
4468 MAKE_ENTRY(lg_bsize
);
4470 MAKE_ENTRY(lg_size
);
4476 MAKE_ENTRY(w_mbytes
);
4477 MAKE_ENTRY(w_bytes
);
4478 MAKE_ENTRY(wc_mbytes
);
4479 MAKE_ENTRY(wc_bytes
);
4481 MAKE_ENTRY(wcount_fill
);
4486 MAKE_ENTRY(cur_file
);
4487 MAKE_ENTRY(cur_offset
);
4488 MAKE_ENTRY(disk_file
);
4489 MAKE_ENTRY(disk_offset
);
4490 MAKE_ENTRY(maxcommitperflush
);
4491 MAKE_ENTRY(mincommitperflush
);
4492 MAKE_ENTRY(regsize
);
4493 MAKE_ENTRY(region_wait
);
4494 MAKE_ENTRY(region_nowait
);
4499 } /* DBEnv_log_stat */
4500 #endif /* DBVER >= 4.0 for log_stat method */
4504 DBEnv_lock_stat(DBEnvObject
* self
, PyObject
* args
)
4509 u_int32_t flags
= 0;
4511 if (!PyArg_ParseTuple(args
, "|i:lock_stat", &flags
))
4513 CHECK_ENV_NOT_CLOSED(self
);
4515 MYDB_BEGIN_ALLOW_THREADS
;
4517 err
= self
->db_env
->lock_stat(self
->db_env
, &sp
, flags
);
4520 err
= lock_stat(self
->db_env
, &sp
);
4522 err
= lock_stat(self
->db_env
, &sp
, NULL
);
4525 MYDB_END_ALLOW_THREADS
;
4528 /* Turn the stat structure into a dictionary */
4535 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4542 MAKE_ENTRY(maxlocks
);
4543 MAKE_ENTRY(maxlockers
);
4544 MAKE_ENTRY(maxobjects
);
4546 MAKE_ENTRY(maxnlocks
);
4548 MAKE_ENTRY(nlockers
);
4549 MAKE_ENTRY(maxnlockers
);
4551 MAKE_ENTRY(nobjects
);
4552 MAKE_ENTRY(maxnobjects
);
4554 MAKE_ENTRY(nrequests
);
4555 MAKE_ENTRY(nreleases
);
4557 MAKE_ENTRY(nnowaits
); /* these were renamed in 4.4 */
4558 MAKE_ENTRY(nconflicts
);
4560 MAKE_ENTRY(lock_nowait
);
4561 MAKE_ENTRY(lock_wait
);
4563 MAKE_ENTRY(ndeadlocks
);
4564 MAKE_ENTRY(regsize
);
4565 MAKE_ENTRY(region_wait
);
4566 MAKE_ENTRY(region_nowait
);
4575 DBEnv_log_archive(DBEnvObject
* self
, PyObject
* args
)
4579 char **log_list
= NULL
;
4581 PyObject
* item
= NULL
;
4583 if (!PyArg_ParseTuple(args
, "|i:log_archive", &flags
))
4586 CHECK_ENV_NOT_CLOSED(self
);
4587 MYDB_BEGIN_ALLOW_THREADS
;
4589 err
= self
->db_env
->log_archive(self
->db_env
, &log_list
, flags
);
4591 err
= log_archive(self
->db_env
, &log_list
, flags
);
4593 err
= log_archive(self
->db_env
, &log_list
, flags
, NULL
);
4595 MYDB_END_ALLOW_THREADS
;
4598 list
= PyList_New(0);
4606 char **log_list_start
;
4607 for (log_list_start
= log_list
; *log_list
!= NULL
; ++log_list
) {
4608 item
= PyString_FromString (*log_list
);
4614 PyList_Append(list
, item
);
4617 free(log_list_start
);
4624 DBEnv_txn_stat(DBEnvObject
* self
, PyObject
* args
)
4631 if (!PyArg_ParseTuple(args
, "|i:txn_stat", &flags
))
4633 CHECK_ENV_NOT_CLOSED(self
);
4635 MYDB_BEGIN_ALLOW_THREADS
;
4637 err
= self
->db_env
->txn_stat(self
->db_env
, &sp
, flags
);
4639 err
= txn_stat(self
->db_env
, &sp
);
4641 err
= txn_stat(self
->db_env
, &sp
, NULL
);
4643 MYDB_END_ALLOW_THREADS
;
4646 /* Turn the stat structure into a dictionary */
4653 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4654 #define MAKE_TIME_T_ENTRY(name)_addTimeTToDict(d, #name, sp->st_##name)
4656 MAKE_TIME_T_ENTRY(time_ckp
);
4657 MAKE_ENTRY(last_txnid
);
4658 MAKE_ENTRY(maxtxns
);
4659 MAKE_ENTRY(nactive
);
4660 MAKE_ENTRY(maxnactive
);
4661 MAKE_ENTRY(nbegins
);
4662 MAKE_ENTRY(naborts
);
4663 MAKE_ENTRY(ncommits
);
4664 MAKE_ENTRY(regsize
);
4665 MAKE_ENTRY(region_wait
);
4666 MAKE_ENTRY(region_nowait
);
4669 #undef MAKE_TIME_T_ENTRY
4676 DBEnv_set_get_returns_none(DBEnvObject
* self
, PyObject
* args
)
4681 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
4683 CHECK_ENV_NOT_CLOSED(self
);
4685 if (self
->moduleFlags
.getReturnsNone
)
4687 if (self
->moduleFlags
.cursorSetReturnsNone
)
4689 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
4690 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
4691 return PyInt_FromLong(oldValue
);
4695 /* --------------------------------------------------------------------- */
4700 DBTxn_commit(DBTxnObject
* self
, PyObject
* args
)
4705 if (!PyArg_ParseTuple(args
, "|i:commit", &flags
))
4709 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4710 "after txn_commit or txn_abort");
4711 PyErr_SetObject(DBError
, t
);
4716 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
4717 MYDB_BEGIN_ALLOW_THREADS
;
4719 err
= txn
->commit(txn
, flags
);
4721 err
= txn_commit(txn
, flags
);
4723 MYDB_END_ALLOW_THREADS
;
4729 DBTxn_prepare(DBTxnObject
* self
, PyObject
* args
)
4736 if (!PyArg_ParseTuple(args
, "s#:prepare", &gid
, &gid_size
))
4739 if (gid_size
!= DB_XIDDATASIZE
) {
4740 PyErr_SetString(PyExc_TypeError
,
4741 "gid must be DB_XIDDATASIZE bytes long");
4746 PyObject
*t
= Py_BuildValue("(is)", 0,"DBTxn must not be used "
4747 "after txn_commit or txn_abort");
4748 PyErr_SetObject(DBError
, t
);
4752 MYDB_BEGIN_ALLOW_THREADS
;
4754 err
= self
->txn
->prepare(self
->txn
, (u_int8_t
*)gid
);
4756 err
= txn_prepare(self
->txn
, (u_int8_t
*)gid
);
4758 MYDB_END_ALLOW_THREADS
;
4764 if (!PyArg_ParseTuple(args
, ":prepare"))
4768 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4769 "after txn_commit or txn_abort");
4770 PyErr_SetObject(DBError
, t
);
4774 MYDB_BEGIN_ALLOW_THREADS
;
4775 err
= txn_prepare(self
->txn
);
4776 MYDB_END_ALLOW_THREADS
;
4784 DBTxn_abort(DBTxnObject
* self
, PyObject
* args
)
4789 if (!PyArg_ParseTuple(args
, ":abort"))
4793 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4794 "after txn_commit or txn_abort");
4795 PyErr_SetObject(DBError
, t
);
4800 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
4801 MYDB_BEGIN_ALLOW_THREADS
;
4803 err
= txn
->abort(txn
);
4805 err
= txn_abort(txn
);
4807 MYDB_END_ALLOW_THREADS
;
4814 DBTxn_id(DBTxnObject
* self
, PyObject
* args
)
4818 if (!PyArg_ParseTuple(args
, ":id"))
4822 PyObject
*t
= Py_BuildValue("(is)", 0, "DBTxn must not be used "
4823 "after txn_commit or txn_abort");
4824 PyErr_SetObject(DBError
, t
);
4828 MYDB_BEGIN_ALLOW_THREADS
;
4830 id
= self
->txn
->id(self
->txn
);
4832 id
= txn_id(self
->txn
);
4834 MYDB_END_ALLOW_THREADS
;
4835 return PyInt_FromLong(id
);
4839 /* --------------------------------------------------------------------- */
4840 /* DBSequence methods */
4844 DBSequence_close(DBSequenceObject
* self
, PyObject
* args
)
4847 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
4849 CHECK_SEQUENCE_NOT_CLOSED(self
)
4851 MYDB_BEGIN_ALLOW_THREADS
4852 err
= self
->sequence
->close(self
->sequence
, flags
);
4853 self
->sequence
= NULL
;
4854 MYDB_END_ALLOW_THREADS
4862 DBSequence_get(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4867 PyObject
*txnobj
= NULL
;
4869 static char* kwnames
[] = {"delta", "txn", "flags", NULL
};
4870 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iOi:get", kwnames
, &delta
, &txnobj
, &flags
))
4872 CHECK_SEQUENCE_NOT_CLOSED(self
)
4874 if (!checkTxnObj(txnobj
, &txn
))
4877 MYDB_BEGIN_ALLOW_THREADS
4878 err
= self
->sequence
->get(self
->sequence
, txn
, delta
, &value
, flags
);
4879 MYDB_END_ALLOW_THREADS
4882 return PyLong_FromLongLong(value
);
4887 DBSequence_get_dbp(DBSequenceObject
* self
, PyObject
* args
)
4889 if (!PyArg_ParseTuple(args
,":get_dbp"))
4891 CHECK_SEQUENCE_NOT_CLOSED(self
)
4892 Py_INCREF(self
->mydb
);
4893 return (PyObject
* )self
->mydb
;
4897 DBSequence_get_key(DBSequenceObject
* self
, PyObject
* args
)
4901 CHECK_SEQUENCE_NOT_CLOSED(self
)
4902 MYDB_BEGIN_ALLOW_THREADS
4903 err
= self
->sequence
->get_key(self
->sequence
, &key
);
4904 MYDB_END_ALLOW_THREADS
4908 return PyString_FromStringAndSize(key
.data
, key
.size
);
4912 DBSequence_init_value(DBSequenceObject
* self
, PyObject
* args
)
4916 if (!PyArg_ParseTuple(args
,"L:init_value", &value
))
4918 CHECK_SEQUENCE_NOT_CLOSED(self
)
4920 MYDB_BEGIN_ALLOW_THREADS
4921 err
= self
->sequence
->initial_value(self
->sequence
, value
);
4922 MYDB_END_ALLOW_THREADS
4930 DBSequence_open(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4934 PyObject
*txnobj
= NULL
;
4938 static char* kwnames
[] = {"key", "txn", "flags", NULL
};
4939 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:open", kwnames
, &keyobj
, &txnobj
, &flags
))
4942 if (!checkTxnObj(txnobj
, &txn
))
4945 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
4948 MYDB_BEGIN_ALLOW_THREADS
4949 err
= self
->sequence
->open(self
->sequence
, txn
, &key
, flags
);
4950 MYDB_END_ALLOW_THREADS
4959 DBSequence_remove(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4962 PyObject
*txnobj
= NULL
;
4965 static char* kwnames
[] = {"txn", "flags", NULL
};
4966 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:remove", kwnames
, &txnobj
, &flags
))
4969 if (!checkTxnObj(txnobj
, &txn
))
4972 CHECK_SEQUENCE_NOT_CLOSED(self
)
4974 MYDB_BEGIN_ALLOW_THREADS
4975 err
= self
->sequence
->remove(self
->sequence
, txn
, flags
);
4976 MYDB_END_ALLOW_THREADS
4983 DBSequence_set_cachesize(DBSequenceObject
* self
, PyObject
* args
)
4986 if (!PyArg_ParseTuple(args
,"i:set_cachesize", &size
))
4988 CHECK_SEQUENCE_NOT_CLOSED(self
)
4990 MYDB_BEGIN_ALLOW_THREADS
4991 err
= self
->sequence
->set_cachesize(self
->sequence
, size
);
4992 MYDB_END_ALLOW_THREADS
4999 DBSequence_get_cachesize(DBSequenceObject
* self
, PyObject
* args
)
5002 if (!PyArg_ParseTuple(args
,":get_cachesize"))
5004 CHECK_SEQUENCE_NOT_CLOSED(self
)
5006 MYDB_BEGIN_ALLOW_THREADS
5007 err
= self
->sequence
->get_cachesize(self
->sequence
, &size
);
5008 MYDB_END_ALLOW_THREADS
5011 return PyInt_FromLong(size
);
5015 DBSequence_set_flags(DBSequenceObject
* self
, PyObject
* args
)
5018 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
5020 CHECK_SEQUENCE_NOT_CLOSED(self
)
5022 MYDB_BEGIN_ALLOW_THREADS
5023 err
= self
->sequence
->set_flags(self
->sequence
, flags
);
5024 MYDB_END_ALLOW_THREADS
5032 DBSequence_get_flags(DBSequenceObject
* self
, PyObject
* args
)
5036 if (!PyArg_ParseTuple(args
,":get_flags"))
5038 CHECK_SEQUENCE_NOT_CLOSED(self
)
5040 MYDB_BEGIN_ALLOW_THREADS
5041 err
= self
->sequence
->get_flags(self
->sequence
, &flags
);
5042 MYDB_END_ALLOW_THREADS
5045 return PyInt_FromLong((int)flags
);
5049 DBSequence_set_range(DBSequenceObject
* self
, PyObject
* args
)
5053 if (!PyArg_ParseTuple(args
,"(LL):set_range", &min
, &max
))
5055 CHECK_SEQUENCE_NOT_CLOSED(self
)
5057 MYDB_BEGIN_ALLOW_THREADS
5058 err
= self
->sequence
->set_range(self
->sequence
, min
, max
);
5059 MYDB_END_ALLOW_THREADS
5066 DBSequence_get_range(DBSequenceObject
* self
, PyObject
* args
)
5070 if (!PyArg_ParseTuple(args
,":get_range"))
5072 CHECK_SEQUENCE_NOT_CLOSED(self
)
5074 MYDB_BEGIN_ALLOW_THREADS
5075 err
= self
->sequence
->get_range(self
->sequence
, &min
, &max
);
5076 MYDB_END_ALLOW_THREADS
5079 return Py_BuildValue("(LL)", min
, max
);
5083 DBSequence_stat(DBSequenceObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5086 DB_SEQUENCE_STAT
* sp
= NULL
;
5087 PyObject
* dict_stat
;
5088 static char* kwnames
[] = {"flags", NULL
};
5089 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i:stat", kwnames
, &flags
))
5091 CHECK_SEQUENCE_NOT_CLOSED(self
);
5093 MYDB_BEGIN_ALLOW_THREADS
;
5094 err
= self
->sequence
->stat(self
->sequence
, &sp
, flags
);
5095 MYDB_END_ALLOW_THREADS
;
5098 if ((dict_stat
= PyDict_New()) == NULL
) {
5104 #define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name)
5105 #define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
5107 MAKE_INT_ENTRY(wait
);
5108 MAKE_INT_ENTRY(nowait
);
5109 MAKE_LONG_LONG_ENTRY(current
);
5110 MAKE_LONG_LONG_ENTRY(value
);
5111 MAKE_LONG_LONG_ENTRY(last_value
);
5112 MAKE_LONG_LONG_ENTRY(min
);
5113 MAKE_LONG_LONG_ENTRY(max
);
5114 MAKE_INT_ENTRY(cache_size
);
5115 MAKE_INT_ENTRY(flags
);
5117 #undef MAKE_INT_ENTRY
5118 #undef MAKE_LONG_LONG_ENTRY
5126 /* --------------------------------------------------------------------- */
5127 /* Method definition tables and type objects */
5129 static PyMethodDef DB_methods
[] = {
5130 {"append", (PyCFunction
)DB_append
, METH_VARARGS
},
5132 {"associate", (PyCFunction
)DB_associate
, METH_VARARGS
|METH_KEYWORDS
},
5134 {"close", (PyCFunction
)DB_close
, METH_VARARGS
},
5136 {"consume", (PyCFunction
)DB_consume
, METH_VARARGS
|METH_KEYWORDS
},
5137 {"consume_wait", (PyCFunction
)DB_consume_wait
, METH_VARARGS
|METH_KEYWORDS
},
5139 {"cursor", (PyCFunction
)DB_cursor
, METH_VARARGS
|METH_KEYWORDS
},
5140 {"delete", (PyCFunction
)DB_delete
, METH_VARARGS
|METH_KEYWORDS
},
5141 {"fd", (PyCFunction
)DB_fd
, METH_VARARGS
},
5142 {"get", (PyCFunction
)DB_get
, METH_VARARGS
|METH_KEYWORDS
},
5144 {"pget", (PyCFunction
)DB_pget
, METH_VARARGS
|METH_KEYWORDS
},
5146 {"get_both", (PyCFunction
)DB_get_both
, METH_VARARGS
|METH_KEYWORDS
},
5147 {"get_byteswapped", (PyCFunction
)DB_get_byteswapped
,METH_VARARGS
},
5148 {"get_size", (PyCFunction
)DB_get_size
, METH_VARARGS
|METH_KEYWORDS
},
5149 {"get_type", (PyCFunction
)DB_get_type
, METH_VARARGS
},
5150 {"join", (PyCFunction
)DB_join
, METH_VARARGS
},
5151 {"key_range", (PyCFunction
)DB_key_range
, METH_VARARGS
|METH_KEYWORDS
},
5152 {"has_key", (PyCFunction
)DB_has_key
, METH_VARARGS
},
5153 {"items", (PyCFunction
)DB_items
, METH_VARARGS
},
5154 {"keys", (PyCFunction
)DB_keys
, METH_VARARGS
},
5155 {"open", (PyCFunction
)DB_open
, METH_VARARGS
|METH_KEYWORDS
},
5156 {"put", (PyCFunction
)DB_put
, METH_VARARGS
|METH_KEYWORDS
},
5157 {"remove", (PyCFunction
)DB_remove
, METH_VARARGS
|METH_KEYWORDS
},
5158 {"rename", (PyCFunction
)DB_rename
, METH_VARARGS
},
5159 {"set_bt_minkey", (PyCFunction
)DB_set_bt_minkey
, METH_VARARGS
},
5161 {"set_bt_compare", (PyCFunction
)DB_set_bt_compare
, METH_VARARGS
},
5163 {"set_cachesize", (PyCFunction
)DB_set_cachesize
, METH_VARARGS
},
5165 {"set_encrypt", (PyCFunction
)DB_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
5167 {"set_flags", (PyCFunction
)DB_set_flags
, METH_VARARGS
},
5168 {"set_h_ffactor", (PyCFunction
)DB_set_h_ffactor
, METH_VARARGS
},
5169 {"set_h_nelem", (PyCFunction
)DB_set_h_nelem
, METH_VARARGS
},
5170 {"set_lorder", (PyCFunction
)DB_set_lorder
, METH_VARARGS
},
5171 {"set_pagesize", (PyCFunction
)DB_set_pagesize
, METH_VARARGS
},
5172 {"set_re_delim", (PyCFunction
)DB_set_re_delim
, METH_VARARGS
},
5173 {"set_re_len", (PyCFunction
)DB_set_re_len
, METH_VARARGS
},
5174 {"set_re_pad", (PyCFunction
)DB_set_re_pad
, METH_VARARGS
},
5175 {"set_re_source", (PyCFunction
)DB_set_re_source
, METH_VARARGS
},
5177 {"set_q_extentsize",(PyCFunction
)DB_set_q_extentsize
,METH_VARARGS
},
5179 {"stat", (PyCFunction
)DB_stat
, METH_VARARGS
|METH_KEYWORDS
},
5180 {"sync", (PyCFunction
)DB_sync
, METH_VARARGS
},
5182 {"truncate", (PyCFunction
)DB_truncate
, METH_VARARGS
|METH_KEYWORDS
},
5184 {"type", (PyCFunction
)DB_get_type
, METH_VARARGS
},
5185 {"upgrade", (PyCFunction
)DB_upgrade
, METH_VARARGS
},
5186 {"values", (PyCFunction
)DB_values
, METH_VARARGS
},
5187 {"verify", (PyCFunction
)DB_verify
, METH_VARARGS
|METH_KEYWORDS
},
5188 {"set_get_returns_none",(PyCFunction
)DB_set_get_returns_none
, METH_VARARGS
},
5189 {NULL
, NULL
} /* sentinel */
5193 static PyMappingMethods DB_mapping
= {
5194 DB_length
, /*mp_length*/
5195 (binaryfunc
)DB_subscript
, /*mp_subscript*/
5196 (objobjargproc
)DB_ass_sub
, /*mp_ass_subscript*/
5200 static PyMethodDef DBCursor_methods
[] = {
5201 {"close", (PyCFunction
)DBC_close
, METH_VARARGS
},
5202 {"count", (PyCFunction
)DBC_count
, METH_VARARGS
},
5203 {"current", (PyCFunction
)DBC_current
, METH_VARARGS
|METH_KEYWORDS
},
5204 {"delete", (PyCFunction
)DBC_delete
, METH_VARARGS
},
5205 {"dup", (PyCFunction
)DBC_dup
, METH_VARARGS
},
5206 {"first", (PyCFunction
)DBC_first
, METH_VARARGS
|METH_KEYWORDS
},
5207 {"get", (PyCFunction
)DBC_get
, METH_VARARGS
|METH_KEYWORDS
},
5209 {"pget", (PyCFunction
)DBC_pget
, METH_VARARGS
|METH_KEYWORDS
},
5211 {"get_recno", (PyCFunction
)DBC_get_recno
, METH_VARARGS
},
5212 {"last", (PyCFunction
)DBC_last
, METH_VARARGS
|METH_KEYWORDS
},
5213 {"next", (PyCFunction
)DBC_next
, METH_VARARGS
|METH_KEYWORDS
},
5214 {"prev", (PyCFunction
)DBC_prev
, METH_VARARGS
|METH_KEYWORDS
},
5215 {"put", (PyCFunction
)DBC_put
, METH_VARARGS
|METH_KEYWORDS
},
5216 {"set", (PyCFunction
)DBC_set
, METH_VARARGS
|METH_KEYWORDS
},
5217 {"set_range", (PyCFunction
)DBC_set_range
, METH_VARARGS
|METH_KEYWORDS
},
5218 {"get_both", (PyCFunction
)DBC_get_both
, METH_VARARGS
},
5219 {"get_current_size",(PyCFunction
)DBC_get_current_size
, METH_VARARGS
},
5220 {"set_both", (PyCFunction
)DBC_set_both
, METH_VARARGS
},
5221 {"set_recno", (PyCFunction
)DBC_set_recno
, METH_VARARGS
|METH_KEYWORDS
},
5222 {"consume", (PyCFunction
)DBC_consume
, METH_VARARGS
|METH_KEYWORDS
},
5223 {"next_dup", (PyCFunction
)DBC_next_dup
, METH_VARARGS
|METH_KEYWORDS
},
5224 {"next_nodup", (PyCFunction
)DBC_next_nodup
, METH_VARARGS
|METH_KEYWORDS
},
5225 {"prev_nodup", (PyCFunction
)DBC_prev_nodup
, METH_VARARGS
|METH_KEYWORDS
},
5226 {"join_item", (PyCFunction
)DBC_join_item
, METH_VARARGS
},
5227 {NULL
, NULL
} /* sentinel */
5231 static PyMethodDef DBEnv_methods
[] = {
5232 {"close", (PyCFunction
)DBEnv_close
, METH_VARARGS
},
5233 {"open", (PyCFunction
)DBEnv_open
, METH_VARARGS
},
5234 {"remove", (PyCFunction
)DBEnv_remove
, METH_VARARGS
},
5236 {"dbremove", (PyCFunction
)DBEnv_dbremove
, METH_VARARGS
|METH_KEYWORDS
},
5237 {"dbrename", (PyCFunction
)DBEnv_dbrename
, METH_VARARGS
|METH_KEYWORDS
},
5238 {"set_encrypt", (PyCFunction
)DBEnv_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
5241 {"set_timeout", (PyCFunction
)DBEnv_set_timeout
, METH_VARARGS
|METH_KEYWORDS
},
5243 {"set_shm_key", (PyCFunction
)DBEnv_set_shm_key
, METH_VARARGS
},
5244 {"set_cachesize", (PyCFunction
)DBEnv_set_cachesize
, METH_VARARGS
},
5245 {"set_data_dir", (PyCFunction
)DBEnv_set_data_dir
, METH_VARARGS
},
5247 {"set_flags", (PyCFunction
)DBEnv_set_flags
, METH_VARARGS
},
5249 {"set_lg_bsize", (PyCFunction
)DBEnv_set_lg_bsize
, METH_VARARGS
},
5250 {"set_lg_dir", (PyCFunction
)DBEnv_set_lg_dir
, METH_VARARGS
},
5251 {"set_lg_max", (PyCFunction
)DBEnv_set_lg_max
, METH_VARARGS
},
5253 {"set_lg_regionmax",(PyCFunction
)DBEnv_set_lg_regionmax
, METH_VARARGS
},
5255 {"set_lk_detect", (PyCFunction
)DBEnv_set_lk_detect
, METH_VARARGS
},
5257 {"set_lk_max", (PyCFunction
)DBEnv_set_lk_max
, METH_VARARGS
},
5260 {"set_lk_max_locks", (PyCFunction
)DBEnv_set_lk_max_locks
, METH_VARARGS
},
5261 {"set_lk_max_lockers", (PyCFunction
)DBEnv_set_lk_max_lockers
, METH_VARARGS
},
5262 {"set_lk_max_objects", (PyCFunction
)DBEnv_set_lk_max_objects
, METH_VARARGS
},
5264 {"set_mp_mmapsize", (PyCFunction
)DBEnv_set_mp_mmapsize
, METH_VARARGS
},
5265 {"set_tmp_dir", (PyCFunction
)DBEnv_set_tmp_dir
, METH_VARARGS
},
5266 {"txn_begin", (PyCFunction
)DBEnv_txn_begin
, METH_VARARGS
|METH_KEYWORDS
},
5267 {"txn_checkpoint", (PyCFunction
)DBEnv_txn_checkpoint
, METH_VARARGS
},
5268 {"txn_stat", (PyCFunction
)DBEnv_txn_stat
, METH_VARARGS
},
5269 {"set_tx_max", (PyCFunction
)DBEnv_set_tx_max
, METH_VARARGS
},
5270 {"set_tx_timestamp", (PyCFunction
)DBEnv_set_tx_timestamp
, METH_VARARGS
},
5271 {"lock_detect", (PyCFunction
)DBEnv_lock_detect
, METH_VARARGS
},
5272 {"lock_get", (PyCFunction
)DBEnv_lock_get
, METH_VARARGS
},
5273 {"lock_id", (PyCFunction
)DBEnv_lock_id
, METH_VARARGS
},
5274 {"lock_put", (PyCFunction
)DBEnv_lock_put
, METH_VARARGS
},
5275 {"lock_stat", (PyCFunction
)DBEnv_lock_stat
, METH_VARARGS
},
5276 {"log_archive", (PyCFunction
)DBEnv_log_archive
, METH_VARARGS
},
5278 {"log_stat", (PyCFunction
)DBEnv_log_stat
, METH_VARARGS
},
5281 {"lsn_reset", (PyCFunction
)DBEnv_lsn_reset
, METH_VARARGS
|METH_KEYWORDS
},
5283 {"set_get_returns_none",(PyCFunction
)DBEnv_set_get_returns_none
, METH_VARARGS
},
5284 {NULL
, NULL
} /* sentinel */
5288 static PyMethodDef DBTxn_methods
[] = {
5289 {"commit", (PyCFunction
)DBTxn_commit
, METH_VARARGS
},
5290 {"prepare", (PyCFunction
)DBTxn_prepare
, METH_VARARGS
},
5291 {"abort", (PyCFunction
)DBTxn_abort
, METH_VARARGS
},
5292 {"id", (PyCFunction
)DBTxn_id
, METH_VARARGS
},
5293 {NULL
, NULL
} /* sentinel */
5298 static PyMethodDef DBSequence_methods
[] = {
5299 {"close", (PyCFunction
)DBSequence_close
, METH_VARARGS
},
5300 {"get", (PyCFunction
)DBSequence_get
, METH_VARARGS
|METH_KEYWORDS
},
5301 {"get_dbp", (PyCFunction
)DBSequence_get_dbp
, METH_VARARGS
},
5302 {"get_key", (PyCFunction
)DBSequence_get_key
, METH_VARARGS
},
5303 {"init_value", (PyCFunction
)DBSequence_init_value
, METH_VARARGS
},
5304 {"open", (PyCFunction
)DBSequence_open
, METH_VARARGS
|METH_KEYWORDS
},
5305 {"remove", (PyCFunction
)DBSequence_remove
, METH_VARARGS
|METH_KEYWORDS
},
5306 {"set_cachesize", (PyCFunction
)DBSequence_set_cachesize
, METH_VARARGS
},
5307 {"get_cachesize", (PyCFunction
)DBSequence_get_cachesize
, METH_VARARGS
},
5308 {"set_flags", (PyCFunction
)DBSequence_set_flags
, METH_VARARGS
},
5309 {"get_flags", (PyCFunction
)DBSequence_get_flags
, METH_VARARGS
},
5310 {"set_range", (PyCFunction
)DBSequence_set_range
, METH_VARARGS
},
5311 {"get_range", (PyCFunction
)DBSequence_get_range
, METH_VARARGS
},
5312 {"stat", (PyCFunction
)DBSequence_stat
, METH_VARARGS
|METH_KEYWORDS
},
5313 {NULL
, NULL
} /* sentinel */
5319 DB_getattr(DBObject
* self
, char *name
)
5321 return Py_FindMethod(DB_methods
, (PyObject
* )self
, name
);
5326 DBEnv_getattr(DBEnvObject
* self
, char *name
)
5328 if (!strcmp(name
, "db_home")) {
5329 CHECK_ENV_NOT_CLOSED(self
);
5330 if (self
->db_env
->db_home
== NULL
) {
5333 return PyString_FromString(self
->db_env
->db_home
);
5336 return Py_FindMethod(DBEnv_methods
, (PyObject
* )self
, name
);
5341 DBCursor_getattr(DBCursorObject
* self
, char *name
)
5343 return Py_FindMethod(DBCursor_methods
, (PyObject
* )self
, name
);
5347 DBTxn_getattr(DBTxnObject
* self
, char *name
)
5349 return Py_FindMethod(DBTxn_methods
, (PyObject
* )self
, name
);
5353 DBLock_getattr(DBLockObject
* self
, char *name
)
5360 DBSequence_getattr(DBSequenceObject
* self
, char *name
)
5362 return Py_FindMethod(DBSequence_methods
, (PyObject
* )self
, name
);
5366 statichere PyTypeObject DB_Type
= {
5367 PyObject_HEAD_INIT(NULL
)
5370 sizeof(DBObject
), /*tp_basicsize*/
5373 (destructor
)DB_dealloc
, /*tp_dealloc*/
5375 (getattrfunc
)DB_getattr
, /*tp_getattr*/
5380 0, /*tp_as_sequence*/
5381 &DB_mapping
,/*tp_as_mapping*/
5386 0, /* tp_getattro */
5387 0, /* tp_setattro */
5388 0, /* tp_as_buffer */
5389 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5391 0, /* tp_traverse */
5393 0, /* tp_richcompare */
5394 offsetof(DBObject
, in_weakreflist
), /* tp_weaklistoffset */
5399 statichere PyTypeObject DBCursor_Type
= {
5400 PyObject_HEAD_INIT(NULL
)
5402 "DBCursor", /*tp_name*/
5403 sizeof(DBCursorObject
), /*tp_basicsize*/
5406 (destructor
)DBCursor_dealloc
,/*tp_dealloc*/
5408 (getattrfunc
)DBCursor_getattr
, /*tp_getattr*/
5413 0, /*tp_as_sequence*/
5414 0, /*tp_as_mapping*/
5419 0, /* tp_getattro */
5420 0, /* tp_setattro */
5421 0, /* tp_as_buffer */
5422 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5424 0, /* tp_traverse */
5426 0, /* tp_richcompare */
5427 offsetof(DBCursorObject
, in_weakreflist
), /* tp_weaklistoffset */
5432 statichere PyTypeObject DBEnv_Type
= {
5433 PyObject_HEAD_INIT(NULL
)
5435 "DBEnv", /*tp_name*/
5436 sizeof(DBEnvObject
), /*tp_basicsize*/
5439 (destructor
)DBEnv_dealloc
, /*tp_dealloc*/
5441 (getattrfunc
)DBEnv_getattr
, /*tp_getattr*/
5446 0, /*tp_as_sequence*/
5447 0, /*tp_as_mapping*/
5452 0, /* tp_getattro */
5453 0, /* tp_setattro */
5454 0, /* tp_as_buffer */
5455 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5457 0, /* tp_traverse */
5459 0, /* tp_richcompare */
5460 offsetof(DBEnvObject
, in_weakreflist
), /* tp_weaklistoffset */
5464 statichere PyTypeObject DBTxn_Type
= {
5465 PyObject_HEAD_INIT(NULL
)
5467 "DBTxn", /*tp_name*/
5468 sizeof(DBTxnObject
), /*tp_basicsize*/
5471 (destructor
)DBTxn_dealloc
, /*tp_dealloc*/
5473 (getattrfunc
)DBTxn_getattr
, /*tp_getattr*/
5478 0, /*tp_as_sequence*/
5479 0, /*tp_as_mapping*/
5484 0, /* tp_getattro */
5485 0, /* tp_setattro */
5486 0, /* tp_as_buffer */
5487 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5489 0, /* tp_traverse */
5491 0, /* tp_richcompare */
5492 offsetof(DBTxnObject
, in_weakreflist
), /* tp_weaklistoffset */
5497 statichere PyTypeObject DBLock_Type
= {
5498 PyObject_HEAD_INIT(NULL
)
5500 "DBLock", /*tp_name*/
5501 sizeof(DBLockObject
), /*tp_basicsize*/
5504 (destructor
)DBLock_dealloc
, /*tp_dealloc*/
5506 (getattrfunc
)DBLock_getattr
, /*tp_getattr*/
5511 0, /*tp_as_sequence*/
5512 0, /*tp_as_mapping*/
5517 0, /* tp_getattro */
5518 0, /* tp_setattro */
5519 0, /* tp_as_buffer */
5520 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5522 0, /* tp_traverse */
5524 0, /* tp_richcompare */
5525 offsetof(DBLockObject
, in_weakreflist
), /* tp_weaklistoffset */
5530 statichere PyTypeObject DBSequence_Type
= {
5531 PyObject_HEAD_INIT(NULL
)
5533 "DBSequence", /*tp_name*/
5534 sizeof(DBSequenceObject
), /*tp_basicsize*/
5537 (destructor
)DBSequence_dealloc
, /*tp_dealloc*/
5539 (getattrfunc
)DBSequence_getattr
,/*tp_getattr*/
5544 0, /*tp_as_sequence*/
5545 0, /*tp_as_mapping*/
5550 0, /* tp_getattro */
5551 0, /* tp_setattro */
5552 0, /* tp_as_buffer */
5553 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
5555 0, /* tp_traverse */
5557 0, /* tp_richcompare */
5558 offsetof(DBSequenceObject
, in_weakreflist
), /* tp_weaklistoffset */
5563 /* --------------------------------------------------------------------- */
5564 /* Module-level functions */
5567 DB_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5569 PyObject
* dbenvobj
= NULL
;
5571 static char* kwnames
[] = { "dbEnv", "flags", NULL
};
5573 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:DB", kwnames
,
5576 if (dbenvobj
== Py_None
)
5578 else if (dbenvobj
&& !DBEnvObject_Check(dbenvobj
)) {
5579 makeTypeError("DBEnv", dbenvobj
);
5583 return (PyObject
* )newDBObject((DBEnvObject
*)dbenvobj
, flags
);
5588 DBEnv_construct(PyObject
* self
, PyObject
* args
)
5591 if (!PyArg_ParseTuple(args
, "|i:DbEnv", &flags
)) return NULL
;
5592 return (PyObject
* )newDBEnvObject(flags
);
5597 DBSequence_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
5601 static char* kwnames
[] = { "db", "flags", NULL
};
5603 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|i:DBSequence", kwnames
, &dbobj
, &flags
))
5605 if (!DBObject_Check(dbobj
)) {
5606 makeTypeError("DB", dbobj
);
5609 return (PyObject
* )newDBSequenceObject((DBObject
*)dbobj
, flags
);
5613 static char bsddb_version_doc
[] =
5614 "Returns a tuple of major, minor, and patch release numbers of the\n\
5615 underlying DB library.";
5618 bsddb_version(PyObject
* self
, PyObject
* args
)
5620 int major
, minor
, patch
;
5622 if (!PyArg_ParseTuple(args
, ":version"))
5624 db_version(&major
, &minor
, &patch
);
5625 return Py_BuildValue("(iii)", major
, minor
, patch
);
5629 /* List of functions defined in the module */
5631 static PyMethodDef bsddb_methods
[] = {
5632 {"DB", (PyCFunction
)DB_construct
, METH_VARARGS
| METH_KEYWORDS
},
5633 {"DBEnv", (PyCFunction
)DBEnv_construct
, METH_VARARGS
},
5635 {"DBSequence", (PyCFunction
)DBSequence_construct
, METH_VARARGS
| METH_KEYWORDS
},
5637 {"version", (PyCFunction
)bsddb_version
, METH_VARARGS
, bsddb_version_doc
},
5638 {NULL
, NULL
} /* sentinel */
5642 /* --------------------------------------------------------------------- */
5643 /* Module initialization */
5646 /* Convenience routine to export an integer value.
5647 * Errors are silently ignored, for better or for worse...
5649 #define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
5651 #define MODULE_NAME_MAX_LEN 11
5652 static char _bsddbModuleName
[MODULE_NAME_MAX_LEN
+1] = "_bsddb";
5654 DL_EXPORT(void) init_bsddb(void)
5658 PyObject
* pybsddb_version_s
= PyString_FromString( PY_BSDDB_VERSION
);
5659 PyObject
* db_version_s
= PyString_FromString( DB_VERSION_STRING
);
5660 PyObject
* cvsid_s
= PyString_FromString( rcs_id
);
5662 /* Initialize the type of the new type objects here; doing it here
5663 is required for portability to Windows without requiring C++. */
5664 DB_Type
.ob_type
= &PyType_Type
;
5665 DBCursor_Type
.ob_type
= &PyType_Type
;
5666 DBEnv_Type
.ob_type
= &PyType_Type
;
5667 DBTxn_Type
.ob_type
= &PyType_Type
;
5668 DBLock_Type
.ob_type
= &PyType_Type
;
5670 DBSequence_Type
.ob_type
= &PyType_Type
;
5674 #if defined(WITH_THREAD) && !defined(MYDB_USE_GILSTATE)
5675 /* Save the current interpreter, so callbacks can do the right thing. */
5676 _db_interpreterState
= PyThreadState_GET()->interp
;
5679 /* Create the module and add the functions */
5680 m
= Py_InitModule(_bsddbModuleName
, bsddb_methods
);
5684 /* Add some symbolic constants to the module */
5685 d
= PyModule_GetDict(m
);
5686 PyDict_SetItemString(d
, "__version__", pybsddb_version_s
);
5687 PyDict_SetItemString(d
, "cvsid", cvsid_s
);
5688 PyDict_SetItemString(d
, "DB_VERSION_STRING", db_version_s
);
5689 Py_DECREF(pybsddb_version_s
);
5690 pybsddb_version_s
= NULL
;
5693 Py_DECREF(db_version_s
);
5694 db_version_s
= NULL
;
5696 ADD_INT(d
, DB_VERSION_MAJOR
);
5697 ADD_INT(d
, DB_VERSION_MINOR
);
5698 ADD_INT(d
, DB_VERSION_PATCH
);
5700 ADD_INT(d
, DB_MAX_PAGES
);
5701 ADD_INT(d
, DB_MAX_RECORDS
);
5704 ADD_INT(d
, DB_RPCCLIENT
);
5706 ADD_INT(d
, DB_CLIENT
);
5707 /* allow apps to be written using DB_RPCCLIENT on older BerkeleyDB */
5708 _addIntToDict(d
, "DB_RPCCLIENT", DB_CLIENT
);
5710 ADD_INT(d
, DB_XA_CREATE
);
5712 ADD_INT(d
, DB_CREATE
);
5713 ADD_INT(d
, DB_NOMMAP
);
5714 ADD_INT(d
, DB_THREAD
);
5716 ADD_INT(d
, DB_FORCE
);
5717 ADD_INT(d
, DB_INIT_CDB
);
5718 ADD_INT(d
, DB_INIT_LOCK
);
5719 ADD_INT(d
, DB_INIT_LOG
);
5720 ADD_INT(d
, DB_INIT_MPOOL
);
5721 ADD_INT(d
, DB_INIT_TXN
);
5723 ADD_INT(d
, DB_JOINENV
);
5726 ADD_INT(d
, DB_RECOVER
);
5727 ADD_INT(d
, DB_RECOVER_FATAL
);
5728 ADD_INT(d
, DB_TXN_NOSYNC
);
5729 ADD_INT(d
, DB_USE_ENVIRON
);
5730 ADD_INT(d
, DB_USE_ENVIRON_ROOT
);
5732 ADD_INT(d
, DB_LOCKDOWN
);
5733 ADD_INT(d
, DB_PRIVATE
);
5734 ADD_INT(d
, DB_SYSTEM_MEM
);
5736 ADD_INT(d
, DB_TXN_SYNC
);
5737 ADD_INT(d
, DB_TXN_NOWAIT
);
5739 ADD_INT(d
, DB_EXCL
);
5740 ADD_INT(d
, DB_FCNTL_LOCKING
);
5741 ADD_INT(d
, DB_ODDFILESIZE
);
5742 ADD_INT(d
, DB_RDWRMASTER
);
5743 ADD_INT(d
, DB_RDONLY
);
5744 ADD_INT(d
, DB_TRUNCATE
);
5746 ADD_INT(d
, DB_EXTENT
);
5747 ADD_INT(d
, DB_CDB_ALLDB
);
5748 ADD_INT(d
, DB_VERIFY
);
5750 ADD_INT(d
, DB_UPGRADE
);
5752 ADD_INT(d
, DB_AGGRESSIVE
);
5753 ADD_INT(d
, DB_NOORDERCHK
);
5754 ADD_INT(d
, DB_ORDERCHKONLY
);
5755 ADD_INT(d
, DB_PR_PAGE
);
5757 ADD_INT(d
, DB_VRFY_FLAGMASK
);
5758 ADD_INT(d
, DB_PR_HEADERS
);
5760 ADD_INT(d
, DB_PR_RECOVERYTEST
);
5761 ADD_INT(d
, DB_SALVAGE
);
5763 ADD_INT(d
, DB_LOCK_NORUN
);
5764 ADD_INT(d
, DB_LOCK_DEFAULT
);
5765 ADD_INT(d
, DB_LOCK_OLDEST
);
5766 ADD_INT(d
, DB_LOCK_RANDOM
);
5767 ADD_INT(d
, DB_LOCK_YOUNGEST
);
5769 ADD_INT(d
, DB_LOCK_MAXLOCKS
);
5770 ADD_INT(d
, DB_LOCK_MINLOCKS
);
5771 ADD_INT(d
, DB_LOCK_MINWRITE
);
5776 /* docs say to use zero instead */
5777 _addIntToDict(d
, "DB_LOCK_CONFLICT", 0);
5779 ADD_INT(d
, DB_LOCK_CONFLICT
);
5782 ADD_INT(d
, DB_LOCK_DUMP
);
5783 ADD_INT(d
, DB_LOCK_GET
);
5784 ADD_INT(d
, DB_LOCK_INHERIT
);
5785 ADD_INT(d
, DB_LOCK_PUT
);
5786 ADD_INT(d
, DB_LOCK_PUT_ALL
);
5787 ADD_INT(d
, DB_LOCK_PUT_OBJ
);
5789 ADD_INT(d
, DB_LOCK_NG
);
5790 ADD_INT(d
, DB_LOCK_READ
);
5791 ADD_INT(d
, DB_LOCK_WRITE
);
5792 ADD_INT(d
, DB_LOCK_NOWAIT
);
5794 ADD_INT(d
, DB_LOCK_WAIT
);
5796 ADD_INT(d
, DB_LOCK_IWRITE
);
5797 ADD_INT(d
, DB_LOCK_IREAD
);
5798 ADD_INT(d
, DB_LOCK_IWR
);
5801 ADD_INT(d
, DB_LOCK_DIRTY
);
5803 ADD_INT(d
, DB_LOCK_READ_UNCOMMITTED
); /* renamed in 4.4 */
5805 ADD_INT(d
, DB_LOCK_WWRITE
);
5808 ADD_INT(d
, DB_LOCK_RECORD
);
5809 ADD_INT(d
, DB_LOCK_UPGRADE
);
5811 ADD_INT(d
, DB_LOCK_SWITCH
);
5814 ADD_INT(d
, DB_LOCK_UPGRADE_WRITE
);
5817 ADD_INT(d
, DB_LOCK_NOWAIT
);
5818 ADD_INT(d
, DB_LOCK_RECORD
);
5819 ADD_INT(d
, DB_LOCK_UPGRADE
);
5822 ADD_INT(d
, DB_LSTAT_ABORTED
);
5824 ADD_INT(d
, DB_LSTAT_ERR
);
5826 ADD_INT(d
, DB_LSTAT_FREE
);
5827 ADD_INT(d
, DB_LSTAT_HELD
);
5829 ADD_INT(d
, DB_LSTAT_NOGRANT
);
5831 ADD_INT(d
, DB_LSTAT_PENDING
);
5832 ADD_INT(d
, DB_LSTAT_WAITING
);
5835 ADD_INT(d
, DB_ARCH_ABS
);
5836 ADD_INT(d
, DB_ARCH_DATA
);
5837 ADD_INT(d
, DB_ARCH_LOG
);
5839 ADD_INT(d
, DB_ARCH_REMOVE
);
5842 ADD_INT(d
, DB_BTREE
);
5843 ADD_INT(d
, DB_HASH
);
5844 ADD_INT(d
, DB_RECNO
);
5845 ADD_INT(d
, DB_QUEUE
);
5846 ADD_INT(d
, DB_UNKNOWN
);
5849 ADD_INT(d
, DB_DUPSORT
);
5850 ADD_INT(d
, DB_RECNUM
);
5851 ADD_INT(d
, DB_RENUMBER
);
5852 ADD_INT(d
, DB_REVSPLITOFF
);
5853 ADD_INT(d
, DB_SNAPSHOT
);
5855 ADD_INT(d
, DB_JOIN_NOSORT
);
5857 ADD_INT(d
, DB_AFTER
);
5858 ADD_INT(d
, DB_APPEND
);
5859 ADD_INT(d
, DB_BEFORE
);
5861 ADD_INT(d
, DB_CACHED_COUNTS
);
5864 _addIntToDict(d
, "DB_CHECKPOINT", 0);
5866 ADD_INT(d
, DB_CHECKPOINT
);
5867 ADD_INT(d
, DB_CURLSN
);
5869 #if ((DBVER >= 33) && (DBVER <= 41))
5870 ADD_INT(d
, DB_COMMIT
);
5872 ADD_INT(d
, DB_CONSUME
);
5874 ADD_INT(d
, DB_CONSUME_WAIT
);
5876 ADD_INT(d
, DB_CURRENT
);
5878 ADD_INT(d
, DB_FAST_STAT
);
5880 ADD_INT(d
, DB_FIRST
);
5881 ADD_INT(d
, DB_FLUSH
);
5882 ADD_INT(d
, DB_GET_BOTH
);
5883 ADD_INT(d
, DB_GET_RECNO
);
5884 ADD_INT(d
, DB_JOIN_ITEM
);
5885 ADD_INT(d
, DB_KEYFIRST
);
5886 ADD_INT(d
, DB_KEYLAST
);
5887 ADD_INT(d
, DB_LAST
);
5888 ADD_INT(d
, DB_NEXT
);
5889 ADD_INT(d
, DB_NEXT_DUP
);
5890 ADD_INT(d
, DB_NEXT_NODUP
);
5891 ADD_INT(d
, DB_NODUPDATA
);
5892 ADD_INT(d
, DB_NOOVERWRITE
);
5893 ADD_INT(d
, DB_NOSYNC
);
5894 ADD_INT(d
, DB_POSITION
);
5895 ADD_INT(d
, DB_PREV
);
5896 ADD_INT(d
, DB_PREV_NODUP
);
5898 ADD_INT(d
, DB_RECORDCOUNT
);
5901 ADD_INT(d
, DB_SET_RANGE
);
5902 ADD_INT(d
, DB_SET_RECNO
);
5903 ADD_INT(d
, DB_WRITECURSOR
);
5905 ADD_INT(d
, DB_OPFLAGS_MASK
);
5908 ADD_INT(d
, DB_DIRTY_READ
);
5909 ADD_INT(d
, DB_MULTIPLE
);
5910 ADD_INT(d
, DB_MULTIPLE_KEY
);
5914 ADD_INT(d
, DB_READ_UNCOMMITTED
); /* replaces DB_DIRTY_READ in 4.4 */
5915 ADD_INT(d
, DB_READ_COMMITTED
);
5919 ADD_INT(d
, DB_DONOTINDEX
);
5923 _addIntToDict(d
, "DB_INCOMPLETE", 0);
5925 ADD_INT(d
, DB_INCOMPLETE
);
5927 ADD_INT(d
, DB_KEYEMPTY
);
5928 ADD_INT(d
, DB_KEYEXIST
);
5929 ADD_INT(d
, DB_LOCK_DEADLOCK
);
5930 ADD_INT(d
, DB_LOCK_NOTGRANTED
);
5931 ADD_INT(d
, DB_NOSERVER
);
5932 ADD_INT(d
, DB_NOSERVER_HOME
);
5933 ADD_INT(d
, DB_NOSERVER_ID
);
5934 ADD_INT(d
, DB_NOTFOUND
);
5935 ADD_INT(d
, DB_OLD_VERSION
);
5936 ADD_INT(d
, DB_RUNRECOVERY
);
5937 ADD_INT(d
, DB_VERIFY_BAD
);
5939 ADD_INT(d
, DB_PAGE_NOTFOUND
);
5940 ADD_INT(d
, DB_SECONDARY_BAD
);
5943 ADD_INT(d
, DB_STAT_CLEAR
);
5944 ADD_INT(d
, DB_REGION_INIT
);
5945 ADD_INT(d
, DB_NOLOCKING
);
5946 ADD_INT(d
, DB_YIELDCPU
);
5947 ADD_INT(d
, DB_PANIC_ENVIRONMENT
);
5948 ADD_INT(d
, DB_NOPANIC
);
5952 ADD_INT(d
, DB_TIME_NOTGRANTED
);
5953 ADD_INT(d
, DB_TXN_NOT_DURABLE
);
5954 ADD_INT(d
, DB_TXN_WRITE_NOSYNC
);
5955 ADD_INT(d
, DB_LOG_AUTOREMOVE
);
5956 ADD_INT(d
, DB_DIRECT_LOG
);
5957 ADD_INT(d
, DB_DIRECT_DB
);
5958 ADD_INT(d
, DB_INIT_REP
);
5959 ADD_INT(d
, DB_ENCRYPT
);
5960 ADD_INT(d
, DB_CHKSUM
);
5964 ADD_INT(d
, DB_LOG_INMEMORY
);
5965 ADD_INT(d
, DB_BUFFER_SMALL
);
5966 ADD_INT(d
, DB_SEQ_DEC
);
5967 ADD_INT(d
, DB_SEQ_INC
);
5968 ADD_INT(d
, DB_SEQ_WRAP
);
5972 ADD_INT(d
, DB_ENCRYPT_AES
);
5973 ADD_INT(d
, DB_AUTO_COMMIT
);
5975 /* allow berkeleydb 4.1 aware apps to run on older versions */
5976 _addIntToDict(d
, "DB_AUTO_COMMIT", 0);
5990 ADD_INT(d
, DB_SET_LOCK_TIMEOUT
);
5991 ADD_INT(d
, DB_SET_TXN_TIMEOUT
);
5994 /* The exception name must be correct for pickled exception *
5995 * objects to unpickle properly. */
5996 #ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
5997 #define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
5999 #define PYBSDDB_EXCEPTION_BASE "bsddb.db."
6002 /* All the rest of the exceptions derive only from DBError */
6003 #define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
6004 PyDict_SetItemString(d, #name, name)
6006 /* The base exception class is DBError */
6007 DBError
= NULL
; /* used in MAKE_EX so that it derives from nothing */
6010 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
6011 * from both DBError and KeyError, since the API only supports
6012 * using one base class. */
6013 PyDict_SetItemString(d
, "KeyError", PyExc_KeyError
);
6014 PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
6015 "class DBKeyEmptyError(DBError, KeyError): pass",
6016 Py_file_input
, d
, d
);
6017 DBNotFoundError
= PyDict_GetItemString(d
, "DBNotFoundError");
6018 DBKeyEmptyError
= PyDict_GetItemString(d
, "DBKeyEmptyError");
6019 PyDict_DelItemString(d
, "KeyError");
6022 #if !INCOMPLETE_IS_WARNING
6023 MAKE_EX(DBIncompleteError
);
6025 MAKE_EX(DBCursorClosedError
);
6026 MAKE_EX(DBKeyEmptyError
);
6027 MAKE_EX(DBKeyExistError
);
6028 MAKE_EX(DBLockDeadlockError
);
6029 MAKE_EX(DBLockNotGrantedError
);
6030 MAKE_EX(DBOldVersionError
);
6031 MAKE_EX(DBRunRecoveryError
);
6032 MAKE_EX(DBVerifyBadError
);
6033 MAKE_EX(DBNoServerError
);
6034 MAKE_EX(DBNoServerHomeError
);
6035 MAKE_EX(DBNoServerIDError
);
6037 MAKE_EX(DBPageNotFoundError
);
6038 MAKE_EX(DBSecondaryBadError
);
6041 MAKE_EX(DBInvalidArgError
);
6042 MAKE_EX(DBAccessError
);
6043 MAKE_EX(DBNoSpaceError
);
6044 MAKE_EX(DBNoMemoryError
);
6045 MAKE_EX(DBAgainError
);
6046 MAKE_EX(DBBusyError
);
6047 MAKE_EX(DBFileExistsError
);
6048 MAKE_EX(DBNoSuchFileError
);
6049 MAKE_EX(DBPermissionsError
);
6053 /* Check for errors */
6054 if (PyErr_Occurred()) {
6056 Py_FatalError("can't initialize module _bsddb");
6060 /* allow this module to be named _pybsddb so that it can be installed
6061 * and imported on top of python >= 2.3 that includes its own older
6062 * copy of the library named _bsddb without importing the old version. */
6063 DL_EXPORT(void) init_pybsddb(void)
6065 strncpy(_bsddbModuleName
, "_pybsddb", MODULE_NAME_MAX_LEN
);