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 5 types:
67 * DBCursor (Database Cursor)
68 * DBEnv (database environment)
69 * DBTxn (An explicit database transaction)
70 * DBLock (A lock handle)
74 /* --------------------------------------------------------------------- */
77 * Portions of this module, associated unit tests and build scripts are the
78 * result of a contract with The Written Word (http://thewrittenword.com/)
79 * Many thanks go out to them for causing me to raise the bar on quality and
80 * functionality, resulting in a better bsddb3 package for all of us to use.
85 /* --------------------------------------------------------------------- */
90 /* --------------------------------------------------------------------- */
91 /* Various macro definitions */
93 /* 40 = 4.0, 33 = 3.3; this will break if the second number is > 9 */
94 #define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
96 #define PY_BSDDB_VERSION "4.2.0.2"
97 static char *rcs_id
= "$Id$";
102 /* These are for when calling Python --> C */
103 #define MYDB_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS;
104 #define MYDB_END_ALLOW_THREADS Py_END_ALLOW_THREADS;
106 /* For 2.3, use the PyGILState_ calls */
107 #if (PY_VERSION_HEX >= 0x02030000)
108 #define MYDB_USE_GILSTATE
111 /* and these are for calling C --> Python */
112 #if defined(MYDB_USE_GILSTATE)
113 #define MYDB_BEGIN_BLOCK_THREADS \
114 PyGILState_STATE __savestate = PyGILState_Ensure();
115 #define MYDB_END_BLOCK_THREADS \
116 PyGILState_Release(__savestate);
117 #else /* MYDB_USE_GILSTATE */
118 /* Pre GILState API - do it the long old way */
119 static PyInterpreterState
* _db_interpreterState
= NULL
;
120 #define MYDB_BEGIN_BLOCK_THREADS { \
121 PyThreadState* prevState; \
122 PyThreadState* newState; \
123 PyEval_AcquireLock(); \
124 newState = PyThreadState_New(_db_interpreterState); \
125 prevState = PyThreadState_Swap(newState);
127 #define MYDB_END_BLOCK_THREADS \
128 newState = PyThreadState_Swap(prevState); \
129 PyThreadState_Clear(newState); \
130 PyEval_ReleaseLock(); \
131 PyThreadState_Delete(newState); \
133 #endif /* MYDB_USE_GILSTATE */
136 /* Compiled without threads - avoid all this cruft */
137 #define MYDB_BEGIN_ALLOW_THREADS
138 #define MYDB_END_ALLOW_THREADS
139 #define MYDB_BEGIN_BLOCK_THREADS
140 #define MYDB_END_BLOCK_THREADS
144 /* Should DB_INCOMPLETE be turned into a warning or an exception? */
145 #define INCOMPLETE_IS_WARNING 1
147 /* --------------------------------------------------------------------- */
150 static PyObject
* DBError
; /* Base class, all others derive from this */
151 static PyObject
* DBKeyEmptyError
; /* DB_KEYEMPTY */
152 static PyObject
* DBKeyExistError
; /* DB_KEYEXIST */
153 static PyObject
* DBLockDeadlockError
; /* DB_LOCK_DEADLOCK */
154 static PyObject
* DBLockNotGrantedError
; /* DB_LOCK_NOTGRANTED */
155 static PyObject
* DBNotFoundError
; /* DB_NOTFOUND: also derives from KeyError */
156 static PyObject
* DBOldVersionError
; /* DB_OLD_VERSION */
157 static PyObject
* DBRunRecoveryError
; /* DB_RUNRECOVERY */
158 static PyObject
* DBVerifyBadError
; /* DB_VERIFY_BAD */
159 static PyObject
* DBNoServerError
; /* DB_NOSERVER */
160 static PyObject
* DBNoServerHomeError
; /* DB_NOSERVER_HOME */
161 static PyObject
* DBNoServerIDError
; /* DB_NOSERVER_ID */
163 static PyObject
* DBPageNotFoundError
; /* DB_PAGE_NOTFOUND */
164 static PyObject
* DBSecondaryBadError
; /* DB_SECONDARY_BAD */
167 #if !INCOMPLETE_IS_WARNING
168 static PyObject
* DBIncompleteError
; /* DB_INCOMPLETE */
171 static PyObject
* DBInvalidArgError
; /* EINVAL */
172 static PyObject
* DBAccessError
; /* EACCES */
173 static PyObject
* DBNoSpaceError
; /* ENOSPC */
174 static PyObject
* DBNoMemoryError
; /* ENOMEM */
175 static PyObject
* DBAgainError
; /* EAGAIN */
176 static PyObject
* DBBusyError
; /* EBUSY */
177 static PyObject
* DBFileExistsError
; /* EEXIST */
178 static PyObject
* DBNoSuchFileError
; /* ENOENT */
179 static PyObject
* DBPermissionsError
; /* EPERM */
183 /* --------------------------------------------------------------------- */
184 /* Structure definitions */
186 struct behaviourFlags
{
187 /* What is the default behaviour when DB->get or DBCursor->get returns a
188 DB_NOTFOUND error? Return None or raise an exception? */
189 unsigned int getReturnsNone
: 1;
190 /* What is the default behaviour for DBCursor.set* methods when DBCursor->get
191 * returns a DB_NOTFOUND error? Return None or raise an exception? */
192 unsigned int cursorSetReturnsNone
: 1;
195 #define DEFAULT_GET_RETURNS_NONE 1
196 #define DEFAULT_CURSOR_SET_RETURNS_NONE 0 /* 0 in pybsddb < 4.2, python < 2.4 */
201 u_int32_t flags
; /* saved flags from open() */
203 struct behaviourFlags moduleFlags
;
210 DBEnvObject
* myenvobj
; /* PyObject containing the DB_ENV */
211 u_int32_t flags
; /* saved flags from open() */
212 u_int32_t setflags
; /* saved flags from set_flags() */
214 struct behaviourFlags moduleFlags
;
216 PyObject
* associateCallback
;
242 staticforward PyTypeObject DB_Type
, DBCursor_Type
, DBEnv_Type
, DBTxn_Type
, DBLock_Type
;
244 #define DBObject_Check(v) ((v)->ob_type == &DB_Type)
245 #define DBCursorObject_Check(v) ((v)->ob_type == &DBCursor_Type)
246 #define DBEnvObject_Check(v) ((v)->ob_type == &DBEnv_Type)
247 #define DBTxnObject_Check(v) ((v)->ob_type == &DBTxn_Type)
248 #define DBLockObject_Check(v) ((v)->ob_type == &DBLock_Type)
251 /* --------------------------------------------------------------------- */
252 /* Utility macros and functions */
254 #define RETURN_IF_ERR() \
255 if (makeDBError(err)) { \
259 #define RETURN_NONE() Py_INCREF(Py_None); return Py_None;
261 #define CHECK_DB_NOT_CLOSED(dbobj) \
262 if (dbobj->db == NULL) { \
263 PyErr_SetObject(DBError, Py_BuildValue("(is)", 0, \
264 "DB object has been closed")); \
268 #define CHECK_ENV_NOT_CLOSED(env) \
269 if (env->db_env == NULL) { \
270 PyErr_SetObject(DBError, Py_BuildValue("(is)", 0, \
271 "DBEnv object has been closed"));\
275 #define CHECK_CURSOR_NOT_CLOSED(curs) \
276 if (curs->dbc == NULL) { \
277 PyErr_SetObject(DBError, Py_BuildValue("(is)", 0, \
278 "DBCursor object has been closed"));\
284 #define CHECK_DBFLAG(mydb, flag) (((mydb)->flags & (flag)) || \
285 (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))
287 #define CLEAR_DBT(dbt) (memset(&(dbt), 0, sizeof(dbt)))
289 #define FREE_DBT(dbt) if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
290 dbt.data != NULL) { free(dbt.data); }
293 static int makeDBError(int err
);
296 /* Return the access method type of the DBObject */
297 static int _DB_get_type(DBObject
* self
)
302 err
= self
->db
->get_type(self
->db
, &type
);
303 if (makeDBError(err
)) {
308 return self
->db
->get_type(self
->db
);
313 /* Create a DBT structure (containing key and data values) from Python
314 strings. Returns 1 on success, 0 on an error. */
315 static int make_dbt(PyObject
* obj
, DBT
* dbt
)
318 if (obj
== Py_None
) {
319 /* no need to do anything, the structure has already been zeroed */
321 else if (!PyArg_Parse(obj
, "s#", &dbt
->data
, &dbt
->size
)) {
322 PyErr_SetString(PyExc_TypeError
,
323 "Key and Data values must be of type string or None.");
330 /* Recno and Queue DBs can have integer keys. This function figures out
331 what's been given, verifies that it's allowed, and then makes the DBT.
333 Caller should call FREE_DBT(key) when done. */
335 make_key_dbt(DBObject
* self
, PyObject
* keyobj
, DBT
* key
, int* pflags
)
341 if (keyobj
== Py_None
) { /* TODO: is None really okay for keys? */
342 /* no need to do anything, the structure has already been zeroed */
345 else if (PyString_Check(keyobj
)) {
346 /* verify access method type */
347 type
= _DB_get_type(self
);
350 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
353 "String keys not allowed for Recno and Queue DB's");
357 key
->data
= PyString_AS_STRING(keyobj
);
358 key
->size
= PyString_GET_SIZE(keyobj
);
361 else if (PyInt_Check(keyobj
)) {
362 /* verify access method type */
363 type
= _DB_get_type(self
);
366 if (type
== DB_BTREE
&& pflags
!= NULL
) {
367 /* if BTREE then an Integer key is allowed with the
368 * DB_SET_RECNO flag */
369 *pflags
|= DB_SET_RECNO
;
371 else if (type
!= DB_RECNO
&& type
!= DB_QUEUE
) {
374 "Integer keys only allowed for Recno and Queue DB's");
378 /* Make a key out of the requested recno, use allocated space so DB
379 * will be able to realloc room for the real key if needed. */
380 recno
= PyInt_AS_LONG(keyobj
);
381 key
->data
= malloc(sizeof(db_recno_t
));
382 if (key
->data
== NULL
) {
383 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
386 key
->ulen
= key
->size
= sizeof(db_recno_t
);
387 memcpy(key
->data
, &recno
, sizeof(db_recno_t
));
388 key
->flags
= DB_DBT_REALLOC
;
391 PyErr_Format(PyExc_TypeError
,
392 "String or Integer object expected for key, %s found",
393 keyobj
->ob_type
->tp_name
);
401 /* Add partial record access to an existing DBT data struct.
402 If dlen and doff are set, then the DB_DBT_PARTIAL flag will be set
403 and the data storage/retrieval will be done using dlen and doff. */
404 static int add_partial_dbt(DBT
* d
, int dlen
, int doff
) {
405 /* if neither were set we do nothing (-1 is the default value) */
406 if ((dlen
== -1) && (doff
== -1)) {
410 if ((dlen
< 0) || (doff
< 0)) {
411 PyErr_SetString(PyExc_TypeError
, "dlen and doff must both be >= 0");
415 d
->flags
= d
->flags
| DB_DBT_PARTIAL
;
416 d
->dlen
= (unsigned int) dlen
;
417 d
->doff
= (unsigned int) doff
;
422 /* Callback used to save away more information about errors from the DB
424 static char _db_errmsg
[1024];
425 static void _db_errorCallback(const char* prefix
, char* msg
)
427 strcpy(_db_errmsg
, msg
);
431 /* make a nice exception object to raise for errors. */
432 static int makeDBError(int err
)
434 char errTxt
[2048]; /* really big, just in case... */
435 PyObject
*errObj
= NULL
;
436 PyObject
*errTuple
= NULL
;
437 int exceptionRaised
= 0;
440 case 0: /* successful, no error */ break;
444 #if INCOMPLETE_IS_WARNING
445 strcpy(errTxt
, db_strerror(err
));
447 strcat(errTxt
, " -- ");
448 strcat(errTxt
, _db_errmsg
);
451 /* if Python 2.1 or better use warning framework */
452 #if PYTHON_API_VERSION >= 1010
453 exceptionRaised
= PyErr_Warn(PyExc_RuntimeWarning
, errTxt
);
455 fprintf(stderr
, errTxt
);
456 fprintf(stderr
, "\n");
459 #else /* do an exception instead */
460 errObj
= DBIncompleteError
;
463 #endif /* DBVER < 41 */
465 case DB_KEYEMPTY
: errObj
= DBKeyEmptyError
; break;
466 case DB_KEYEXIST
: errObj
= DBKeyExistError
; break;
467 case DB_LOCK_DEADLOCK
: errObj
= DBLockDeadlockError
; break;
468 case DB_LOCK_NOTGRANTED
: errObj
= DBLockNotGrantedError
; break;
469 case DB_NOTFOUND
: errObj
= DBNotFoundError
; break;
470 case DB_OLD_VERSION
: errObj
= DBOldVersionError
; break;
471 case DB_RUNRECOVERY
: errObj
= DBRunRecoveryError
; break;
472 case DB_VERIFY_BAD
: errObj
= DBVerifyBadError
; break;
473 case DB_NOSERVER
: errObj
= DBNoServerError
; break;
474 case DB_NOSERVER_HOME
: errObj
= DBNoServerHomeError
; break;
475 case DB_NOSERVER_ID
: errObj
= DBNoServerIDError
; break;
477 case DB_PAGE_NOTFOUND
: errObj
= DBPageNotFoundError
; break;
478 case DB_SECONDARY_BAD
: errObj
= DBSecondaryBadError
; break;
481 case EINVAL
: errObj
= DBInvalidArgError
; break;
482 case EACCES
: errObj
= DBAccessError
; break;
483 case ENOSPC
: errObj
= DBNoSpaceError
; break;
484 case ENOMEM
: errObj
= DBNoMemoryError
; break;
485 case EAGAIN
: errObj
= DBAgainError
; break;
486 case EBUSY
: errObj
= DBBusyError
; break;
487 case EEXIST
: errObj
= DBFileExistsError
; break;
488 case ENOENT
: errObj
= DBNoSuchFileError
; break;
489 case EPERM
: errObj
= DBPermissionsError
; break;
491 default: errObj
= DBError
; break;
494 if (errObj
!= NULL
) {
495 /* FIXME this needs proper bounds checking on errTxt */
496 strcpy(errTxt
, db_strerror(err
));
498 strcat(errTxt
, " -- ");
499 strcat(errTxt
, _db_errmsg
);
503 errTuple
= Py_BuildValue("(is)", err
, errTxt
);
504 PyErr_SetObject(errObj
, errTuple
);
508 return ((errObj
!= NULL
) || exceptionRaised
);
513 /* set a type exception */
514 static void makeTypeError(char* expected
, PyObject
* found
)
516 PyErr_Format(PyExc_TypeError
, "Expected %s argument, %s found.",
517 expected
, found
->ob_type
->tp_name
);
521 /* verify that an obj is either None or a DBTxn, and set the txn pointer */
522 static int checkTxnObj(PyObject
* txnobj
, DB_TXN
** txn
)
524 if (txnobj
== Py_None
|| txnobj
== NULL
) {
528 if (DBTxnObject_Check(txnobj
)) {
529 *txn
= ((DBTxnObject
*)txnobj
)->txn
;
533 makeTypeError("DBTxn", txnobj
);
538 /* Delete a key from a database
539 Returns 0 on success, -1 on an error. */
540 static int _DB_delete(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, int flags
)
544 MYDB_BEGIN_ALLOW_THREADS
;
545 err
= self
->db
->del(self
->db
, txn
, key
, 0);
546 MYDB_END_ALLOW_THREADS
;
547 if (makeDBError(err
)) {
555 /* Store a key into a database
556 Returns 0 on success, -1 on an error. */
557 static int _DB_put(DBObject
* self
, DB_TXN
*txn
, DBT
*key
, DBT
*data
, int flags
)
561 MYDB_BEGIN_ALLOW_THREADS
;
562 err
= self
->db
->put(self
->db
, txn
, key
, data
, flags
);
563 MYDB_END_ALLOW_THREADS
;
564 if (makeDBError(err
)) {
571 /* Get a key/data pair from a cursor */
572 static PyObject
* _DBCursor_get(DBCursorObject
* self
, int extra_flags
,
573 PyObject
*args
, PyObject
*kwargs
, char *format
)
576 PyObject
* retval
= NULL
;
581 char* kwnames
[] = { "flags", "dlen", "doff", NULL
};
583 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, format
, kwnames
,
584 &flags
, &dlen
, &doff
))
587 CHECK_CURSOR_NOT_CLOSED(self
);
589 flags
|= extra_flags
;
592 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
593 /* Tell BerkeleyDB to malloc the return value (thread safe) */
594 data
.flags
= DB_DBT_MALLOC
;
595 key
.flags
= DB_DBT_MALLOC
;
597 if (!add_partial_dbt(&data
, dlen
, doff
))
600 MYDB_BEGIN_ALLOW_THREADS
;
601 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
602 MYDB_END_ALLOW_THREADS
;
604 if ((err
== DB_NOTFOUND
) && self
->mydb
->moduleFlags
.getReturnsNone
) {
608 else if (makeDBError(err
)) {
611 else { /* otherwise, success! */
613 /* if Recno or Queue, return the key as an Int */
614 switch (_DB_get_type(self
->mydb
)) {
621 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
622 data
.data
, data
.size
);
627 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
628 data
.data
, data
.size
);
640 /* add an integer to a dictionary using the given name as a key */
641 static void _addIntToDict(PyObject
* dict
, char *name
, int value
)
643 PyObject
* v
= PyInt_FromLong((long) value
);
644 if (!v
|| PyDict_SetItemString(dict
, name
, v
))
653 /* --------------------------------------------------------------------- */
654 /* Allocators and deallocators */
657 newDBObject(DBEnvObject
* arg
, int flags
)
660 DB_ENV
* db_env
= NULL
;
663 #if PYTHON_API_VERSION <= 1007
664 /* 1.5 compatibility */
665 self
= PyObject_NEW(DBObject
, &DB_Type
);
667 self
= PyObject_New(DBObject
, &DB_Type
);
676 self
->myenvobj
= NULL
;
678 self
->associateCallback
= NULL
;
679 self
->primaryDBType
= 0;
682 /* keep a reference to our python DBEnv object */
685 self
->myenvobj
= arg
;
686 db_env
= arg
->db_env
;
690 self
->moduleFlags
= self
->myenvobj
->moduleFlags
;
692 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
693 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
695 MYDB_BEGIN_ALLOW_THREADS
;
696 err
= db_create(&self
->db
, db_env
, flags
);
697 self
->db
->set_errcall(self
->db
, _db_errorCallback
);
699 self
->db
->app_private
= (void*)self
;
701 MYDB_END_ALLOW_THREADS
;
702 if (makeDBError(err
)) {
703 if (self
->myenvobj
) {
704 Py_DECREF(self
->myenvobj
);
705 self
->myenvobj
= NULL
;
714 DB_dealloc(DBObject
* self
)
716 if (self
->db
!= NULL
) {
717 /* avoid closing a DB when its DBEnv has been closed out from under
719 if (!self
->myenvobj
||
720 (self
->myenvobj
&& self
->myenvobj
->db_env
))
722 MYDB_BEGIN_ALLOW_THREADS
;
723 self
->db
->close(self
->db
, 0);
724 MYDB_END_ALLOW_THREADS
;
725 /* if Python 2.1 or better use warning framework */
726 #if PYTHON_API_VERSION >= 1010
728 PyErr_Warn(PyExc_RuntimeWarning
,
729 "DB could not be closed in destructor: DBEnv already closed");
734 if (self
->myenvobj
) {
735 Py_DECREF(self
->myenvobj
);
736 self
->myenvobj
= NULL
;
739 if (self
->associateCallback
!= NULL
) {
740 Py_DECREF(self
->associateCallback
);
741 self
->associateCallback
= NULL
;
744 #if PYTHON_API_VERSION <= 1007
752 static DBCursorObject
*
753 newDBCursorObject(DBC
* dbc
, DBObject
* db
)
755 DBCursorObject
* self
;
756 #if PYTHON_API_VERSION <= 1007
757 self
= PyObject_NEW(DBCursorObject
, &DBCursor_Type
);
759 self
= PyObject_New(DBCursorObject
, &DBCursor_Type
);
766 Py_INCREF(self
->mydb
);
772 DBCursor_dealloc(DBCursorObject
* self
)
775 if (self
->dbc
!= NULL
) {
776 MYDB_BEGIN_ALLOW_THREADS
;
777 /* If the underlying database has been closed, we don't
778 need to do anything. If the environment has been closed
779 we need to leak, as BerkeleyDB will crash trying to access
780 the environment. There was an exception when the
781 user closed the environment even though there still was
783 if (self
->mydb
->db
&& self
->mydb
->myenvobj
&&
784 !self
->mydb
->myenvobj
->closed
)
785 err
= self
->dbc
->c_close(self
->dbc
);
787 MYDB_END_ALLOW_THREADS
;
789 Py_XDECREF( self
->mydb
);
790 #if PYTHON_API_VERSION <= 1007
799 newDBEnvObject(int flags
)
803 #if PYTHON_API_VERSION <= 1007
804 self
= PyObject_NEW(DBEnvObject
, &DBEnv_Type
);
806 self
= PyObject_New(DBEnvObject
, &DBEnv_Type
);
814 self
->moduleFlags
.getReturnsNone
= DEFAULT_GET_RETURNS_NONE
;
815 self
->moduleFlags
.cursorSetReturnsNone
= DEFAULT_CURSOR_SET_RETURNS_NONE
;
817 MYDB_BEGIN_ALLOW_THREADS
;
818 err
= db_env_create(&self
->db_env
, flags
);
819 MYDB_END_ALLOW_THREADS
;
820 if (makeDBError(err
)) {
824 self
->db_env
->set_errcall(self
->db_env
, _db_errorCallback
);
831 DBEnv_dealloc(DBEnvObject
* self
)
834 MYDB_BEGIN_ALLOW_THREADS
;
835 self
->db_env
->close(self
->db_env
, 0);
836 MYDB_END_ALLOW_THREADS
;
838 #if PYTHON_API_VERSION <= 1007
847 newDBTxnObject(DBEnvObject
* myenv
, DB_TXN
*parent
, int flags
)
852 #if PYTHON_API_VERSION <= 1007
853 self
= PyObject_NEW(DBTxnObject
, &DBTxn_Type
);
855 self
= PyObject_New(DBTxnObject
, &DBTxn_Type
);
860 MYDB_BEGIN_ALLOW_THREADS
;
862 err
= myenv
->db_env
->txn_begin(myenv
->db_env
, parent
, &(self
->txn
), flags
);
864 err
= txn_begin(myenv
->db_env
, parent
, &(self
->txn
), flags
);
866 MYDB_END_ALLOW_THREADS
;
867 if (makeDBError(err
)) {
875 DBTxn_dealloc(DBTxnObject
* self
)
877 /* XXX nothing to do for transaction objects?!? */
879 /* TODO: if it hasn't been commited, should we abort it? */
881 #if PYTHON_API_VERSION <= 1007
890 newDBLockObject(DBEnvObject
* myenv
, u_int32_t locker
, DBT
* obj
,
891 db_lockmode_t lock_mode
, int flags
)
896 #if PYTHON_API_VERSION <= 1007
897 self
= PyObject_NEW(DBLockObject
, &DBLock_Type
);
899 self
= PyObject_New(DBLockObject
, &DBLock_Type
);
904 MYDB_BEGIN_ALLOW_THREADS
;
906 err
= myenv
->db_env
->lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
,
909 err
= lock_get(myenv
->db_env
, locker
, flags
, obj
, lock_mode
, &self
->lock
);
911 MYDB_END_ALLOW_THREADS
;
912 if (makeDBError(err
)) {
921 DBLock_dealloc(DBLockObject
* self
)
923 /* TODO: if it hasn't been released, should we do it? */
925 #if PYTHON_API_VERSION <= 1007
933 /* --------------------------------------------------------------------- */
937 DB_append(DBObject
* self
, PyObject
* args
)
939 PyObject
* txnobj
= NULL
;
945 if (!PyArg_ParseTuple(args
, "O|O:append", &dataobj
, &txnobj
))
948 CHECK_DB_NOT_CLOSED(self
);
950 /* make a dummy key out of a recno */
954 key
.size
= sizeof(recno
);
956 key
.flags
= DB_DBT_USERMEM
;
958 if (!make_dbt(dataobj
, &data
)) return NULL
;
959 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
961 if (-1 == _DB_put(self
, txn
, &key
, &data
, DB_APPEND
))
964 return PyInt_FromLong(recno
);
971 _db_associateCallback(DB
* db
, const DBT
* priKey
, const DBT
* priData
,
974 int retval
= DB_DONOTINDEX
;
975 DBObject
* secondaryDB
= (DBObject
*)db
->app_private
;
976 PyObject
* callback
= secondaryDB
->associateCallback
;
977 int type
= secondaryDB
->primaryDBType
;
984 if (callback
!= NULL
) {
985 MYDB_BEGIN_BLOCK_THREADS
;
987 if (type
== DB_RECNO
|| type
== DB_QUEUE
) {
988 key
= PyInt_FromLong( *((db_recno_t
*)priKey
->data
));
991 key
= PyString_FromStringAndSize(priKey
->data
, priKey
->size
);
993 data
= PyString_FromStringAndSize(priData
->data
, priData
->size
);
994 args
= PyTuple_New(2);
995 PyTuple_SET_ITEM(args
, 0, key
); /* steals reference */
996 PyTuple_SET_ITEM(args
, 1, data
); /* steals reference */
998 result
= PyEval_CallObject(callback
, args
);
1000 if (result
== NULL
) {
1003 else if (result
== Py_None
) {
1004 retval
= DB_DONOTINDEX
;
1006 else if (PyInt_Check(result
)) {
1007 retval
= PyInt_AsLong(result
);
1009 else if (PyString_Check(result
)) {
1014 #if PYTHON_API_VERSION <= 1007
1015 /* 1.5 compatibility */
1016 size
= PyString_Size(result
);
1017 data
= PyString_AsString(result
);
1019 PyString_AsStringAndSize(result
, &data
, &size
);
1021 secKey
->flags
= DB_DBT_APPMALLOC
; /* DB will free */
1022 secKey
->data
= malloc(size
); /* TODO, check this */
1024 memcpy(secKey
->data
, data
, size
);
1025 secKey
->size
= size
;
1029 PyErr_SetString(PyExc_MemoryError
,
1030 "malloc failed in _db_associateCallback");
1037 "DB associate callback should return DB_DONOTINDEX or string.");
1046 MYDB_END_BLOCK_THREADS
;
1053 DB_associate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1056 DBObject
* secondaryDB
;
1059 PyObject
*txnobj
= NULL
;
1061 char* kwnames
[] = {"secondaryDB", "callback", "flags", "txn", NULL
};
1063 char* kwnames
[] = {"secondaryDB", "callback", "flags", NULL
};
1067 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iO:associate", kwnames
,
1068 &secondaryDB
, &callback
, &flags
,
1071 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|i:associate", kwnames
,
1072 &secondaryDB
, &callback
, &flags
)) {
1078 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1081 CHECK_DB_NOT_CLOSED(self
);
1082 if (!DBObject_Check(secondaryDB
)) {
1083 makeTypeError("DB", (PyObject
*)secondaryDB
);
1086 if (callback
== Py_None
) {
1089 else if (!PyCallable_Check(callback
)) {
1090 makeTypeError("Callable", callback
);
1094 /* Save a reference to the callback in the secondary DB. */
1095 if (self
->associateCallback
!= NULL
) {
1096 Py_DECREF(self
->associateCallback
);
1098 Py_INCREF(callback
);
1099 secondaryDB
->associateCallback
= callback
;
1100 secondaryDB
->primaryDBType
= _DB_get_type(self
);
1102 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1103 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1104 * The global interepreter lock is not initialized until the first
1105 * thread is created using thread.start_new_thread() or fork() is
1106 * called. that would cause the ALLOW_THREADS here to segfault due
1107 * to a null pointer reference if no threads or child processes
1108 * have been created. This works around that and is a no-op if
1109 * threads have already been initialized.
1110 * (see pybsddb-users mailing list post on 2002-08-07)
1113 PyEval_InitThreads();
1115 MYDB_BEGIN_ALLOW_THREADS
;
1117 err
= self
->db
->associate(self
->db
,
1120 _db_associateCallback
,
1123 err
= self
->db
->associate(self
->db
,
1125 _db_associateCallback
,
1128 MYDB_END_ALLOW_THREADS
;
1131 Py_DECREF(self
->associateCallback
);
1132 self
->associateCallback
= NULL
;
1133 secondaryDB
->primaryDBType
= 0;
1145 DB_close(DBObject
* self
, PyObject
* args
)
1148 if (!PyArg_ParseTuple(args
,"|i:close", &flags
))
1150 if (self
->db
!= NULL
) {
1152 CHECK_ENV_NOT_CLOSED(self
->myenvobj
);
1153 err
= self
->db
->close(self
->db
, flags
);
1163 _DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1165 int err
, flags
=0, type
;
1166 PyObject
* txnobj
= NULL
;
1167 PyObject
* retval
= NULL
;
1170 char* kwnames
[] = { "txn", "flags", NULL
};
1172 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:consume", kwnames
,
1176 CHECK_DB_NOT_CLOSED(self
);
1177 type
= _DB_get_type(self
);
1180 if (type
!= DB_QUEUE
) {
1181 PyErr_SetString(PyExc_TypeError
,
1182 "Consume methods only allowed for Queue DB's");
1185 if (!checkTxnObj(txnobj
, &txn
))
1190 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1191 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1192 data
.flags
= DB_DBT_MALLOC
;
1193 key
.flags
= DB_DBT_MALLOC
;
1196 MYDB_BEGIN_ALLOW_THREADS
;
1197 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
|consume_flag
);
1198 MYDB_END_ALLOW_THREADS
;
1200 if ((err
== DB_NOTFOUND
) && self
->moduleFlags
.getReturnsNone
) {
1206 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
1217 DB_consume(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
, int consume_flag
)
1219 return _DB_consume(self
, args
, kwargs
, DB_CONSUME
);
1223 DB_consume_wait(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
,
1226 return _DB_consume(self
, args
, kwargs
, DB_CONSUME_WAIT
);
1233 DB_cursor(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1237 PyObject
* txnobj
= NULL
;
1239 char* kwnames
[] = { "txn", "flags", NULL
};
1241 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
1244 CHECK_DB_NOT_CLOSED(self
);
1245 if (!checkTxnObj(txnobj
, &txn
))
1248 MYDB_BEGIN_ALLOW_THREADS
;
1249 err
= self
->db
->cursor(self
->db
, txn
, &dbc
, flags
);
1250 MYDB_END_ALLOW_THREADS
;
1252 return (PyObject
*) newDBCursorObject(dbc
, self
);
1257 DB_delete(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1259 PyObject
* txnobj
= NULL
;
1264 char* kwnames
[] = { "key", "txn", "flags", NULL
};
1266 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:delete", kwnames
,
1267 &keyobj
, &txnobj
, &flags
))
1269 CHECK_DB_NOT_CLOSED(self
);
1270 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1272 if (!checkTxnObj(txnobj
, &txn
))
1275 if (-1 == _DB_delete(self
, txn
, &key
, 0))
1284 DB_fd(DBObject
* self
, PyObject
* args
)
1288 if (!PyArg_ParseTuple(args
,":fd"))
1290 CHECK_DB_NOT_CLOSED(self
);
1292 MYDB_BEGIN_ALLOW_THREADS
;
1293 err
= self
->db
->fd(self
->db
, &the_fd
);
1294 MYDB_END_ALLOW_THREADS
;
1296 return PyInt_FromLong(the_fd
);
1301 DB_get(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1304 PyObject
* txnobj
= NULL
;
1306 PyObject
* dfltobj
= NULL
;
1307 PyObject
* retval
= NULL
;
1312 char* kwnames
[] = {"key", "default", "txn", "flags", "dlen", "doff", NULL
};
1314 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|OOiii:get", kwnames
,
1315 &keyobj
, &dfltobj
, &txnobj
, &flags
, &dlen
,
1319 CHECK_DB_NOT_CLOSED(self
);
1320 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1322 if (!checkTxnObj(txnobj
, &txn
))
1326 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1327 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1328 data
.flags
= DB_DBT_MALLOC
;
1330 if (!add_partial_dbt(&data
, dlen
, doff
))
1333 MYDB_BEGIN_ALLOW_THREADS
;
1334 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1335 MYDB_END_ALLOW_THREADS
;
1337 if ((err
== DB_NOTFOUND
) && (dfltobj
!= NULL
)) {
1342 else if ((err
== DB_NOTFOUND
) && self
->moduleFlags
.getReturnsNone
) {
1348 if (flags
& DB_SET_RECNO
) /* return both key and data */
1349 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
1351 else /* return just the data */
1352 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
1362 /* Return size of entry */
1364 DB_get_size(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1367 PyObject
* txnobj
= NULL
;
1369 PyObject
* retval
= NULL
;
1372 char* kwnames
[] = { "key", "txn", NULL
};
1374 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O:get_size", kwnames
,
1377 CHECK_DB_NOT_CLOSED(self
);
1378 if (!make_key_dbt(self
, keyobj
, &key
, &flags
))
1380 if (!checkTxnObj(txnobj
, &txn
))
1384 /* We don't allocate any memory, forcing a ENOMEM error and thus
1385 getting the record size. */
1386 data
.flags
= DB_DBT_USERMEM
;
1388 MYDB_BEGIN_ALLOW_THREADS
;
1389 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1390 MYDB_END_ALLOW_THREADS
;
1391 if (err
== ENOMEM
) {
1392 retval
= PyInt_FromLong((long)data
.size
);
1404 DB_get_both(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1407 PyObject
* txnobj
= NULL
;
1410 PyObject
* retval
= NULL
;
1413 char* kwnames
[] = { "key", "data", "txn", "flags", NULL
};
1416 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oi:get_both", kwnames
,
1417 &keyobj
, &dataobj
, &txnobj
, &flags
))
1420 CHECK_DB_NOT_CLOSED(self
);
1421 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
1423 if (!make_dbt(dataobj
, &data
))
1425 if (!checkTxnObj(txnobj
, &txn
))
1428 flags
|= DB_GET_BOTH
;
1430 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
1431 /* Tell BerkeleyDB to malloc the return value (thread safe) */
1432 data
.flags
= DB_DBT_MALLOC
;
1433 /* TODO: Is this flag needed? We're passing a data object that should
1434 match what's in the DB, so there should be no need to malloc.
1435 We run the risk of freeing something twice! Check this. */
1438 MYDB_BEGIN_ALLOW_THREADS
;
1439 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, flags
);
1440 MYDB_END_ALLOW_THREADS
;
1442 if ((err
== DB_NOTFOUND
) && self
->moduleFlags
.getReturnsNone
) {
1448 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
1449 FREE_DBT(data
); /* Only if retrieval was successful */
1459 DB_get_byteswapped(DBObject
* self
, PyObject
* args
)
1466 if (!PyArg_ParseTuple(args
,":get_byteswapped"))
1468 CHECK_DB_NOT_CLOSED(self
);
1471 MYDB_BEGIN_ALLOW_THREADS
;
1472 err
= self
->db
->get_byteswapped(self
->db
, &retval
);
1473 MYDB_END_ALLOW_THREADS
;
1476 MYDB_BEGIN_ALLOW_THREADS
;
1477 retval
= self
->db
->get_byteswapped(self
->db
);
1478 MYDB_END_ALLOW_THREADS
;
1480 return PyInt_FromLong(retval
);
1485 DB_get_type(DBObject
* self
, PyObject
* args
)
1489 if (!PyArg_ParseTuple(args
,":get_type"))
1491 CHECK_DB_NOT_CLOSED(self
);
1493 MYDB_BEGIN_ALLOW_THREADS
;
1494 type
= _DB_get_type(self
);
1495 MYDB_END_ALLOW_THREADS
;
1498 return PyInt_FromLong(type
);
1503 DB_join(DBObject
* self
, PyObject
* args
)
1507 PyObject
* cursorsObj
;
1512 if (!PyArg_ParseTuple(args
,"O|i:join", &cursorsObj
, &flags
))
1515 CHECK_DB_NOT_CLOSED(self
);
1517 if (!PySequence_Check(cursorsObj
)) {
1518 PyErr_SetString(PyExc_TypeError
,
1519 "Sequence of DBCursor objects expected");
1523 length
= PyObject_Length(cursorsObj
);
1524 cursors
= malloc((length
+1) * sizeof(DBC
*));
1525 cursors
[length
] = NULL
;
1526 for (x
=0; x
<length
; x
++) {
1527 PyObject
* item
= PySequence_GetItem(cursorsObj
, x
);
1528 if (!DBCursorObject_Check(item
)) {
1529 PyErr_SetString(PyExc_TypeError
,
1530 "Sequence of DBCursor objects expected");
1534 cursors
[x
] = ((DBCursorObject
*)item
)->dbc
;
1537 MYDB_BEGIN_ALLOW_THREADS
;
1538 err
= self
->db
->join(self
->db
, cursors
, &dbc
, flags
);
1539 MYDB_END_ALLOW_THREADS
;
1543 // FIXME: this is a buggy interface. The returned cursor
1544 // contains internal references to the passed in cursors
1545 // but does not hold python references to them or prevent
1546 // them from being closed prematurely. This can cause
1547 // python to crash when things are done in the wrong order.
1548 return (PyObject
*) newDBCursorObject(dbc
, self
);
1553 DB_key_range(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1556 PyObject
* txnobj
= NULL
;
1561 char* kwnames
[] = { "key", "txn", "flags", NULL
};
1563 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|Oi:key_range", kwnames
,
1564 &keyobj
, &txnobj
, &flags
))
1566 CHECK_DB_NOT_CLOSED(self
);
1567 if (!make_dbt(keyobj
, &key
))
1568 /* BTree only, don't need to allow for an int key */
1570 if (!checkTxnObj(txnobj
, &txn
))
1573 MYDB_BEGIN_ALLOW_THREADS
;
1574 err
= self
->db
->key_range(self
->db
, txn
, &key
, &range
, flags
);
1575 MYDB_END_ALLOW_THREADS
;
1578 return Py_BuildValue("ddd", range
.less
, range
.equal
, range
.greater
);
1583 DB_open(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1585 int err
, type
= DB_UNKNOWN
, flags
=0, mode
=0660;
1586 char* filename
= NULL
;
1587 char* dbname
= NULL
;
1589 PyObject
*txnobj
= NULL
;
1593 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL
};
1594 /* without dbname */
1595 char* kwnames_basic
[] = {
1596 "filename", "dbtype", "flags", "mode", "txn", NULL
};
1600 "filename", "dbname", "dbtype", "flags", "mode", NULL
};
1601 /* without dbname */
1602 char* kwnames_basic
[] = {
1603 "filename", "dbtype", "flags", "mode", NULL
};
1607 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziiiO:open", kwnames
,
1608 &filename
, &dbname
, &type
, &flags
, &mode
,
1611 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "z|ziii:open", kwnames
,
1612 &filename
, &dbname
, &type
, &flags
,
1617 type
= DB_UNKNOWN
; flags
= 0; mode
= 0660;
1618 filename
= NULL
; dbname
= NULL
;
1620 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iiiO:open",
1622 &filename
, &type
, &flags
, &mode
,
1626 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,"z|iii:open",
1628 &filename
, &type
, &flags
, &mode
))
1634 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1637 if (NULL
== self
->db
) {
1638 PyErr_SetObject(DBError
, Py_BuildValue("(is)", 0,
1639 "Cannot call open() twice for DB object"));
1643 #if 0 && (DBVER >= 41)
1644 if ((!txn
) && (txnobj
!= Py_None
) && self
->myenvobj
1645 && (self
->myenvobj
->flags
& DB_INIT_TXN
))
1647 /* If no 'txn' parameter was supplied (no DbTxn object and None was not
1648 * explicitly passed) but we are in a transaction ready environment:
1649 * add DB_AUTO_COMMIT to allow for older pybsddb apps using transactions
1650 * to work on BerkeleyDB 4.1 without needing to modify their
1651 * DBEnv or DB open calls.
1652 * TODO make this behaviour of the library configurable.
1654 flags
|= DB_AUTO_COMMIT
;
1658 MYDB_BEGIN_ALLOW_THREADS
;
1660 err
= self
->db
->open(self
->db
, txn
, filename
, dbname
, type
, flags
, mode
);
1662 err
= self
->db
->open(self
->db
, filename
, dbname
, type
, flags
, mode
);
1664 MYDB_END_ALLOW_THREADS
;
1665 if (makeDBError(err
)) {
1666 self
->db
->close(self
->db
, 0);
1671 self
->flags
= flags
;
1677 DB_put(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1680 PyObject
* txnobj
= NULL
;
1683 PyObject
* keyobj
, *dataobj
, *retval
;
1686 char* kwnames
[] = { "key", "data", "txn", "flags", "dlen", "doff", NULL
};
1688 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|Oiii:put", kwnames
,
1689 &keyobj
, &dataobj
, &txnobj
, &flags
, &dlen
, &doff
))
1692 CHECK_DB_NOT_CLOSED(self
);
1693 if (!make_key_dbt(self
, keyobj
, &key
, NULL
)) return NULL
;
1694 if (!make_dbt(dataobj
, &data
)) return NULL
;
1695 if (!add_partial_dbt(&data
, dlen
, doff
)) return NULL
;
1696 if (!checkTxnObj(txnobj
, &txn
)) return NULL
;
1698 if (-1 == _DB_put(self
, txn
, &key
, &data
, flags
)) {
1703 if (flags
& DB_APPEND
)
1704 retval
= PyInt_FromLong(*((db_recno_t
*)key
.data
));
1716 DB_remove(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
1719 char* database
= NULL
;
1721 char* kwnames
[] = { "filename", "dbname", "flags", NULL
};
1723 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zi:remove", kwnames
,
1724 &filename
, &database
, &flags
))
1726 CHECK_DB_NOT_CLOSED(self
);
1728 err
= self
->db
->remove(self
->db
, filename
, database
, flags
);
1737 DB_rename(DBObject
* self
, PyObject
* args
)
1744 if (!PyArg_ParseTuple(args
, "sss|i:rename", &filename
, &database
, &newname
,
1747 CHECK_DB_NOT_CLOSED(self
);
1749 MYDB_BEGIN_ALLOW_THREADS
;
1750 err
= self
->db
->rename(self
->db
, filename
, database
, newname
, flags
);
1751 MYDB_END_ALLOW_THREADS
;
1758 DB_set_bt_minkey(DBObject
* self
, PyObject
* args
)
1762 if (!PyArg_ParseTuple(args
,"i:set_bt_minkey", &minkey
))
1764 CHECK_DB_NOT_CLOSED(self
);
1766 MYDB_BEGIN_ALLOW_THREADS
;
1767 err
= self
->db
->set_bt_minkey(self
->db
, minkey
);
1768 MYDB_END_ALLOW_THREADS
;
1775 DB_set_cachesize(DBObject
* self
, PyObject
* args
)
1778 int gbytes
= 0, bytes
= 0, ncache
= 0;
1780 if (!PyArg_ParseTuple(args
,"ii|i:set_cachesize",
1781 &gbytes
,&bytes
,&ncache
))
1783 CHECK_DB_NOT_CLOSED(self
);
1785 MYDB_BEGIN_ALLOW_THREADS
;
1786 err
= self
->db
->set_cachesize(self
->db
, gbytes
, bytes
, ncache
);
1787 MYDB_END_ALLOW_THREADS
;
1794 DB_set_flags(DBObject
* self
, PyObject
* args
)
1798 if (!PyArg_ParseTuple(args
,"i:set_flags", &flags
))
1800 CHECK_DB_NOT_CLOSED(self
);
1802 MYDB_BEGIN_ALLOW_THREADS
;
1803 err
= self
->db
->set_flags(self
->db
, flags
);
1804 MYDB_END_ALLOW_THREADS
;
1807 self
->setflags
|= flags
;
1813 DB_set_h_ffactor(DBObject
* self
, PyObject
* args
)
1817 if (!PyArg_ParseTuple(args
,"i:set_h_ffactor", &ffactor
))
1819 CHECK_DB_NOT_CLOSED(self
);
1821 MYDB_BEGIN_ALLOW_THREADS
;
1822 err
= self
->db
->set_h_ffactor(self
->db
, ffactor
);
1823 MYDB_END_ALLOW_THREADS
;
1830 DB_set_h_nelem(DBObject
* self
, PyObject
* args
)
1834 if (!PyArg_ParseTuple(args
,"i:set_h_nelem", &nelem
))
1836 CHECK_DB_NOT_CLOSED(self
);
1838 MYDB_BEGIN_ALLOW_THREADS
;
1839 err
= self
->db
->set_h_nelem(self
->db
, nelem
);
1840 MYDB_END_ALLOW_THREADS
;
1847 DB_set_lorder(DBObject
* self
, PyObject
* args
)
1851 if (!PyArg_ParseTuple(args
,"i:set_lorder", &lorder
))
1853 CHECK_DB_NOT_CLOSED(self
);
1855 MYDB_BEGIN_ALLOW_THREADS
;
1856 err
= self
->db
->set_lorder(self
->db
, lorder
);
1857 MYDB_END_ALLOW_THREADS
;
1864 DB_set_pagesize(DBObject
* self
, PyObject
* args
)
1868 if (!PyArg_ParseTuple(args
,"i:set_pagesize", &pagesize
))
1870 CHECK_DB_NOT_CLOSED(self
);
1872 MYDB_BEGIN_ALLOW_THREADS
;
1873 err
= self
->db
->set_pagesize(self
->db
, pagesize
);
1874 MYDB_END_ALLOW_THREADS
;
1881 DB_set_re_delim(DBObject
* self
, PyObject
* args
)
1886 if (!PyArg_ParseTuple(args
,"b:set_re_delim", &delim
)) {
1888 if (!PyArg_ParseTuple(args
,"c:set_re_delim", &delim
))
1892 CHECK_DB_NOT_CLOSED(self
);
1894 MYDB_BEGIN_ALLOW_THREADS
;
1895 err
= self
->db
->set_re_delim(self
->db
, delim
);
1896 MYDB_END_ALLOW_THREADS
;
1902 DB_set_re_len(DBObject
* self
, PyObject
* args
)
1906 if (!PyArg_ParseTuple(args
,"i:set_re_len", &len
))
1908 CHECK_DB_NOT_CLOSED(self
);
1910 MYDB_BEGIN_ALLOW_THREADS
;
1911 err
= self
->db
->set_re_len(self
->db
, len
);
1912 MYDB_END_ALLOW_THREADS
;
1919 DB_set_re_pad(DBObject
* self
, PyObject
* args
)
1924 if (!PyArg_ParseTuple(args
,"b:set_re_pad", &pad
)) {
1926 if (!PyArg_ParseTuple(args
,"c:set_re_pad", &pad
))
1929 CHECK_DB_NOT_CLOSED(self
);
1931 MYDB_BEGIN_ALLOW_THREADS
;
1932 err
= self
->db
->set_re_pad(self
->db
, pad
);
1933 MYDB_END_ALLOW_THREADS
;
1940 DB_set_re_source(DBObject
* self
, PyObject
* args
)
1945 if (!PyArg_ParseTuple(args
,"s:set_re_source", &re_source
))
1947 CHECK_DB_NOT_CLOSED(self
);
1949 MYDB_BEGIN_ALLOW_THREADS
;
1950 err
= self
->db
->set_re_source(self
->db
, re_source
);
1951 MYDB_END_ALLOW_THREADS
;
1959 DB_set_q_extentsize(DBObject
* self
, PyObject
* args
)
1964 if (!PyArg_ParseTuple(args
,"i:set_q_extentsize", &extentsize
))
1966 CHECK_DB_NOT_CLOSED(self
);
1968 MYDB_BEGIN_ALLOW_THREADS
;
1969 err
= self
->db
->set_q_extentsize(self
->db
, extentsize
);
1970 MYDB_END_ALLOW_THREADS
;
1977 DB_stat(DBObject
* self
, PyObject
* args
)
1979 int err
, flags
= 0, type
;
1984 if (!PyArg_ParseTuple(args
, "|i:stat", &flags
))
1986 CHECK_DB_NOT_CLOSED(self
);
1988 MYDB_BEGIN_ALLOW_THREADS
;
1990 err
= self
->db
->stat(self
->db
, &sp
, flags
);
1992 err
= self
->db
->stat(self
->db
, &sp
, NULL
, flags
);
1994 MYDB_END_ALLOW_THREADS
;
1999 /* Turn the stat structure into a dictionary */
2000 type
= _DB_get_type(self
);
2001 if ((type
== -1) || ((d
= PyDict_New()) == NULL
)) {
2006 #define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
2007 #define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
2008 #define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
2012 MAKE_HASH_ENTRY(magic
);
2013 MAKE_HASH_ENTRY(version
);
2014 MAKE_HASH_ENTRY(nkeys
);
2015 MAKE_HASH_ENTRY(ndata
);
2016 MAKE_HASH_ENTRY(pagesize
);
2018 MAKE_HASH_ENTRY(nelem
);
2020 MAKE_HASH_ENTRY(ffactor
);
2021 MAKE_HASH_ENTRY(buckets
);
2022 MAKE_HASH_ENTRY(free
);
2023 MAKE_HASH_ENTRY(bfree
);
2024 MAKE_HASH_ENTRY(bigpages
);
2025 MAKE_HASH_ENTRY(big_bfree
);
2026 MAKE_HASH_ENTRY(overflows
);
2027 MAKE_HASH_ENTRY(ovfl_free
);
2028 MAKE_HASH_ENTRY(dup
);
2029 MAKE_HASH_ENTRY(dup_free
);
2034 MAKE_BT_ENTRY(magic
);
2035 MAKE_BT_ENTRY(version
);
2036 MAKE_BT_ENTRY(nkeys
);
2037 MAKE_BT_ENTRY(ndata
);
2038 MAKE_BT_ENTRY(pagesize
);
2039 MAKE_BT_ENTRY(minkey
);
2040 MAKE_BT_ENTRY(re_len
);
2041 MAKE_BT_ENTRY(re_pad
);
2042 MAKE_BT_ENTRY(levels
);
2043 MAKE_BT_ENTRY(int_pg
);
2044 MAKE_BT_ENTRY(leaf_pg
);
2045 MAKE_BT_ENTRY(dup_pg
);
2046 MAKE_BT_ENTRY(over_pg
);
2047 MAKE_BT_ENTRY(free
);
2048 MAKE_BT_ENTRY(int_pgfree
);
2049 MAKE_BT_ENTRY(leaf_pgfree
);
2050 MAKE_BT_ENTRY(dup_pgfree
);
2051 MAKE_BT_ENTRY(over_pgfree
);
2055 MAKE_QUEUE_ENTRY(magic
);
2056 MAKE_QUEUE_ENTRY(version
);
2057 MAKE_QUEUE_ENTRY(nkeys
);
2058 MAKE_QUEUE_ENTRY(ndata
);
2059 MAKE_QUEUE_ENTRY(pagesize
);
2060 MAKE_QUEUE_ENTRY(pages
);
2061 MAKE_QUEUE_ENTRY(re_len
);
2062 MAKE_QUEUE_ENTRY(re_pad
);
2063 MAKE_QUEUE_ENTRY(pgfree
);
2065 MAKE_QUEUE_ENTRY(start
);
2067 MAKE_QUEUE_ENTRY(first_recno
);
2068 MAKE_QUEUE_ENTRY(cur_recno
);
2072 PyErr_SetString(PyExc_TypeError
, "Unknown DB type, unable to stat");
2077 #undef MAKE_HASH_ENTRY
2078 #undef MAKE_BT_ENTRY
2079 #undef MAKE_QUEUE_ENTRY
2086 DB_sync(DBObject
* self
, PyObject
* args
)
2091 if (!PyArg_ParseTuple(args
,"|i:sync", &flags
))
2093 CHECK_DB_NOT_CLOSED(self
);
2095 MYDB_BEGIN_ALLOW_THREADS
;
2096 err
= self
->db
->sync(self
->db
, flags
);
2097 MYDB_END_ALLOW_THREADS
;
2105 DB_truncate(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2109 PyObject
* txnobj
= NULL
;
2111 char* kwnames
[] = { "txn", "flags", NULL
};
2113 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:cursor", kwnames
,
2116 CHECK_DB_NOT_CLOSED(self
);
2117 if (!checkTxnObj(txnobj
, &txn
))
2120 MYDB_BEGIN_ALLOW_THREADS
;
2121 err
= self
->db
->truncate(self
->db
, txn
, &count
, flags
);
2122 MYDB_END_ALLOW_THREADS
;
2124 return PyInt_FromLong(count
);
2130 DB_upgrade(DBObject
* self
, PyObject
* args
)
2135 if (!PyArg_ParseTuple(args
,"s|i:upgrade", &filename
, &flags
))
2137 CHECK_DB_NOT_CLOSED(self
);
2139 MYDB_BEGIN_ALLOW_THREADS
;
2140 err
= self
->db
->upgrade(self
->db
, filename
, flags
);
2141 MYDB_END_ALLOW_THREADS
;
2148 DB_verify(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2153 char* outFileName
=NULL
;
2155 char* kwnames
[] = { "filename", "dbname", "outfile", "flags", NULL
};
2157 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|zzi:verify", kwnames
,
2158 &fileName
, &dbName
, &outFileName
, &flags
))
2161 CHECK_DB_NOT_CLOSED(self
);
2163 outFile
= fopen(outFileName
, "w");
2165 MYDB_BEGIN_ALLOW_THREADS
;
2166 err
= self
->db
->verify(self
->db
, fileName
, dbName
, outFile
, flags
);
2167 MYDB_END_ALLOW_THREADS
;
2171 /* DB.verify acts as a DB handle destructor (like close); this was
2172 * documented in BerkeleyDB 4.2 but had the undocumented effect
2173 * of not being safe in prior versions while still requiring an explicit
2174 * DB.close call afterwards. Lets call close for the user to emulate
2175 * the safe 4.2 behaviour. */
2177 self
->db
->close(self
->db
, 0);
2187 DB_set_get_returns_none(DBObject
* self
, PyObject
* args
)
2192 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
2194 CHECK_DB_NOT_CLOSED(self
);
2196 if (self
->moduleFlags
.getReturnsNone
)
2198 if (self
->moduleFlags
.cursorSetReturnsNone
)
2200 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
2201 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
2202 return PyInt_FromLong(oldValue
);
2207 DB_set_encrypt(DBObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2211 char *passwd
= NULL
;
2212 char* kwnames
[] = { "passwd", "flags", NULL
};
2214 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
2219 MYDB_BEGIN_ALLOW_THREADS
;
2220 err
= self
->db
->set_encrypt(self
->db
, passwd
, flags
);
2221 MYDB_END_ALLOW_THREADS
;
2226 #endif /* DBVER >= 41 */
2229 /*-------------------------------------------------------------- */
2230 /* Mapping and Dictionary-like access routines */
2232 int DB_length(DBObject
* self
)
2239 if (self
->db
== NULL
) {
2240 PyErr_SetObject(DBError
,
2241 Py_BuildValue("(is)", 0, "DB object has been closed"));
2245 if (self
->haveStat
) { /* Has the stat function been called recently? If
2246 so, we can use the cached value. */
2247 flags
= DB_CACHED_COUNTS
;
2250 MYDB_BEGIN_ALLOW_THREADS
;
2252 err
= self
->db
->stat(self
->db
, &sp
, flags
);
2254 err
= self
->db
->stat(self
->db
, &sp
, NULL
, flags
);
2256 MYDB_END_ALLOW_THREADS
;
2263 /* All the stat structures have matching fields upto the ndata field,
2264 so we can use any of them for the type cast */
2265 size
= ((DB_BTREE_STAT
*)sp
)->bt_ndata
;
2271 PyObject
* DB_subscript(DBObject
* self
, PyObject
* keyobj
)
2278 CHECK_DB_NOT_CLOSED(self
);
2279 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2283 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2284 /* Tell BerkeleyDB to malloc the return value (thread safe) */
2285 data
.flags
= DB_DBT_MALLOC
;
2287 MYDB_BEGIN_ALLOW_THREADS
;
2288 err
= self
->db
->get(self
->db
, NULL
, &key
, &data
, 0);
2289 MYDB_END_ALLOW_THREADS
;
2290 if (err
== DB_NOTFOUND
|| err
== DB_KEYEMPTY
) {
2291 PyErr_SetObject(PyExc_KeyError
, keyobj
);
2294 else if (makeDBError(err
)) {
2298 retval
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
2308 DB_ass_sub(DBObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
)
2314 if (self
->db
== NULL
) {
2315 PyErr_SetObject(DBError
,
2316 Py_BuildValue("(is)", 0, "DB object has been closed"));
2320 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2323 if (dataobj
!= NULL
) {
2324 if (!make_dbt(dataobj
, &data
))
2327 if (self
->setflags
& (DB_DUP
|DB_DUPSORT
))
2328 /* dictionaries shouldn't have duplicate keys */
2329 flags
= DB_NOOVERWRITE
;
2330 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2332 if ((retval
== -1) && (self
->setflags
& (DB_DUP
|DB_DUPSORT
))) {
2333 /* try deleting any old record that matches and then PUT it
2335 _DB_delete(self
, NULL
, &key
, 0);
2337 retval
= _DB_put(self
, NULL
, &key
, &data
, flags
);
2342 /* dataobj == NULL, so delete the key */
2343 retval
= _DB_delete(self
, NULL
, &key
, 0);
2351 DB_has_key(DBObject
* self
, PyObject
* args
)
2356 PyObject
* txnobj
= NULL
;
2359 if (!PyArg_ParseTuple(args
,"O|O:has_key", &keyobj
, &txnobj
))
2361 CHECK_DB_NOT_CLOSED(self
);
2362 if (!make_key_dbt(self
, keyobj
, &key
, NULL
))
2364 if (!checkTxnObj(txnobj
, &txn
))
2367 /* This causes ENOMEM to be returned when the db has the key because
2368 it has a record but can't allocate a buffer for the data. This saves
2369 having to deal with data we won't be using.
2372 data
.flags
= DB_DBT_USERMEM
;
2374 MYDB_BEGIN_ALLOW_THREADS
;
2375 err
= self
->db
->get(self
->db
, txn
, &key
, &data
, 0);
2376 MYDB_END_ALLOW_THREADS
;
2378 return PyInt_FromLong((err
== ENOMEM
) || (err
== 0));
2382 #define _KEYS_LIST 1
2383 #define _VALUES_LIST 2
2384 #define _ITEMS_LIST 3
2387 _DB_make_list(DBObject
* self
, DB_TXN
* txn
, int type
)
2394 PyObject
* item
= NULL
;
2396 CHECK_DB_NOT_CLOSED(self
);
2400 dbtype
= _DB_get_type(self
);
2404 list
= PyList_New(0);
2406 PyErr_SetString(PyExc_MemoryError
, "PyList_New failed");
2411 MYDB_BEGIN_ALLOW_THREADS
;
2412 err
= self
->db
->cursor(self
->db
, NULL
, &cursor
, 0);
2413 MYDB_END_ALLOW_THREADS
;
2416 if (CHECK_DBFLAG(self
, DB_THREAD
)) {
2417 key
.flags
= DB_DBT_REALLOC
;
2418 data
.flags
= DB_DBT_REALLOC
;
2421 while (1) { /* use the cursor to traverse the DB, collecting items */
2422 MYDB_BEGIN_ALLOW_THREADS
;
2423 err
= cursor
->c_get(cursor
, &key
, &data
, DB_NEXT
);
2424 MYDB_END_ALLOW_THREADS
;
2427 /* for any error, break out of the loop */
2437 item
= PyString_FromStringAndSize((char*)key
.data
, key
.size
);
2441 item
= PyInt_FromLong(*((db_recno_t
*)key
.data
));
2447 item
= PyString_FromStringAndSize((char*)data
.data
, data
.size
);
2455 item
= Py_BuildValue("s#s#", key
.data
, key
.size
, data
.data
,
2460 item
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
2461 data
.data
, data
.size
);
2468 PyErr_SetString(PyExc_MemoryError
, "List item creation failed");
2472 PyList_Append(list
, item
);
2476 /* DB_NOTFOUND is okay, it just means we got to the end */
2477 if (err
!= DB_NOTFOUND
&& makeDBError(err
)) {
2485 MYDB_BEGIN_ALLOW_THREADS
;
2486 cursor
->c_close(cursor
);
2487 MYDB_END_ALLOW_THREADS
;
2493 DB_keys(DBObject
* self
, PyObject
* args
)
2495 PyObject
* txnobj
= NULL
;
2498 if (!PyArg_ParseTuple(args
,"|O:keys", &txnobj
))
2500 if (!checkTxnObj(txnobj
, &txn
))
2502 return _DB_make_list(self
, txn
, _KEYS_LIST
);
2507 DB_items(DBObject
* self
, PyObject
* args
)
2509 PyObject
* txnobj
= NULL
;
2512 if (!PyArg_ParseTuple(args
,"|O:items", &txnobj
))
2514 if (!checkTxnObj(txnobj
, &txn
))
2516 return _DB_make_list(self
, txn
, _ITEMS_LIST
);
2521 DB_values(DBObject
* self
, PyObject
* args
)
2523 PyObject
* txnobj
= NULL
;
2526 if (!PyArg_ParseTuple(args
,"|O:values", &txnobj
))
2528 if (!checkTxnObj(txnobj
, &txn
))
2530 return _DB_make_list(self
, txn
, _VALUES_LIST
);
2533 /* --------------------------------------------------------------------- */
2534 /* DBCursor methods */
2538 DBC_close(DBCursorObject
* self
, PyObject
* args
)
2542 if (!PyArg_ParseTuple(args
, ":close"))
2545 if (self
->dbc
!= NULL
) {
2546 MYDB_BEGIN_ALLOW_THREADS
;
2547 err
= self
->dbc
->c_close(self
->dbc
);
2549 MYDB_END_ALLOW_THREADS
;
2557 DBC_count(DBCursorObject
* self
, PyObject
* args
)
2563 if (!PyArg_ParseTuple(args
, "|i:count", &flags
))
2566 CHECK_CURSOR_NOT_CLOSED(self
);
2568 MYDB_BEGIN_ALLOW_THREADS
;
2569 err
= self
->dbc
->c_count(self
->dbc
, &count
, flags
);
2570 MYDB_END_ALLOW_THREADS
;
2573 return PyInt_FromLong(count
);
2578 DBC_current(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2580 return _DBCursor_get(self
,DB_CURRENT
,args
,kwargs
,"|iii:current");
2585 DBC_delete(DBCursorObject
* self
, PyObject
* args
)
2589 if (!PyArg_ParseTuple(args
, "|i:delete", &flags
))
2592 CHECK_CURSOR_NOT_CLOSED(self
);
2594 MYDB_BEGIN_ALLOW_THREADS
;
2595 err
= self
->dbc
->c_del(self
->dbc
, flags
);
2596 MYDB_END_ALLOW_THREADS
;
2599 self
->mydb
->haveStat
= 0;
2605 DBC_dup(DBCursorObject
* self
, PyObject
* args
)
2610 if (!PyArg_ParseTuple(args
, "|i:dup", &flags
))
2613 CHECK_CURSOR_NOT_CLOSED(self
);
2615 MYDB_BEGIN_ALLOW_THREADS
;
2616 err
= self
->dbc
->c_dup(self
->dbc
, &dbc
, flags
);
2617 MYDB_END_ALLOW_THREADS
;
2620 return (PyObject
*) newDBCursorObject(dbc
, self
->mydb
);
2624 DBC_first(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2626 return _DBCursor_get(self
,DB_FIRST
,args
,kwargs
,"|iii:first");
2631 DBC_get(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2634 PyObject
* keyobj
= NULL
;
2635 PyObject
* dataobj
= NULL
;
2636 PyObject
* retval
= NULL
;
2640 char* kwnames
[] = { "key","data", "flags", "dlen", "doff", NULL
};
2644 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|ii:get", &kwnames
[2],
2645 &flags
, &dlen
, &doff
))
2648 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "Oi|ii:get",
2650 &keyobj
, &flags
, &dlen
, &doff
))
2653 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OOi|ii:get",
2654 kwnames
, &keyobj
, &dataobj
,
2655 &flags
, &dlen
, &doff
))
2662 CHECK_CURSOR_NOT_CLOSED(self
);
2664 if (keyobj
&& !make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
2666 if (dataobj
&& !make_dbt(dataobj
, &data
))
2668 if (!add_partial_dbt(&data
, dlen
, doff
))
2671 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
2672 data
.flags
= DB_DBT_MALLOC
;
2673 key
.flags
= DB_DBT_MALLOC
;
2676 MYDB_BEGIN_ALLOW_THREADS
;
2677 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
);
2678 MYDB_END_ALLOW_THREADS
;
2681 if ((err
== DB_NOTFOUND
) && self
->mydb
->moduleFlags
.getReturnsNone
) {
2685 else if (makeDBError(err
)) {
2689 switch (_DB_get_type(self
->mydb
)) {
2696 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
2697 data
.data
, data
.size
);
2701 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
2702 data
.data
, data
.size
);
2713 DBC_get_recno(DBCursorObject
* self
, PyObject
* args
)
2720 if (!PyArg_ParseTuple(args
, ":get_recno"))
2723 CHECK_CURSOR_NOT_CLOSED(self
);
2727 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
2728 /* Tell BerkeleyDB to malloc the return value (thread safe) */
2729 data
.flags
= DB_DBT_MALLOC
;
2730 key
.flags
= DB_DBT_MALLOC
;
2733 MYDB_BEGIN_ALLOW_THREADS
;
2734 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, DB_GET_RECNO
);
2735 MYDB_END_ALLOW_THREADS
;
2738 recno
= *((db_recno_t
*)data
.data
);
2741 return PyInt_FromLong(recno
);
2746 DBC_last(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2748 return _DBCursor_get(self
,DB_LAST
,args
,kwargs
,"|iii:last");
2753 DBC_next(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2755 return _DBCursor_get(self
,DB_NEXT
,args
,kwargs
,"|iii:next");
2760 DBC_prev(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2762 return _DBCursor_get(self
,DB_PREV
,args
,kwargs
,"|iii:prev");
2767 DBC_put(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2770 PyObject
* keyobj
, *dataobj
;
2772 char* kwnames
[] = { "key", "data", "flags", "dlen", "doff", NULL
};
2776 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "OO|iii:put", kwnames
,
2777 &keyobj
, &dataobj
, &flags
, &dlen
, &doff
))
2780 CHECK_CURSOR_NOT_CLOSED(self
);
2782 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
2784 if (!make_dbt(dataobj
, &data
))
2786 if (!add_partial_dbt(&data
, dlen
, doff
)) return NULL
;
2788 MYDB_BEGIN_ALLOW_THREADS
;
2789 err
= self
->dbc
->c_put(self
->dbc
, &key
, &data
, flags
);
2790 MYDB_END_ALLOW_THREADS
;
2793 self
->mydb
->haveStat
= 0;
2799 DBC_set(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
2803 PyObject
* retval
, *keyobj
;
2804 char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
2808 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set", kwnames
,
2809 &keyobj
, &flags
, &dlen
, &doff
))
2812 CHECK_CURSOR_NOT_CLOSED(self
);
2814 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
2818 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
2819 /* Tell BerkeleyDB to malloc the return value (thread safe) */
2820 data
.flags
= DB_DBT_MALLOC
;
2822 if (!add_partial_dbt(&data
, dlen
, doff
))
2825 MYDB_BEGIN_ALLOW_THREADS
;
2826 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET
);
2827 MYDB_END_ALLOW_THREADS
;
2828 if ((err
== DB_NOTFOUND
) && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
2832 else if (makeDBError(err
)) {
2836 switch (_DB_get_type(self
->mydb
)) {
2843 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
2844 data
.data
, data
.size
);
2848 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
2849 data
.data
, data
.size
);
2852 if (_DB_get_type(self
->mydb
) == DB_BTREE
) {
2853 /* the only time a malloced key is returned is when we
2854 * call this on a BTree database because it performs
2855 * partial matching and needs to return the real key.
2856 * All others leave key untouched [where calling free()
2857 * on it would often segfault].
2869 DBC_set_range(DBCursorObject
* self
, PyObject
* args
, PyObject
* kwargs
)
2873 PyObject
* retval
, *keyobj
;
2874 char* kwnames
[] = { "key", "flags", "dlen", "doff", NULL
};
2878 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|iii:set_range", kwnames
,
2879 &keyobj
, &flags
, &dlen
, &doff
))
2882 CHECK_CURSOR_NOT_CLOSED(self
);
2884 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
2888 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
2889 /* Tell BerkeleyDB to malloc the return value (thread safe) */
2890 data
.flags
= DB_DBT_MALLOC
;
2891 key
.flags
= DB_DBT_MALLOC
;
2893 if (!add_partial_dbt(&data
, dlen
, doff
))
2895 MYDB_BEGIN_ALLOW_THREADS
;
2896 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RANGE
);
2897 MYDB_END_ALLOW_THREADS
;
2898 if ((err
== DB_NOTFOUND
) && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
2902 else if (makeDBError(err
)) {
2906 switch (_DB_get_type(self
->mydb
)) {
2913 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
2914 data
.data
, data
.size
);
2918 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
2919 data
.data
, data
.size
);
2922 if (_DB_get_type(self
->mydb
) == DB_BTREE
) {
2923 /* the only time a malloced key is returned is when we
2924 * call this on a BTree database because it performs
2925 * partial matching and needs to return the real key.
2926 * All others leave key untouched [where calling free()
2927 * on it would often segfault].
2938 _DBC_get_set_both(DBCursorObject
* self
, PyObject
* keyobj
, PyObject
* dataobj
,
2939 int flags
, unsigned int returnsNone
)
2945 // the caller did this: CHECK_CURSOR_NOT_CLOSED(self);
2946 if (!make_key_dbt(self
->mydb
, keyobj
, &key
, NULL
))
2948 if (!make_dbt(dataobj
, &data
))
2951 MYDB_BEGIN_ALLOW_THREADS
;
2952 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_GET_BOTH
);
2953 MYDB_END_ALLOW_THREADS
;
2954 if ((err
== DB_NOTFOUND
) && returnsNone
) {
2958 else if (makeDBError(err
)) {
2962 switch (_DB_get_type(self
->mydb
)) {
2969 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
2970 data
.data
, data
.size
);
2974 retval
= Py_BuildValue("is#", *((db_recno_t
*)key
.data
),
2975 data
.data
, data
.size
);
2985 DBC_get_both(DBCursorObject
* self
, PyObject
* args
)
2988 PyObject
*keyobj
, *dataobj
;
2990 if (!PyArg_ParseTuple(args
, "OO|i:get_both", &keyobj
, &dataobj
, &flags
))
2993 // if the cursor is closed, self->mydb may be invalid
2994 CHECK_CURSOR_NOT_CLOSED(self
);
2996 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
2997 self
->mydb
->moduleFlags
.getReturnsNone
);
3001 DBC_set_both(DBCursorObject
* self
, PyObject
* args
)
3004 PyObject
*keyobj
, *dataobj
;
3006 if (!PyArg_ParseTuple(args
, "OO|i:set_both", &keyobj
, &dataobj
, &flags
))
3009 // if the cursor is closed, self->mydb may be invalid
3010 CHECK_CURSOR_NOT_CLOSED(self
);
3012 return _DBC_get_set_both(self
, keyobj
, dataobj
, flags
,
3013 self
->mydb
->moduleFlags
.cursorSetReturnsNone
);
3018 DBC_set_recno(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3020 int err
, irecno
, flags
=0;
3026 char* kwnames
[] = { "recno","flags", "dlen", "doff", NULL
};
3028 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|iii:set_recno", kwnames
,
3029 &irecno
, &flags
, &dlen
, &doff
))
3032 CHECK_CURSOR_NOT_CLOSED(self
);
3035 recno
= (db_recno_t
) irecno
;
3036 /* use allocated space so DB will be able to realloc room for the real
3038 key
.data
= malloc(sizeof(db_recno_t
));
3039 if (key
.data
== NULL
) {
3040 PyErr_SetString(PyExc_MemoryError
, "Key memory allocation failed");
3043 key
.size
= sizeof(db_recno_t
);
3044 key
.ulen
= key
.size
;
3045 memcpy(key
.data
, &recno
, sizeof(db_recno_t
));
3046 key
.flags
= DB_DBT_REALLOC
;
3049 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3050 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3051 data
.flags
= DB_DBT_MALLOC
;
3053 if (!add_partial_dbt(&data
, dlen
, doff
))
3056 MYDB_BEGIN_ALLOW_THREADS
;
3057 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
|DB_SET_RECNO
);
3058 MYDB_END_ALLOW_THREADS
;
3059 if ((err
== DB_NOTFOUND
) && self
->mydb
->moduleFlags
.cursorSetReturnsNone
) {
3063 else if (makeDBError(err
)) {
3066 else { /* Can only be used for BTrees, so no need to return int key */
3067 retval
= Py_BuildValue("s#s#", key
.data
, key
.size
,
3068 data
.data
, data
.size
);
3078 DBC_consume(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3080 return _DBCursor_get(self
,DB_CONSUME
,args
,kwargs
,"|iii:consume");
3085 DBC_next_dup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3087 return _DBCursor_get(self
,DB_NEXT_DUP
,args
,kwargs
,"|iii:next_dup");
3092 DBC_next_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3094 return _DBCursor_get(self
,DB_NEXT_NODUP
,args
,kwargs
,"|iii:next_nodup");
3099 DBC_prev_nodup(DBCursorObject
* self
, PyObject
* args
, PyObject
*kwargs
)
3101 return _DBCursor_get(self
,DB_PREV_NODUP
,args
,kwargs
,"|iii:prev_nodup");
3106 DBC_join_item(DBCursorObject
* self
, PyObject
* args
)
3112 if (!PyArg_ParseTuple(args
, "|i:join_item", &flags
))
3115 CHECK_CURSOR_NOT_CLOSED(self
);
3119 if (CHECK_DBFLAG(self
->mydb
, DB_THREAD
)) {
3120 /* Tell BerkeleyDB to malloc the return value (thread safe) */
3121 key
.flags
= DB_DBT_MALLOC
;
3124 MYDB_BEGIN_ALLOW_THREADS
;
3125 err
= self
->dbc
->c_get(self
->dbc
, &key
, &data
, flags
| DB_JOIN_ITEM
);
3126 MYDB_END_ALLOW_THREADS
;
3127 if ((err
== DB_NOTFOUND
) && self
->mydb
->moduleFlags
.getReturnsNone
) {
3131 else if (makeDBError(err
)) {
3135 retval
= Py_BuildValue("s#", key
.data
, key
.size
);
3144 /* --------------------------------------------------------------------- */
3149 DBEnv_close(DBEnvObject
* self
, PyObject
* args
)
3153 if (!PyArg_ParseTuple(args
, "|i:close", &flags
))
3155 if (!self
->closed
) { /* Don't close more than once */
3156 MYDB_BEGIN_ALLOW_THREADS
;
3157 err
= self
->db_env
->close(self
->db_env
, flags
);
3158 MYDB_END_ALLOW_THREADS
;
3159 /* after calling DBEnv->close, regardless of error, this DBEnv
3160 * may not be accessed again (BerkeleyDB docs). */
3162 self
->db_env
= NULL
;
3170 DBEnv_open(DBEnvObject
* self
, PyObject
* args
)
3172 int err
, flags
=0, mode
=0660;
3175 if (!PyArg_ParseTuple(args
, "z|ii:open", &db_home
, &flags
, &mode
))
3178 CHECK_ENV_NOT_CLOSED(self
);
3180 MYDB_BEGIN_ALLOW_THREADS
;
3181 err
= self
->db_env
->open(self
->db_env
, db_home
, flags
, mode
);
3182 MYDB_END_ALLOW_THREADS
;
3185 self
->flags
= flags
;
3191 DBEnv_remove(DBEnvObject
* self
, PyObject
* args
)
3196 if (!PyArg_ParseTuple(args
, "s|i:remove", &db_home
, &flags
))
3198 CHECK_ENV_NOT_CLOSED(self
);
3199 MYDB_BEGIN_ALLOW_THREADS
;
3200 err
= self
->db_env
->remove(self
->db_env
, db_home
, flags
);
3201 MYDB_END_ALLOW_THREADS
;
3208 DBEnv_dbremove(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3213 char *database
= NULL
;
3214 PyObject
*txnobj
= NULL
;
3216 char* kwnames
[] = { "file", "database", "txn", "flags", NULL
};
3218 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ss|Oi:dbremove", kwnames
,
3219 &file
, &database
, &txnobj
, &flags
)) {
3222 if (!checkTxnObj(txnobj
, &txn
)) {
3225 CHECK_ENV_NOT_CLOSED(self
);
3226 MYDB_BEGIN_ALLOW_THREADS
;
3227 err
= self
->db_env
->dbremove(self
->db_env
, txn
, file
, database
, flags
);
3228 MYDB_END_ALLOW_THREADS
;
3234 DBEnv_dbrename(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3239 char *database
= NULL
;
3240 char *newname
= NULL
;
3241 PyObject
*txnobj
= NULL
;
3243 char* kwnames
[] = { "file", "database", "newname", "txn", "flags", NULL
};
3245 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "sss|Oi:dbrename", kwnames
,
3246 &file
, &database
, &newname
, &txnobj
, &flags
)) {
3249 if (!checkTxnObj(txnobj
, &txn
)) {
3252 CHECK_ENV_NOT_CLOSED(self
);
3253 MYDB_BEGIN_ALLOW_THREADS
;
3254 err
= self
->db_env
->dbrename(self
->db_env
, txn
, file
, database
, newname
,
3256 MYDB_END_ALLOW_THREADS
;
3262 DBEnv_set_encrypt(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3266 char *passwd
= NULL
;
3267 char* kwnames
[] = { "passwd", "flags", NULL
};
3269 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|i:set_encrypt", kwnames
,
3274 MYDB_BEGIN_ALLOW_THREADS
;
3275 err
= self
->db_env
->set_encrypt(self
->db_env
, passwd
, flags
);
3276 MYDB_END_ALLOW_THREADS
;
3281 #endif /* DBVER >= 41 */
3285 DBEnv_set_timeout(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3289 u_int32_t timeout
= 0;
3290 char* kwnames
[] = { "timeout", "flags", NULL
};
3292 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ii:set_timeout", kwnames
,
3293 &timeout
, &flags
)) {
3297 MYDB_BEGIN_ALLOW_THREADS
;
3298 err
= self
->db_env
->set_timeout(self
->db_env
, (db_timeout_t
)timeout
, flags
);
3299 MYDB_END_ALLOW_THREADS
;
3304 #endif /* DBVER >= 40 */
3307 DBEnv_set_shm_key(DBEnvObject
* self
, PyObject
* args
)
3312 if (!PyArg_ParseTuple(args
, "l:set_shm_key", &shm_key
))
3314 CHECK_ENV_NOT_CLOSED(self
);
3316 err
= self
->db_env
->set_shm_key(self
->db_env
, shm_key
);
3322 DBEnv_set_cachesize(DBEnvObject
* self
, PyObject
* args
)
3324 int err
, gbytes
=0, bytes
=0, ncache
=0;
3326 if (!PyArg_ParseTuple(args
, "ii|i:set_cachesize",
3327 &gbytes
, &bytes
, &ncache
))
3329 CHECK_ENV_NOT_CLOSED(self
);
3331 MYDB_BEGIN_ALLOW_THREADS
;
3332 err
= self
->db_env
->set_cachesize(self
->db_env
, gbytes
, bytes
, ncache
);
3333 MYDB_END_ALLOW_THREADS
;
3341 DBEnv_set_flags(DBEnvObject
* self
, PyObject
* args
)
3343 int err
, flags
=0, onoff
=0;
3345 if (!PyArg_ParseTuple(args
, "ii:set_flags",
3348 CHECK_ENV_NOT_CLOSED(self
);
3350 MYDB_BEGIN_ALLOW_THREADS
;
3351 err
= self
->db_env
->set_flags(self
->db_env
, flags
, onoff
);
3352 MYDB_END_ALLOW_THREADS
;
3360 DBEnv_set_data_dir(DBEnvObject
* self
, PyObject
* args
)
3365 if (!PyArg_ParseTuple(args
, "s:set_data_dir", &dir
))
3367 CHECK_ENV_NOT_CLOSED(self
);
3369 MYDB_BEGIN_ALLOW_THREADS
;
3370 err
= self
->db_env
->set_data_dir(self
->db_env
, dir
);
3371 MYDB_END_ALLOW_THREADS
;
3378 DBEnv_set_lg_bsize(DBEnvObject
* self
, PyObject
* args
)
3382 if (!PyArg_ParseTuple(args
, "i:set_lg_bsize", &lg_bsize
))
3384 CHECK_ENV_NOT_CLOSED(self
);
3386 MYDB_BEGIN_ALLOW_THREADS
;
3387 err
= self
->db_env
->set_lg_bsize(self
->db_env
, lg_bsize
);
3388 MYDB_END_ALLOW_THREADS
;
3395 DBEnv_set_lg_dir(DBEnvObject
* self
, PyObject
* args
)
3400 if (!PyArg_ParseTuple(args
, "s:set_lg_dir", &dir
))
3402 CHECK_ENV_NOT_CLOSED(self
);
3404 MYDB_BEGIN_ALLOW_THREADS
;
3405 err
= self
->db_env
->set_lg_dir(self
->db_env
, dir
);
3406 MYDB_END_ALLOW_THREADS
;
3412 DBEnv_set_lg_max(DBEnvObject
* self
, PyObject
* args
)
3416 if (!PyArg_ParseTuple(args
, "i:set_lg_max", &lg_max
))
3418 CHECK_ENV_NOT_CLOSED(self
);
3420 MYDB_BEGIN_ALLOW_THREADS
;
3421 err
= self
->db_env
->set_lg_max(self
->db_env
, lg_max
);
3422 MYDB_END_ALLOW_THREADS
;
3429 DBEnv_set_lk_detect(DBEnvObject
* self
, PyObject
* args
)
3433 if (!PyArg_ParseTuple(args
, "i:set_lk_detect", &lk_detect
))
3435 CHECK_ENV_NOT_CLOSED(self
);
3437 MYDB_BEGIN_ALLOW_THREADS
;
3438 err
= self
->db_env
->set_lk_detect(self
->db_env
, lk_detect
);
3439 MYDB_END_ALLOW_THREADS
;
3446 DBEnv_set_lk_max(DBEnvObject
* self
, PyObject
* args
)
3450 if (!PyArg_ParseTuple(args
, "i:set_lk_max", &max
))
3452 CHECK_ENV_NOT_CLOSED(self
);
3454 MYDB_BEGIN_ALLOW_THREADS
;
3455 err
= self
->db_env
->set_lk_max(self
->db_env
, max
);
3456 MYDB_END_ALLOW_THREADS
;
3465 DBEnv_set_lk_max_locks(DBEnvObject
* self
, PyObject
* args
)
3469 if (!PyArg_ParseTuple(args
, "i:set_lk_max_locks", &max
))
3471 CHECK_ENV_NOT_CLOSED(self
);
3473 MYDB_BEGIN_ALLOW_THREADS
;
3474 err
= self
->db_env
->set_lk_max_locks(self
->db_env
, max
);
3475 MYDB_END_ALLOW_THREADS
;
3482 DBEnv_set_lk_max_lockers(DBEnvObject
* self
, PyObject
* args
)
3486 if (!PyArg_ParseTuple(args
, "i:set_lk_max_lockers", &max
))
3488 CHECK_ENV_NOT_CLOSED(self
);
3490 MYDB_BEGIN_ALLOW_THREADS
;
3491 err
= self
->db_env
->set_lk_max_lockers(self
->db_env
, max
);
3492 MYDB_END_ALLOW_THREADS
;
3499 DBEnv_set_lk_max_objects(DBEnvObject
* self
, PyObject
* args
)
3503 if (!PyArg_ParseTuple(args
, "i:set_lk_max_objects", &max
))
3505 CHECK_ENV_NOT_CLOSED(self
);
3507 MYDB_BEGIN_ALLOW_THREADS
;
3508 err
= self
->db_env
->set_lk_max_objects(self
->db_env
, max
);
3509 MYDB_END_ALLOW_THREADS
;
3518 DBEnv_set_mp_mmapsize(DBEnvObject
* self
, PyObject
* args
)
3520 int err
, mp_mmapsize
;
3522 if (!PyArg_ParseTuple(args
, "i:set_mp_mmapsize", &mp_mmapsize
))
3524 CHECK_ENV_NOT_CLOSED(self
);
3526 MYDB_BEGIN_ALLOW_THREADS
;
3527 err
= self
->db_env
->set_mp_mmapsize(self
->db_env
, mp_mmapsize
);
3528 MYDB_END_ALLOW_THREADS
;
3535 DBEnv_set_tmp_dir(DBEnvObject
* self
, PyObject
* args
)
3540 if (!PyArg_ParseTuple(args
, "s:set_tmp_dir", &dir
))
3542 CHECK_ENV_NOT_CLOSED(self
);
3544 MYDB_BEGIN_ALLOW_THREADS
;
3545 err
= self
->db_env
->set_tmp_dir(self
->db_env
, dir
);
3546 MYDB_END_ALLOW_THREADS
;
3553 DBEnv_txn_begin(DBEnvObject
* self
, PyObject
* args
, PyObject
* kwargs
)
3556 PyObject
* txnobj
= NULL
;
3558 char* kwnames
[] = { "parent", "flags", NULL
};
3560 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:txn_begin", kwnames
,
3564 if (!checkTxnObj(txnobj
, &txn
))
3566 CHECK_ENV_NOT_CLOSED(self
);
3568 return (PyObject
*)newDBTxnObject(self
, txn
, flags
);
3573 DBEnv_txn_checkpoint(DBEnvObject
* self
, PyObject
* args
)
3575 int err
, kbyte
=0, min
=0, flags
=0;
3577 if (!PyArg_ParseTuple(args
, "|iii:txn_checkpoint", &kbyte
, &min
, &flags
))
3579 CHECK_ENV_NOT_CLOSED(self
);
3581 MYDB_BEGIN_ALLOW_THREADS
;
3583 err
= self
->db_env
->txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
3585 err
= txn_checkpoint(self
->db_env
, kbyte
, min
, flags
);
3587 MYDB_END_ALLOW_THREADS
;
3594 DBEnv_set_tx_max(DBEnvObject
* self
, PyObject
* args
)
3598 if (!PyArg_ParseTuple(args
, "i:set_tx_max", &max
))
3600 CHECK_ENV_NOT_CLOSED(self
);
3602 MYDB_BEGIN_ALLOW_THREADS
;
3603 err
= self
->db_env
->set_tx_max(self
->db_env
, max
);
3604 MYDB_END_ALLOW_THREADS
;
3611 DBEnv_lock_detect(DBEnvObject
* self
, PyObject
* args
)
3613 int err
, atype
, flags
=0;
3616 if (!PyArg_ParseTuple(args
, "i|i:lock_detect", &atype
, &flags
))
3618 CHECK_ENV_NOT_CLOSED(self
);
3620 MYDB_BEGIN_ALLOW_THREADS
;
3622 err
= self
->db_env
->lock_detect(self
->db_env
, flags
, atype
, &aborted
);
3624 err
= lock_detect(self
->db_env
, flags
, atype
, &aborted
);
3626 MYDB_END_ALLOW_THREADS
;
3628 return PyInt_FromLong(aborted
);
3633 DBEnv_lock_get(DBEnvObject
* self
, PyObject
* args
)
3636 int locker
, lock_mode
;
3640 if (!PyArg_ParseTuple(args
, "iOi|i:lock_get", &locker
, &objobj
, &lock_mode
, &flags
))
3644 if (!make_dbt(objobj
, &obj
))
3647 return (PyObject
*)newDBLockObject(self
, locker
, &obj
, lock_mode
, flags
);
3652 DBEnv_lock_id(DBEnvObject
* self
, PyObject
* args
)
3657 if (!PyArg_ParseTuple(args
, ":lock_id"))
3660 CHECK_ENV_NOT_CLOSED(self
);
3661 MYDB_BEGIN_ALLOW_THREADS
;
3663 err
= self
->db_env
->lock_id(self
->db_env
, &theID
);
3665 err
= lock_id(self
->db_env
, &theID
);
3667 MYDB_END_ALLOW_THREADS
;
3670 return PyInt_FromLong((long)theID
);
3675 DBEnv_lock_put(DBEnvObject
* self
, PyObject
* args
)
3678 DBLockObject
* dblockobj
;
3680 if (!PyArg_ParseTuple(args
, "O!:lock_put", &DBLock_Type
, &dblockobj
))
3683 CHECK_ENV_NOT_CLOSED(self
);
3684 MYDB_BEGIN_ALLOW_THREADS
;
3686 err
= self
->db_env
->lock_put(self
->db_env
, &dblockobj
->lock
);
3688 err
= lock_put(self
->db_env
, &dblockobj
->lock
);
3690 MYDB_END_ALLOW_THREADS
;
3697 DBEnv_lock_stat(DBEnvObject
* self
, PyObject
* args
)
3702 u_int32_t flags
= 0;
3704 if (!PyArg_ParseTuple(args
, "|i:lock_stat", &flags
))
3706 CHECK_ENV_NOT_CLOSED(self
);
3708 MYDB_BEGIN_ALLOW_THREADS
;
3710 err
= self
->db_env
->lock_stat(self
->db_env
, &sp
, flags
);
3713 err
= lock_stat(self
->db_env
, &sp
);
3715 err
= lock_stat(self
->db_env
, &sp
, NULL
);
3718 MYDB_END_ALLOW_THREADS
;
3721 /* Turn the stat structure into a dictionary */
3728 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
3735 MAKE_ENTRY(maxlocks
);
3736 MAKE_ENTRY(maxlockers
);
3737 MAKE_ENTRY(maxobjects
);
3739 MAKE_ENTRY(maxnlocks
);
3741 MAKE_ENTRY(nlockers
);
3742 MAKE_ENTRY(maxnlockers
);
3744 MAKE_ENTRY(nobjects
);
3745 MAKE_ENTRY(maxnobjects
);
3747 MAKE_ENTRY(nrequests
);
3748 MAKE_ENTRY(nreleases
);
3749 MAKE_ENTRY(nnowaits
);
3750 MAKE_ENTRY(nconflicts
);
3751 MAKE_ENTRY(ndeadlocks
);
3752 MAKE_ENTRY(regsize
);
3753 MAKE_ENTRY(region_wait
);
3754 MAKE_ENTRY(region_nowait
);
3763 DBEnv_log_archive(DBEnvObject
* self
, PyObject
* args
)
3767 char **log_list_start
, **log_list
;
3769 PyObject
* item
= NULL
;
3771 if (!PyArg_ParseTuple(args
, "|i:log_archive", &flags
))
3774 CHECK_ENV_NOT_CLOSED(self
);
3775 MYDB_BEGIN_ALLOW_THREADS
;
3777 err
= self
->db_env
->log_archive(self
->db_env
, &log_list
, flags
);
3779 err
= log_archive(self
->db_env
, &log_list
, flags
);
3781 err
= log_archive(self
->db_env
, &log_list
, flags
, NULL
);
3783 MYDB_END_ALLOW_THREADS
;
3786 list
= PyList_New(0);
3788 PyErr_SetString(PyExc_MemoryError
, "PyList_New failed");
3793 for (log_list_start
= log_list
; *log_list
!= NULL
; ++log_list
) {
3794 item
= PyString_FromString (*log_list
);
3797 PyErr_SetString(PyExc_MemoryError
,
3798 "List item creation failed");
3802 PyList_Append(list
, item
);
3805 free(log_list_start
);
3812 DBEnv_txn_stat(DBEnvObject
* self
, PyObject
* args
)
3819 if (!PyArg_ParseTuple(args
, "|i:txn_stat", &flags
))
3821 CHECK_ENV_NOT_CLOSED(self
);
3823 MYDB_BEGIN_ALLOW_THREADS
;
3825 err
= self
->db_env
->txn_stat(self
->db_env
, &sp
, flags
);
3827 err
= txn_stat(self
->db_env
, &sp
);
3829 err
= txn_stat(self
->db_env
, &sp
, NULL
);
3831 MYDB_END_ALLOW_THREADS
;
3834 /* Turn the stat structure into a dictionary */
3841 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
3843 MAKE_ENTRY(time_ckp
);
3844 MAKE_ENTRY(last_txnid
);
3845 MAKE_ENTRY(maxtxns
);
3846 MAKE_ENTRY(nactive
);
3847 MAKE_ENTRY(maxnactive
);
3848 MAKE_ENTRY(nbegins
);
3849 MAKE_ENTRY(naborts
);
3850 MAKE_ENTRY(ncommits
);
3851 MAKE_ENTRY(regsize
);
3852 MAKE_ENTRY(region_wait
);
3853 MAKE_ENTRY(region_nowait
);
3862 DBEnv_set_get_returns_none(DBEnvObject
* self
, PyObject
* args
)
3867 if (!PyArg_ParseTuple(args
,"i:set_get_returns_none", &flags
))
3869 CHECK_ENV_NOT_CLOSED(self
);
3871 if (self
->moduleFlags
.getReturnsNone
)
3873 if (self
->moduleFlags
.cursorSetReturnsNone
)
3875 self
->moduleFlags
.getReturnsNone
= (flags
>= 1);
3876 self
->moduleFlags
.cursorSetReturnsNone
= (flags
>= 2);
3877 return PyInt_FromLong(oldValue
);
3881 /* --------------------------------------------------------------------- */
3886 DBTxn_commit(DBTxnObject
* self
, PyObject
* args
)
3891 if (!PyArg_ParseTuple(args
, "|i:commit", &flags
))
3895 PyErr_SetObject(DBError
, Py_BuildValue("(is)", 0,
3896 "DBTxn must not be used after txn_commit or txn_abort"));
3900 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
3901 MYDB_BEGIN_ALLOW_THREADS
;
3903 err
= txn
->commit(txn
, flags
);
3905 err
= txn_commit(txn
, flags
);
3907 MYDB_END_ALLOW_THREADS
;
3913 DBTxn_prepare(DBTxnObject
* self
, PyObject
* args
)
3920 if (!PyArg_ParseTuple(args
, "s#:prepare", &gid
, &gid_size
))
3923 if (gid_size
!= DB_XIDDATASIZE
) {
3924 PyErr_SetString(PyExc_TypeError
,
3925 "gid must be DB_XIDDATASIZE bytes long");
3930 PyErr_SetObject(DBError
, Py_BuildValue("(is)", 0,
3931 "DBTxn must not be used after txn_commit or txn_abort"));
3934 MYDB_BEGIN_ALLOW_THREADS
;
3936 err
= self
->txn
->prepare(self
->txn
, (u_int8_t
*)gid
);
3938 err
= txn_prepare(self
->txn
, (u_int8_t
*)gid
);
3940 MYDB_END_ALLOW_THREADS
;
3946 if (!PyArg_ParseTuple(args
, ":prepare"))
3950 PyErr_SetObject(DBError
, Py_BuildValue("(is)", 0,
3951 "DBTxn must not be used after txn_commit or txn_abort"));
3954 MYDB_BEGIN_ALLOW_THREADS
;
3955 err
= txn_prepare(self
->txn
);
3956 MYDB_END_ALLOW_THREADS
;
3964 DBTxn_abort(DBTxnObject
* self
, PyObject
* args
)
3969 if (!PyArg_ParseTuple(args
, ":abort"))
3973 PyErr_SetObject(DBError
, Py_BuildValue("(is)", 0,
3974 "DBTxn must not be used after txn_commit or txn_abort"));
3978 self
->txn
= NULL
; /* this DB_TXN is no longer valid after this call */
3979 MYDB_BEGIN_ALLOW_THREADS
;
3981 err
= txn
->abort(txn
);
3983 err
= txn_abort(txn
);
3985 MYDB_END_ALLOW_THREADS
;
3992 DBTxn_id(DBTxnObject
* self
, PyObject
* args
)
3996 if (!PyArg_ParseTuple(args
, ":id"))
4000 PyErr_SetObject(DBError
, Py_BuildValue("(is)", 0,
4001 "DBTxn must not be used after txn_commit or txn_abort"));
4004 MYDB_BEGIN_ALLOW_THREADS
;
4006 id
= self
->txn
->id(self
->txn
);
4008 id
= txn_id(self
->txn
);
4010 MYDB_END_ALLOW_THREADS
;
4011 return PyInt_FromLong(id
);
4014 /* --------------------------------------------------------------------- */
4015 /* Method definition tables and type objects */
4017 static PyMethodDef DB_methods
[] = {
4018 {"append", (PyCFunction
)DB_append
, METH_VARARGS
},
4020 {"associate", (PyCFunction
)DB_associate
, METH_VARARGS
|METH_KEYWORDS
},
4022 {"close", (PyCFunction
)DB_close
, METH_VARARGS
},
4024 {"consume", (PyCFunction
)DB_consume
, METH_VARARGS
|METH_KEYWORDS
},
4025 {"consume_wait", (PyCFunction
)DB_consume_wait
, METH_VARARGS
|METH_KEYWORDS
},
4027 {"cursor", (PyCFunction
)DB_cursor
, METH_VARARGS
|METH_KEYWORDS
},
4028 {"delete", (PyCFunction
)DB_delete
, METH_VARARGS
|METH_KEYWORDS
},
4029 {"fd", (PyCFunction
)DB_fd
, METH_VARARGS
},
4030 {"get", (PyCFunction
)DB_get
, METH_VARARGS
|METH_KEYWORDS
},
4031 {"get_both", (PyCFunction
)DB_get_both
, METH_VARARGS
|METH_KEYWORDS
},
4032 {"get_byteswapped", (PyCFunction
)DB_get_byteswapped
,METH_VARARGS
},
4033 {"get_size", (PyCFunction
)DB_get_size
, METH_VARARGS
|METH_KEYWORDS
},
4034 {"get_type", (PyCFunction
)DB_get_type
, METH_VARARGS
},
4035 {"join", (PyCFunction
)DB_join
, METH_VARARGS
},
4036 {"key_range", (PyCFunction
)DB_key_range
, METH_VARARGS
|METH_KEYWORDS
},
4037 {"has_key", (PyCFunction
)DB_has_key
, METH_VARARGS
},
4038 {"items", (PyCFunction
)DB_items
, METH_VARARGS
},
4039 {"keys", (PyCFunction
)DB_keys
, METH_VARARGS
},
4040 {"open", (PyCFunction
)DB_open
, METH_VARARGS
|METH_KEYWORDS
},
4041 {"put", (PyCFunction
)DB_put
, METH_VARARGS
|METH_KEYWORDS
},
4042 {"remove", (PyCFunction
)DB_remove
, METH_VARARGS
|METH_KEYWORDS
},
4043 {"rename", (PyCFunction
)DB_rename
, METH_VARARGS
},
4044 {"set_bt_minkey", (PyCFunction
)DB_set_bt_minkey
, METH_VARARGS
},
4045 {"set_cachesize", (PyCFunction
)DB_set_cachesize
, METH_VARARGS
},
4047 {"set_encrypt", (PyCFunction
)DB_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
4049 {"set_flags", (PyCFunction
)DB_set_flags
, METH_VARARGS
},
4050 {"set_h_ffactor", (PyCFunction
)DB_set_h_ffactor
, METH_VARARGS
},
4051 {"set_h_nelem", (PyCFunction
)DB_set_h_nelem
, METH_VARARGS
},
4052 {"set_lorder", (PyCFunction
)DB_set_lorder
, METH_VARARGS
},
4053 {"set_pagesize", (PyCFunction
)DB_set_pagesize
, METH_VARARGS
},
4054 {"set_re_delim", (PyCFunction
)DB_set_re_delim
, METH_VARARGS
},
4055 {"set_re_len", (PyCFunction
)DB_set_re_len
, METH_VARARGS
},
4056 {"set_re_pad", (PyCFunction
)DB_set_re_pad
, METH_VARARGS
},
4057 {"set_re_source", (PyCFunction
)DB_set_re_source
, METH_VARARGS
},
4059 {"set_q_extentsize",(PyCFunction
)DB_set_q_extentsize
,METH_VARARGS
},
4061 {"stat", (PyCFunction
)DB_stat
, METH_VARARGS
},
4062 {"sync", (PyCFunction
)DB_sync
, METH_VARARGS
},
4064 {"truncate", (PyCFunction
)DB_truncate
, METH_VARARGS
|METH_KEYWORDS
},
4066 {"type", (PyCFunction
)DB_get_type
, METH_VARARGS
},
4067 {"upgrade", (PyCFunction
)DB_upgrade
, METH_VARARGS
},
4068 {"values", (PyCFunction
)DB_values
, METH_VARARGS
},
4069 {"verify", (PyCFunction
)DB_verify
, METH_VARARGS
|METH_KEYWORDS
},
4070 {"set_get_returns_none",(PyCFunction
)DB_set_get_returns_none
, METH_VARARGS
},
4071 {NULL
, NULL
} /* sentinel */
4075 static PyMappingMethods DB_mapping
= {
4076 (inquiry
)DB_length
, /*mp_length*/
4077 (binaryfunc
)DB_subscript
, /*mp_subscript*/
4078 (objobjargproc
)DB_ass_sub
, /*mp_ass_subscript*/
4082 static PyMethodDef DBCursor_methods
[] = {
4083 {"close", (PyCFunction
)DBC_close
, METH_VARARGS
},
4084 {"count", (PyCFunction
)DBC_count
, METH_VARARGS
},
4085 {"current", (PyCFunction
)DBC_current
, METH_VARARGS
|METH_KEYWORDS
},
4086 {"delete", (PyCFunction
)DBC_delete
, METH_VARARGS
},
4087 {"dup", (PyCFunction
)DBC_dup
, METH_VARARGS
},
4088 {"first", (PyCFunction
)DBC_first
, METH_VARARGS
|METH_KEYWORDS
},
4089 {"get", (PyCFunction
)DBC_get
, METH_VARARGS
|METH_KEYWORDS
},
4090 {"get_recno", (PyCFunction
)DBC_get_recno
, METH_VARARGS
},
4091 {"last", (PyCFunction
)DBC_last
, METH_VARARGS
|METH_KEYWORDS
},
4092 {"next", (PyCFunction
)DBC_next
, METH_VARARGS
|METH_KEYWORDS
},
4093 {"prev", (PyCFunction
)DBC_prev
, METH_VARARGS
|METH_KEYWORDS
},
4094 {"put", (PyCFunction
)DBC_put
, METH_VARARGS
|METH_KEYWORDS
},
4095 {"set", (PyCFunction
)DBC_set
, METH_VARARGS
|METH_KEYWORDS
},
4096 {"set_range", (PyCFunction
)DBC_set_range
, METH_VARARGS
|METH_KEYWORDS
},
4097 {"get_both", (PyCFunction
)DBC_get_both
, METH_VARARGS
},
4098 {"set_both", (PyCFunction
)DBC_set_both
, METH_VARARGS
},
4099 {"set_recno", (PyCFunction
)DBC_set_recno
, METH_VARARGS
|METH_KEYWORDS
},
4100 {"consume", (PyCFunction
)DBC_consume
, METH_VARARGS
|METH_KEYWORDS
},
4101 {"next_dup", (PyCFunction
)DBC_next_dup
, METH_VARARGS
|METH_KEYWORDS
},
4102 {"next_nodup", (PyCFunction
)DBC_next_nodup
, METH_VARARGS
|METH_KEYWORDS
},
4103 {"prev_nodup", (PyCFunction
)DBC_prev_nodup
, METH_VARARGS
|METH_KEYWORDS
},
4104 {"join_item", (PyCFunction
)DBC_join_item
, METH_VARARGS
},
4105 {NULL
, NULL
} /* sentinel */
4109 static PyMethodDef DBEnv_methods
[] = {
4110 {"close", (PyCFunction
)DBEnv_close
, METH_VARARGS
},
4111 {"open", (PyCFunction
)DBEnv_open
, METH_VARARGS
},
4112 {"remove", (PyCFunction
)DBEnv_remove
, METH_VARARGS
},
4114 {"dbremove", (PyCFunction
)DBEnv_dbremove
, METH_VARARGS
|METH_KEYWORDS
},
4115 {"dbrename", (PyCFunction
)DBEnv_dbrename
, METH_VARARGS
|METH_KEYWORDS
},
4116 {"set_encrypt", (PyCFunction
)DBEnv_set_encrypt
, METH_VARARGS
|METH_KEYWORDS
},
4119 {"set_timeout", (PyCFunction
)DBEnv_set_timeout
, METH_VARARGS
|METH_KEYWORDS
},
4121 {"set_shm_key", (PyCFunction
)DBEnv_set_shm_key
, METH_VARARGS
},
4122 {"set_cachesize", (PyCFunction
)DBEnv_set_cachesize
, METH_VARARGS
},
4123 {"set_data_dir", (PyCFunction
)DBEnv_set_data_dir
, METH_VARARGS
},
4125 {"set_flags", (PyCFunction
)DBEnv_set_flags
, METH_VARARGS
},
4127 {"set_lg_bsize", (PyCFunction
)DBEnv_set_lg_bsize
, METH_VARARGS
},
4128 {"set_lg_dir", (PyCFunction
)DBEnv_set_lg_dir
, METH_VARARGS
},
4129 {"set_lg_max", (PyCFunction
)DBEnv_set_lg_max
, METH_VARARGS
},
4130 {"set_lk_detect", (PyCFunction
)DBEnv_set_lk_detect
, METH_VARARGS
},
4131 {"set_lk_max", (PyCFunction
)DBEnv_set_lk_max
, METH_VARARGS
},
4133 {"set_lk_max_locks", (PyCFunction
)DBEnv_set_lk_max_locks
, METH_VARARGS
},
4134 {"set_lk_max_lockers", (PyCFunction
)DBEnv_set_lk_max_lockers
, METH_VARARGS
},
4135 {"set_lk_max_objects", (PyCFunction
)DBEnv_set_lk_max_objects
, METH_VARARGS
},
4137 {"set_mp_mmapsize", (PyCFunction
)DBEnv_set_mp_mmapsize
, METH_VARARGS
},
4138 {"set_tmp_dir", (PyCFunction
)DBEnv_set_tmp_dir
, METH_VARARGS
},
4139 {"txn_begin", (PyCFunction
)DBEnv_txn_begin
, METH_VARARGS
|METH_KEYWORDS
},
4140 {"txn_checkpoint", (PyCFunction
)DBEnv_txn_checkpoint
, METH_VARARGS
},
4141 {"txn_stat", (PyCFunction
)DBEnv_txn_stat
, METH_VARARGS
},
4142 {"set_tx_max", (PyCFunction
)DBEnv_set_tx_max
, METH_VARARGS
},
4143 {"lock_detect", (PyCFunction
)DBEnv_lock_detect
, METH_VARARGS
},
4144 {"lock_get", (PyCFunction
)DBEnv_lock_get
, METH_VARARGS
},
4145 {"lock_id", (PyCFunction
)DBEnv_lock_id
, METH_VARARGS
},
4146 {"lock_put", (PyCFunction
)DBEnv_lock_put
, METH_VARARGS
},
4147 {"lock_stat", (PyCFunction
)DBEnv_lock_stat
, METH_VARARGS
},
4148 {"log_archive", (PyCFunction
)DBEnv_log_archive
, METH_VARARGS
},
4149 {"set_get_returns_none",(PyCFunction
)DBEnv_set_get_returns_none
, METH_VARARGS
},
4150 {NULL
, NULL
} /* sentinel */
4154 static PyMethodDef DBTxn_methods
[] = {
4155 {"commit", (PyCFunction
)DBTxn_commit
, METH_VARARGS
},
4156 {"prepare", (PyCFunction
)DBTxn_prepare
, METH_VARARGS
},
4157 {"abort", (PyCFunction
)DBTxn_abort
, METH_VARARGS
},
4158 {"id", (PyCFunction
)DBTxn_id
, METH_VARARGS
},
4159 {NULL
, NULL
} /* sentinel */
4164 DB_getattr(DBObject
* self
, char *name
)
4166 return Py_FindMethod(DB_methods
, (PyObject
* )self
, name
);
4171 DBEnv_getattr(DBEnvObject
* self
, char *name
)
4173 if (!strcmp(name
, "db_home")) {
4174 CHECK_ENV_NOT_CLOSED(self
);
4175 if (self
->db_env
->db_home
== NULL
) {
4178 return PyString_FromString(self
->db_env
->db_home
);
4181 return Py_FindMethod(DBEnv_methods
, (PyObject
* )self
, name
);
4186 DBCursor_getattr(DBCursorObject
* self
, char *name
)
4188 return Py_FindMethod(DBCursor_methods
, (PyObject
* )self
, name
);
4192 DBTxn_getattr(DBTxnObject
* self
, char *name
)
4194 return Py_FindMethod(DBTxn_methods
, (PyObject
* )self
, name
);
4198 DBLock_getattr(DBLockObject
* self
, char *name
)
4203 statichere PyTypeObject DB_Type
= {
4204 PyObject_HEAD_INIT(NULL
)
4207 sizeof(DBObject
), /*tp_basicsize*/
4210 (destructor
)DB_dealloc
, /*tp_dealloc*/
4212 (getattrfunc
)DB_getattr
, /*tp_getattr*/
4217 0, /*tp_as_sequence*/
4218 &DB_mapping
,/*tp_as_mapping*/
4223 statichere PyTypeObject DBCursor_Type
= {
4224 PyObject_HEAD_INIT(NULL
)
4226 "DBCursor", /*tp_name*/
4227 sizeof(DBCursorObject
), /*tp_basicsize*/
4230 (destructor
)DBCursor_dealloc
,/*tp_dealloc*/
4232 (getattrfunc
)DBCursor_getattr
, /*tp_getattr*/
4237 0, /*tp_as_sequence*/
4238 0, /*tp_as_mapping*/
4243 statichere PyTypeObject DBEnv_Type
= {
4244 PyObject_HEAD_INIT(NULL
)
4246 "DBEnv", /*tp_name*/
4247 sizeof(DBEnvObject
), /*tp_basicsize*/
4250 (destructor
)DBEnv_dealloc
, /*tp_dealloc*/
4252 (getattrfunc
)DBEnv_getattr
, /*tp_getattr*/
4257 0, /*tp_as_sequence*/
4258 0, /*tp_as_mapping*/
4262 statichere PyTypeObject DBTxn_Type
= {
4263 PyObject_HEAD_INIT(NULL
)
4265 "DBTxn", /*tp_name*/
4266 sizeof(DBTxnObject
), /*tp_basicsize*/
4269 (destructor
)DBTxn_dealloc
, /*tp_dealloc*/
4271 (getattrfunc
)DBTxn_getattr
, /*tp_getattr*/
4276 0, /*tp_as_sequence*/
4277 0, /*tp_as_mapping*/
4282 statichere PyTypeObject DBLock_Type
= {
4283 PyObject_HEAD_INIT(NULL
)
4285 "DBLock", /*tp_name*/
4286 sizeof(DBLockObject
), /*tp_basicsize*/
4289 (destructor
)DBLock_dealloc
, /*tp_dealloc*/
4291 (getattrfunc
)DBLock_getattr
, /*tp_getattr*/
4296 0, /*tp_as_sequence*/
4297 0, /*tp_as_mapping*/
4302 /* --------------------------------------------------------------------- */
4303 /* Module-level functions */
4306 DB_construct(PyObject
* self
, PyObject
* args
, PyObject
* kwargs
)
4308 PyObject
* dbenvobj
= NULL
;
4310 char* kwnames
[] = { "dbEnv", "flags", NULL
};
4312 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Oi:DB", kwnames
,
4315 if (dbenvobj
== Py_None
)
4317 else if (dbenvobj
&& !DBEnvObject_Check(dbenvobj
)) {
4318 makeTypeError("DBEnv", dbenvobj
);
4322 return (PyObject
* )newDBObject((DBEnvObject
*)dbenvobj
, flags
);
4327 DBEnv_construct(PyObject
* self
, PyObject
* args
)
4330 if (!PyArg_ParseTuple(args
, "|i:DbEnv", &flags
)) return NULL
;
4331 return (PyObject
* )newDBEnvObject(flags
);
4335 static char bsddb_version_doc
[] =
4336 "Returns a tuple of major, minor, and patch release numbers of the\n\
4337 underlying DB library.";
4340 bsddb_version(PyObject
* self
, PyObject
* args
)
4342 int major
, minor
, patch
;
4344 if (!PyArg_ParseTuple(args
, ":version"))
4346 db_version(&major
, &minor
, &patch
);
4347 return Py_BuildValue("(iii)", major
, minor
, patch
);
4351 /* List of functions defined in the module */
4353 static PyMethodDef bsddb_methods
[] = {
4354 {"DB", (PyCFunction
)DB_construct
, METH_VARARGS
| METH_KEYWORDS
},
4355 {"DBEnv", (PyCFunction
)DBEnv_construct
, METH_VARARGS
},
4356 {"version", (PyCFunction
)bsddb_version
, METH_VARARGS
, bsddb_version_doc
},
4357 {NULL
, NULL
} /* sentinel */
4361 /* --------------------------------------------------------------------- */
4362 /* Module initialization */
4365 /* Convenience routine to export an integer value.
4366 * Errors are silently ignored, for better or for worse...
4368 #define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
4370 DL_EXPORT(void) init_bsddb(void)
4374 PyObject
* pybsddb_version_s
= PyString_FromString( PY_BSDDB_VERSION
);
4375 PyObject
* db_version_s
= PyString_FromString( DB_VERSION_STRING
);
4376 PyObject
* cvsid_s
= PyString_FromString( rcs_id
);
4378 /* Initialize the type of the new type objects here; doing it here
4379 is required for portability to Windows without requiring C++. */
4380 DB_Type
.ob_type
= &PyType_Type
;
4381 DBCursor_Type
.ob_type
= &PyType_Type
;
4382 DBEnv_Type
.ob_type
= &PyType_Type
;
4383 DBTxn_Type
.ob_type
= &PyType_Type
;
4384 DBLock_Type
.ob_type
= &PyType_Type
;
4387 #if defined(WITH_THREAD) && !defined(MYDB_USE_GILSTATE)
4388 /* Save the current interpreter, so callbacks can do the right thing. */
4389 _db_interpreterState
= PyThreadState_Get()->interp
;
4392 /* Create the module and add the functions */
4393 m
= Py_InitModule("_bsddb", bsddb_methods
);
4395 /* Add some symbolic constants to the module */
4396 d
= PyModule_GetDict(m
);
4397 PyDict_SetItemString(d
, "__version__", pybsddb_version_s
);
4398 PyDict_SetItemString(d
, "cvsid", cvsid_s
);
4399 PyDict_SetItemString(d
, "DB_VERSION_STRING", db_version_s
);
4400 Py_DECREF(pybsddb_version_s
);
4401 pybsddb_version_s
= NULL
;
4404 Py_DECREF(db_version_s
);
4405 db_version_s
= NULL
;
4407 ADD_INT(d
, DB_VERSION_MAJOR
);
4408 ADD_INT(d
, DB_VERSION_MINOR
);
4409 ADD_INT(d
, DB_VERSION_PATCH
);
4411 ADD_INT(d
, DB_MAX_PAGES
);
4412 ADD_INT(d
, DB_MAX_RECORDS
);
4415 ADD_INT(d
, DB_RPCCLIENT
);
4417 ADD_INT(d
, DB_CLIENT
);
4418 /* allow apps to be written using DB_RPCCLIENT on older BerkeleyDB */
4419 _addIntToDict(d
, "DB_RPCCLIENT", DB_CLIENT
);
4421 ADD_INT(d
, DB_XA_CREATE
);
4423 ADD_INT(d
, DB_CREATE
);
4424 ADD_INT(d
, DB_NOMMAP
);
4425 ADD_INT(d
, DB_THREAD
);
4427 ADD_INT(d
, DB_FORCE
);
4428 ADD_INT(d
, DB_INIT_CDB
);
4429 ADD_INT(d
, DB_INIT_LOCK
);
4430 ADD_INT(d
, DB_INIT_LOG
);
4431 ADD_INT(d
, DB_INIT_MPOOL
);
4432 ADD_INT(d
, DB_INIT_TXN
);
4434 ADD_INT(d
, DB_JOINENV
);
4437 ADD_INT(d
, DB_RECOVER
);
4438 ADD_INT(d
, DB_RECOVER_FATAL
);
4439 ADD_INT(d
, DB_TXN_NOSYNC
);
4440 ADD_INT(d
, DB_USE_ENVIRON
);
4441 ADD_INT(d
, DB_USE_ENVIRON_ROOT
);
4443 ADD_INT(d
, DB_LOCKDOWN
);
4444 ADD_INT(d
, DB_PRIVATE
);
4445 ADD_INT(d
, DB_SYSTEM_MEM
);
4447 ADD_INT(d
, DB_TXN_SYNC
);
4448 ADD_INT(d
, DB_TXN_NOWAIT
);
4450 ADD_INT(d
, DB_EXCL
);
4451 ADD_INT(d
, DB_FCNTL_LOCKING
);
4452 ADD_INT(d
, DB_ODDFILESIZE
);
4453 ADD_INT(d
, DB_RDWRMASTER
);
4454 ADD_INT(d
, DB_RDONLY
);
4455 ADD_INT(d
, DB_TRUNCATE
);
4457 ADD_INT(d
, DB_EXTENT
);
4458 ADD_INT(d
, DB_CDB_ALLDB
);
4459 ADD_INT(d
, DB_VERIFY
);
4461 ADD_INT(d
, DB_UPGRADE
);
4463 ADD_INT(d
, DB_AGGRESSIVE
);
4464 ADD_INT(d
, DB_NOORDERCHK
);
4465 ADD_INT(d
, DB_ORDERCHKONLY
);
4466 ADD_INT(d
, DB_PR_PAGE
);
4468 ADD_INT(d
, DB_VRFY_FLAGMASK
);
4469 ADD_INT(d
, DB_PR_HEADERS
);
4471 ADD_INT(d
, DB_PR_RECOVERYTEST
);
4472 ADD_INT(d
, DB_SALVAGE
);
4474 ADD_INT(d
, DB_LOCK_NORUN
);
4475 ADD_INT(d
, DB_LOCK_DEFAULT
);
4476 ADD_INT(d
, DB_LOCK_OLDEST
);
4477 ADD_INT(d
, DB_LOCK_RANDOM
);
4478 ADD_INT(d
, DB_LOCK_YOUNGEST
);
4480 ADD_INT(d
, DB_LOCK_MAXLOCKS
);
4481 ADD_INT(d
, DB_LOCK_MINLOCKS
);
4482 ADD_INT(d
, DB_LOCK_MINWRITE
);
4487 /* docs say to use zero instead */
4488 _addIntToDict(d
, "DB_LOCK_CONFLICT", 0);
4490 ADD_INT(d
, DB_LOCK_CONFLICT
);
4493 ADD_INT(d
, DB_LOCK_DUMP
);
4494 ADD_INT(d
, DB_LOCK_GET
);
4495 ADD_INT(d
, DB_LOCK_INHERIT
);
4496 ADD_INT(d
, DB_LOCK_PUT
);
4497 ADD_INT(d
, DB_LOCK_PUT_ALL
);
4498 ADD_INT(d
, DB_LOCK_PUT_OBJ
);
4500 ADD_INT(d
, DB_LOCK_NG
);
4501 ADD_INT(d
, DB_LOCK_READ
);
4502 ADD_INT(d
, DB_LOCK_WRITE
);
4503 ADD_INT(d
, DB_LOCK_NOWAIT
);
4505 ADD_INT(d
, DB_LOCK_WAIT
);
4507 ADD_INT(d
, DB_LOCK_IWRITE
);
4508 ADD_INT(d
, DB_LOCK_IREAD
);
4509 ADD_INT(d
, DB_LOCK_IWR
);
4511 ADD_INT(d
, DB_LOCK_DIRTY
);
4512 ADD_INT(d
, DB_LOCK_WWRITE
);
4515 ADD_INT(d
, DB_LOCK_RECORD
);
4516 ADD_INT(d
, DB_LOCK_UPGRADE
);
4518 ADD_INT(d
, DB_LOCK_SWITCH
);
4521 ADD_INT(d
, DB_LOCK_UPGRADE_WRITE
);
4524 ADD_INT(d
, DB_LOCK_NOWAIT
);
4525 ADD_INT(d
, DB_LOCK_RECORD
);
4526 ADD_INT(d
, DB_LOCK_UPGRADE
);
4529 ADD_INT(d
, DB_LSTAT_ABORTED
);
4530 ADD_INT(d
, DB_LSTAT_ERR
);
4531 ADD_INT(d
, DB_LSTAT_FREE
);
4532 ADD_INT(d
, DB_LSTAT_HELD
);
4534 ADD_INT(d
, DB_LSTAT_NOGRANT
);
4536 ADD_INT(d
, DB_LSTAT_PENDING
);
4537 ADD_INT(d
, DB_LSTAT_WAITING
);
4540 ADD_INT(d
, DB_ARCH_ABS
);
4541 ADD_INT(d
, DB_ARCH_DATA
);
4542 ADD_INT(d
, DB_ARCH_LOG
);
4544 ADD_INT(d
, DB_BTREE
);
4545 ADD_INT(d
, DB_HASH
);
4546 ADD_INT(d
, DB_RECNO
);
4547 ADD_INT(d
, DB_QUEUE
);
4548 ADD_INT(d
, DB_UNKNOWN
);
4551 ADD_INT(d
, DB_DUPSORT
);
4552 ADD_INT(d
, DB_RECNUM
);
4553 ADD_INT(d
, DB_RENUMBER
);
4554 ADD_INT(d
, DB_REVSPLITOFF
);
4555 ADD_INT(d
, DB_SNAPSHOT
);
4557 ADD_INT(d
, DB_JOIN_NOSORT
);
4559 ADD_INT(d
, DB_AFTER
);
4560 ADD_INT(d
, DB_APPEND
);
4561 ADD_INT(d
, DB_BEFORE
);
4562 ADD_INT(d
, DB_CACHED_COUNTS
);
4564 _addIntToDict(d
, "DB_CHECKPOINT", 0);
4566 ADD_INT(d
, DB_CHECKPOINT
);
4567 ADD_INT(d
, DB_CURLSN
);
4569 #if ((DBVER >= 33) && (DBVER <= 41))
4570 ADD_INT(d
, DB_COMMIT
);
4572 ADD_INT(d
, DB_CONSUME
);
4574 ADD_INT(d
, DB_CONSUME_WAIT
);
4576 ADD_INT(d
, DB_CURRENT
);
4578 ADD_INT(d
, DB_FAST_STAT
);
4580 ADD_INT(d
, DB_FIRST
);
4581 ADD_INT(d
, DB_FLUSH
);
4582 ADD_INT(d
, DB_GET_BOTH
);
4583 ADD_INT(d
, DB_GET_RECNO
);
4584 ADD_INT(d
, DB_JOIN_ITEM
);
4585 ADD_INT(d
, DB_KEYFIRST
);
4586 ADD_INT(d
, DB_KEYLAST
);
4587 ADD_INT(d
, DB_LAST
);
4588 ADD_INT(d
, DB_NEXT
);
4589 ADD_INT(d
, DB_NEXT_DUP
);
4590 ADD_INT(d
, DB_NEXT_NODUP
);
4591 ADD_INT(d
, DB_NODUPDATA
);
4592 ADD_INT(d
, DB_NOOVERWRITE
);
4593 ADD_INT(d
, DB_NOSYNC
);
4594 ADD_INT(d
, DB_POSITION
);
4595 ADD_INT(d
, DB_PREV
);
4596 ADD_INT(d
, DB_PREV_NODUP
);
4597 ADD_INT(d
, DB_RECORDCOUNT
);
4599 ADD_INT(d
, DB_SET_RANGE
);
4600 ADD_INT(d
, DB_SET_RECNO
);
4601 ADD_INT(d
, DB_WRITECURSOR
);
4603 ADD_INT(d
, DB_OPFLAGS_MASK
);
4606 ADD_INT(d
, DB_DIRTY_READ
);
4607 ADD_INT(d
, DB_MULTIPLE
);
4608 ADD_INT(d
, DB_MULTIPLE_KEY
);
4612 ADD_INT(d
, DB_DONOTINDEX
);
4616 _addIntToDict(d
, "DB_INCOMPLETE", 0);
4618 ADD_INT(d
, DB_INCOMPLETE
);
4620 ADD_INT(d
, DB_KEYEMPTY
);
4621 ADD_INT(d
, DB_KEYEXIST
);
4622 ADD_INT(d
, DB_LOCK_DEADLOCK
);
4623 ADD_INT(d
, DB_LOCK_NOTGRANTED
);
4624 ADD_INT(d
, DB_NOSERVER
);
4625 ADD_INT(d
, DB_NOSERVER_HOME
);
4626 ADD_INT(d
, DB_NOSERVER_ID
);
4627 ADD_INT(d
, DB_NOTFOUND
);
4628 ADD_INT(d
, DB_OLD_VERSION
);
4629 ADD_INT(d
, DB_RUNRECOVERY
);
4630 ADD_INT(d
, DB_VERIFY_BAD
);
4632 ADD_INT(d
, DB_PAGE_NOTFOUND
);
4633 ADD_INT(d
, DB_SECONDARY_BAD
);
4636 ADD_INT(d
, DB_STAT_CLEAR
);
4637 ADD_INT(d
, DB_REGION_INIT
);
4638 ADD_INT(d
, DB_NOLOCKING
);
4639 ADD_INT(d
, DB_YIELDCPU
);
4640 ADD_INT(d
, DB_PANIC_ENVIRONMENT
);
4641 ADD_INT(d
, DB_NOPANIC
);
4645 ADD_INT(d
, DB_TIME_NOTGRANTED
);
4646 ADD_INT(d
, DB_TXN_NOT_DURABLE
);
4647 ADD_INT(d
, DB_TXN_WRITE_NOSYNC
);
4648 ADD_INT(d
, DB_LOG_AUTOREMOVE
);
4649 ADD_INT(d
, DB_DIRECT_LOG
);
4650 ADD_INT(d
, DB_DIRECT_DB
);
4651 ADD_INT(d
, DB_INIT_REP
);
4652 ADD_INT(d
, DB_ENCRYPT
);
4653 ADD_INT(d
, DB_CHKSUM
);
4657 ADD_INT(d
, DB_ENCRYPT_AES
);
4658 ADD_INT(d
, DB_AUTO_COMMIT
);
4660 /* allow berkeleydb 4.1 aware apps to run on older versions */
4661 _addIntToDict(d
, "DB_AUTO_COMMIT", 0);
4675 ADD_INT(d
, DB_SET_LOCK_TIMEOUT
);
4676 ADD_INT(d
, DB_SET_TXN_TIMEOUT
);
4679 /* The base exception class is DBError */
4680 DBError
= PyErr_NewException("bsddb._db.DBError", NULL
, NULL
);
4681 PyDict_SetItemString(d
, "DBError", DBError
);
4683 /* Some magic to make DBNotFoundError derive from both DBError and
4684 KeyError, since the API only supports using one base class. */
4685 PyDict_SetItemString(d
, "KeyError", PyExc_KeyError
);
4686 PyRun_String("class DBNotFoundError(DBError, KeyError): pass",
4687 Py_file_input
, d
, d
);
4688 DBNotFoundError
= PyDict_GetItemString(d
, "DBNotFoundError");
4689 PyDict_DelItemString(d
, "KeyError");
4692 /* All the rest of the exceptions derive only from DBError */
4693 #define MAKE_EX(name) name = PyErr_NewException("bsddb._db." #name, DBError, NULL); \
4694 PyDict_SetItemString(d, #name, name)
4696 #if !INCOMPLETE_IS_WARNING
4697 MAKE_EX(DBIncompleteError
);
4699 MAKE_EX(DBKeyEmptyError
);
4700 MAKE_EX(DBKeyExistError
);
4701 MAKE_EX(DBLockDeadlockError
);
4702 MAKE_EX(DBLockNotGrantedError
);
4703 MAKE_EX(DBOldVersionError
);
4704 MAKE_EX(DBRunRecoveryError
);
4705 MAKE_EX(DBVerifyBadError
);
4706 MAKE_EX(DBNoServerError
);
4707 MAKE_EX(DBNoServerHomeError
);
4708 MAKE_EX(DBNoServerIDError
);
4710 MAKE_EX(DBPageNotFoundError
);
4711 MAKE_EX(DBSecondaryBadError
);
4714 MAKE_EX(DBInvalidArgError
);
4715 MAKE_EX(DBAccessError
);
4716 MAKE_EX(DBNoSpaceError
);
4717 MAKE_EX(DBNoMemoryError
);
4718 MAKE_EX(DBAgainError
);
4719 MAKE_EX(DBBusyError
);
4720 MAKE_EX(DBFileExistsError
);
4721 MAKE_EX(DBNoSuchFileError
);
4722 MAKE_EX(DBPermissionsError
);
4726 /* Check for errors */
4727 if (PyErr_Occurred()) {
4729 Py_FatalError("can't initialize module _bsddb");