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