00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 #include <stddef.h>
00092 #include <Python.h>
00093 #include <db.h>
00094
00095
00096
00097
00098
00099 #define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
00100 #if DB_VERSION_MINOR > 9
00101 #error "eek! DBVER can't handle minor versions > 9"
00102 #endif
00103
00104 #define PY_BSDDB_VERSION "4.2.4"
00105 static char *rcs_id = "$Id: _rpmdb.c,v 1.7.2.3 2003/12/16 05:00:41 jbj Exp $";
00106
00107
00108 #ifdef WITH_THREAD
00109
00110
00111 #define MYDB_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS;
00112 #define MYDB_END_ALLOW_THREADS Py_END_ALLOW_THREADS;
00113
00114
00115 #if (PY_VERSION_HEX >= 0x02030000)
00116 #define MYDB_USE_GILSTATE
00117 #endif
00118
00119
00120 #if defined(MYDB_USE_GILSTATE)
00121 #define MYDB_BEGIN_BLOCK_THREADS \
00122 PyGILState_STATE __savestate = PyGILState_Ensure();
00123 #define MYDB_END_BLOCK_THREADS \
00124 PyGILState_Release(__savestate);
00125 #else
00126
00127 static PyInterpreterState* _db_interpreterState = NULL;
00128 #define MYDB_BEGIN_BLOCK_THREADS { \
00129 PyThreadState* prevState; \
00130 PyThreadState* newState; \
00131 PyEval_AcquireLock(); \
00132 newState = PyThreadState_New(_db_interpreterState); \
00133 prevState = PyThreadState_Swap(newState);
00134
00135 #define MYDB_END_BLOCK_THREADS \
00136 newState = PyThreadState_Swap(prevState); \
00137 PyThreadState_Clear(newState); \
00138 PyEval_ReleaseLock(); \
00139 PyThreadState_Delete(newState); \
00140 }
00141 #endif
00142
00143 #else
00144
00145 #define MYDB_BEGIN_ALLOW_THREADS
00146 #define MYDB_END_ALLOW_THREADS
00147 #define MYDB_BEGIN_BLOCK_THREADS
00148 #define MYDB_END_BLOCK_THREADS
00149
00150 #endif
00151
00152
00153 #define INCOMPLETE_IS_WARNING 1
00154
00155
00156
00157
00158 static PyObject* DBError;
00159 static PyObject* DBCursorClosedError;
00160 static PyObject* DBKeyEmptyError;
00161 static PyObject* DBKeyExistError;
00162 static PyObject* DBLockDeadlockError;
00163 static PyObject* DBLockNotGrantedError;
00164 static PyObject* DBNotFoundError;
00165 static PyObject* DBOldVersionError;
00166 static PyObject* DBRunRecoveryError;
00167 static PyObject* DBVerifyBadError;
00168 static PyObject* DBNoServerError;
00169 static PyObject* DBNoServerHomeError;
00170 static PyObject* DBNoServerIDError;
00171 #if (DBVER >= 33)
00172 static PyObject* DBPageNotFoundError;
00173 static PyObject* DBSecondaryBadError;
00174 #endif
00175
00176 #if !INCOMPLETE_IS_WARNING
00177 static PyObject* DBIncompleteError;
00178 #endif
00179
00180 static PyObject* DBInvalidArgError;
00181 static PyObject* DBAccessError;
00182 static PyObject* DBNoSpaceError;
00183 static PyObject* DBNoMemoryError;
00184 static PyObject* DBAgainError;
00185 static PyObject* DBBusyError;
00186 static PyObject* DBFileExistsError;
00187 static PyObject* DBNoSuchFileError;
00188 static PyObject* DBPermissionsError;
00189
00190
00191
00192
00193
00194
00195 #if PYTHON_API_VERSION >= 1010
00196 #define HAVE_WEAKREF
00197 #else
00198 #undef HAVE_WEAKREF
00199 #endif
00200
00201 struct behaviourFlags {
00202
00203
00204 unsigned int getReturnsNone : 1;
00205
00206
00207 unsigned int cursorSetReturnsNone : 1;
00208 };
00209
00210 #define DEFAULT_GET_RETURNS_NONE 1
00211 #define DEFAULT_CURSOR_SET_RETURNS_NONE 1
00212
00213 typedef struct {
00214 PyObject_HEAD
00215 DB_ENV* db_env;
00216 u_int32_t flags;
00217 int closed;
00218 struct behaviourFlags moduleFlags;
00219 } DBEnvObject;
00220
00221
00222 typedef struct {
00223 PyObject_HEAD
00224 DB* db;
00225 DBEnvObject* myenvobj;
00226 u_int32_t flags;
00227 u_int32_t setflags;
00228 int haveStat;
00229 struct behaviourFlags moduleFlags;
00230 #if (DBVER >= 33)
00231 PyObject* associateCallback;
00232 int primaryDBType;
00233 #endif
00234 } DBObject;
00235
00236
00237 typedef struct {
00238 PyObject_HEAD
00239 DBC* dbc;
00240 DBObject* mydb;
00241 #ifdef HAVE_WEAKREF
00242 PyObject *in_weakreflist;
00243 #endif
00244 } DBCursorObject;
00245
00246
00247 typedef struct {
00248 PyObject_HEAD
00249 DB_TXN* txn;
00250 } DBTxnObject;
00251
00252
00253 typedef struct {
00254 PyObject_HEAD
00255 DB_LOCK lock;
00256 } DBLockObject;
00257
00258
00259
00260 staticforward PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type, DBLock_Type;
00261
00262 #define DBObject_Check(v) ((v)->ob_type == &DB_Type)
00263 #define DBCursorObject_Check(v) ((v)->ob_type == &DBCursor_Type)
00264 #define DBEnvObject_Check(v) ((v)->ob_type == &DBEnv_Type)
00265 #define DBTxnObject_Check(v) ((v)->ob_type == &DBTxn_Type)
00266 #define DBLockObject_Check(v) ((v)->ob_type == &DBLock_Type)
00267
00268
00269
00270
00271
00272 #define RETURN_IF_ERR() \
00273 if (makeDBError(err)) { \
00274 return NULL; \
00275 }
00276
00277 #define RETURN_NONE() Py_INCREF(Py_None); return Py_None;
00278
00279 #define _CHECK_OBJECT_NOT_CLOSED(nonNull, pyErrObj, name) \
00280 if ((nonNull) == NULL) { \
00281 PyObject *errTuple = NULL; \
00282 errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
00283 PyErr_SetObject((pyErrObj), errTuple); \
00284 Py_DECREF(errTuple); \
00285 return NULL; \
00286 }
00287
00288 #define CHECK_DB_NOT_CLOSED(dbobj) \
00289 _CHECK_OBJECT_NOT_CLOSED(dbobj->db, DBError, DB)
00290
00291 #define CHECK_ENV_NOT_CLOSED(env) \
00292 _CHECK_OBJECT_NOT_CLOSED(env->db_env, DBError, DBEnv)
00293
00294 #define CHECK_CURSOR_NOT_CLOSED(curs) \
00295 _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)
00296
00297
00298 #define CHECK_DBFLAG(mydb, flag) (((mydb)->flags & (flag)) || \
00299 (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))
00300
00301 #define CLEAR_DBT(dbt) (memset(&(dbt), 0, sizeof(dbt)))
00302
00303 #define FREE_DBT(dbt) if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
00304 dbt.data != NULL) { free(dbt.data); }
00305
00306
00307 static int makeDBError(int err);
00308
00309
00310
00311 static int _DB_get_type(DBObject* self)
00312 {
00313 #if (DBVER >= 33)
00314 DBTYPE type;
00315 int err;
00316 err = self->db->get_type(self->db, &type);
00317 if (makeDBError(err)) {
00318 return -1;
00319 }
00320 return type;
00321 #else
00322 return self->db->get_type(self->db);
00323 #endif
00324 }
00325
00326
00327
00328
00329 static int make_dbt(PyObject* obj, DBT* dbt)
00330 {
00331 CLEAR_DBT(*dbt);
00332 if (obj == Py_None) {
00333
00334 }
00335 else if (!PyArg_Parse(obj, "s#", &dbt->data, &dbt->size)) {
00336 PyErr_SetString(PyExc_TypeError,
00337 "Key and Data values must be of type string or None.");
00338 return 0;
00339 }
00340 return 1;
00341 }
00342
00343
00344
00345
00346
00347
00348 static int
00349 make_key_dbt(DBObject* self, PyObject* keyobj, DBT* key, int* pflags)
00350 {
00351 db_recno_t recno;
00352 int type;
00353
00354 CLEAR_DBT(*key);
00355 if (keyobj == Py_None) {
00356
00357 }
00358
00359 else if (PyString_Check(keyobj)) {
00360
00361 type = _DB_get_type(self);
00362 if (type == -1)
00363 return 0;
00364 if (type == DB_RECNO || type == DB_QUEUE) {
00365 PyErr_SetString(
00366 PyExc_TypeError,
00367 "String keys not allowed for Recno and Queue DB's");
00368 return 0;
00369 }
00370
00371 key->data = PyString_AS_STRING(keyobj);
00372 key->size = PyString_GET_SIZE(keyobj);
00373 }
00374
00375 else if (PyInt_Check(keyobj)) {
00376
00377 type = _DB_get_type(self);
00378 if (type == -1)
00379 return 0;
00380 if (type == DB_BTREE && pflags != NULL) {
00381
00382
00383 *pflags |= DB_SET_RECNO;
00384 }
00385 else if (type != DB_RECNO && type != DB_QUEUE) {
00386 PyErr_SetString(
00387 PyExc_TypeError,
00388 "Integer keys only allowed for Recno and Queue DB's");
00389 return 0;
00390 }
00391
00392
00393
00394 recno = PyInt_AS_LONG(keyobj);
00395 key->data = malloc(sizeof(db_recno_t));
00396 if (key->data == NULL) {
00397 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
00398 return 0;
00399 }
00400 key->ulen = key->size = sizeof(db_recno_t);
00401 memcpy(key->data, &recno, sizeof(db_recno_t));
00402 key->flags = DB_DBT_REALLOC;
00403 }
00404 else {
00405 PyErr_Format(PyExc_TypeError,
00406 "String or Integer object expected for key, %s found",
00407 keyobj->ob_type->tp_name);
00408 return 0;
00409 }
00410
00411 return 1;
00412 }
00413
00414
00415
00416
00417
00418 static int add_partial_dbt(DBT* d, int dlen, int doff) {
00419
00420 if ((dlen == -1) && (doff == -1)) {
00421 return 1;
00422 }
00423
00424 if ((dlen < 0) || (doff < 0)) {
00425 PyErr_SetString(PyExc_TypeError, "dlen and doff must both be >= 0");
00426 return 0;
00427 }
00428
00429 d->flags = d->flags | DB_DBT_PARTIAL;
00430 d->dlen = (unsigned int) dlen;
00431 d->doff = (unsigned int) doff;
00432 return 1;
00433 }
00434
00435
00436
00437
00438 static char _db_errmsg[1024];
00439 static void _db_errorCallback(const char* prefix, char* msg)
00440 {
00441 strcpy(_db_errmsg, msg);
00442 }
00443
00444
00445
00446 static int makeDBError(int err)
00447 {
00448 char errTxt[2048];
00449 PyObject *errObj = NULL;
00450 PyObject *errTuple = NULL;
00451 int exceptionRaised = 0;
00452
00453 switch (err) {
00454 case 0: break;
00455
00456 #if (DBVER < 41)
00457 case DB_INCOMPLETE:
00458 #if INCOMPLETE_IS_WARNING
00459 strcpy(errTxt, db_strerror(err));
00460 if (_db_errmsg[0]) {
00461 strcat(errTxt, " -- ");
00462 strcat(errTxt, _db_errmsg);
00463 _db_errmsg[0] = 0;
00464 }
00465
00466 #if PYTHON_API_VERSION >= 1010
00467 exceptionRaised = PyErr_Warn(PyExc_RuntimeWarning, errTxt);
00468 #else
00469 fprintf(stderr, errTxt);
00470 fprintf(stderr, "\n");
00471 #endif
00472
00473 #else
00474 errObj = DBIncompleteError;
00475 #endif
00476 break;
00477 #endif
00478
00479 case DB_KEYEMPTY: errObj = DBKeyEmptyError; break;
00480 case DB_KEYEXIST: errObj = DBKeyExistError; break;
00481 case DB_LOCK_DEADLOCK: errObj = DBLockDeadlockError; break;
00482 case DB_LOCK_NOTGRANTED: errObj = DBLockNotGrantedError; break;
00483 case DB_NOTFOUND: errObj = DBNotFoundError; break;
00484 case DB_OLD_VERSION: errObj = DBOldVersionError; break;
00485 case DB_RUNRECOVERY: errObj = DBRunRecoveryError; break;
00486 case DB_VERIFY_BAD: errObj = DBVerifyBadError; break;
00487 case DB_NOSERVER: errObj = DBNoServerError; break;
00488 case DB_NOSERVER_HOME: errObj = DBNoServerHomeError; break;
00489 case DB_NOSERVER_ID: errObj = DBNoServerIDError; break;
00490 #if (DBVER >= 33)
00491 case DB_PAGE_NOTFOUND: errObj = DBPageNotFoundError; break;
00492 case DB_SECONDARY_BAD: errObj = DBSecondaryBadError; break;
00493 #endif
00494
00495 case EINVAL: errObj = DBInvalidArgError; break;
00496 case EACCES: errObj = DBAccessError; break;
00497 case ENOSPC: errObj = DBNoSpaceError; break;
00498 case ENOMEM: errObj = DBNoMemoryError; break;
00499 case EAGAIN: errObj = DBAgainError; break;
00500 case EBUSY : errObj = DBBusyError; break;
00501 case EEXIST: errObj = DBFileExistsError; break;
00502 case ENOENT: errObj = DBNoSuchFileError; break;
00503 case EPERM : errObj = DBPermissionsError; break;
00504
00505 default: errObj = DBError; break;
00506 }
00507
00508 if (errObj != NULL) {
00509
00510 strcpy(errTxt, db_strerror(err));
00511 if (_db_errmsg[0]) {
00512 strcat(errTxt, " -- ");
00513 strcat(errTxt, _db_errmsg);
00514 _db_errmsg[0] = 0;
00515 }
00516
00517 errTuple = Py_BuildValue("(is)", err, errTxt);
00518 PyErr_SetObject(errObj, errTuple);
00519 Py_DECREF(errTuple);
00520 }
00521
00522 return ((errObj != NULL) || exceptionRaised);
00523 }
00524
00525
00526
00527
00528 static void makeTypeError(char* expected, PyObject* found)
00529 {
00530 PyErr_Format(PyExc_TypeError, "Expected %s argument, %s found.",
00531 expected, found->ob_type->tp_name);
00532 }
00533
00534
00535
00536 static int checkTxnObj(PyObject* txnobj, DB_TXN** txn)
00537 {
00538 if (txnobj == Py_None || txnobj == NULL) {
00539 *txn = NULL;
00540 return 1;
00541 }
00542 if (DBTxnObject_Check(txnobj)) {
00543 *txn = ((DBTxnObject*)txnobj)->txn;
00544 return 1;
00545 }
00546 else
00547 makeTypeError("DBTxn", txnobj);
00548 return 0;
00549 }
00550
00551
00552
00553
00554 static int _DB_delete(DBObject* self, DB_TXN *txn, DBT *key, int flags)
00555 {
00556 int err;
00557
00558 MYDB_BEGIN_ALLOW_THREADS;
00559 err = self->db->del(self->db, txn, key, 0);
00560 MYDB_END_ALLOW_THREADS;
00561 if (makeDBError(err)) {
00562 return -1;
00563 }
00564 self->haveStat = 0;
00565 return 0;
00566 }
00567
00568
00569
00570
00571 static int _DB_put(DBObject* self, DB_TXN *txn, DBT *key, DBT *data, int flags)
00572 {
00573 int err;
00574
00575 MYDB_BEGIN_ALLOW_THREADS;
00576 err = self->db->put(self->db, txn, key, data, flags);
00577 MYDB_END_ALLOW_THREADS;
00578 if (makeDBError(err)) {
00579 return -1;
00580 }
00581 self->haveStat = 0;
00582 return 0;
00583 }
00584
00585
00586 static PyObject* _DBCursor_get(DBCursorObject* self, int extra_flags,
00587 PyObject *args, PyObject *kwargs, char *format)
00588 {
00589 int err;
00590 PyObject* retval = NULL;
00591 DBT key, data;
00592 int dlen = -1;
00593 int doff = -1;
00594 int flags = 0;
00595 char* kwnames[] = { "flags", "dlen", "doff", NULL };
00596
00597 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, kwnames,
00598 &flags, &dlen, &doff))
00599 return NULL;
00600
00601 CHECK_CURSOR_NOT_CLOSED(self);
00602
00603 flags |= extra_flags;
00604 CLEAR_DBT(key);
00605 CLEAR_DBT(data);
00606 if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
00607
00608 data.flags = DB_DBT_MALLOC;
00609 key.flags = DB_DBT_MALLOC;
00610 }
00611 if (!add_partial_dbt(&data, dlen, doff))
00612 return NULL;
00613
00614 MYDB_BEGIN_ALLOW_THREADS;
00615 err = self->dbc->c_get(self->dbc, &key, &data, flags);
00616 MYDB_END_ALLOW_THREADS;
00617
00618 if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.getReturnsNone) {
00619 Py_INCREF(Py_None);
00620 retval = Py_None;
00621 }
00622 else if (makeDBError(err)) {
00623 retval = NULL;
00624 }
00625 else {
00626
00627
00628 switch (_DB_get_type(self->mydb)) {
00629 case -1:
00630 retval = NULL;
00631 break;
00632
00633 case DB_RECNO:
00634 case DB_QUEUE:
00635 retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
00636 data.data, data.size);
00637 break;
00638 case DB_HASH:
00639 case DB_BTREE:
00640 default:
00641 retval = Py_BuildValue("s#s#", key.data, key.size,
00642 data.data, data.size);
00643 break;
00644 }
00645 }
00646 if (!err) {
00647 FREE_DBT(key);
00648 FREE_DBT(data);
00649 }
00650 return retval;
00651 }
00652
00653
00654
00655 static void _addIntToDict(PyObject* dict, char *name, int value)
00656 {
00657 PyObject* v = PyInt_FromLong((long) value);
00658 if (!v || PyDict_SetItemString(dict, name, v))
00659 PyErr_Clear();
00660
00661 Py_XDECREF(v);
00662 }
00663
00664
00665
00666
00667
00668
00669
00670 static DBObject*
00671 newDBObject(DBEnvObject* arg, int flags)
00672 {
00673 DBObject* self;
00674 DB_ENV* db_env = NULL;
00675 int err;
00676
00677 #if PYTHON_API_VERSION <= 1007
00678
00679 self = PyObject_NEW(DBObject, &DB_Type);
00680 #else
00681 self = PyObject_New(DBObject, &DB_Type);
00682 #endif
00683
00684 if (self == NULL)
00685 return NULL;
00686
00687 self->haveStat = 0;
00688 self->flags = 0;
00689 self->setflags = 0;
00690 self->myenvobj = NULL;
00691 #if (DBVER >= 33)
00692 self->associateCallback = NULL;
00693 self->primaryDBType = 0;
00694 #endif
00695
00696
00697 if (arg) {
00698 Py_INCREF(arg);
00699 self->myenvobj = arg;
00700 db_env = arg->db_env;
00701 }
00702
00703 if (self->myenvobj)
00704 self->moduleFlags = self->myenvobj->moduleFlags;
00705 else
00706 self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
00707 self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
00708
00709 MYDB_BEGIN_ALLOW_THREADS;
00710 err = db_create(&self->db, db_env, flags);
00711 self->db->set_errcall(self->db, _db_errorCallback);
00712 #if (DBVER >= 33)
00713 self->db->app_private = (void*)self;
00714 #endif
00715 MYDB_END_ALLOW_THREADS;
00716 if (makeDBError(err)) {
00717 if (self->myenvobj) {
00718 Py_DECREF(self->myenvobj);
00719 self->myenvobj = NULL;
00720 }
00721 self = NULL;
00722 }
00723 return self;
00724 }
00725
00726
00727 static void
00728 DB_dealloc(DBObject* self)
00729 {
00730 if (self->db != NULL) {
00731
00732
00733 if (!self->myenvobj ||
00734 (self->myenvobj && self->myenvobj->db_env))
00735 {
00736 MYDB_BEGIN_ALLOW_THREADS;
00737 self->db->close(self->db, 0);
00738 MYDB_END_ALLOW_THREADS;
00739
00740 #if PYTHON_API_VERSION >= 1010
00741 } else {
00742 PyErr_Warn(PyExc_RuntimeWarning,
00743 "DB could not be closed in destructor: DBEnv already closed");
00744 #endif
00745 }
00746 self->db = NULL;
00747 }
00748 if (self->myenvobj) {
00749 Py_DECREF(self->myenvobj);
00750 self->myenvobj = NULL;
00751 }
00752 #if (DBVER >= 33)
00753 if (self->associateCallback != NULL) {
00754 Py_DECREF(self->associateCallback);
00755 self->associateCallback = NULL;
00756 }
00757 #endif
00758 #if PYTHON_API_VERSION <= 1007
00759 PyMem_DEL(self);
00760 #else
00761 PyObject_Del(self);
00762 #endif
00763 }
00764
00765
00766 static DBCursorObject*
00767 newDBCursorObject(DBC* dbc, DBObject* db)
00768 {
00769 DBCursorObject* self;
00770 #if PYTHON_API_VERSION <= 1007
00771 self = PyObject_NEW(DBCursorObject, &DBCursor_Type);
00772 #else
00773 self = PyObject_New(DBCursorObject, &DBCursor_Type);
00774 #endif
00775 if (self == NULL)
00776 return NULL;
00777
00778 self->dbc = dbc;
00779 self->mydb = db;
00780 #ifdef HAVE_WEAKREF
00781 self->in_weakreflist = NULL;
00782 #endif
00783 Py_INCREF(self->mydb);
00784 return self;
00785 }
00786
00787
00788 static void
00789 DBCursor_dealloc(DBCursorObject* self)
00790 {
00791 int err;
00792
00793 #ifdef HAVE_WEAKREF
00794 if (self->in_weakreflist != NULL) {
00795 PyObject_ClearWeakRefs((PyObject *) self);
00796 }
00797 #endif
00798
00799 if (self->dbc != NULL) {
00800 MYDB_BEGIN_ALLOW_THREADS;
00801
00802
00803
00804
00805
00806
00807 if (self->mydb->db && self->mydb->myenvobj &&
00808 !self->mydb->myenvobj->closed)
00809 err = self->dbc->c_close(self->dbc);
00810 self->dbc = NULL;
00811 MYDB_END_ALLOW_THREADS;
00812 }
00813 Py_XDECREF( self->mydb );
00814 #if PYTHON_API_VERSION <= 1007
00815 PyMem_DEL(self);
00816 #else
00817 PyObject_Del(self);
00818 #endif
00819 }
00820
00821
00822 static DBEnvObject*
00823 newDBEnvObject(int flags)
00824 {
00825 int err;
00826 DBEnvObject* self;
00827 #if PYTHON_API_VERSION <= 1007
00828 self = PyObject_NEW(DBEnvObject, &DBEnv_Type);
00829 #else
00830 self = PyObject_New(DBEnvObject, &DBEnv_Type);
00831 #endif
00832
00833 if (self == NULL)
00834 return NULL;
00835
00836 self->closed = 1;
00837 self->flags = flags;
00838 self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
00839 self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
00840
00841 MYDB_BEGIN_ALLOW_THREADS;
00842 err = db_env_create(&self->db_env, flags);
00843 MYDB_END_ALLOW_THREADS;
00844 if (makeDBError(err)) {
00845 self = NULL;
00846 }
00847 else {
00848 self->db_env->set_errcall(self->db_env, _db_errorCallback);
00849 }
00850 return self;
00851 }
00852
00853
00854 static void
00855 DBEnv_dealloc(DBEnvObject* self)
00856 {
00857 if (!self->closed) {
00858 MYDB_BEGIN_ALLOW_THREADS;
00859 self->db_env->close(self->db_env, 0);
00860 MYDB_END_ALLOW_THREADS;
00861 }
00862 #if PYTHON_API_VERSION <= 1007
00863 PyMem_DEL(self);
00864 #else
00865 PyObject_Del(self);
00866 #endif
00867 }
00868
00869
00870 static DBTxnObject*
00871 newDBTxnObject(DBEnvObject* myenv, DB_TXN *parent, int flags)
00872 {
00873 int err;
00874 DBTxnObject* self;
00875
00876 #if PYTHON_API_VERSION <= 1007
00877 self = PyObject_NEW(DBTxnObject, &DBTxn_Type);
00878 #else
00879 self = PyObject_New(DBTxnObject, &DBTxn_Type);
00880 #endif
00881 if (self == NULL)
00882 return NULL;
00883
00884 MYDB_BEGIN_ALLOW_THREADS;
00885 #if (DBVER >= 40)
00886 err = myenv->db_env->txn_begin(myenv->db_env, parent, &(self->txn), flags);
00887 #else
00888 err = txn_begin(myenv->db_env, parent, &(self->txn), flags);
00889 #endif
00890 MYDB_END_ALLOW_THREADS;
00891 if (makeDBError(err)) {
00892 self = NULL;
00893 }
00894 return self;
00895 }
00896
00897
00898 static void
00899 DBTxn_dealloc(DBTxnObject* self)
00900 {
00901
00902
00903
00904
00905 #if PYTHON_API_VERSION <= 1007
00906 PyMem_DEL(self);
00907 #else
00908 PyObject_Del(self);
00909 #endif
00910 }
00911
00912
00913 static DBLockObject*
00914 newDBLockObject(DBEnvObject* myenv, u_int32_t locker, DBT* obj,
00915 db_lockmode_t lock_mode, int flags)
00916 {
00917 int err;
00918 DBLockObject* self;
00919
00920 #if PYTHON_API_VERSION <= 1007
00921 self = PyObject_NEW(DBLockObject, &DBLock_Type);
00922 #else
00923 self = PyObject_New(DBLockObject, &DBLock_Type);
00924 #endif
00925 if (self == NULL)
00926 return NULL;
00927
00928 MYDB_BEGIN_ALLOW_THREADS;
00929 #if (DBVER >= 40)
00930 err = myenv->db_env->lock_get(myenv->db_env, locker, flags, obj, lock_mode,
00931 &self->lock);
00932 #else
00933 err = lock_get(myenv->db_env, locker, flags, obj, lock_mode, &self->lock);
00934 #endif
00935 MYDB_END_ALLOW_THREADS;
00936 if (makeDBError(err)) {
00937 self = NULL;
00938 }
00939
00940 return self;
00941 }
00942
00943
00944 static void
00945 DBLock_dealloc(DBLockObject* self)
00946 {
00947
00948
00949 #if PYTHON_API_VERSION <= 1007
00950 PyMem_DEL(self);
00951 #else
00952 PyObject_Del(self);
00953 #endif
00954 }
00955
00956
00957
00958
00959
00960 static PyObject*
00961 DB_append(DBObject* self, PyObject* args)
00962 {
00963 PyObject* txnobj = NULL;
00964 PyObject* dataobj;
00965 db_recno_t recno;
00966 DBT key, data;
00967 DB_TXN *txn = NULL;
00968
00969 if (!PyArg_ParseTuple(args, "O|O:append", &dataobj, &txnobj))
00970 return NULL;
00971
00972 CHECK_DB_NOT_CLOSED(self);
00973
00974
00975 recno = 0;
00976 CLEAR_DBT(key);
00977 key.data = &recno;
00978 key.size = sizeof(recno);
00979 key.ulen = key.size;
00980 key.flags = DB_DBT_USERMEM;
00981
00982 if (!make_dbt(dataobj, &data)) return NULL;
00983 if (!checkTxnObj(txnobj, &txn)) return NULL;
00984
00985 if (-1 == _DB_put(self, txn, &key, &data, DB_APPEND))
00986 return NULL;
00987
00988 return PyInt_FromLong(recno);
00989 }
00990
00991
00992 #if (DBVER >= 33)
00993
00994 static int
00995 _db_associateCallback(DB* db, const DBT* priKey, const DBT* priData,
00996 DBT* secKey)
00997 {
00998 int retval = DB_DONOTINDEX;
00999 DBObject* secondaryDB = (DBObject*)db->app_private;
01000 PyObject* callback = secondaryDB->associateCallback;
01001 int type = secondaryDB->primaryDBType;
01002 PyObject* key;
01003 PyObject* data;
01004 PyObject* args;
01005 PyObject* result;
01006
01007
01008 if (callback != NULL) {
01009 MYDB_BEGIN_BLOCK_THREADS;
01010
01011 if (type == DB_RECNO || type == DB_QUEUE) {
01012 key = PyInt_FromLong( *((db_recno_t*)priKey->data));
01013 }
01014 else {
01015 key = PyString_FromStringAndSize(priKey->data, priKey->size);
01016 }
01017 data = PyString_FromStringAndSize(priData->data, priData->size);
01018 args = PyTuple_New(2);
01019 PyTuple_SET_ITEM(args, 0, key);
01020 PyTuple_SET_ITEM(args, 1, data);
01021
01022 result = PyEval_CallObject(callback, args);
01023
01024 if (result == NULL) {
01025 PyErr_Print();
01026 }
01027 else if (result == Py_None) {
01028 retval = DB_DONOTINDEX;
01029 }
01030 else if (PyInt_Check(result)) {
01031 retval = PyInt_AsLong(result);
01032 }
01033 else if (PyString_Check(result)) {
01034 char* data;
01035 int size;
01036
01037 CLEAR_DBT(*secKey);
01038 #if PYTHON_API_VERSION <= 1007
01039
01040 size = PyString_Size(result);
01041 data = PyString_AsString(result);
01042 #else
01043 PyString_AsStringAndSize(result, &data, &size);
01044 #endif
01045 secKey->flags = DB_DBT_APPMALLOC;
01046 secKey->data = malloc(size);
01047 if (secKey->data) {
01048 memcpy(secKey->data, data, size);
01049 secKey->size = size;
01050 retval = 0;
01051 }
01052 else {
01053 PyErr_SetString(PyExc_MemoryError,
01054 "malloc failed in _db_associateCallback");
01055 PyErr_Print();
01056 }
01057 }
01058 else {
01059 PyErr_SetString(
01060 PyExc_TypeError,
01061 "DB associate callback should return DB_DONOTINDEX or string.");
01062 PyErr_Print();
01063 }
01064
01065 Py_DECREF(args);
01066 if (result) {
01067 Py_DECREF(result);
01068 }
01069
01070 MYDB_END_BLOCK_THREADS;
01071 }
01072 return retval;
01073 }
01074
01075
01076 static PyObject*
01077 DB_associate(DBObject* self, PyObject* args, PyObject* kwargs)
01078 {
01079 int err, flags=0;
01080 DBObject* secondaryDB;
01081 PyObject* callback;
01082 #if (DBVER >= 41)
01083 PyObject *txnobj = NULL;
01084 DB_TXN *txn = NULL;
01085 char* kwnames[] = {"secondaryDB", "callback", "flags", "txn", NULL};
01086 #else
01087 char* kwnames[] = {"secondaryDB", "callback", "flags", NULL};
01088 #endif
01089
01090 #if (DBVER >= 41)
01091 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iO:associate", kwnames,
01092 &secondaryDB, &callback, &flags,
01093 &txnobj)) {
01094 #else
01095 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:associate", kwnames,
01096 &secondaryDB, &callback, &flags)) {
01097 #endif
01098 return NULL;
01099 }
01100
01101 #if (DBVER >= 41)
01102 if (!checkTxnObj(txnobj, &txn)) return NULL;
01103 #endif
01104
01105 CHECK_DB_NOT_CLOSED(self);
01106 if (!DBObject_Check(secondaryDB)) {
01107 makeTypeError("DB", (PyObject*)secondaryDB);
01108 return NULL;
01109 }
01110 if (callback == Py_None) {
01111 callback = NULL;
01112 }
01113 else if (!PyCallable_Check(callback)) {
01114 makeTypeError("Callable", callback);
01115 return NULL;
01116 }
01117
01118
01119 if (self->associateCallback != NULL) {
01120 Py_DECREF(self->associateCallback);
01121 }
01122 Py_INCREF(callback);
01123 secondaryDB->associateCallback = callback;
01124 secondaryDB->primaryDBType = _DB_get_type(self);
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136 #ifdef WITH_THREAD
01137 PyEval_InitThreads();
01138 #endif
01139 MYDB_BEGIN_ALLOW_THREADS;
01140 #if (DBVER >= 41)
01141 err = self->db->associate(self->db,
01142 txn,
01143 secondaryDB->db,
01144 _db_associateCallback,
01145 flags);
01146 #else
01147 err = self->db->associate(self->db,
01148 secondaryDB->db,
01149 _db_associateCallback,
01150 flags);
01151 #endif
01152 MYDB_END_ALLOW_THREADS;
01153
01154 if (err) {
01155 Py_DECREF(self->associateCallback);
01156 self->associateCallback = NULL;
01157 secondaryDB->primaryDBType = 0;
01158 }
01159
01160 RETURN_IF_ERR();
01161 RETURN_NONE();
01162 }
01163
01164
01165 #endif
01166
01167
01168 static PyObject*
01169 DB_close(DBObject* self, PyObject* args)
01170 {
01171 int err, flags=0;
01172 if (!PyArg_ParseTuple(args,"|i:close", &flags))
01173 return NULL;
01174 if (self->db != NULL) {
01175 if (self->myenvobj)
01176 CHECK_ENV_NOT_CLOSED(self->myenvobj);
01177 err = self->db->close(self->db, flags);
01178 self->db = NULL;
01179 RETURN_IF_ERR();
01180 }
01181 RETURN_NONE();
01182 }
01183
01184
01185 #if (DBVER >= 32)
01186 static PyObject*
01187 _DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
01188 {
01189 int err, flags=0, type;
01190 PyObject* txnobj = NULL;
01191 PyObject* retval = NULL;
01192 DBT key, data;
01193 DB_TXN *txn = NULL;
01194 char* kwnames[] = { "txn", "flags", NULL };
01195
01196 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:consume", kwnames,
01197 &txnobj, &flags))
01198 return NULL;
01199
01200 CHECK_DB_NOT_CLOSED(self);
01201 type = _DB_get_type(self);
01202 if (type == -1)
01203 return NULL;
01204 if (type != DB_QUEUE) {
01205 PyErr_SetString(PyExc_TypeError,
01206 "Consume methods only allowed for Queue DB's");
01207 return NULL;
01208 }
01209 if (!checkTxnObj(txnobj, &txn))
01210 return NULL;
01211
01212 CLEAR_DBT(key);
01213 CLEAR_DBT(data);
01214 if (CHECK_DBFLAG(self, DB_THREAD)) {
01215
01216 data.flags = DB_DBT_MALLOC;
01217 key.flags = DB_DBT_MALLOC;
01218 }
01219
01220 MYDB_BEGIN_ALLOW_THREADS;
01221 err = self->db->get(self->db, txn, &key, &data, flags|consume_flag);
01222 MYDB_END_ALLOW_THREADS;
01223
01224 if ((err == DB_NOTFOUND) && self->moduleFlags.getReturnsNone) {
01225 err = 0;
01226 Py_INCREF(Py_None);
01227 retval = Py_None;
01228 }
01229 else if (!err) {
01230 retval = Py_BuildValue("s#s#", key.data, key.size, data.data,
01231 data.size);
01232 FREE_DBT(key);
01233 FREE_DBT(data);
01234 }
01235
01236 RETURN_IF_ERR();
01237 return retval;
01238 }
01239
01240 static PyObject*
01241 DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
01242 {
01243 return _DB_consume(self, args, kwargs, DB_CONSUME);
01244 }
01245
01246 static PyObject*
01247 DB_consume_wait(DBObject* self, PyObject* args, PyObject* kwargs,
01248 int consume_flag)
01249 {
01250 return _DB_consume(self, args, kwargs, DB_CONSUME_WAIT);
01251 }
01252 #endif
01253
01254
01255
01256 static PyObject*
01257 DB_cursor(DBObject* self, PyObject* args, PyObject* kwargs)
01258 {
01259 int err, flags=0;
01260 DBC* dbc;
01261 PyObject* txnobj = NULL;
01262 DB_TXN *txn = NULL;
01263 char* kwnames[] = { "txn", "flags", NULL };
01264
01265 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
01266 &txnobj, &flags))
01267 return NULL;
01268 CHECK_DB_NOT_CLOSED(self);
01269 if (!checkTxnObj(txnobj, &txn))
01270 return NULL;
01271
01272 MYDB_BEGIN_ALLOW_THREADS;
01273 err = self->db->cursor(self->db, txn, &dbc, flags);
01274 MYDB_END_ALLOW_THREADS;
01275 RETURN_IF_ERR();
01276 return (PyObject*) newDBCursorObject(dbc, self);
01277 }
01278
01279
01280 static PyObject*
01281 DB_delete(DBObject* self, PyObject* args, PyObject* kwargs)
01282 {
01283 PyObject* txnobj = NULL;
01284 int flags = 0;
01285 PyObject* keyobj;
01286 DBT key;
01287 DB_TXN *txn = NULL;
01288 char* kwnames[] = { "key", "txn", "flags", NULL };
01289
01290 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:delete", kwnames,
01291 &keyobj, &txnobj, &flags))
01292 return NULL;
01293 CHECK_DB_NOT_CLOSED(self);
01294 if (!make_key_dbt(self, keyobj, &key, NULL))
01295 return NULL;
01296 if (!checkTxnObj(txnobj, &txn))
01297 return NULL;
01298
01299 if (-1 == _DB_delete(self, txn, &key, 0))
01300 return NULL;
01301
01302 FREE_DBT(key);
01303 RETURN_NONE();
01304 }
01305
01306
01307 static PyObject*
01308 DB_fd(DBObject* self, PyObject* args)
01309 {
01310 int err, the_fd;
01311
01312 if (!PyArg_ParseTuple(args,":fd"))
01313 return NULL;
01314 CHECK_DB_NOT_CLOSED(self);
01315
01316 MYDB_BEGIN_ALLOW_THREADS;
01317 err = self->db->fd(self->db, &the_fd);
01318 MYDB_END_ALLOW_THREADS;
01319 RETURN_IF_ERR();
01320 return PyInt_FromLong(the_fd);
01321 }
01322
01323
01324 static PyObject*
01325 DB_get(DBObject* self, PyObject* args, PyObject* kwargs)
01326 {
01327 int err, flags=0;
01328 PyObject* txnobj = NULL;
01329 PyObject* keyobj;
01330 PyObject* dfltobj = NULL;
01331 PyObject* retval = NULL;
01332 int dlen = -1;
01333 int doff = -1;
01334 DBT key, data;
01335 DB_TXN *txn = NULL;
01336 char* kwnames[] = {"key", "default", "txn", "flags", "dlen", "doff", NULL};
01337
01338 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:get", kwnames,
01339 &keyobj, &dfltobj, &txnobj, &flags, &dlen,
01340 &doff))
01341 return NULL;
01342
01343 CHECK_DB_NOT_CLOSED(self);
01344 if (!make_key_dbt(self, keyobj, &key, &flags))
01345 return NULL;
01346 if (!checkTxnObj(txnobj, &txn))
01347 return NULL;
01348
01349 CLEAR_DBT(data);
01350 if (CHECK_DBFLAG(self, DB_THREAD)) {
01351
01352 data.flags = DB_DBT_MALLOC;
01353 }
01354 if (!add_partial_dbt(&data, dlen, doff))
01355 return NULL;
01356
01357 MYDB_BEGIN_ALLOW_THREADS;
01358 err = self->db->get(self->db, txn, &key, &data, flags);
01359 MYDB_END_ALLOW_THREADS;
01360
01361 if ((err == DB_NOTFOUND) && (dfltobj != NULL)) {
01362 err = 0;
01363 Py_INCREF(dfltobj);
01364 retval = dfltobj;
01365 }
01366 else if ((err == DB_NOTFOUND) && self->moduleFlags.getReturnsNone) {
01367 err = 0;
01368 Py_INCREF(Py_None);
01369 retval = Py_None;
01370 }
01371 else if (!err) {
01372 if (flags & DB_SET_RECNO)
01373 retval = Py_BuildValue("s#s#", key.data, key.size, data.data,
01374 data.size);
01375 else
01376 retval = PyString_FromStringAndSize((char*)data.data, data.size);
01377 FREE_DBT(key);
01378 FREE_DBT(data);
01379 }
01380
01381 RETURN_IF_ERR();
01382 return retval;
01383 }
01384
01385
01386
01387 static PyObject*
01388 DB_get_size(DBObject* self, PyObject* args, PyObject* kwargs)
01389 {
01390 int err, flags=0;
01391 PyObject* txnobj = NULL;
01392 PyObject* keyobj;
01393 PyObject* retval = NULL;
01394 DBT key, data;
01395 DB_TXN *txn = NULL;
01396 char* kwnames[] = { "key", "txn", NULL };
01397
01398 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:get_size", kwnames,
01399 &keyobj, &txnobj))
01400 return NULL;
01401 CHECK_DB_NOT_CLOSED(self);
01402 if (!make_key_dbt(self, keyobj, &key, &flags))
01403 return NULL;
01404 if (!checkTxnObj(txnobj, &txn))
01405 return NULL;
01406 CLEAR_DBT(data);
01407
01408
01409
01410 data.flags = DB_DBT_USERMEM;
01411 data.ulen = 0;
01412 MYDB_BEGIN_ALLOW_THREADS;
01413 err = self->db->get(self->db, txn, &key, &data, flags);
01414 MYDB_END_ALLOW_THREADS;
01415 if (err == ENOMEM) {
01416 retval = PyInt_FromLong((long)data.size);
01417 err = 0;
01418 }
01419
01420 FREE_DBT(key);
01421 FREE_DBT(data);
01422 RETURN_IF_ERR();
01423 return retval;
01424 }
01425
01426
01427 static PyObject*
01428 DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
01429 {
01430 int err, flags=0;
01431 PyObject* txnobj = NULL;
01432 PyObject* keyobj;
01433 PyObject* dataobj;
01434 PyObject* retval = NULL;
01435 DBT key, data;
01436 DB_TXN *txn = NULL;
01437 char* kwnames[] = { "key", "data", "txn", "flags", NULL };
01438
01439
01440 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oi:get_both", kwnames,
01441 &keyobj, &dataobj, &txnobj, &flags))
01442 return NULL;
01443
01444 CHECK_DB_NOT_CLOSED(self);
01445 if (!make_key_dbt(self, keyobj, &key, NULL))
01446 return NULL;
01447 if (!make_dbt(dataobj, &data))
01448 return NULL;
01449 if (!checkTxnObj(txnobj, &txn))
01450 return NULL;
01451
01452 flags |= DB_GET_BOTH;
01453
01454 if (CHECK_DBFLAG(self, DB_THREAD)) {
01455
01456 data.flags = DB_DBT_MALLOC;
01457
01458
01459
01460 }
01461
01462 MYDB_BEGIN_ALLOW_THREADS;
01463 err = self->db->get(self->db, txn, &key, &data, flags);
01464 MYDB_END_ALLOW_THREADS;
01465
01466 if ((err == DB_NOTFOUND) && self->moduleFlags.getReturnsNone) {
01467 err = 0;
01468 Py_INCREF(Py_None);
01469 retval = Py_None;
01470 }
01471 else if (!err) {
01472 retval = PyString_FromStringAndSize((char*)data.data, data.size);
01473 FREE_DBT(data);
01474 }
01475
01476 FREE_DBT(key);
01477 RETURN_IF_ERR();
01478 return retval;
01479 }
01480
01481
01482 static PyObject*
01483 DB_get_byteswapped(DBObject* self, PyObject* args)
01484 {
01485 #if (DBVER >= 33)
01486 int err = 0;
01487 #endif
01488 int retval = -1;
01489
01490 if (!PyArg_ParseTuple(args,":get_byteswapped"))
01491 return NULL;
01492 CHECK_DB_NOT_CLOSED(self);
01493
01494 #if (DBVER >= 33)
01495 MYDB_BEGIN_ALLOW_THREADS;
01496 err = self->db->get_byteswapped(self->db, &retval);
01497 MYDB_END_ALLOW_THREADS;
01498 RETURN_IF_ERR();
01499 #else
01500 MYDB_BEGIN_ALLOW_THREADS;
01501 retval = self->db->get_byteswapped(self->db);
01502 MYDB_END_ALLOW_THREADS;
01503 #endif
01504 return PyInt_FromLong(retval);
01505 }
01506
01507
01508 static PyObject*
01509 DB_get_type(DBObject* self, PyObject* args)
01510 {
01511 int type;
01512
01513 if (!PyArg_ParseTuple(args,":get_type"))
01514 return NULL;
01515 CHECK_DB_NOT_CLOSED(self);
01516
01517 MYDB_BEGIN_ALLOW_THREADS;
01518 type = _DB_get_type(self);
01519 MYDB_END_ALLOW_THREADS;
01520 if (type == -1)
01521 return NULL;
01522 return PyInt_FromLong(type);
01523 }
01524
01525
01526 static PyObject*
01527 DB_join(DBObject* self, PyObject* args)
01528 {
01529 int err, flags=0;
01530 int length, x;
01531 PyObject* cursorsObj;
01532 DBC** cursors;
01533 DBC* dbc;
01534
01535
01536 if (!PyArg_ParseTuple(args,"O|i:join", &cursorsObj, &flags))
01537 return NULL;
01538
01539 CHECK_DB_NOT_CLOSED(self);
01540
01541 if (!PySequence_Check(cursorsObj)) {
01542 PyErr_SetString(PyExc_TypeError,
01543 "Sequence of DBCursor objects expected");
01544 return NULL;
01545 }
01546
01547 length = PyObject_Length(cursorsObj);
01548 cursors = malloc((length+1) * sizeof(DBC*));
01549 cursors[length] = NULL;
01550 for (x=0; x<length; x++) {
01551 PyObject* item = PySequence_GetItem(cursorsObj, x);
01552 if (!DBCursorObject_Check(item)) {
01553 PyErr_SetString(PyExc_TypeError,
01554 "Sequence of DBCursor objects expected");
01555 free(cursors);
01556 return NULL;
01557 }
01558 cursors[x] = ((DBCursorObject*)item)->dbc;
01559 }
01560
01561 MYDB_BEGIN_ALLOW_THREADS;
01562 err = self->db->join(self->db, cursors, &dbc, flags);
01563 MYDB_END_ALLOW_THREADS;
01564 free(cursors);
01565 RETURN_IF_ERR();
01566
01567
01568
01569
01570
01571
01572 return (PyObject*) newDBCursorObject(dbc, self);
01573 }
01574
01575
01576 static PyObject*
01577 DB_key_range(DBObject* self, PyObject* args, PyObject* kwargs)
01578 {
01579 int err, flags=0;
01580 PyObject* txnobj = NULL;
01581 PyObject* keyobj;
01582 DBT key;
01583 DB_TXN *txn = NULL;
01584 DB_KEY_RANGE range;
01585 char* kwnames[] = { "key", "txn", "flags", NULL };
01586
01587 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:key_range", kwnames,
01588 &keyobj, &txnobj, &flags))
01589 return NULL;
01590 CHECK_DB_NOT_CLOSED(self);
01591 if (!make_dbt(keyobj, &key))
01592
01593 return NULL;
01594 if (!checkTxnObj(txnobj, &txn))
01595 return NULL;
01596
01597 MYDB_BEGIN_ALLOW_THREADS;
01598 err = self->db->key_range(self->db, txn, &key, &range, flags);
01599 MYDB_END_ALLOW_THREADS;
01600
01601 RETURN_IF_ERR();
01602 return Py_BuildValue("ddd", range.less, range.equal, range.greater);
01603 }
01604
01605
01606 static PyObject*
01607 DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
01608 {
01609 int err, type = DB_UNKNOWN, flags=0, mode=0660;
01610 char* filename = NULL;
01611 char* dbname = NULL;
01612 #if (DBVER >= 41)
01613 PyObject *txnobj = NULL;
01614 DB_TXN *txn = NULL;
01615
01616 char* kwnames[] = {
01617 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL};
01618
01619 char* kwnames_basic[] = {
01620 "filename", "dbtype", "flags", "mode", "txn", NULL};
01621 #else
01622
01623 char* kwnames[] = {
01624 "filename", "dbname", "dbtype", "flags", "mode", NULL};
01625
01626 char* kwnames_basic[] = {
01627 "filename", "dbtype", "flags", "mode", NULL};
01628 #endif
01629
01630 #if (DBVER >= 41)
01631 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziiiO:open", kwnames,
01632 &filename, &dbname, &type, &flags, &mode,
01633 &txnobj))
01634 #else
01635 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziii:open", kwnames,
01636 &filename, &dbname, &type, &flags,
01637 &mode))
01638 #endif
01639 {
01640 PyErr_Clear();
01641 type = DB_UNKNOWN; flags = 0; mode = 0660;
01642 filename = NULL; dbname = NULL;
01643 #if (DBVER >= 41)
01644 if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iiiO:open",
01645 kwnames_basic,
01646 &filename, &type, &flags, &mode,
01647 &txnobj))
01648 return NULL;
01649 #else
01650 if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iii:open",
01651 kwnames_basic,
01652 &filename, &type, &flags, &mode))
01653 return NULL;
01654 #endif
01655 }
01656
01657 #if (DBVER >= 41)
01658 if (!checkTxnObj(txnobj, &txn)) return NULL;
01659 #endif
01660
01661 if (NULL == self->db) {
01662 PyErr_SetObject(DBError, Py_BuildValue("(is)", 0,
01663 "Cannot call open() twice for DB object"));
01664 return NULL;
01665 }
01666
01667 #if 0 && (DBVER >= 41)
01668 if ((!txn) && (txnobj != Py_None) && self->myenvobj
01669 && (self->myenvobj->flags & DB_INIT_TXN))
01670 {
01671
01672
01673
01674
01675
01676
01677
01678 flags |= DB_AUTO_COMMIT;
01679 }
01680 #endif
01681
01682 MYDB_BEGIN_ALLOW_THREADS;
01683 #if (DBVER >= 41)
01684 err = self->db->open(self->db, txn, filename, dbname, type, flags, mode);
01685 #else
01686 err = self->db->open(self->db, filename, dbname, type, flags, mode);
01687 #endif
01688 MYDB_END_ALLOW_THREADS;
01689 if (makeDBError(err)) {
01690 self->db->close(self->db, 0);
01691 self->db = NULL;
01692 return NULL;
01693 }
01694
01695 self->flags = flags;
01696 RETURN_NONE();
01697 }
01698
01699
01700 static PyObject*
01701 DB_put(DBObject* self, PyObject* args, PyObject* kwargs)
01702 {
01703 int flags=0;
01704 PyObject* txnobj = NULL;
01705 int dlen = -1;
01706 int doff = -1;
01707 PyObject* keyobj, *dataobj, *retval;
01708 DBT key, data;
01709 DB_TXN *txn = NULL;
01710 char* kwnames[] = { "key", "data", "txn", "flags", "dlen", "doff", NULL };
01711
01712 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oiii:put", kwnames,
01713 &keyobj, &dataobj, &txnobj, &flags, &dlen, &doff))
01714 return NULL;
01715
01716 CHECK_DB_NOT_CLOSED(self);
01717 if (!make_key_dbt(self, keyobj, &key, NULL)) return NULL;
01718 if (!make_dbt(dataobj, &data)) return NULL;
01719 if (!add_partial_dbt(&data, dlen, doff)) return NULL;
01720 if (!checkTxnObj(txnobj, &txn)) return NULL;
01721
01722 if (-1 == _DB_put(self, txn, &key, &data, flags)) {
01723 FREE_DBT(key);
01724 return NULL;
01725 }
01726
01727 if (flags & DB_APPEND)
01728 retval = PyInt_FromLong(*((db_recno_t*)key.data));
01729 else {
01730 retval = Py_None;
01731 Py_INCREF(retval);
01732 }
01733 FREE_DBT(key);
01734 return retval;
01735 }
01736
01737
01738
01739 static PyObject*
01740 DB_remove(DBObject* self, PyObject* args, PyObject* kwargs)
01741 {
01742 char* filename;
01743 char* database = NULL;
01744 int err, flags=0;
01745 char* kwnames[] = { "filename", "dbname", "flags", NULL};
01746
01747 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zi:remove", kwnames,
01748 &filename, &database, &flags))
01749 return NULL;
01750 CHECK_DB_NOT_CLOSED(self);
01751
01752 err = self->db->remove(self->db, filename, database, flags);
01753 self->db = NULL;
01754 RETURN_IF_ERR();
01755 RETURN_NONE();
01756 }
01757
01758
01759
01760 static PyObject*
01761 DB_rename(DBObject* self, PyObject* args)
01762 {
01763 char* filename;
01764 char* database;
01765 char* newname;
01766 int err, flags=0;
01767
01768 if (!PyArg_ParseTuple(args, "sss|i:rename", &filename, &database, &newname,
01769 &flags))
01770 return NULL;
01771 CHECK_DB_NOT_CLOSED(self);
01772
01773 MYDB_BEGIN_ALLOW_THREADS;
01774 err = self->db->rename(self->db, filename, database, newname, flags);
01775 MYDB_END_ALLOW_THREADS;
01776 RETURN_IF_ERR();
01777 RETURN_NONE();
01778 }
01779
01780
01781 static PyObject*
01782 DB_set_bt_minkey(DBObject* self, PyObject* args)
01783 {
01784 int err, minkey;
01785
01786 if (!PyArg_ParseTuple(args,"i:set_bt_minkey", &minkey ))
01787 return NULL;
01788 CHECK_DB_NOT_CLOSED(self);
01789
01790 MYDB_BEGIN_ALLOW_THREADS;
01791 err = self->db->set_bt_minkey(self->db, minkey);
01792 MYDB_END_ALLOW_THREADS;
01793 RETURN_IF_ERR();
01794 RETURN_NONE();
01795 }
01796
01797
01798 static PyObject*
01799 DB_set_cachesize(DBObject* self, PyObject* args)
01800 {
01801 int err;
01802 int gbytes = 0, bytes = 0, ncache = 0;
01803
01804 if (!PyArg_ParseTuple(args,"ii|i:set_cachesize",
01805 &gbytes,&bytes,&ncache))
01806 return NULL;
01807 CHECK_DB_NOT_CLOSED(self);
01808
01809 MYDB_BEGIN_ALLOW_THREADS;
01810 err = self->db->set_cachesize(self->db, gbytes, bytes, ncache);
01811 MYDB_END_ALLOW_THREADS;
01812 RETURN_IF_ERR();
01813 RETURN_NONE();
01814 }
01815
01816
01817 static PyObject*
01818 DB_set_flags(DBObject* self, PyObject* args)
01819 {
01820 int err, flags;
01821
01822 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
01823 return NULL;
01824 CHECK_DB_NOT_CLOSED(self);
01825
01826 MYDB_BEGIN_ALLOW_THREADS;
01827 err = self->db->set_flags(self->db, flags);
01828 MYDB_END_ALLOW_THREADS;
01829 RETURN_IF_ERR();
01830
01831 self->setflags |= flags;
01832 RETURN_NONE();
01833 }
01834
01835
01836 static PyObject*
01837 DB_set_h_ffactor(DBObject* self, PyObject* args)
01838 {
01839 int err, ffactor;
01840
01841 if (!PyArg_ParseTuple(args,"i:set_h_ffactor", &ffactor))
01842 return NULL;
01843 CHECK_DB_NOT_CLOSED(self);
01844
01845 MYDB_BEGIN_ALLOW_THREADS;
01846 err = self->db->set_h_ffactor(self->db, ffactor);
01847 MYDB_END_ALLOW_THREADS;
01848 RETURN_IF_ERR();
01849 RETURN_NONE();
01850 }
01851
01852
01853 static PyObject*
01854 DB_set_h_nelem(DBObject* self, PyObject* args)
01855 {
01856 int err, nelem;
01857
01858 if (!PyArg_ParseTuple(args,"i:set_h_nelem", &nelem))
01859 return NULL;
01860 CHECK_DB_NOT_CLOSED(self);
01861
01862 MYDB_BEGIN_ALLOW_THREADS;
01863 err = self->db->set_h_nelem(self->db, nelem);
01864 MYDB_END_ALLOW_THREADS;
01865 RETURN_IF_ERR();
01866 RETURN_NONE();
01867 }
01868
01869
01870 static PyObject*
01871 DB_set_lorder(DBObject* self, PyObject* args)
01872 {
01873 int err, lorder;
01874
01875 if (!PyArg_ParseTuple(args,"i:set_lorder", &lorder))
01876 return NULL;
01877 CHECK_DB_NOT_CLOSED(self);
01878
01879 MYDB_BEGIN_ALLOW_THREADS;
01880 err = self->db->set_lorder(self->db, lorder);
01881 MYDB_END_ALLOW_THREADS;
01882 RETURN_IF_ERR();
01883 RETURN_NONE();
01884 }
01885
01886
01887 static PyObject*
01888 DB_set_pagesize(DBObject* self, PyObject* args)
01889 {
01890 int err, pagesize;
01891
01892 if (!PyArg_ParseTuple(args,"i:set_pagesize", &pagesize))
01893 return NULL;
01894 CHECK_DB_NOT_CLOSED(self);
01895
01896 MYDB_BEGIN_ALLOW_THREADS;
01897 err = self->db->set_pagesize(self->db, pagesize);
01898 MYDB_END_ALLOW_THREADS;
01899 RETURN_IF_ERR();
01900 RETURN_NONE();
01901 }
01902
01903
01904 static PyObject*
01905 DB_set_re_delim(DBObject* self, PyObject* args)
01906 {
01907 int err;
01908 char delim;
01909
01910 if (!PyArg_ParseTuple(args,"b:set_re_delim", &delim)) {
01911 PyErr_Clear();
01912 if (!PyArg_ParseTuple(args,"c:set_re_delim", &delim))
01913 return NULL;
01914 }
01915
01916 CHECK_DB_NOT_CLOSED(self);
01917
01918 MYDB_BEGIN_ALLOW_THREADS;
01919 err = self->db->set_re_delim(self->db, delim);
01920 MYDB_END_ALLOW_THREADS;
01921 RETURN_IF_ERR();
01922 RETURN_NONE();
01923 }
01924
01925 static PyObject*
01926 DB_set_re_len(DBObject* self, PyObject* args)
01927 {
01928 int err, len;
01929
01930 if (!PyArg_ParseTuple(args,"i:set_re_len", &len))
01931 return NULL;
01932 CHECK_DB_NOT_CLOSED(self);
01933
01934 MYDB_BEGIN_ALLOW_THREADS;
01935 err = self->db->set_re_len(self->db, len);
01936 MYDB_END_ALLOW_THREADS;
01937 RETURN_IF_ERR();
01938 RETURN_NONE();
01939 }
01940
01941
01942 static PyObject*
01943 DB_set_re_pad(DBObject* self, PyObject* args)
01944 {
01945 int err;
01946 char pad;
01947
01948 if (!PyArg_ParseTuple(args,"b:set_re_pad", &pad)) {
01949 PyErr_Clear();
01950 if (!PyArg_ParseTuple(args,"c:set_re_pad", &pad))
01951 return NULL;
01952 }
01953 CHECK_DB_NOT_CLOSED(self);
01954
01955 MYDB_BEGIN_ALLOW_THREADS;
01956 err = self->db->set_re_pad(self->db, pad);
01957 MYDB_END_ALLOW_THREADS;
01958 RETURN_IF_ERR();
01959 RETURN_NONE();
01960 }
01961
01962
01963 static PyObject*
01964 DB_set_re_source(DBObject* self, PyObject* args)
01965 {
01966 int err;
01967 char *re_source;
01968
01969 if (!PyArg_ParseTuple(args,"s:set_re_source", &re_source))
01970 return NULL;
01971 CHECK_DB_NOT_CLOSED(self);
01972
01973 MYDB_BEGIN_ALLOW_THREADS;
01974 err = self->db->set_re_source(self->db, re_source);
01975 MYDB_END_ALLOW_THREADS;
01976 RETURN_IF_ERR();
01977 RETURN_NONE();
01978 }
01979
01980
01981 #if (DBVER >= 32)
01982 static PyObject*
01983 DB_set_q_extentsize(DBObject* self, PyObject* args)
01984 {
01985 int err;
01986 int extentsize;
01987
01988 if (!PyArg_ParseTuple(args,"i:set_q_extentsize", &extentsize))
01989 return NULL;
01990 CHECK_DB_NOT_CLOSED(self);
01991
01992 MYDB_BEGIN_ALLOW_THREADS;
01993 err = self->db->set_q_extentsize(self->db, extentsize);
01994 MYDB_END_ALLOW_THREADS;
01995 RETURN_IF_ERR();
01996 RETURN_NONE();
01997 }
01998 #endif
01999
02000 static PyObject*
02001 DB_stat(DBObject* self, PyObject* args)
02002 {
02003 int err, flags = 0, type;
02004 void* sp;
02005 PyObject* d;
02006
02007
02008 if (!PyArg_ParseTuple(args, "|i:stat", &flags))
02009 return NULL;
02010 CHECK_DB_NOT_CLOSED(self);
02011
02012 MYDB_BEGIN_ALLOW_THREADS;
02013 #if (DBVER >= 33)
02014 err = self->db->stat(self->db, &sp, flags);
02015 #else
02016 err = self->db->stat(self->db, &sp, NULL, flags);
02017 #endif
02018 MYDB_END_ALLOW_THREADS;
02019 RETURN_IF_ERR();
02020
02021 self->haveStat = 1;
02022
02023
02024 type = _DB_get_type(self);
02025 if ((type == -1) || ((d = PyDict_New()) == NULL)) {
02026 free(sp);
02027 return NULL;
02028 }
02029
02030 #define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
02031 #define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
02032 #define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
02033
02034 switch (type) {
02035 case DB_HASH:
02036 MAKE_HASH_ENTRY(magic);
02037 MAKE_HASH_ENTRY(version);
02038 MAKE_HASH_ENTRY(nkeys);
02039 MAKE_HASH_ENTRY(ndata);
02040 MAKE_HASH_ENTRY(pagesize);
02041 #if (DBVER < 41)
02042 MAKE_HASH_ENTRY(nelem);
02043 #endif
02044 MAKE_HASH_ENTRY(ffactor);
02045 MAKE_HASH_ENTRY(buckets);
02046 MAKE_HASH_ENTRY(free);
02047 MAKE_HASH_ENTRY(bfree);
02048 MAKE_HASH_ENTRY(bigpages);
02049 MAKE_HASH_ENTRY(big_bfree);
02050 MAKE_HASH_ENTRY(overflows);
02051 MAKE_HASH_ENTRY(ovfl_free);
02052 MAKE_HASH_ENTRY(dup);
02053 MAKE_HASH_ENTRY(dup_free);
02054 break;
02055
02056 case DB_BTREE:
02057 case DB_RECNO:
02058 MAKE_BT_ENTRY(magic);
02059 MAKE_BT_ENTRY(version);
02060 MAKE_BT_ENTRY(nkeys);
02061 MAKE_BT_ENTRY(ndata);
02062 MAKE_BT_ENTRY(pagesize);
02063 MAKE_BT_ENTRY(minkey);
02064 MAKE_BT_ENTRY(re_len);
02065 MAKE_BT_ENTRY(re_pad);
02066 MAKE_BT_ENTRY(levels);
02067 MAKE_BT_ENTRY(int_pg);
02068 MAKE_BT_ENTRY(leaf_pg);
02069 MAKE_BT_ENTRY(dup_pg);
02070 MAKE_BT_ENTRY(over_pg);
02071 MAKE_BT_ENTRY(free);
02072 MAKE_BT_ENTRY(int_pgfree);
02073 MAKE_BT_ENTRY(leaf_pgfree);
02074 MAKE_BT_ENTRY(dup_pgfree);
02075 MAKE_BT_ENTRY(over_pgfree);
02076 break;
02077
02078 case DB_QUEUE:
02079 MAKE_QUEUE_ENTRY(magic);
02080 MAKE_QUEUE_ENTRY(version);
02081 MAKE_QUEUE_ENTRY(nkeys);
02082 MAKE_QUEUE_ENTRY(ndata);
02083 MAKE_QUEUE_ENTRY(pagesize);
02084 MAKE_QUEUE_ENTRY(pages);
02085 MAKE_QUEUE_ENTRY(re_len);
02086 MAKE_QUEUE_ENTRY(re_pad);
02087 MAKE_QUEUE_ENTRY(pgfree);
02088 #if (DBVER == 31)
02089 MAKE_QUEUE_ENTRY(start);
02090 #endif
02091 MAKE_QUEUE_ENTRY(first_recno);
02092 MAKE_QUEUE_ENTRY(cur_recno);
02093 break;
02094
02095 default:
02096 PyErr_SetString(PyExc_TypeError, "Unknown DB type, unable to stat");
02097 Py_DECREF(d);
02098 d = NULL;
02099 }
02100
02101 #undef MAKE_HASH_ENTRY
02102 #undef MAKE_BT_ENTRY
02103 #undef MAKE_QUEUE_ENTRY
02104
02105 free(sp);
02106 return d;
02107 }
02108
02109 static PyObject*
02110 DB_sync(DBObject* self, PyObject* args)
02111 {
02112 int err;
02113 int flags = 0;
02114
02115 if (!PyArg_ParseTuple(args,"|i:sync", &flags ))
02116 return NULL;
02117 CHECK_DB_NOT_CLOSED(self);
02118
02119 MYDB_BEGIN_ALLOW_THREADS;
02120 err = self->db->sync(self->db, flags);
02121 MYDB_END_ALLOW_THREADS;
02122 RETURN_IF_ERR();
02123 RETURN_NONE();
02124 }
02125
02126
02127 #if (DBVER >= 33)
02128 static PyObject*
02129 DB_truncate(DBObject* self, PyObject* args, PyObject* kwargs)
02130 {
02131 int err, flags=0;
02132 u_int32_t count=0;
02133 PyObject* txnobj = NULL;
02134 DB_TXN *txn = NULL;
02135 char* kwnames[] = { "txn", "flags", NULL };
02136
02137 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
02138 &txnobj, &flags))
02139 return NULL;
02140 CHECK_DB_NOT_CLOSED(self);
02141 if (!checkTxnObj(txnobj, &txn))
02142 return NULL;
02143
02144 MYDB_BEGIN_ALLOW_THREADS;
02145 err = self->db->truncate(self->db, txn, &count, flags);
02146 MYDB_END_ALLOW_THREADS;
02147 RETURN_IF_ERR();
02148 return PyInt_FromLong(count);
02149 }
02150 #endif
02151
02152
02153 static PyObject*
02154 DB_upgrade(DBObject* self, PyObject* args)
02155 {
02156 int err, flags=0;
02157 char *filename;
02158
02159 if (!PyArg_ParseTuple(args,"s|i:upgrade", &filename, &flags))
02160 return NULL;
02161 CHECK_DB_NOT_CLOSED(self);
02162
02163 MYDB_BEGIN_ALLOW_THREADS;
02164 err = self->db->upgrade(self->db, filename, flags);
02165 MYDB_END_ALLOW_THREADS;
02166 RETURN_IF_ERR();
02167 RETURN_NONE();
02168 }
02169
02170
02171 static PyObject*
02172 DB_verify(DBObject* self, PyObject* args, PyObject* kwargs)
02173 {
02174 int err, flags=0;
02175 char* fileName;
02176 char* dbName=NULL;
02177 char* outFileName=NULL;
02178 FILE* outFile=NULL;
02179 char* kwnames[] = { "filename", "dbname", "outfile", "flags", NULL };
02180
02181 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zzi:verify", kwnames,
02182 &fileName, &dbName, &outFileName, &flags))
02183 return NULL;
02184
02185 CHECK_DB_NOT_CLOSED(self);
02186 if (outFileName)
02187 outFile = fopen(outFileName, "w");
02188
02189 MYDB_BEGIN_ALLOW_THREADS;
02190 err = self->db->verify(self->db, fileName, dbName, outFile, flags);
02191 MYDB_END_ALLOW_THREADS;
02192 if (outFileName)
02193 fclose(outFile);
02194
02195
02196
02197
02198
02199
02200 #if (DBVER <= 41)
02201 self->db->close(self->db, 0);
02202 #endif
02203 self->db = NULL;
02204
02205 RETURN_IF_ERR();
02206 RETURN_NONE();
02207 }
02208
02209
02210 static PyObject*
02211 DB_set_get_returns_none(DBObject* self, PyObject* args)
02212 {
02213 int flags=0;
02214 int oldValue=0;
02215
02216 if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
02217 return NULL;
02218 CHECK_DB_NOT_CLOSED(self);
02219
02220 if (self->moduleFlags.getReturnsNone)
02221 ++oldValue;
02222 if (self->moduleFlags.cursorSetReturnsNone)
02223 ++oldValue;
02224 self->moduleFlags.getReturnsNone = (flags >= 1);
02225 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
02226 return PyInt_FromLong(oldValue);
02227 }
02228
02229 #if (DBVER >= 41)
02230 static PyObject*
02231 DB_set_encrypt(DBObject* self, PyObject* args, PyObject* kwargs)
02232 {
02233 int err;
02234 u_int32_t flags=0;
02235 char *passwd = NULL;
02236 char* kwnames[] = { "passwd", "flags", NULL };
02237
02238 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
02239 &passwd, &flags)) {
02240 return NULL;
02241 }
02242
02243 MYDB_BEGIN_ALLOW_THREADS;
02244 err = self->db->set_encrypt(self->db, passwd, flags);
02245 MYDB_END_ALLOW_THREADS;
02246
02247 RETURN_IF_ERR();
02248 RETURN_NONE();
02249 }
02250 #endif
02251
02252
02253
02254
02255
02256 int DB_length(DBObject* self)
02257 {
02258 int err;
02259 long size = 0;
02260 int flags = 0;
02261 void* sp;
02262
02263 if (self->db == NULL) {
02264 PyErr_SetObject(DBError,
02265 Py_BuildValue("(is)", 0, "DB object has been closed"));
02266 return -1;
02267 }
02268
02269 if (self->haveStat) {
02270
02271 flags = DB_CACHED_COUNTS;
02272 }
02273
02274 MYDB_BEGIN_ALLOW_THREADS;
02275 #if (DBVER >= 33)
02276 err = self->db->stat(self->db, &sp, flags);
02277 #else
02278 err = self->db->stat(self->db, &sp, NULL, flags);
02279 #endif
02280 MYDB_END_ALLOW_THREADS;
02281
02282 if (err)
02283 return -1;
02284
02285 self->haveStat = 1;
02286
02287
02288
02289 size = ((DB_BTREE_STAT*)sp)->bt_ndata;
02290 free(sp);
02291 return size;
02292 }
02293
02294
02295 PyObject* DB_subscript(DBObject* self, PyObject* keyobj)
02296 {
02297 int err;
02298 PyObject* retval;
02299 DBT key;
02300 DBT data;
02301
02302 CHECK_DB_NOT_CLOSED(self);
02303 if (!make_key_dbt(self, keyobj, &key, NULL))
02304 return NULL;
02305
02306 CLEAR_DBT(data);
02307 if (CHECK_DBFLAG(self, DB_THREAD)) {
02308
02309 data.flags = DB_DBT_MALLOC;
02310 }
02311 MYDB_BEGIN_ALLOW_THREADS;
02312 err = self->db->get(self->db, NULL, &key, &data, 0);
02313 MYDB_END_ALLOW_THREADS;
02314 if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
02315 PyErr_SetObject(PyExc_KeyError, keyobj);
02316 retval = NULL;
02317 }
02318 else if (makeDBError(err)) {
02319 retval = NULL;
02320 }
02321 else {
02322 retval = PyString_FromStringAndSize((char*)data.data, data.size);
02323 FREE_DBT(data);
02324 }
02325
02326 FREE_DBT(key);
02327 return retval;
02328 }
02329
02330
02331 static int
02332 DB_ass_sub(DBObject* self, PyObject* keyobj, PyObject* dataobj)
02333 {
02334 DBT key, data;
02335 int retval;
02336 int flags = 0;
02337
02338 if (self->db == NULL) {
02339 PyErr_SetObject(DBError,
02340 Py_BuildValue("(is)", 0, "DB object has been closed"));
02341 return -1;
02342 }
02343
02344 if (!make_key_dbt(self, keyobj, &key, NULL))
02345 return -1;
02346
02347 if (dataobj != NULL) {
02348 if (!make_dbt(dataobj, &data))
02349 retval = -1;
02350 else {
02351 if (self->setflags & (DB_DUP|DB_DUPSORT))
02352
02353 flags = DB_NOOVERWRITE;
02354 retval = _DB_put(self, NULL, &key, &data, flags);
02355
02356 if ((retval == -1) && (self->setflags & (DB_DUP|DB_DUPSORT))) {
02357
02358
02359 _DB_delete(self, NULL, &key, 0);
02360 PyErr_Clear();
02361 retval = _DB_put(self, NULL, &key, &data, flags);
02362 }
02363 }
02364 }
02365 else {
02366
02367 retval = _DB_delete(self, NULL, &key, 0);
02368 }
02369 FREE_DBT(key);
02370 return retval;
02371 }
02372
02373
02374 static PyObject*
02375 DB_has_key(DBObject* self, PyObject* args)
02376 {
02377 int err;
02378 PyObject* keyobj;
02379 DBT key, data;
02380 PyObject* txnobj = NULL;
02381 DB_TXN *txn = NULL;
02382
02383 if (!PyArg_ParseTuple(args,"O|O:has_key", &keyobj, &txnobj))
02384 return NULL;
02385 CHECK_DB_NOT_CLOSED(self);
02386 if (!make_key_dbt(self, keyobj, &key, NULL))
02387 return NULL;
02388 if (!checkTxnObj(txnobj, &txn))
02389 return NULL;
02390
02391
02392
02393
02394
02395 CLEAR_DBT(data);
02396 data.flags = DB_DBT_USERMEM;
02397
02398 MYDB_BEGIN_ALLOW_THREADS;
02399 err = self->db->get(self->db, NULL, &key, &data, 0);
02400 MYDB_END_ALLOW_THREADS;
02401 FREE_DBT(key);
02402 return PyInt_FromLong((err == ENOMEM) || (err == 0));
02403 }
02404
02405
02406 #define _KEYS_LIST 1
02407 #define _VALUES_LIST 2
02408 #define _ITEMS_LIST 3
02409
02410 static PyObject*
02411 _DB_make_list(DBObject* self, DB_TXN* txn, int type)
02412 {
02413 int err, dbtype;
02414 DBT key;
02415 DBT data;
02416 DBC *cursor;
02417 PyObject* list;
02418 PyObject* item = NULL;
02419
02420 CHECK_DB_NOT_CLOSED(self);
02421 CLEAR_DBT(key);
02422 CLEAR_DBT(data);
02423
02424 dbtype = _DB_get_type(self);
02425 if (dbtype == -1)
02426 return NULL;
02427
02428 list = PyList_New(0);
02429 if (list == NULL) {
02430 PyErr_SetString(PyExc_MemoryError, "PyList_New failed");
02431 return NULL;
02432 }
02433
02434
02435 MYDB_BEGIN_ALLOW_THREADS;
02436 err = self->db->cursor(self->db, NULL, &cursor, 0);
02437 MYDB_END_ALLOW_THREADS;
02438 RETURN_IF_ERR();
02439
02440 if (CHECK_DBFLAG(self, DB_THREAD)) {
02441 key.flags = DB_DBT_REALLOC;
02442 data.flags = DB_DBT_REALLOC;
02443 }
02444
02445 while (1) {
02446 MYDB_BEGIN_ALLOW_THREADS;
02447 err = cursor->c_get(cursor, &key, &data, DB_NEXT);
02448 MYDB_END_ALLOW_THREADS;
02449
02450 if (err) {
02451
02452 break;
02453 }
02454
02455 switch (type) {
02456 case _KEYS_LIST:
02457 switch(dbtype) {
02458 case DB_BTREE:
02459 case DB_HASH:
02460 default:
02461 item = PyString_FromStringAndSize((char*)key.data, key.size);
02462 break;
02463 case DB_RECNO:
02464 case DB_QUEUE:
02465 item = PyInt_FromLong(*((db_recno_t*)key.data));
02466 break;
02467 }
02468 break;
02469
02470 case _VALUES_LIST:
02471 item = PyString_FromStringAndSize((char*)data.data, data.size);
02472 break;
02473
02474 case _ITEMS_LIST:
02475 switch(dbtype) {
02476 case DB_BTREE:
02477 case DB_HASH:
02478 default:
02479 item = Py_BuildValue("s#s#", key.data, key.size, data.data,
02480 data.size);
02481 break;
02482 case DB_RECNO:
02483 case DB_QUEUE:
02484 item = Py_BuildValue("is#", *((db_recno_t*)key.data),
02485 data.data, data.size);
02486 break;
02487 }
02488 break;
02489 }
02490 if (item == NULL) {
02491 Py_DECREF(list);
02492 PyErr_SetString(PyExc_MemoryError, "List item creation failed");
02493 list = NULL;
02494 goto done;
02495 }
02496 PyList_Append(list, item);
02497 Py_DECREF(item);
02498 }
02499
02500
02501 if (err != DB_NOTFOUND && makeDBError(err)) {
02502 Py_DECREF(list);
02503 list = NULL;
02504 }
02505
02506 done:
02507 FREE_DBT(key);
02508 FREE_DBT(data);
02509 MYDB_BEGIN_ALLOW_THREADS;
02510 cursor->c_close(cursor);
02511 MYDB_END_ALLOW_THREADS;
02512 return list;
02513 }
02514
02515
02516 static PyObject*
02517 DB_keys(DBObject* self, PyObject* args)
02518 {
02519 PyObject* txnobj = NULL;
02520 DB_TXN *txn = NULL;
02521
02522 if (!PyArg_ParseTuple(args,"|O:keys", &txnobj))
02523 return NULL;
02524 if (!checkTxnObj(txnobj, &txn))
02525 return NULL;
02526 return _DB_make_list(self, txn, _KEYS_LIST);
02527 }
02528
02529
02530 static PyObject*
02531 DB_items(DBObject* self, PyObject* args)
02532 {
02533 PyObject* txnobj = NULL;
02534 DB_TXN *txn = NULL;
02535
02536 if (!PyArg_ParseTuple(args,"|O:items", &txnobj))
02537 return NULL;
02538 if (!checkTxnObj(txnobj, &txn))
02539 return NULL;
02540 return _DB_make_list(self, txn, _ITEMS_LIST);
02541 }
02542
02543
02544 static PyObject*
02545 DB_values(DBObject* self, PyObject* args)
02546 {
02547 PyObject* txnobj = NULL;
02548 DB_TXN *txn = NULL;
02549
02550 if (!PyArg_ParseTuple(args,"|O:values", &txnobj))
02551 return NULL;
02552 if (!checkTxnObj(txnobj, &txn))
02553 return NULL;
02554 return _DB_make_list(self, txn, _VALUES_LIST);
02555 }
02556
02557
02558
02559
02560
02561 static PyObject*
02562 DBC_close(DBCursorObject* self, PyObject* args)
02563 {
02564 int err = 0;
02565
02566 if (!PyArg_ParseTuple(args, ":close"))
02567 return NULL;
02568
02569 if (self->dbc != NULL) {
02570 MYDB_BEGIN_ALLOW_THREADS;
02571 err = self->dbc->c_close(self->dbc);
02572 self->dbc = NULL;
02573 MYDB_END_ALLOW_THREADS;
02574 }
02575 RETURN_IF_ERR();
02576 RETURN_NONE();
02577 }
02578
02579
02580 static PyObject*
02581 DBC_count(DBCursorObject* self, PyObject* args)
02582 {
02583 int err = 0;
02584 db_recno_t count;
02585 int flags = 0;
02586
02587 if (!PyArg_ParseTuple(args, "|i:count", &flags))
02588 return NULL;
02589
02590 CHECK_CURSOR_NOT_CLOSED(self);
02591
02592 MYDB_BEGIN_ALLOW_THREADS;
02593 err = self->dbc->c_count(self->dbc, &count, flags);
02594 MYDB_END_ALLOW_THREADS;
02595 RETURN_IF_ERR();
02596
02597 return PyInt_FromLong(count);
02598 }
02599
02600
02601 static PyObject*
02602 DBC_current(DBCursorObject* self, PyObject* args, PyObject *kwargs)
02603 {
02604 return _DBCursor_get(self,DB_CURRENT,args,kwargs,"|iii:current");
02605 }
02606
02607
02608 static PyObject*
02609 DBC_delete(DBCursorObject* self, PyObject* args)
02610 {
02611 int err, flags=0;
02612
02613 if (!PyArg_ParseTuple(args, "|i:delete", &flags))
02614 return NULL;
02615
02616 CHECK_CURSOR_NOT_CLOSED(self);
02617
02618 MYDB_BEGIN_ALLOW_THREADS;
02619 err = self->dbc->c_del(self->dbc, flags);
02620 MYDB_END_ALLOW_THREADS;
02621 RETURN_IF_ERR();
02622
02623 self->mydb->haveStat = 0;
02624 RETURN_NONE();
02625 }
02626
02627
02628 static PyObject*
02629 DBC_dup(DBCursorObject* self, PyObject* args)
02630 {
02631 int err, flags =0;
02632 DBC* dbc = NULL;
02633
02634 if (!PyArg_ParseTuple(args, "|i:dup", &flags))
02635 return NULL;
02636
02637 CHECK_CURSOR_NOT_CLOSED(self);
02638
02639 MYDB_BEGIN_ALLOW_THREADS;
02640 err = self->dbc->c_dup(self->dbc, &dbc, flags);
02641 MYDB_END_ALLOW_THREADS;
02642 RETURN_IF_ERR();
02643
02644 return (PyObject*) newDBCursorObject(dbc, self->mydb);
02645 }
02646
02647 static PyObject*
02648 DBC_first(DBCursorObject* self, PyObject* args, PyObject* kwargs)
02649 {
02650 return _DBCursor_get(self,DB_FIRST,args,kwargs,"|iii:first");
02651 }
02652
02653
02654 static PyObject*
02655 DBC_get(DBCursorObject* self, PyObject* args, PyObject *kwargs)
02656 {
02657 int err, flags=0;
02658 PyObject* keyobj = NULL;
02659 PyObject* dataobj = NULL;
02660 PyObject* retval = NULL;
02661 int dlen = -1;
02662 int doff = -1;
02663 DBT key, data;
02664 char* kwnames[] = { "key","data", "flags", "dlen", "doff", NULL };
02665
02666 CLEAR_DBT(key);
02667 CLEAR_DBT(data);
02668 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:get", &kwnames[2],
02669 &flags, &dlen, &doff))
02670 {
02671 PyErr_Clear();
02672 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:get",
02673 &kwnames[1],
02674 &keyobj, &flags, &dlen, &doff))
02675 {
02676 PyErr_Clear();
02677 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:get",
02678 kwnames, &keyobj, &dataobj,
02679 &flags, &dlen, &doff))
02680 {
02681 return NULL;
02682 }
02683 }
02684 }
02685
02686 CHECK_CURSOR_NOT_CLOSED(self);
02687
02688 if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
02689 return NULL;
02690 if (dataobj && !make_dbt(dataobj, &data))
02691 return NULL;
02692 if (!add_partial_dbt(&data, dlen, doff))
02693 return NULL;
02694
02695 if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
02696 data.flags = DB_DBT_MALLOC;
02697 key.flags = DB_DBT_MALLOC;
02698 }
02699
02700 MYDB_BEGIN_ALLOW_THREADS;
02701 err = self->dbc->c_get(self->dbc, &key, &data, flags);
02702 MYDB_END_ALLOW_THREADS;
02703
02704
02705 if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.getReturnsNone) {
02706 Py_INCREF(Py_None);
02707 retval = Py_None;
02708 }
02709 else if (makeDBError(err)) {
02710 retval = NULL;
02711 }
02712 else {
02713 switch (_DB_get_type(self->mydb)) {
02714 case -1:
02715 retval = NULL;
02716 break;
02717 case DB_BTREE:
02718 case DB_HASH:
02719 default:
02720 retval = Py_BuildValue("s#s#", key.data, key.size,
02721 data.data, data.size);
02722 break;
02723 case DB_RECNO:
02724 case DB_QUEUE:
02725 retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
02726 data.data, data.size);
02727 break;
02728 }
02729 FREE_DBT(key);
02730 FREE_DBT(data);
02731 }
02732 return retval;
02733 }
02734
02735
02736 static PyObject*
02737 DBC_get_recno(DBCursorObject* self, PyObject* args)
02738 {
02739 int err;
02740 db_recno_t recno;
02741 DBT key;
02742 DBT data;
02743
02744 if (!PyArg_ParseTuple(args, ":get_recno"))
02745 return NULL;
02746
02747 CHECK_CURSOR_NOT_CLOSED(self);
02748
02749 CLEAR_DBT(key);
02750 CLEAR_DBT(data);
02751 if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
02752
02753 data.flags = DB_DBT_MALLOC;
02754 key.flags = DB_DBT_MALLOC;
02755 }
02756
02757 MYDB_BEGIN_ALLOW_THREADS;
02758 err = self->dbc->c_get(self->dbc, &key, &data, DB_GET_RECNO);
02759 MYDB_END_ALLOW_THREADS;
02760 RETURN_IF_ERR();
02761
02762 recno = *((db_recno_t*)data.data);
02763 FREE_DBT(key);
02764 FREE_DBT(data);
02765 return PyInt_FromLong(recno);
02766 }
02767
02768
02769 static PyObject*
02770 DBC_last(DBCursorObject* self, PyObject* args, PyObject *kwargs)
02771 {
02772 return _DBCursor_get(self,DB_LAST,args,kwargs,"|iii:last");
02773 }
02774
02775
02776 static PyObject*
02777 DBC_next(DBCursorObject* self, PyObject* args, PyObject *kwargs)
02778 {
02779 return _DBCursor_get(self,DB_NEXT,args,kwargs,"|iii:next");
02780 }
02781
02782
02783 static PyObject*
02784 DBC_prev(DBCursorObject* self, PyObject* args, PyObject *kwargs)
02785 {
02786 return _DBCursor_get(self,DB_PREV,args,kwargs,"|iii:prev");
02787 }
02788
02789
02790 static PyObject*
02791 DBC_put(DBCursorObject* self, PyObject* args, PyObject* kwargs)
02792 {
02793 int err, flags = 0;
02794 PyObject* keyobj, *dataobj;
02795 DBT key, data;
02796 char* kwnames[] = { "key", "data", "flags", "dlen", "doff", NULL };
02797 int dlen = -1;
02798 int doff = -1;
02799
02800 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iii:put", kwnames,
02801 &keyobj, &dataobj, &flags, &dlen, &doff))
02802 return NULL;
02803
02804 CHECK_CURSOR_NOT_CLOSED(self);
02805
02806 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
02807 return NULL;
02808 if (!make_dbt(dataobj, &data))
02809 return NULL;
02810 if (!add_partial_dbt(&data, dlen, doff)) return NULL;
02811
02812 MYDB_BEGIN_ALLOW_THREADS;
02813 err = self->dbc->c_put(self->dbc, &key, &data, flags);
02814 MYDB_END_ALLOW_THREADS;
02815 FREE_DBT(key);
02816 RETURN_IF_ERR();
02817 self->mydb->haveStat = 0;
02818 RETURN_NONE();
02819 }
02820
02821
02822 static PyObject*
02823 DBC_set(DBCursorObject* self, PyObject* args, PyObject *kwargs)
02824 {
02825 int err, flags = 0;
02826 DBT key, data;
02827 PyObject* retval, *keyobj;
02828 char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
02829 int dlen = -1;
02830 int doff = -1;
02831
02832 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set", kwnames,
02833 &keyobj, &flags, &dlen, &doff))
02834 return NULL;
02835
02836 CHECK_CURSOR_NOT_CLOSED(self);
02837
02838 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
02839 return NULL;
02840
02841 CLEAR_DBT(data);
02842 if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
02843
02844 data.flags = DB_DBT_MALLOC;
02845 }
02846 if (!add_partial_dbt(&data, dlen, doff))
02847 return NULL;
02848
02849 MYDB_BEGIN_ALLOW_THREADS;
02850 err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET);
02851 MYDB_END_ALLOW_THREADS;
02852 if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.cursorSetReturnsNone) {
02853 Py_INCREF(Py_None);
02854 retval = Py_None;
02855 }
02856 else if (makeDBError(err)) {
02857 retval = NULL;
02858 }
02859 else {
02860 switch (_DB_get_type(self->mydb)) {
02861 case -1:
02862 retval = NULL;
02863 break;
02864 case DB_BTREE:
02865 case DB_HASH:
02866 default:
02867 retval = Py_BuildValue("s#s#", key.data, key.size,
02868 data.data, data.size);
02869 break;
02870 case DB_RECNO:
02871 case DB_QUEUE:
02872 retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
02873 data.data, data.size);
02874 break;
02875 }
02876 FREE_DBT(key);
02877 FREE_DBT(data);
02878 }
02879
02880 return retval;
02881 }
02882
02883
02884 static PyObject*
02885 DBC_set_range(DBCursorObject* self, PyObject* args, PyObject* kwargs)
02886 {
02887 int err, flags = 0;
02888 DBT key, data;
02889 PyObject* retval, *keyobj;
02890 char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
02891 int dlen = -1;
02892 int doff = -1;
02893
02894 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set_range", kwnames,
02895 &keyobj, &flags, &dlen, &doff))
02896 return NULL;
02897
02898 CHECK_CURSOR_NOT_CLOSED(self);
02899
02900 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
02901 return NULL;
02902
02903 CLEAR_DBT(data);
02904 if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
02905
02906 data.flags = DB_DBT_MALLOC;
02907 key.flags = DB_DBT_MALLOC;
02908 }
02909 if (!add_partial_dbt(&data, dlen, doff))
02910 return NULL;
02911 MYDB_BEGIN_ALLOW_THREADS;
02912 err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET_RANGE);
02913 MYDB_END_ALLOW_THREADS;
02914 if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.cursorSetReturnsNone) {
02915 Py_INCREF(Py_None);
02916 retval = Py_None;
02917 }
02918 else if (makeDBError(err)) {
02919 retval = NULL;
02920 }
02921 else {
02922 switch (_DB_get_type(self->mydb)) {
02923 case -1:
02924 retval = NULL;
02925 break;
02926 case DB_BTREE:
02927 case DB_HASH:
02928 default:
02929 retval = Py_BuildValue("s#s#", key.data, key.size,
02930 data.data, data.size);
02931 break;
02932 case DB_RECNO:
02933 case DB_QUEUE:
02934 retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
02935 data.data, data.size);
02936 break;
02937 }
02938 FREE_DBT(key);
02939 FREE_DBT(data);
02940 }
02941
02942 return retval;
02943 }
02944
02945 static PyObject*
02946 _DBC_get_set_both(DBCursorObject* self, PyObject* keyobj, PyObject* dataobj,
02947 int flags, unsigned int returnsNone)
02948 {
02949 int err;
02950 DBT key, data;
02951 PyObject* retval;
02952
02953
02954 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
02955 return NULL;
02956 if (!make_dbt(dataobj, &data))
02957 return NULL;
02958
02959 MYDB_BEGIN_ALLOW_THREADS;
02960 err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_GET_BOTH);
02961 MYDB_END_ALLOW_THREADS;
02962 if ((err == DB_NOTFOUND) && returnsNone) {
02963 Py_INCREF(Py_None);
02964 retval = Py_None;
02965 }
02966 else if (makeDBError(err)) {
02967 retval = NULL;
02968 }
02969 else {
02970 switch (_DB_get_type(self->mydb)) {
02971 case -1:
02972 retval = NULL;
02973 break;
02974 case DB_BTREE:
02975 case DB_HASH:
02976 default:
02977 retval = Py_BuildValue("s#s#", key.data, key.size,
02978 data.data, data.size);
02979 break;
02980 case DB_RECNO:
02981 case DB_QUEUE:
02982 retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
02983 data.data, data.size);
02984 break;
02985 }
02986 }
02987
02988 FREE_DBT(key);
02989 return retval;
02990 }
02991
02992 static PyObject*
02993 DBC_get_both(DBCursorObject* self, PyObject* args)
02994 {
02995 int flags=0;
02996 PyObject *keyobj, *dataobj;
02997
02998 if (!PyArg_ParseTuple(args, "OO|i:get_both", &keyobj, &dataobj, &flags))
02999 return NULL;
03000
03001
03002 CHECK_CURSOR_NOT_CLOSED(self);
03003
03004 return _DBC_get_set_both(self, keyobj, dataobj, flags,
03005 self->mydb->moduleFlags.getReturnsNone);
03006 }
03007
03008
03009 static PyObject*
03010 DBC_get_current_size(DBCursorObject* self, PyObject* args)
03011 {
03012 int err, flags=DB_CURRENT;
03013 PyObject* retval = NULL;
03014 DBT key, data;
03015
03016 if (!PyArg_ParseTuple(args, ":get_current_size"))
03017 return NULL;
03018 CHECK_CURSOR_NOT_CLOSED(self);
03019 CLEAR_DBT(key);
03020 CLEAR_DBT(data);
03021
03022
03023
03024 data.flags = DB_DBT_USERMEM;
03025 data.ulen = 0;
03026 MYDB_BEGIN_ALLOW_THREADS;
03027 err = self->dbc->c_get(self->dbc, &key, &data, flags);
03028 MYDB_END_ALLOW_THREADS;
03029 if (err == ENOMEM || !err) {
03030
03031 retval = PyInt_FromLong((long)data.size);
03032 err = 0;
03033 }
03034
03035 FREE_DBT(key);
03036 FREE_DBT(data);
03037 RETURN_IF_ERR();
03038 return retval;
03039 }
03040
03041 static PyObject*
03042 DBC_set_both(DBCursorObject* self, PyObject* args)
03043 {
03044 int flags=0;
03045 PyObject *keyobj, *dataobj;
03046
03047 if (!PyArg_ParseTuple(args, "OO|i:set_both", &keyobj, &dataobj, &flags))
03048 return NULL;
03049
03050
03051 CHECK_CURSOR_NOT_CLOSED(self);
03052
03053 return _DBC_get_set_both(self, keyobj, dataobj, flags,
03054 self->mydb->moduleFlags.cursorSetReturnsNone);
03055 }
03056
03057
03058 static PyObject*
03059 DBC_set_recno(DBCursorObject* self, PyObject* args, PyObject *kwargs)
03060 {
03061 int err, irecno, flags=0;
03062 db_recno_t recno;
03063 DBT key, data;
03064 PyObject* retval;
03065 int dlen = -1;
03066 int doff = -1;
03067 char* kwnames[] = { "recno","flags", "dlen", "doff", NULL };
03068
03069 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|iii:set_recno", kwnames,
03070 &irecno, &flags, &dlen, &doff))
03071 return NULL;
03072
03073 CHECK_CURSOR_NOT_CLOSED(self);
03074
03075 CLEAR_DBT(key);
03076 recno = (db_recno_t) irecno;
03077
03078
03079 key.data = malloc(sizeof(db_recno_t));
03080 if (key.data == NULL) {
03081 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
03082 return NULL;
03083 }
03084 key.size = sizeof(db_recno_t);
03085 key.ulen = key.size;
03086 memcpy(key.data, &recno, sizeof(db_recno_t));
03087 key.flags = DB_DBT_REALLOC;
03088
03089 CLEAR_DBT(data);
03090 if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
03091
03092 data.flags = DB_DBT_MALLOC;
03093 }
03094 if (!add_partial_dbt(&data, dlen, doff))
03095 return NULL;
03096
03097 MYDB_BEGIN_ALLOW_THREADS;
03098 err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET_RECNO);
03099 MYDB_END_ALLOW_THREADS;
03100 if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.cursorSetReturnsNone) {
03101 Py_INCREF(Py_None);
03102 retval = Py_None;
03103 }
03104 else if (makeDBError(err)) {
03105 retval = NULL;
03106 }
03107 else {
03108 retval = Py_BuildValue("s#s#", key.data, key.size,
03109 data.data, data.size);
03110 FREE_DBT(key);
03111 FREE_DBT(data);
03112 }
03113
03114 return retval;
03115 }
03116
03117
03118 static PyObject*
03119 DBC_consume(DBCursorObject* self, PyObject* args, PyObject *kwargs)
03120 {
03121 return _DBCursor_get(self,DB_CONSUME,args,kwargs,"|iii:consume");
03122 }
03123
03124
03125 static PyObject*
03126 DBC_next_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
03127 {
03128 return _DBCursor_get(self,DB_NEXT_DUP,args,kwargs,"|iii:next_dup");
03129 }
03130
03131
03132 static PyObject*
03133 DBC_next_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
03134 {
03135 return _DBCursor_get(self,DB_NEXT_NODUP,args,kwargs,"|iii:next_nodup");
03136 }
03137
03138
03139 static PyObject*
03140 DBC_prev_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
03141 {
03142 return _DBCursor_get(self,DB_PREV_NODUP,args,kwargs,"|iii:prev_nodup");
03143 }
03144
03145
03146 static PyObject*
03147 DBC_join_item(DBCursorObject* self, PyObject* args)
03148 {
03149 int err, flags=0;
03150 DBT key, data;
03151 PyObject* retval;
03152
03153 if (!PyArg_ParseTuple(args, "|i:join_item", &flags))
03154 return NULL;
03155
03156 CHECK_CURSOR_NOT_CLOSED(self);
03157
03158 CLEAR_DBT(key);
03159 CLEAR_DBT(data);
03160 if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
03161
03162 key.flags = DB_DBT_MALLOC;
03163 }
03164
03165 MYDB_BEGIN_ALLOW_THREADS;
03166 err = self->dbc->c_get(self->dbc, &key, &data, flags | DB_JOIN_ITEM);
03167 MYDB_END_ALLOW_THREADS;
03168 if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.getReturnsNone) {
03169 Py_INCREF(Py_None);
03170 retval = Py_None;
03171 }
03172 else if (makeDBError(err)) {
03173 retval = NULL;
03174 }
03175 else {
03176 retval = Py_BuildValue("s#", key.data, key.size);
03177 FREE_DBT(key);
03178 }
03179
03180 return retval;
03181 }
03182
03183
03184
03185
03186
03187
03188
03189 static PyObject*
03190 DBEnv_close(DBEnvObject* self, PyObject* args)
03191 {
03192 int err, flags = 0;
03193
03194 if (!PyArg_ParseTuple(args, "|i:close", &flags))
03195 return NULL;
03196 if (!self->closed) {
03197 MYDB_BEGIN_ALLOW_THREADS;
03198 err = self->db_env->close(self->db_env, flags);
03199 MYDB_END_ALLOW_THREADS;
03200
03201
03202 self->closed = 1;
03203 self->db_env = NULL;
03204 RETURN_IF_ERR();
03205 }
03206 RETURN_NONE();
03207 }
03208
03209
03210 static PyObject*
03211 DBEnv_open(DBEnvObject* self, PyObject* args)
03212 {
03213 int err, flags=0, mode=0660;
03214 char *db_home;
03215
03216 if (!PyArg_ParseTuple(args, "z|ii:open", &db_home, &flags, &mode))
03217 return NULL;
03218
03219 CHECK_ENV_NOT_CLOSED(self);
03220
03221 MYDB_BEGIN_ALLOW_THREADS;
03222 err = self->db_env->open(self->db_env, db_home, flags, mode);
03223 MYDB_END_ALLOW_THREADS;
03224 RETURN_IF_ERR();
03225 self->closed = 0;
03226 self->flags = flags;
03227 RETURN_NONE();
03228 }
03229
03230
03231 static PyObject*
03232 DBEnv_remove(DBEnvObject* self, PyObject* args)
03233 {
03234 int err, flags=0;
03235 char *db_home;
03236
03237 if (!PyArg_ParseTuple(args, "s|i:remove", &db_home, &flags))
03238 return NULL;
03239 CHECK_ENV_NOT_CLOSED(self);
03240 MYDB_BEGIN_ALLOW_THREADS;
03241 err = self->db_env->remove(self->db_env, db_home, flags);
03242 MYDB_END_ALLOW_THREADS;
03243 RETURN_IF_ERR();
03244 RETURN_NONE();
03245 }
03246
03247 #if (DBVER >= 41)
03248 static PyObject*
03249 DBEnv_dbremove(DBEnvObject* self, PyObject* args, PyObject* kwargs)
03250 {
03251 int err;
03252 u_int32_t flags=0;
03253 char *file = NULL;
03254 char *database = NULL;
03255 PyObject *txnobj = NULL;
03256 DB_TXN *txn = NULL;
03257 char* kwnames[] = { "file", "database", "txn", "flags", NULL };
03258
03259 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss|Oi:dbremove", kwnames,
03260 &file, &database, &txnobj, &flags)) {
03261 return NULL;
03262 }
03263 if (!checkTxnObj(txnobj, &txn)) {
03264 return NULL;
03265 }
03266 CHECK_ENV_NOT_CLOSED(self);
03267 MYDB_BEGIN_ALLOW_THREADS;
03268 err = self->db_env->dbremove(self->db_env, txn, file, database, flags);
03269 MYDB_END_ALLOW_THREADS;
03270 RETURN_IF_ERR();
03271 RETURN_NONE();
03272 }
03273
03274 static PyObject*
03275 DBEnv_dbrename(DBEnvObject* self, PyObject* args, PyObject* kwargs)
03276 {
03277 int err;
03278 u_int32_t flags=0;
03279 char *file = NULL;
03280 char *database = NULL;
03281 char *newname = NULL;
03282 PyObject *txnobj = NULL;
03283 DB_TXN *txn = NULL;
03284 char* kwnames[] = { "file", "database", "newname", "txn", "flags", NULL };
03285
03286 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sss|Oi:dbrename", kwnames,
03287 &file, &database, &newname, &txnobj, &flags)) {
03288 return NULL;
03289 }
03290 if (!checkTxnObj(txnobj, &txn)) {
03291 return NULL;
03292 }
03293 CHECK_ENV_NOT_CLOSED(self);
03294 MYDB_BEGIN_ALLOW_THREADS;
03295 err = self->db_env->dbrename(self->db_env, txn, file, database, newname,
03296 flags);
03297 MYDB_END_ALLOW_THREADS;
03298 RETURN_IF_ERR();
03299 RETURN_NONE();
03300 }
03301
03302 static PyObject*
03303 DBEnv_set_encrypt(DBEnvObject* self, PyObject* args, PyObject* kwargs)
03304 {
03305 int err;
03306 u_int32_t flags=0;
03307 char *passwd = NULL;
03308 char* kwnames[] = { "passwd", "flags", NULL };
03309
03310 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
03311 &passwd, &flags)) {
03312 return NULL;
03313 }
03314
03315 MYDB_BEGIN_ALLOW_THREADS;
03316 err = self->db_env->set_encrypt(self->db_env, passwd, flags);
03317 MYDB_END_ALLOW_THREADS;
03318
03319 RETURN_IF_ERR();
03320 RETURN_NONE();
03321 }
03322 #endif
03323
03324 #if (DBVER >= 40)
03325 static PyObject*
03326 DBEnv_set_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
03327 {
03328 int err;
03329 u_int32_t flags=0;
03330 u_int32_t timeout = 0;
03331 char* kwnames[] = { "timeout", "flags", NULL };
03332
03333 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
03334 &timeout, &flags)) {
03335 return NULL;
03336 }
03337
03338 MYDB_BEGIN_ALLOW_THREADS;
03339 err = self->db_env->set_timeout(self->db_env, (db_timeout_t)timeout, flags);
03340 MYDB_END_ALLOW_THREADS;
03341
03342 RETURN_IF_ERR();
03343 RETURN_NONE();
03344 }
03345 #endif
03346
03347 static PyObject*
03348 DBEnv_set_shm_key(DBEnvObject* self, PyObject* args)
03349 {
03350 int err;
03351 long shm_key = 0;
03352
03353 if (!PyArg_ParseTuple(args, "l:set_shm_key", &shm_key))
03354 return NULL;
03355 CHECK_ENV_NOT_CLOSED(self);
03356
03357 err = self->db_env->set_shm_key(self->db_env, shm_key);
03358 RETURN_IF_ERR();
03359 RETURN_NONE();
03360 }
03361
03362 static PyObject*
03363 DBEnv_set_cachesize(DBEnvObject* self, PyObject* args)
03364 {
03365 int err, gbytes=0, bytes=0, ncache=0;
03366
03367 if (!PyArg_ParseTuple(args, "ii|i:set_cachesize",
03368 &gbytes, &bytes, &ncache))
03369 return NULL;
03370 CHECK_ENV_NOT_CLOSED(self);
03371
03372 MYDB_BEGIN_ALLOW_THREADS;
03373 err = self->db_env->set_cachesize(self->db_env, gbytes, bytes, ncache);
03374 MYDB_END_ALLOW_THREADS;
03375 RETURN_IF_ERR();
03376 RETURN_NONE();
03377 }
03378
03379
03380 #if (DBVER >= 32)
03381 static PyObject*
03382 DBEnv_set_flags(DBEnvObject* self, PyObject* args)
03383 {
03384 int err, flags=0, onoff=0;
03385
03386 if (!PyArg_ParseTuple(args, "ii:set_flags",
03387 &flags, &onoff))
03388 return NULL;
03389 CHECK_ENV_NOT_CLOSED(self);
03390
03391 MYDB_BEGIN_ALLOW_THREADS;
03392 err = self->db_env->set_flags(self->db_env, flags, onoff);
03393 MYDB_END_ALLOW_THREADS;
03394 RETURN_IF_ERR();
03395 RETURN_NONE();
03396 }
03397 #endif
03398
03399
03400 static PyObject*
03401 DBEnv_set_data_dir(DBEnvObject* self, PyObject* args)
03402 {
03403 int err;
03404 char *dir;
03405
03406 if (!PyArg_ParseTuple(args, "s:set_data_dir", &dir))
03407 return NULL;
03408 CHECK_ENV_NOT_CLOSED(self);
03409
03410 MYDB_BEGIN_ALLOW_THREADS;
03411 err = self->db_env->set_data_dir(self->db_env, dir);
03412 MYDB_END_ALLOW_THREADS;
03413 RETURN_IF_ERR();
03414 RETURN_NONE();
03415 }
03416
03417
03418 static PyObject*
03419 DBEnv_set_lg_bsize(DBEnvObject* self, PyObject* args)
03420 {
03421 int err, lg_bsize;
03422
03423 if (!PyArg_ParseTuple(args, "i:set_lg_bsize", &lg_bsize))
03424 return NULL;
03425 CHECK_ENV_NOT_CLOSED(self);
03426
03427 MYDB_BEGIN_ALLOW_THREADS;
03428 err = self->db_env->set_lg_bsize(self->db_env, lg_bsize);
03429 MYDB_END_ALLOW_THREADS;
03430 RETURN_IF_ERR();
03431 RETURN_NONE();
03432 }
03433
03434
03435 static PyObject*
03436 DBEnv_set_lg_dir(DBEnvObject* self, PyObject* args)
03437 {
03438 int err;
03439 char *dir;
03440
03441 if (!PyArg_ParseTuple(args, "s:set_lg_dir", &dir))
03442 return NULL;
03443 CHECK_ENV_NOT_CLOSED(self);
03444
03445 MYDB_BEGIN_ALLOW_THREADS;
03446 err = self->db_env->set_lg_dir(self->db_env, dir);
03447 MYDB_END_ALLOW_THREADS;
03448 RETURN_IF_ERR();
03449 RETURN_NONE();
03450 }
03451
03452 static PyObject*
03453 DBEnv_set_lg_max(DBEnvObject* self, PyObject* args)
03454 {
03455 int err, lg_max;
03456
03457 if (!PyArg_ParseTuple(args, "i:set_lg_max", &lg_max))
03458 return NULL;
03459 CHECK_ENV_NOT_CLOSED(self);
03460
03461 MYDB_BEGIN_ALLOW_THREADS;
03462 err = self->db_env->set_lg_max(self->db_env, lg_max);
03463 MYDB_END_ALLOW_THREADS;
03464 RETURN_IF_ERR();
03465 RETURN_NONE();
03466 }
03467
03468
03469 static PyObject*
03470 DBEnv_set_lk_detect(DBEnvObject* self, PyObject* args)
03471 {
03472 int err, lk_detect;
03473
03474 if (!PyArg_ParseTuple(args, "i:set_lk_detect", &lk_detect))
03475 return NULL;
03476 CHECK_ENV_NOT_CLOSED(self);
03477
03478 MYDB_BEGIN_ALLOW_THREADS;
03479 err = self->db_env->set_lk_detect(self->db_env, lk_detect);
03480 MYDB_END_ALLOW_THREADS;
03481 RETURN_IF_ERR();
03482 RETURN_NONE();
03483 }
03484
03485
03486 static PyObject*
03487 DBEnv_set_lk_max(DBEnvObject* self, PyObject* args)
03488 {
03489 int err, max;
03490
03491 if (!PyArg_ParseTuple(args, "i:set_lk_max", &max))
03492 return NULL;
03493 CHECK_ENV_NOT_CLOSED(self);
03494
03495 MYDB_BEGIN_ALLOW_THREADS;
03496 err = self->db_env->set_lk_max(self->db_env, max);
03497 MYDB_END_ALLOW_THREADS;
03498 RETURN_IF_ERR();
03499 RETURN_NONE();
03500 }
03501
03502
03503 #if (DBVER >= 32)
03504
03505 static PyObject*
03506 DBEnv_set_lk_max_locks(DBEnvObject* self, PyObject* args)
03507 {
03508 int err, max;
03509
03510 if (!PyArg_ParseTuple(args, "i:set_lk_max_locks", &max))
03511 return NULL;
03512 CHECK_ENV_NOT_CLOSED(self);
03513
03514 MYDB_BEGIN_ALLOW_THREADS;
03515 err = self->db_env->set_lk_max_locks(self->db_env, max);
03516 MYDB_END_ALLOW_THREADS;
03517 RETURN_IF_ERR();
03518 RETURN_NONE();
03519 }
03520
03521
03522 static PyObject*
03523 DBEnv_set_lk_max_lockers(DBEnvObject* self, PyObject* args)
03524 {
03525 int err, max;
03526
03527 if (!PyArg_ParseTuple(args, "i:set_lk_max_lockers", &max))
03528 return NULL;
03529 CHECK_ENV_NOT_CLOSED(self);
03530
03531 MYDB_BEGIN_ALLOW_THREADS;
03532 err = self->db_env->set_lk_max_lockers(self->db_env, max);
03533 MYDB_END_ALLOW_THREADS;
03534 RETURN_IF_ERR();
03535 RETURN_NONE();
03536 }
03537
03538
03539 static PyObject*
03540 DBEnv_set_lk_max_objects(DBEnvObject* self, PyObject* args)
03541 {
03542 int err, max;
03543
03544 if (!PyArg_ParseTuple(args, "i:set_lk_max_objects", &max))
03545 return NULL;
03546 CHECK_ENV_NOT_CLOSED(self);
03547
03548 MYDB_BEGIN_ALLOW_THREADS;
03549 err = self->db_env->set_lk_max_objects(self->db_env, max);
03550 MYDB_END_ALLOW_THREADS;
03551 RETURN_IF_ERR();
03552 RETURN_NONE();
03553 }
03554
03555 #endif
03556
03557
03558 static PyObject*
03559 DBEnv_set_mp_mmapsize(DBEnvObject* self, PyObject* args)
03560 {
03561 int err, mp_mmapsize;
03562
03563 if (!PyArg_ParseTuple(args, "i:set_mp_mmapsize", &mp_mmapsize))
03564 return NULL;
03565 CHECK_ENV_NOT_CLOSED(self);
03566
03567 MYDB_BEGIN_ALLOW_THREADS;
03568 err = self->db_env->set_mp_mmapsize(self->db_env, mp_mmapsize);
03569 MYDB_END_ALLOW_THREADS;
03570 RETURN_IF_ERR();
03571 RETURN_NONE();
03572 }
03573
03574
03575 static PyObject*
03576 DBEnv_set_tmp_dir(DBEnvObject* self, PyObject* args)
03577 {
03578 int err;
03579 char *dir;
03580
03581 if (!PyArg_ParseTuple(args, "s:set_tmp_dir", &dir))
03582 return NULL;
03583 CHECK_ENV_NOT_CLOSED(self);
03584
03585 MYDB_BEGIN_ALLOW_THREADS;
03586 err = self->db_env->set_tmp_dir(self->db_env, dir);
03587 MYDB_END_ALLOW_THREADS;
03588 RETURN_IF_ERR();
03589 RETURN_NONE();
03590 }
03591
03592
03593 static PyObject*
03594 DBEnv_txn_begin(DBEnvObject* self, PyObject* args, PyObject* kwargs)
03595 {
03596 int flags = 0;
03597 PyObject* txnobj = NULL;
03598 DB_TXN *txn = NULL;
03599 char* kwnames[] = { "parent", "flags", NULL };
03600
03601 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:txn_begin", kwnames,
03602 &txnobj, &flags))
03603 return NULL;
03604
03605 if (!checkTxnObj(txnobj, &txn))
03606 return NULL;
03607 CHECK_ENV_NOT_CLOSED(self);
03608
03609 return (PyObject*)newDBTxnObject(self, txn, flags);
03610 }
03611
03612
03613 static PyObject*
03614 DBEnv_txn_checkpoint(DBEnvObject* self, PyObject* args)
03615 {
03616 int err, kbyte=0, min=0, flags=0;
03617
03618 if (!PyArg_ParseTuple(args, "|iii:txn_checkpoint", &kbyte, &min, &flags))
03619 return NULL;
03620 CHECK_ENV_NOT_CLOSED(self);
03621
03622 MYDB_BEGIN_ALLOW_THREADS;
03623 #if (DBVER >= 40)
03624 err = self->db_env->txn_checkpoint(self->db_env, kbyte, min, flags);
03625 #else
03626 err = txn_checkpoint(self->db_env, kbyte, min, flags);
03627 #endif
03628 MYDB_END_ALLOW_THREADS;
03629 RETURN_IF_ERR();
03630 RETURN_NONE();
03631 }
03632
03633
03634 static PyObject*
03635 DBEnv_set_tx_max(DBEnvObject* self, PyObject* args)
03636 {
03637 int err, max;
03638
03639 if (!PyArg_ParseTuple(args, "i:set_tx_max", &max))
03640 return NULL;
03641 CHECK_ENV_NOT_CLOSED(self);
03642
03643 MYDB_BEGIN_ALLOW_THREADS;
03644 err = self->db_env->set_tx_max(self->db_env, max);
03645 MYDB_END_ALLOW_THREADS;
03646 RETURN_IF_ERR();
03647 RETURN_NONE();
03648 }
03649
03650
03651 static PyObject*
03652 DBEnv_lock_detect(DBEnvObject* self, PyObject* args)
03653 {
03654 int err, atype, flags=0;
03655 int aborted = 0;
03656
03657 if (!PyArg_ParseTuple(args, "i|i:lock_detect", &atype, &flags))
03658 return NULL;
03659 CHECK_ENV_NOT_CLOSED(self);
03660
03661 MYDB_BEGIN_ALLOW_THREADS;
03662 #if (DBVER >= 40)
03663 err = self->db_env->lock_detect(self->db_env, flags, atype, &aborted);
03664 #else
03665 err = lock_detect(self->db_env, flags, atype, &aborted);
03666 #endif
03667 MYDB_END_ALLOW_THREADS;
03668 RETURN_IF_ERR();
03669 return PyInt_FromLong(aborted);
03670 }
03671
03672
03673 static PyObject*
03674 DBEnv_lock_get(DBEnvObject* self, PyObject* args)
03675 {
03676 int flags=0;
03677 int locker, lock_mode;
03678 DBT obj;
03679 PyObject* objobj;
03680
03681 if (!PyArg_ParseTuple(args, "iOi|i:lock_get", &locker, &objobj, &lock_mode, &flags))
03682 return NULL;
03683
03684
03685 if (!make_dbt(objobj, &obj))
03686 return NULL;
03687
03688 return (PyObject*)newDBLockObject(self, locker, &obj, lock_mode, flags);
03689 }
03690
03691
03692 static PyObject*
03693 DBEnv_lock_id(DBEnvObject* self, PyObject* args)
03694 {
03695 int err;
03696 u_int32_t theID;
03697
03698 if (!PyArg_ParseTuple(args, ":lock_id"))
03699 return NULL;
03700
03701 CHECK_ENV_NOT_CLOSED(self);
03702 MYDB_BEGIN_ALLOW_THREADS;
03703 #if (DBVER >= 40)
03704 err = self->db_env->lock_id(self->db_env, &theID);
03705 #else
03706 err = lock_id(self->db_env, &theID);
03707 #endif
03708 MYDB_END_ALLOW_THREADS;
03709 RETURN_IF_ERR();
03710
03711 return PyInt_FromLong((long)theID);
03712 }
03713
03714
03715 static PyObject*
03716 DBEnv_lock_put(DBEnvObject* self, PyObject* args)
03717 {
03718 int err;
03719 DBLockObject* dblockobj;
03720
03721 if (!PyArg_ParseTuple(args, "O!:lock_put", &DBLock_Type, &dblockobj))
03722 return NULL;
03723
03724 CHECK_ENV_NOT_CLOSED(self);
03725 MYDB_BEGIN_ALLOW_THREADS;
03726 #if (DBVER >= 40)
03727 err = self->db_env->lock_put(self->db_env, &dblockobj->lock);
03728 #else
03729 err = lock_put(self->db_env, &dblockobj->lock);
03730 #endif
03731 MYDB_END_ALLOW_THREADS;
03732 RETURN_IF_ERR();
03733 RETURN_NONE();
03734 }
03735
03736
03737 static PyObject*
03738 DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
03739 {
03740 int err;
03741 DB_LOCK_STAT* sp;
03742 PyObject* d = NULL;
03743 u_int32_t flags = 0;
03744
03745 if (!PyArg_ParseTuple(args, "|i:lock_stat", &flags))
03746 return NULL;
03747 CHECK_ENV_NOT_CLOSED(self);
03748
03749 MYDB_BEGIN_ALLOW_THREADS;
03750 #if (DBVER >= 40)
03751 err = self->db_env->lock_stat(self->db_env, &sp, flags);
03752 #else
03753 #if (DBVER >= 33)
03754 err = lock_stat(self->db_env, &sp);
03755 #else
03756 err = lock_stat(self->db_env, &sp, NULL);
03757 #endif
03758 #endif
03759 MYDB_END_ALLOW_THREADS;
03760 RETURN_IF_ERR();
03761
03762
03763 d = PyDict_New();
03764 if (d == NULL) {
03765 free(sp);
03766 return NULL;
03767 }
03768
03769 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
03770
03771 #if (DBVER < 41)
03772 MAKE_ENTRY(lastid);
03773 #endif
03774 MAKE_ENTRY(nmodes);
03775 #if (DBVER >= 32)
03776 MAKE_ENTRY(maxlocks);
03777 MAKE_ENTRY(maxlockers);
03778 MAKE_ENTRY(maxobjects);
03779 MAKE_ENTRY(nlocks);
03780 MAKE_ENTRY(maxnlocks);
03781 #endif
03782 MAKE_ENTRY(nlockers);
03783 MAKE_ENTRY(maxnlockers);
03784 #if (DBVER >= 32)
03785 MAKE_ENTRY(nobjects);
03786 MAKE_ENTRY(maxnobjects);
03787 #endif
03788 MAKE_ENTRY(nrequests);
03789 MAKE_ENTRY(nreleases);
03790 MAKE_ENTRY(nnowaits);
03791 MAKE_ENTRY(nconflicts);
03792 MAKE_ENTRY(ndeadlocks);
03793 MAKE_ENTRY(regsize);
03794 MAKE_ENTRY(region_wait);
03795 MAKE_ENTRY(region_nowait);
03796
03797 #undef MAKE_ENTRY
03798 free(sp);
03799 return d;
03800 }
03801
03802
03803 static PyObject*
03804 DBEnv_log_archive(DBEnvObject* self, PyObject* args)
03805 {
03806 int flags=0;
03807 int err;
03808 char **log_list_start, **log_list;
03809 PyObject* list;
03810 PyObject* item = NULL;
03811
03812 if (!PyArg_ParseTuple(args, "|i:log_archive", &flags))
03813 return NULL;
03814
03815 CHECK_ENV_NOT_CLOSED(self);
03816 MYDB_BEGIN_ALLOW_THREADS;
03817 #if (DBVER >= 40)
03818 err = self->db_env->log_archive(self->db_env, &log_list, flags);
03819 #elif (DBVER == 33)
03820 err = log_archive(self->db_env, &log_list, flags);
03821 #else
03822 err = log_archive(self->db_env, &log_list, flags, NULL);
03823 #endif
03824 MYDB_END_ALLOW_THREADS;
03825 RETURN_IF_ERR();
03826
03827 list = PyList_New(0);
03828 if (list == NULL) {
03829 PyErr_SetString(PyExc_MemoryError, "PyList_New failed");
03830 return NULL;
03831 }
03832
03833 if (log_list) {
03834 for (log_list_start = log_list; *log_list != NULL; ++log_list) {
03835 item = PyString_FromString (*log_list);
03836 if (item == NULL) {
03837 Py_DECREF(list);
03838 PyErr_SetString(PyExc_MemoryError,
03839 "List item creation failed");
03840 list = NULL;
03841 break;
03842 }
03843 PyList_Append(list, item);
03844 Py_DECREF(item);
03845 }
03846 free(log_list_start);
03847 }
03848 return list;
03849 }
03850
03851
03852 static PyObject*
03853 DBEnv_txn_stat(DBEnvObject* self, PyObject* args)
03854 {
03855 int err;
03856 DB_TXN_STAT* sp;
03857 PyObject* d = NULL;
03858 u_int32_t flags=0;
03859
03860 if (!PyArg_ParseTuple(args, "|i:txn_stat", &flags))
03861 return NULL;
03862 CHECK_ENV_NOT_CLOSED(self);
03863
03864 MYDB_BEGIN_ALLOW_THREADS;
03865 #if (DBVER >= 40)
03866 err = self->db_env->txn_stat(self->db_env, &sp, flags);
03867 #elif (DBVER == 33)
03868 err = txn_stat(self->db_env, &sp);
03869 #else
03870 err = txn_stat(self->db_env, &sp, NULL);
03871 #endif
03872 MYDB_END_ALLOW_THREADS;
03873 RETURN_IF_ERR();
03874
03875
03876 d = PyDict_New();
03877 if (d == NULL) {
03878 free(sp);
03879 return NULL;
03880 }
03881
03882 #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
03883
03884 MAKE_ENTRY(time_ckp);
03885 MAKE_ENTRY(last_txnid);
03886 MAKE_ENTRY(maxtxns);
03887 MAKE_ENTRY(nactive);
03888 MAKE_ENTRY(maxnactive);
03889 MAKE_ENTRY(nbegins);
03890 MAKE_ENTRY(naborts);
03891 MAKE_ENTRY(ncommits);
03892 MAKE_ENTRY(regsize);
03893 MAKE_ENTRY(region_wait);
03894 MAKE_ENTRY(region_nowait);
03895
03896 #undef MAKE_ENTRY
03897 free(sp);
03898 return d;
03899 }
03900
03901
03902 static PyObject*
03903 DBEnv_set_get_returns_none(DBEnvObject* self, PyObject* args)
03904 {
03905 int flags=0;
03906 int oldValue=0;
03907
03908 if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
03909 return NULL;
03910 CHECK_ENV_NOT_CLOSED(self);
03911
03912 if (self->moduleFlags.getReturnsNone)
03913 ++oldValue;
03914 if (self->moduleFlags.cursorSetReturnsNone)
03915 ++oldValue;
03916 self->moduleFlags.getReturnsNone = (flags >= 1);
03917 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
03918 return PyInt_FromLong(oldValue);
03919 }
03920
03921
03922
03923
03924
03925
03926 static PyObject*
03927 DBTxn_commit(DBTxnObject* self, PyObject* args)
03928 {
03929 int flags=0, err;
03930 DB_TXN *txn;
03931
03932 if (!PyArg_ParseTuple(args, "|i:commit", &flags))
03933 return NULL;
03934
03935 if (!self->txn) {
03936 PyErr_SetObject(DBError, Py_BuildValue("(is)", 0,
03937 "DBTxn must not be used after txn_commit or txn_abort"));
03938 return NULL;
03939 }
03940 txn = self->txn;
03941 self->txn = NULL;
03942 MYDB_BEGIN_ALLOW_THREADS;
03943 #if (DBVER >= 40)
03944 err = txn->commit(txn, flags);
03945 #else
03946 err = txn_commit(txn, flags);
03947 #endif
03948 MYDB_END_ALLOW_THREADS;
03949 RETURN_IF_ERR();
03950 RETURN_NONE();
03951 }
03952
03953 static PyObject*
03954 DBTxn_prepare(DBTxnObject* self, PyObject* args)
03955 {
03956 #if (DBVER >= 33)
03957 int err;
03958 char* gid=NULL;
03959 int gid_size=0;
03960
03961 if (!PyArg_ParseTuple(args, "s#:prepare", &gid, &gid_size))
03962 return NULL;
03963
03964 if (gid_size != DB_XIDDATASIZE) {
03965 PyErr_SetString(PyExc_TypeError,
03966 "gid must be DB_XIDDATASIZE bytes long");
03967 return NULL;
03968 }
03969
03970 if (!self->txn) {
03971 PyErr_SetObject(DBError, Py_BuildValue("(is)", 0,
03972 "DBTxn must not be used after txn_commit or txn_abort"));
03973 return NULL;
03974 }
03975 MYDB_BEGIN_ALLOW_THREADS;
03976 #if (DBVER >= 40)
03977 err = self->txn->prepare(self->txn, (u_int8_t*)gid);
03978 #else
03979 err = txn_prepare(self->txn, (u_int8_t*)gid);
03980 #endif
03981 MYDB_END_ALLOW_THREADS;
03982 RETURN_IF_ERR();
03983 RETURN_NONE();
03984 #else
03985 int err;
03986
03987 if (!PyArg_ParseTuple(args, ":prepare"))
03988 return NULL;
03989
03990 if (!self->txn) {
03991 PyErr_SetObject(DBError, Py_BuildValue("(is)", 0,
03992 "DBTxn must not be used after txn_commit or txn_abort"));
03993 return NULL;
03994 }
03995 MYDB_BEGIN_ALLOW_THREADS;
03996 err = txn_prepare(self->txn);
03997 MYDB_END_ALLOW_THREADS;
03998 RETURN_IF_ERR();
03999 RETURN_NONE();
04000 #endif
04001 }
04002
04003
04004 static PyObject*
04005 DBTxn_abort(DBTxnObject* self, PyObject* args)
04006 {
04007 int err;
04008 DB_TXN *txn;
04009
04010 if (!PyArg_ParseTuple(args, ":abort"))
04011 return NULL;
04012
04013 if (!self->txn) {
04014 PyErr_SetObject(DBError, Py_BuildValue("(is)", 0,
04015 "DBTxn must not be used after txn_commit or txn_abort"));
04016 return NULL;
04017 }
04018 txn = self->txn;
04019 self->txn = NULL;
04020 MYDB_BEGIN_ALLOW_THREADS;
04021 #if (DBVER >= 40)
04022 err = txn->abort(txn);
04023 #else
04024 err = txn_abort(txn);
04025 #endif
04026 MYDB_END_ALLOW_THREADS;
04027 RETURN_IF_ERR();
04028 RETURN_NONE();
04029 }
04030
04031
04032 static PyObject*
04033 DBTxn_id(DBTxnObject* self, PyObject* args)
04034 {
04035 int id;
04036
04037 if (!PyArg_ParseTuple(args, ":id"))
04038 return NULL;
04039
04040 if (!self->txn) {
04041 PyErr_SetObject(DBError, Py_BuildValue("(is)", 0,
04042 "DBTxn must not be used after txn_commit or txn_abort"));
04043 return NULL;
04044 }
04045 MYDB_BEGIN_ALLOW_THREADS;
04046 #if (DBVER >= 40)
04047 id = self->txn->id(self->txn);
04048 #else
04049 id = txn_id(self->txn);
04050 #endif
04051 MYDB_END_ALLOW_THREADS;
04052 return PyInt_FromLong(id);
04053 }
04054
04055
04056
04057
04058 static PyMethodDef DB_methods[] = {
04059 {"append", (PyCFunction)DB_append, METH_VARARGS},
04060 #if (DBVER >= 33)
04061 {"associate", (PyCFunction)DB_associate, METH_VARARGS|METH_KEYWORDS},
04062 #endif
04063 {"close", (PyCFunction)DB_close, METH_VARARGS},
04064 #if (DBVER >= 32)
04065 {"consume", (PyCFunction)DB_consume, METH_VARARGS|METH_KEYWORDS},
04066 {"consume_wait", (PyCFunction)DB_consume_wait, METH_VARARGS|METH_KEYWORDS},
04067 #endif
04068 {"cursor", (PyCFunction)DB_cursor, METH_VARARGS|METH_KEYWORDS},
04069 {"delete", (PyCFunction)DB_delete, METH_VARARGS|METH_KEYWORDS},
04070 {"fd", (PyCFunction)DB_fd, METH_VARARGS},
04071 {"get", (PyCFunction)DB_get, METH_VARARGS|METH_KEYWORDS},
04072 {"get_both", (PyCFunction)DB_get_both, METH_VARARGS|METH_KEYWORDS},
04073 {"get_byteswapped", (PyCFunction)DB_get_byteswapped,METH_VARARGS},
04074 {"get_size", (PyCFunction)DB_get_size, METH_VARARGS|METH_KEYWORDS},
04075 {"get_type", (PyCFunction)DB_get_type, METH_VARARGS},
04076 {"join", (PyCFunction)DB_join, METH_VARARGS},
04077 {"key_range", (PyCFunction)DB_key_range, METH_VARARGS|METH_KEYWORDS},
04078 {"has_key", (PyCFunction)DB_has_key, METH_VARARGS},
04079 {"items", (PyCFunction)DB_items, METH_VARARGS},
04080 {"keys", (PyCFunction)DB_keys, METH_VARARGS},
04081 {"open", (PyCFunction)DB_open, METH_VARARGS|METH_KEYWORDS},
04082 {"put", (PyCFunction)DB_put, METH_VARARGS|METH_KEYWORDS},
04083 {"remove", (PyCFunction)DB_remove, METH_VARARGS|METH_KEYWORDS},
04084 {"rename", (PyCFunction)DB_rename, METH_VARARGS},
04085 {"set_bt_minkey", (PyCFunction)DB_set_bt_minkey, METH_VARARGS},
04086 {"set_cachesize", (PyCFunction)DB_set_cachesize, METH_VARARGS},
04087 #if (DBVER >= 41)
04088 {"set_encrypt", (PyCFunction)DB_set_encrypt, METH_VARARGS|METH_KEYWORDS},
04089 #endif
04090 {"set_flags", (PyCFunction)DB_set_flags, METH_VARARGS},
04091 {"set_h_ffactor", (PyCFunction)DB_set_h_ffactor, METH_VARARGS},
04092 {"set_h_nelem", (PyCFunction)DB_set_h_nelem, METH_VARARGS},
04093 {"set_lorder", (PyCFunction)DB_set_lorder, METH_VARARGS},
04094 {"set_pagesize", (PyCFunction)DB_set_pagesize, METH_VARARGS},
04095 {"set_re_delim", (PyCFunction)DB_set_re_delim, METH_VARARGS},
04096 {"set_re_len", (PyCFunction)DB_set_re_len, METH_VARARGS},
04097 {"set_re_pad", (PyCFunction)DB_set_re_pad, METH_VARARGS},
04098 {"set_re_source", (PyCFunction)DB_set_re_source, METH_VARARGS},
04099 #if (DBVER >= 32)
04100 {"set_q_extentsize",(PyCFunction)DB_set_q_extentsize,METH_VARARGS},
04101 #endif
04102 {"stat", (PyCFunction)DB_stat, METH_VARARGS},
04103 {"sync", (PyCFunction)DB_sync, METH_VARARGS},
04104 #if (DBVER >= 33)
04105 {"truncate", (PyCFunction)DB_truncate, METH_VARARGS|METH_KEYWORDS},
04106 #endif
04107 {"type", (PyCFunction)DB_get_type, METH_VARARGS},
04108 {"upgrade", (PyCFunction)DB_upgrade, METH_VARARGS},
04109 {"values", (PyCFunction)DB_values, METH_VARARGS},
04110 {"verify", (PyCFunction)DB_verify, METH_VARARGS|METH_KEYWORDS},
04111 {"set_get_returns_none",(PyCFunction)DB_set_get_returns_none, METH_VARARGS},
04112 {NULL, NULL}
04113 };
04114
04115
04116 static PyMappingMethods DB_mapping = {
04117 (inquiry)DB_length,
04118 (binaryfunc)DB_subscript,
04119 (objobjargproc)DB_ass_sub,
04120 };
04121
04122
04123 static PyMethodDef DBCursor_methods[] = {
04124 {"close", (PyCFunction)DBC_close, METH_VARARGS},
04125 {"count", (PyCFunction)DBC_count, METH_VARARGS},
04126 {"current", (PyCFunction)DBC_current, METH_VARARGS|METH_KEYWORDS},
04127 {"delete", (PyCFunction)DBC_delete, METH_VARARGS},
04128 {"dup", (PyCFunction)DBC_dup, METH_VARARGS},
04129 {"first", (PyCFunction)DBC_first, METH_VARARGS|METH_KEYWORDS},
04130 {"get", (PyCFunction)DBC_get, METH_VARARGS|METH_KEYWORDS},
04131 {"get_recno", (PyCFunction)DBC_get_recno, METH_VARARGS},
04132 {"last", (PyCFunction)DBC_last, METH_VARARGS|METH_KEYWORDS},
04133 {"next", (PyCFunction)DBC_next, METH_VARARGS|METH_KEYWORDS},
04134 {"prev", (PyCFunction)DBC_prev, METH_VARARGS|METH_KEYWORDS},
04135 {"put", (PyCFunction)DBC_put, METH_VARARGS|METH_KEYWORDS},
04136 {"set", (PyCFunction)DBC_set, METH_VARARGS|METH_KEYWORDS},
04137 {"set_range", (PyCFunction)DBC_set_range, METH_VARARGS|METH_KEYWORDS},
04138 {"get_both", (PyCFunction)DBC_get_both, METH_VARARGS},
04139 {"get_current_size",(PyCFunction)DBC_get_current_size, METH_VARARGS},
04140 {"set_both", (PyCFunction)DBC_set_both, METH_VARARGS},
04141 {"set_recno", (PyCFunction)DBC_set_recno, METH_VARARGS|METH_KEYWORDS},
04142 {"consume", (PyCFunction)DBC_consume, METH_VARARGS|METH_KEYWORDS},
04143 {"next_dup", (PyCFunction)DBC_next_dup, METH_VARARGS|METH_KEYWORDS},
04144 {"next_nodup", (PyCFunction)DBC_next_nodup, METH_VARARGS|METH_KEYWORDS},
04145 {"prev_nodup", (PyCFunction)DBC_prev_nodup, METH_VARARGS|METH_KEYWORDS},
04146 {"join_item", (PyCFunction)DBC_join_item, METH_VARARGS},
04147 {NULL, NULL}
04148 };
04149
04150
04151 static PyMethodDef DBEnv_methods[] = {
04152 {"close", (PyCFunction)DBEnv_close, METH_VARARGS},
04153 {"open", (PyCFunction)DBEnv_open, METH_VARARGS},
04154 {"remove", (PyCFunction)DBEnv_remove, METH_VARARGS},
04155 #if (DBVER >= 41)
04156 {"dbremove", (PyCFunction)DBEnv_dbremove, METH_VARARGS|METH_KEYWORDS},
04157 {"dbrename", (PyCFunction)DBEnv_dbrename, METH_VARARGS|METH_KEYWORDS},
04158 {"set_encrypt", (PyCFunction)DBEnv_set_encrypt, METH_VARARGS|METH_KEYWORDS},
04159 #endif
04160 #if (DBVER >= 40)
04161 {"set_timeout", (PyCFunction)DBEnv_set_timeout, METH_VARARGS|METH_KEYWORDS},
04162 #endif
04163 {"set_shm_key", (PyCFunction)DBEnv_set_shm_key, METH_VARARGS},
04164 {"set_cachesize", (PyCFunction)DBEnv_set_cachesize, METH_VARARGS},
04165 {"set_data_dir", (PyCFunction)DBEnv_set_data_dir, METH_VARARGS},
04166 #if (DBVER >= 32)
04167 {"set_flags", (PyCFunction)DBEnv_set_flags, METH_VARARGS},
04168 #endif
04169 {"set_lg_bsize", (PyCFunction)DBEnv_set_lg_bsize, METH_VARARGS},
04170 {"set_lg_dir", (PyCFunction)DBEnv_set_lg_dir, METH_VARARGS},
04171 {"set_lg_max", (PyCFunction)DBEnv_set_lg_max, METH_VARARGS},
04172 {"set_lk_detect", (PyCFunction)DBEnv_set_lk_detect, METH_VARARGS},
04173 {"set_lk_max", (PyCFunction)DBEnv_set_lk_max, METH_VARARGS},
04174 #if (DBVER >= 32)
04175 {"set_lk_max_locks", (PyCFunction)DBEnv_set_lk_max_locks, METH_VARARGS},
04176 {"set_lk_max_lockers", (PyCFunction)DBEnv_set_lk_max_lockers, METH_VARARGS},
04177 {"set_lk_max_objects", (PyCFunction)DBEnv_set_lk_max_objects, METH_VARARGS},
04178 #endif
04179 {"set_mp_mmapsize", (PyCFunction)DBEnv_set_mp_mmapsize, METH_VARARGS},
04180 {"set_tmp_dir", (PyCFunction)DBEnv_set_tmp_dir, METH_VARARGS},
04181 {"txn_begin", (PyCFunction)DBEnv_txn_begin, METH_VARARGS|METH_KEYWORDS},
04182 {"txn_checkpoint", (PyCFunction)DBEnv_txn_checkpoint, METH_VARARGS},
04183 {"txn_stat", (PyCFunction)DBEnv_txn_stat, METH_VARARGS},
04184 {"set_tx_max", (PyCFunction)DBEnv_set_tx_max, METH_VARARGS},
04185 {"lock_detect", (PyCFunction)DBEnv_lock_detect, METH_VARARGS},
04186 {"lock_get", (PyCFunction)DBEnv_lock_get, METH_VARARGS},
04187 {"lock_id", (PyCFunction)DBEnv_lock_id, METH_VARARGS},
04188 {"lock_put", (PyCFunction)DBEnv_lock_put, METH_VARARGS},
04189 {"lock_stat", (PyCFunction)DBEnv_lock_stat, METH_VARARGS},
04190 {"log_archive", (PyCFunction)DBEnv_log_archive, METH_VARARGS},
04191 {"set_get_returns_none",(PyCFunction)DBEnv_set_get_returns_none, METH_VARARGS},
04192 {NULL, NULL}
04193 };
04194
04195
04196 static PyMethodDef DBTxn_methods[] = {
04197 {"commit", (PyCFunction)DBTxn_commit, METH_VARARGS},
04198 {"prepare", (PyCFunction)DBTxn_prepare, METH_VARARGS},
04199 {"abort", (PyCFunction)DBTxn_abort, METH_VARARGS},
04200 {"id", (PyCFunction)DBTxn_id, METH_VARARGS},
04201 {NULL, NULL}
04202 };
04203
04204
04205 static PyObject*
04206 DB_getattr(DBObject* self, char *name)
04207 {
04208 return Py_FindMethod(DB_methods, (PyObject* )self, name);
04209 }
04210
04211
04212 static PyObject*
04213 DBEnv_getattr(DBEnvObject* self, char *name)
04214 {
04215 if (!strcmp(name, "db_home")) {
04216 CHECK_ENV_NOT_CLOSED(self);
04217 if (self->db_env->db_home == NULL) {
04218 RETURN_NONE();
04219 }
04220 return PyString_FromString(self->db_env->db_home);
04221 }
04222
04223 return Py_FindMethod(DBEnv_methods, (PyObject* )self, name);
04224 }
04225
04226
04227 static PyObject*
04228 DBCursor_getattr(DBCursorObject* self, char *name)
04229 {
04230 return Py_FindMethod(DBCursor_methods, (PyObject* )self, name);
04231 }
04232
04233 static PyObject*
04234 DBTxn_getattr(DBTxnObject* self, char *name)
04235 {
04236 return Py_FindMethod(DBTxn_methods, (PyObject* )self, name);
04237 }
04238
04239 static PyObject*
04240 DBLock_getattr(DBLockObject* self, char *name)
04241 {
04242 return NULL;
04243 }
04244
04245 statichere PyTypeObject DB_Type = {
04246 PyObject_HEAD_INIT(NULL)
04247 0,
04248 "DB",
04249 sizeof(DBObject),
04250 0,
04251
04252 (destructor)DB_dealloc,
04253 0,
04254 (getattrfunc)DB_getattr,
04255 0,
04256 0,
04257 0,
04258 0,
04259 0,
04260 &DB_mapping,
04261 0,
04262 };
04263
04264
04265 statichere PyTypeObject DBCursor_Type = {
04266 PyObject_HEAD_INIT(NULL)
04267 0,
04268 "DBCursor",
04269 sizeof(DBCursorObject),
04270 0,
04271
04272 (destructor)DBCursor_dealloc,
04273 0,
04274 (getattrfunc)DBCursor_getattr,
04275 0,
04276 0,
04277 0,
04278 0,
04279 0,
04280 0,
04281 0,
04282 #ifdef HAVE_WEAKREF
04283 0,
04284 0,
04285 0,
04286 0,
04287 0,
04288 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS,
04289 0,
04290 0,
04291 0,
04292 0,
04293 offsetof(DBCursorObject, in_weakreflist),
04294 #endif
04295 };
04296
04297
04298 statichere PyTypeObject DBEnv_Type = {
04299 PyObject_HEAD_INIT(NULL)
04300 0,
04301 "DBEnv",
04302 sizeof(DBEnvObject),
04303 0,
04304
04305 (destructor)DBEnv_dealloc,
04306 0,
04307 (getattrfunc)DBEnv_getattr,
04308 0,
04309 0,
04310 0,
04311 0,
04312 0,
04313 0,
04314 0,
04315 };
04316
04317 statichere PyTypeObject DBTxn_Type = {
04318 PyObject_HEAD_INIT(NULL)
04319 0,
04320 "DBTxn",
04321 sizeof(DBTxnObject),
04322 0,
04323
04324 (destructor)DBTxn_dealloc,
04325 0,
04326 (getattrfunc)DBTxn_getattr,
04327 0,
04328 0,
04329 0,
04330 0,
04331 0,
04332 0,
04333 0,
04334 };
04335
04336
04337 statichere PyTypeObject DBLock_Type = {
04338 PyObject_HEAD_INIT(NULL)
04339 0,
04340 "DBLock",
04341 sizeof(DBLockObject),
04342 0,
04343
04344 (destructor)DBLock_dealloc,
04345 0,
04346 (getattrfunc)DBLock_getattr,
04347 0,
04348 0,
04349 0,
04350 0,
04351 0,
04352 0,
04353 0,
04354 };
04355
04356
04357
04358
04359
04360 static PyObject*
04361 DB_construct(PyObject* self, PyObject* args, PyObject* kwargs)
04362 {
04363 PyObject* dbenvobj = NULL;
04364 int flags = 0;
04365 char* kwnames[] = { "dbEnv", "flags", NULL};
04366
04367 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:DB", kwnames,
04368 &dbenvobj, &flags))
04369 return NULL;
04370 if (dbenvobj == Py_None)
04371 dbenvobj = NULL;
04372 else if (dbenvobj && !DBEnvObject_Check(dbenvobj)) {
04373 makeTypeError("DBEnv", dbenvobj);
04374 return NULL;
04375 }
04376
04377 return (PyObject* )newDBObject((DBEnvObject*)dbenvobj, flags);
04378 }
04379
04380
04381 static PyObject*
04382 DBEnv_construct(PyObject* self, PyObject* args)
04383 {
04384 int flags = 0;
04385 if (!PyArg_ParseTuple(args, "|i:DbEnv", &flags)) return NULL;
04386 return (PyObject* )newDBEnvObject(flags);
04387 }
04388
04389
04390 static char bsddb_version_doc[] =
04391 "Returns a tuple of major, minor, and patch release numbers of the\n\
04392 underlying DB library.";
04393
04394 static PyObject*
04395 bsddb_version(PyObject* self, PyObject* args)
04396 {
04397 int major, minor, patch;
04398
04399 if (!PyArg_ParseTuple(args, ":version"))
04400 return NULL;
04401 db_version(&major, &minor, &patch);
04402 return Py_BuildValue("(iii)", major, minor, patch);
04403 }
04404
04405
04406
04407
04408 static PyMethodDef bsddb_methods[] = {
04409 {"DB", (PyCFunction)DB_construct, METH_VARARGS | METH_KEYWORDS },
04410 {"DBEnv", (PyCFunction)DBEnv_construct, METH_VARARGS},
04411 {"version", (PyCFunction)bsddb_version, METH_VARARGS, bsddb_version_doc},
04412 {NULL, NULL}
04413 };
04414
04415
04416
04417
04418
04419
04420
04421
04422
04423 #define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
04424
04425 #define MODULE_NAME_MAX_LEN 11
04426 static char _bsddbModuleName[MODULE_NAME_MAX_LEN+1] = "_bsddb";
04427
04428 DL_EXPORT(void) init_bsddb(void)
04429 {
04430 PyObject* m;
04431 PyObject* d;
04432 PyObject* pybsddb_version_s = PyString_FromString( PY_BSDDB_VERSION );
04433 PyObject* db_version_s = PyString_FromString( DB_VERSION_STRING );
04434 PyObject* cvsid_s = PyString_FromString( rcs_id );
04435
04436
04437
04438 DB_Type.ob_type = &PyType_Type;
04439 DBCursor_Type.ob_type = &PyType_Type;
04440 DBEnv_Type.ob_type = &PyType_Type;
04441 DBTxn_Type.ob_type = &PyType_Type;
04442 DBLock_Type.ob_type = &PyType_Type;
04443
04444
04445 #if defined(WITH_THREAD) && !defined(MYDB_USE_GILSTATE)
04446
04447 _db_interpreterState = PyThreadState_Get()->interp;
04448 #endif
04449
04450
04451 m = Py_InitModule(_bsddbModuleName, bsddb_methods);
04452
04453
04454 d = PyModule_GetDict(m);
04455 PyDict_SetItemString(d, "__version__", pybsddb_version_s);
04456 PyDict_SetItemString(d, "cvsid", cvsid_s);
04457 PyDict_SetItemString(d, "DB_VERSION_STRING", db_version_s);
04458 Py_DECREF(pybsddb_version_s);
04459 pybsddb_version_s = NULL;
04460 Py_DECREF(cvsid_s);
04461 cvsid_s = NULL;
04462 Py_DECREF(db_version_s);
04463 db_version_s = NULL;
04464
04465 ADD_INT(d, DB_VERSION_MAJOR);
04466 ADD_INT(d, DB_VERSION_MINOR);
04467 ADD_INT(d, DB_VERSION_PATCH);
04468
04469 ADD_INT(d, DB_MAX_PAGES);
04470 ADD_INT(d, DB_MAX_RECORDS);
04471
04472 #if (DBVER >= 42)
04473 ADD_INT(d, DB_RPCCLIENT);
04474 #else
04475 ADD_INT(d, DB_CLIENT);
04476
04477 _addIntToDict(d, "DB_RPCCLIENT", DB_CLIENT);
04478 #endif
04479 ADD_INT(d, DB_XA_CREATE);
04480
04481 ADD_INT(d, DB_CREATE);
04482 ADD_INT(d, DB_NOMMAP);
04483 ADD_INT(d, DB_THREAD);
04484
04485 ADD_INT(d, DB_FORCE);
04486 ADD_INT(d, DB_INIT_CDB);
04487 ADD_INT(d, DB_INIT_LOCK);
04488 ADD_INT(d, DB_INIT_LOG);
04489 ADD_INT(d, DB_INIT_MPOOL);
04490 ADD_INT(d, DB_INIT_TXN);
04491 #if (DBVER >= 32)
04492 ADD_INT(d, DB_JOINENV);
04493 #endif
04494
04495 ADD_INT(d, DB_RECOVER);
04496 ADD_INT(d, DB_RECOVER_FATAL);
04497 ADD_INT(d, DB_TXN_NOSYNC);
04498 ADD_INT(d, DB_USE_ENVIRON);
04499 ADD_INT(d, DB_USE_ENVIRON_ROOT);
04500
04501 ADD_INT(d, DB_LOCKDOWN);
04502 ADD_INT(d, DB_PRIVATE);
04503 ADD_INT(d, DB_SYSTEM_MEM);
04504
04505 ADD_INT(d, DB_TXN_SYNC);
04506 ADD_INT(d, DB_TXN_NOWAIT);
04507
04508 ADD_INT(d, DB_EXCL);
04509 ADD_INT(d, DB_FCNTL_LOCKING);
04510 ADD_INT(d, DB_ODDFILESIZE);
04511 ADD_INT(d, DB_RDWRMASTER);
04512 ADD_INT(d, DB_RDONLY);
04513 ADD_INT(d, DB_TRUNCATE);
04514 #if (DBVER >= 32)
04515 ADD_INT(d, DB_EXTENT);
04516 ADD_INT(d, DB_CDB_ALLDB);
04517 ADD_INT(d, DB_VERIFY);
04518 #endif
04519 ADD_INT(d, DB_UPGRADE);
04520
04521 ADD_INT(d, DB_AGGRESSIVE);
04522 ADD_INT(d, DB_NOORDERCHK);
04523 ADD_INT(d, DB_ORDERCHKONLY);
04524 ADD_INT(d, DB_PR_PAGE);
04525 #if ! (DBVER >= 33)
04526 ADD_INT(d, DB_VRFY_FLAGMASK);
04527 ADD_INT(d, DB_PR_HEADERS);
04528 #endif
04529 ADD_INT(d, DB_PR_RECOVERYTEST);
04530 ADD_INT(d, DB_SALVAGE);
04531
04532 ADD_INT(d, DB_LOCK_NORUN);
04533 ADD_INT(d, DB_LOCK_DEFAULT);
04534 ADD_INT(d, DB_LOCK_OLDEST);
04535 ADD_INT(d, DB_LOCK_RANDOM);
04536 ADD_INT(d, DB_LOCK_YOUNGEST);
04537 #if (DBVER >= 33)
04538 ADD_INT(d, DB_LOCK_MAXLOCKS);
04539 ADD_INT(d, DB_LOCK_MINLOCKS);
04540 ADD_INT(d, DB_LOCK_MINWRITE);
04541 #endif
04542
04543
04544 #if (DBVER >= 33)
04545
04546 _addIntToDict(d, "DB_LOCK_CONFLICT", 0);
04547 #else
04548 ADD_INT(d, DB_LOCK_CONFLICT);
04549 #endif
04550
04551 ADD_INT(d, DB_LOCK_DUMP);
04552 ADD_INT(d, DB_LOCK_GET);
04553 ADD_INT(d, DB_LOCK_INHERIT);
04554 ADD_INT(d, DB_LOCK_PUT);
04555 ADD_INT(d, DB_LOCK_PUT_ALL);
04556 ADD_INT(d, DB_LOCK_PUT_OBJ);
04557
04558 ADD_INT(d, DB_LOCK_NG);
04559 ADD_INT(d, DB_LOCK_READ);
04560 ADD_INT(d, DB_LOCK_WRITE);
04561 ADD_INT(d, DB_LOCK_NOWAIT);
04562 #if (DBVER >= 32)
04563 ADD_INT(d, DB_LOCK_WAIT);
04564 #endif
04565 ADD_INT(d, DB_LOCK_IWRITE);
04566 ADD_INT(d, DB_LOCK_IREAD);
04567 ADD_INT(d, DB_LOCK_IWR);
04568 #if (DBVER >= 33)
04569 ADD_INT(d, DB_LOCK_DIRTY);
04570 ADD_INT(d, DB_LOCK_WWRITE);
04571 #endif
04572
04573 ADD_INT(d, DB_LOCK_RECORD);
04574 ADD_INT(d, DB_LOCK_UPGRADE);
04575 #if (DBVER >= 32)
04576 ADD_INT(d, DB_LOCK_SWITCH);
04577 #endif
04578 #if (DBVER >= 33)
04579 ADD_INT(d, DB_LOCK_UPGRADE_WRITE);
04580 #endif
04581
04582 ADD_INT(d, DB_LOCK_NOWAIT);
04583 ADD_INT(d, DB_LOCK_RECORD);
04584 ADD_INT(d, DB_LOCK_UPGRADE);
04585
04586 #if (DBVER >= 33)
04587 ADD_INT(d, DB_LSTAT_ABORTED);
04588 ADD_INT(d, DB_LSTAT_ERR);
04589 ADD_INT(d, DB_LSTAT_FREE);
04590 ADD_INT(d, DB_LSTAT_HELD);
04591 #if (DBVER == 33)
04592 ADD_INT(d, DB_LSTAT_NOGRANT);
04593 #endif
04594 ADD_INT(d, DB_LSTAT_PENDING);
04595 ADD_INT(d, DB_LSTAT_WAITING);
04596 #endif
04597
04598 ADD_INT(d, DB_ARCH_ABS);
04599 ADD_INT(d, DB_ARCH_DATA);
04600 ADD_INT(d, DB_ARCH_LOG);
04601
04602 ADD_INT(d, DB_BTREE);
04603 ADD_INT(d, DB_HASH);
04604 ADD_INT(d, DB_RECNO);
04605 ADD_INT(d, DB_QUEUE);
04606 ADD_INT(d, DB_UNKNOWN);
04607
04608 ADD_INT(d, DB_DUP);
04609 ADD_INT(d, DB_DUPSORT);
04610 ADD_INT(d, DB_RECNUM);
04611 ADD_INT(d, DB_RENUMBER);
04612 ADD_INT(d, DB_REVSPLITOFF);
04613 ADD_INT(d, DB_SNAPSHOT);
04614
04615 ADD_INT(d, DB_JOIN_NOSORT);
04616
04617 ADD_INT(d, DB_AFTER);
04618 ADD_INT(d, DB_APPEND);
04619 ADD_INT(d, DB_BEFORE);
04620 ADD_INT(d, DB_CACHED_COUNTS);
04621 #if (DBVER >= 41)
04622 _addIntToDict(d, "DB_CHECKPOINT", 0);
04623 #else
04624 ADD_INT(d, DB_CHECKPOINT);
04625 ADD_INT(d, DB_CURLSN);
04626 #endif
04627 #if ((DBVER >= 33) && (DBVER <= 41))
04628 ADD_INT(d, DB_COMMIT);
04629 #endif
04630 ADD_INT(d, DB_CONSUME);
04631 #if (DBVER >= 32)
04632 ADD_INT(d, DB_CONSUME_WAIT);
04633 #endif
04634 ADD_INT(d, DB_CURRENT);
04635 #if (DBVER >= 33)
04636 ADD_INT(d, DB_FAST_STAT);
04637 #endif
04638 ADD_INT(d, DB_FIRST);
04639 ADD_INT(d, DB_FLUSH);
04640 ADD_INT(d, DB_GET_BOTH);
04641 ADD_INT(d, DB_GET_RECNO);
04642 ADD_INT(d, DB_JOIN_ITEM);
04643 ADD_INT(d, DB_KEYFIRST);
04644 ADD_INT(d, DB_KEYLAST);
04645 ADD_INT(d, DB_LAST);
04646 ADD_INT(d, DB_NEXT);
04647 ADD_INT(d, DB_NEXT_DUP);
04648 ADD_INT(d, DB_NEXT_NODUP);
04649 ADD_INT(d, DB_NODUPDATA);
04650 ADD_INT(d, DB_NOOVERWRITE);
04651 ADD_INT(d, DB_NOSYNC);
04652 ADD_INT(d, DB_POSITION);
04653 ADD_INT(d, DB_PREV);
04654 ADD_INT(d, DB_PREV_NODUP);
04655 ADD_INT(d, DB_RECORDCOUNT);
04656 ADD_INT(d, DB_SET);
04657 ADD_INT(d, DB_SET_RANGE);
04658 ADD_INT(d, DB_SET_RECNO);
04659 ADD_INT(d, DB_WRITECURSOR);
04660
04661 ADD_INT(d, DB_OPFLAGS_MASK);
04662 ADD_INT(d, DB_RMW);
04663 #if (DBVER >= 33)
04664 ADD_INT(d, DB_DIRTY_READ);
04665 ADD_INT(d, DB_MULTIPLE);
04666 ADD_INT(d, DB_MULTIPLE_KEY);
04667 #endif
04668
04669 #if (DBVER >= 33)
04670 ADD_INT(d, DB_DONOTINDEX);
04671 #endif
04672
04673 #if (DBVER >= 41)
04674 _addIntToDict(d, "DB_INCOMPLETE", 0);
04675 #else
04676 ADD_INT(d, DB_INCOMPLETE);
04677 #endif
04678 ADD_INT(d, DB_KEYEMPTY);
04679 ADD_INT(d, DB_KEYEXIST);
04680 ADD_INT(d, DB_LOCK_DEADLOCK);
04681 ADD_INT(d, DB_LOCK_NOTGRANTED);
04682 ADD_INT(d, DB_NOSERVER);
04683 ADD_INT(d, DB_NOSERVER_HOME);
04684 ADD_INT(d, DB_NOSERVER_ID);
04685 ADD_INT(d, DB_NOTFOUND);
04686 ADD_INT(d, DB_OLD_VERSION);
04687 ADD_INT(d, DB_RUNRECOVERY);
04688 ADD_INT(d, DB_VERIFY_BAD);
04689 #if (DBVER >= 33)
04690 ADD_INT(d, DB_PAGE_NOTFOUND);
04691 ADD_INT(d, DB_SECONDARY_BAD);
04692 #endif
04693 #if (DBVER >= 40)
04694 ADD_INT(d, DB_STAT_CLEAR);
04695 ADD_INT(d, DB_REGION_INIT);
04696 ADD_INT(d, DB_NOLOCKING);
04697 ADD_INT(d, DB_YIELDCPU);
04698 ADD_INT(d, DB_PANIC_ENVIRONMENT);
04699 ADD_INT(d, DB_NOPANIC);
04700 #endif
04701
04702 #if (DBVER >= 42)
04703 ADD_INT(d, DB_TIME_NOTGRANTED);
04704 ADD_INT(d, DB_TXN_NOT_DURABLE);
04705 ADD_INT(d, DB_TXN_WRITE_NOSYNC);
04706 ADD_INT(d, DB_LOG_AUTOREMOVE);
04707 ADD_INT(d, DB_DIRECT_LOG);
04708 ADD_INT(d, DB_DIRECT_DB);
04709 ADD_INT(d, DB_INIT_REP);
04710 ADD_INT(d, DB_ENCRYPT);
04711 ADD_INT(d, DB_CHKSUM);
04712 #endif
04713
04714 #if (DBVER >= 41)
04715 ADD_INT(d, DB_ENCRYPT_AES);
04716 ADD_INT(d, DB_AUTO_COMMIT);
04717 #else
04718
04719 _addIntToDict(d, "DB_AUTO_COMMIT", 0);
04720 #endif
04721
04722 ADD_INT(d, EINVAL);
04723 ADD_INT(d, EACCES);
04724 ADD_INT(d, ENOSPC);
04725 ADD_INT(d, ENOMEM);
04726 ADD_INT(d, EAGAIN);
04727 ADD_INT(d, EBUSY);
04728 ADD_INT(d, EEXIST);
04729 ADD_INT(d, ENOENT);
04730 ADD_INT(d, EPERM);
04731
04732 #if (DBVER >= 40)
04733 ADD_INT(d, DB_SET_LOCK_TIMEOUT);
04734 ADD_INT(d, DB_SET_TXN_TIMEOUT);
04735 #endif
04736
04737
04738 DBError = PyErr_NewException("bsddb._db.DBError", NULL, NULL);
04739 PyDict_SetItemString(d, "DBError", DBError);
04740
04741
04742
04743 PyDict_SetItemString(d, "KeyError", PyExc_KeyError);
04744 PyRun_String("class DBNotFoundError(DBError, KeyError): pass",
04745 Py_file_input, d, d);
04746 DBNotFoundError = PyDict_GetItemString(d, "DBNotFoundError");
04747 PyDict_DelItemString(d, "KeyError");
04748
04749
04750
04751 #define MAKE_EX(name) name = PyErr_NewException("bsddb._db." #name, DBError, NULL); \
04752 PyDict_SetItemString(d, #name, name)
04753
04754 #if !INCOMPLETE_IS_WARNING
04755 MAKE_EX(DBIncompleteError);
04756 #endif
04757 MAKE_EX(DBCursorClosedError);
04758 MAKE_EX(DBKeyEmptyError);
04759 MAKE_EX(DBKeyExistError);
04760 MAKE_EX(DBLockDeadlockError);
04761 MAKE_EX(DBLockNotGrantedError);
04762 MAKE_EX(DBOldVersionError);
04763 MAKE_EX(DBRunRecoveryError);
04764 MAKE_EX(DBVerifyBadError);
04765 MAKE_EX(DBNoServerError);
04766 MAKE_EX(DBNoServerHomeError);
04767 MAKE_EX(DBNoServerIDError);
04768 #if (DBVER >= 33)
04769 MAKE_EX(DBPageNotFoundError);
04770 MAKE_EX(DBSecondaryBadError);
04771 #endif
04772
04773 MAKE_EX(DBInvalidArgError);
04774 MAKE_EX(DBAccessError);
04775 MAKE_EX(DBNoSpaceError);
04776 MAKE_EX(DBNoMemoryError);
04777 MAKE_EX(DBAgainError);
04778 MAKE_EX(DBBusyError);
04779 MAKE_EX(DBFileExistsError);
04780 MAKE_EX(DBNoSuchFileError);
04781 MAKE_EX(DBPermissionsError);
04782
04783 #undef MAKE_EX
04784
04785
04786 if (PyErr_Occurred()) {
04787 PyErr_Print();
04788 Py_FatalError("can't initialize module _bsddb");
04789 }
04790 }
04791
04792
04793
04794
04795 DL_EXPORT(void) init_pybsddb(void)
04796 {
04797 strncpy(_bsddbModuleName, "_pybsddb", MODULE_NAME_MAX_LEN);
04798 init_bsddb();
04799 }
04800
04801
04802 DL_EXPORT(void) init_rpmdb(void)
04803 {
04804 strncpy(_bsddbModuleName, "_rpmdb", MODULE_NAME_MAX_LEN);
04805 init_bsddb();
04806 }