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