Changeset 132 for python


Ignore:
Timestamp:
Jan 4, 2011, 10:35:57 AM (15 years ago)
Author:
Yuri Dario
Message:

python: backported bdb 4.8.x code from Python 2.7

Location:
python/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • python/trunk/Modules/_bsddb.c

    r2 r132  
    7474 * DBSequence   (Sequence)
    7575 *
     76 * More datatypes added:
     77 *
     78 * DBLogCursor  (Log Cursor)
     79 *
    7680 */
    7781
     
    96100#undef COMPILING_BSDDB_C
    97101
    98 static char *rcs_id = "$Id: _bsddb.c 78564 2010-03-01 21:08:21Z florent.xicluna $";
     102static char *rcs_id = "$Id: _bsddb.c 81029 2010-05-09 14:46:46Z antoine.pitrou $";
    99103
    100104/* --------------------------------------------------------------------- */
     
    140144#if defined(MYDB_USE_GILSTATE)
    141145#define MYDB_BEGIN_BLOCK_THREADS \
    142                 PyGILState_STATE __savestate = PyGILState_Ensure();
     146                PyGILState_STATE __savestate = PyGILState_Ensure();
    143147#define MYDB_END_BLOCK_THREADS \
    144                 PyGILState_Release(__savestate);
     148                PyGILState_Release(__savestate);
    145149#else /* MYDB_USE_GILSTATE */
    146150/* Pre GILState API - do it the long old way */
     
    169173
    170174#endif
    171 
    172 /* Should DB_INCOMPLETE be turned into a warning or an exception? */
    173 #define INCOMPLETE_IS_WARNING 1
    174175
    175176/* --------------------------------------------------------------------- */
     
    192193static PyObject* DBSecondaryBadError;   /* DB_SECONDARY_BAD */
    193194
    194 #if !INCOMPLETE_IS_WARNING
    195 static PyObject* DBIncompleteError;     /* DB_INCOMPLETE */
    196 #endif
    197 
    198195static PyObject* DBInvalidArgError;     /* EINVAL */
    199196static PyObject* DBAccessError;         /* EACCES */
     
    209206static PyObject* DBRepHandleDeadError;  /* DB_REP_HANDLE_DEAD */
    210207#endif
     208#if (DBVER >= 44)
     209static PyObject* DBRepLockoutError;     /* DB_REP_LOCKOUT */
     210#endif
     211
     212#if (DBVER >= 46)
     213static PyObject* DBRepLeaseExpiredError; /* DB_REP_LEASE_EXPIRED */
     214#endif
     215
     216#if (DBVER >= 47)
     217static PyObject* DBForeignConflictError; /* DB_FOREIGN_CONFLICT */
     218#endif
     219
    211220
    212221static PyObject* DBRepUnavailError;     /* DB_REP_UNAVAIL */
    213222
    214223#if (DBVER < 43)
    215 #define DB_BUFFER_SMALL         ENOMEM
     224#define DB_BUFFER_SMALL         ENOMEM
     225#endif
     226
     227#if (DBVER < 48)
     228#define DB_GID_SIZE DB_XIDDATASIZE
    216229#endif
    217230
     
    239252
    240253staticforward PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type,
    241               DBLock_Type;
     254              DBLock_Type, DBLogCursor_Type;
    242255#if (DBVER >= 43)
    243256staticforward PyTypeObject DBSequence_Type;
     
    251264#define DBObject_Check(v)           (Py_TYPE(v) == &DB_Type)
    252265#define DBCursorObject_Check(v)     (Py_TYPE(v) == &DBCursor_Type)
     266#define DBLogCursorObject_Check(v)  (Py_TYPE(v) == &DBLogCursor_Type)
    253267#define DBEnvObject_Check(v)        (Py_TYPE(v) == &DBEnv_Type)
    254268#define DBTxnObject_Check(v)        (Py_TYPE(v) == &DBTxn_Type)
     
    356370        _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)
    357371
     372#define CHECK_LOGCURSOR_NOT_CLOSED(logcurs) \
     373        _CHECK_OBJECT_NOT_CLOSED(logcurs->logc, DBCursorClosedError, DBLogCursor)
     374
    358375#if (DBVER >= 43)
    359376#define CHECK_SEQUENCE_NOT_CLOSED(curs) \
     
    538555    srclen = strlen(src);
    539556    if (n <= 0)
    540         return srclen;
     557        return srclen;
    541558    copylen = (srclen > n-1) ? n-1 : srclen;
    542559    /* populate dest[0] thru dest[copylen-1] */
     
    555572#else
    556573static void _db_errorCallback(const DB_ENV *db_env,
    557         const char* prefix, const char* msg)
     574        const char* prefix, const char* msg)
    558575#endif
    559576{
     
    668685
    669686    switch (err) {
    670         case 0:                     /* successful, no error */      break;
    671 
    672 #if (DBVER < 41)
    673         case DB_INCOMPLETE:
    674 #if INCOMPLETE_IS_WARNING
    675             bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
    676             /* Ensure that bytes_left never goes negative */
    677             if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) {
    678                 bytes_left = sizeof(errTxt) - bytes_left - 4 - 1;
    679                 assert(bytes_left >= 0);
    680                 strcat(errTxt, " -- ");
    681                 strncat(errTxt, _db_errmsg, bytes_left);
    682             }
    683             _db_errmsg[0] = 0;
    684             exceptionRaised = PyErr_Warn(PyExc_RuntimeWarning, errTxt);
    685 
    686 #else  /* do an exception instead */
    687         errObj = DBIncompleteError;
    688 #endif
    689         break;
    690 #endif /* DBVER < 41 */
     687        case 0:                     /* successful, no error */
     688            return 0;
    691689
    692690        case DB_KEYEMPTY:           errObj = DBKeyEmptyError;       break;
     
    706704
    707705#if (DBVER >= 43)
    708         /* ENOMEM and DB_BUFFER_SMALL were one and the same until 4.3 */
    709         case ENOMEM:  errObj = PyExc_MemoryError;   break;
     706        /* ENOMEM and DB_BUFFER_SMALL were one and the same until 4.3 */
     707        case ENOMEM:  errObj = PyExc_MemoryError;   break;
    710708#endif
    711709        case EINVAL:  errObj = DBInvalidArgError;   break;
     
    720718#if (DBVER >= 42)
    721719        case DB_REP_HANDLE_DEAD : errObj = DBRepHandleDeadError; break;
     720#endif
     721#if (DBVER >= 44)
     722        case DB_REP_LOCKOUT : errObj = DBRepLockoutError; break;
     723#endif
     724
     725#if (DBVER >= 46)
     726        case DB_REP_LEASE_EXPIRED : errObj = DBRepLeaseExpiredError; break;
     727#endif
     728
     729#if (DBVER >= 47)
     730        case DB_FOREIGN_CONFLICT : errObj = DBForeignConflictError; break;
    722731#endif
    723732
     
    789798        return -1;
    790799    }
    791     self->haveStat = 0;
    792800    return 0;
    793801}
     
    806814        return -1;
    807815    }
    808     self->haveStat = 0;
    809816    return 0;
    810817}
     
    812819/* Get a key/data pair from a cursor */
    813820static PyObject* _DBCursor_get(DBCursorObject* self, int extra_flags,
    814                                PyObject *args, PyObject *kwargs, char *format)
     821                               PyObject *args, PyObject *kwargs, char *format)
    815822{
    816823    int err;
     
    823830
    824831    if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, kwnames,
    825                                      &flags, &dlen, &doff))
     832                                     &flags, &dlen, &doff))
    826833      return NULL;
    827834
     
    839846
    840847    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
    841             && self->mydb->moduleFlags.getReturnsNone) {
     848            && self->mydb->moduleFlags.getReturnsNone) {
    842849        Py_INCREF(Py_None);
    843850        retval = Py_None;
     
    883890{
    884891    PyObject* v;
    885         /* if the value fits in regular int, use that. */
     892        /* if the value fits in regular int, use that. */
    886893#ifdef PY_LONG_LONG
    887         if (sizeof(time_t) > sizeof(long))
    888                 v = PyLong_FromLongLong((PY_LONG_LONG) value);
    889         else
    890 #endif
    891                 v = NUMBER_FromLong((long) value);
     894        if (sizeof(time_t) > sizeof(long))
     895                v = PyLong_FromLongLong((PY_LONG_LONG) value);
     896        else
     897#endif
     898                v = NUMBER_FromLong((long) value);
    892899    if (!v || PyDict_SetItemString(dict, name, v))
    893900        PyErr_Clear();
     
    931938        return NULL;
    932939
    933     self->haveStat = 0;
    934940    self->flags = 0;
    935941    self->setflags = 0;
     
    10391045    INSERT_IN_DOUBLE_LINKED_LIST(self->mydb->children_cursors,self);
    10401046    if (txn && ((PyObject *)txn!=Py_None)) {
    1041             INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->children_cursors,self);
    1042             self->txn=txn;
     1047            INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->children_cursors,self);
     1048            self->txn=txn;
    10431049    } else {
    1044             self->txn=NULL;
     1050            self->txn=NULL;
    10451051    }
    10461052
     
    10781084
    10791085
     1086static DBLogCursorObject*
     1087newDBLogCursorObject(DB_LOGC* dblogc, DBEnvObject* env)
     1088{
     1089    DBLogCursorObject* self;
     1090
     1091    self = PyObject_New(DBLogCursorObject, &DBLogCursor_Type);
     1092
     1093    if (self == NULL)
     1094        return NULL;
     1095
     1096    self->logc = dblogc;
     1097    self->env = env;
     1098
     1099    INSERT_IN_DOUBLE_LINKED_LIST(self->env->children_logcursors, self);
     1100
     1101    self->in_weakreflist = NULL;
     1102    Py_INCREF(self->env);
     1103    return self;
     1104}
     1105
     1106
     1107/* Forward declaration */
     1108static PyObject *DBLogCursor_close_internal(DBLogCursorObject* self);
     1109
     1110static void
     1111DBLogCursor_dealloc(DBLogCursorObject* self)
     1112{
     1113    PyObject *dummy;
     1114
     1115    if (self->logc != NULL) {
     1116        dummy = DBLogCursor_close_internal(self);
     1117        /*
     1118        ** Raising exceptions while doing
     1119        ** garbage collection is a fatal error.
     1120        */
     1121        if (dummy)
     1122            Py_DECREF(dummy);
     1123        else
     1124            PyErr_Clear();
     1125    }
     1126    if (self->in_weakreflist != NULL) {
     1127        PyObject_ClearWeakRefs((PyObject *) self);
     1128    }
     1129    Py_DECREF(self->env);
     1130    PyObject_Del(self);
     1131}
     1132
     1133
    10801134static DBEnvObject*
    10811135newDBEnvObject(int flags)
     
    10931147    self->children_dbs = NULL;
    10941148    self->children_txns = NULL;
     1149    self->children_logcursors = NULL ;
    10951150    Py_INCREF(Py_None);
    10961151    self->private_obj = Py_None;
     
    11641219    self->parent_txn = NULL;
    11651220    self->env = NULL;
     1221    /* We initialize just in case "txn_begin" fails */
     1222    self->txn = NULL;
    11661223
    11671224    if (parent && ((PyObject *)parent!=Py_None)) {
     
    11771234
    11781235        if (makeDBError(err)) {
     1236            /* Free object half initialized */
    11791237            Py_DECREF(self);
    11801238            return NULL;
     
    12101268        int flag_prepare = self->flag_prepare;
    12111269
    1212         dummy=DBTxn_abort_discard_internal(self,0);
     1270        dummy=DBTxn_abort_discard_internal(self, 0);
    12131271        /*
    12141272        ** Raising exceptions while doing
     
    12331291        Py_DECREF(self->env);
    12341292    } else {
    1235         Py_DECREF(self->parent_txn);
     1293        /*
     1294        ** We can have "self->env==NULL" and "self->parent_txn==NULL"
     1295        ** if something happens when creating the transaction object
     1296        ** and we abort the object while half done.
     1297        */
     1298        Py_XDECREF(self->parent_txn);
    12361299    }
    12371300    PyObject_Del(self);
     
    12481311        return NULL;
    12491312    self->in_weakreflist = NULL;
     1313    self->lock_initialized = 0;  /* Just in case the call fails */
    12501314
    12511315    MYDB_BEGIN_ALLOW_THREADS;
     
    12561320        Py_DECREF(self);
    12571321        self = NULL;
     1322    } else {
     1323        self->lock_initialized = 1;
    12581324    }
    12591325
     
    12691335    }
    12701336    /* TODO: is this lock held? should we release it? */
     1337    /* CAUTION: The lock can be not initialized if the creation has failed */
    12711338
    12721339    PyObject_Del(self);
     
    12891356
    12901357    self->in_weakreflist = NULL;
     1358    self->sequence = NULL;  /* Just in case the call fails */
    12911359
    12921360    MYDB_BEGIN_ALLOW_THREADS;
     
    14071475            secKey->flags = DB_DBT_APPMALLOC;   /* DB will free */
    14081476            secKey->data = malloc(size);        /* TODO, check this */
    1409             if (secKey->data) {
    1410                 memcpy(secKey->data, data, size);
    1411                 secKey->size = size;
    1412                 retval = 0;
    1413             }
    1414             else {
    1415                 PyErr_SetString(PyExc_MemoryError,
     1477            if (secKey->data) {
     1478                memcpy(secKey->data, data, size);
     1479                secKey->size = size;
     1480                retval = 0;
     1481            }
     1482            else {
     1483                PyErr_SetString(PyExc_MemoryError,
    14161484                                "malloc failed in _db_associateCallback");
    1417                 PyErr_Print();
    1418             }
     1485                PyErr_Print();
     1486            }
    14191487        }
     1488#if (DBVER >= 46)
     1489        else if (PyList_Check(result))
     1490        {
     1491            char* data;
     1492            Py_ssize_t size;
     1493            int i, listlen;
     1494            DBT* dbts;
     1495
     1496            listlen = PyList_Size(result);
     1497
     1498            dbts = (DBT *)malloc(sizeof(DBT) * listlen);
     1499
     1500            for (i=0; i<listlen; i++)
     1501            {
     1502                if (!PyBytes_Check(PyList_GetItem(result, i)))
     1503                {
     1504                    PyErr_SetString(
     1505                       PyExc_TypeError,
     1506#if (PY_VERSION_HEX < 0x03000000)
     1507"The list returned by DB->associate callback should be a list of strings.");
     1508#else
     1509"The list returned by DB->associate callback should be a list of bytes.");
     1510#endif
     1511                    PyErr_Print();
     1512                }
     1513
     1514                PyBytes_AsStringAndSize(
     1515                    PyList_GetItem(result, i),
     1516                    &data, &size);
     1517
     1518                CLEAR_DBT(dbts[i]);
     1519                dbts[i].data = malloc(size);          /* TODO, check this */
     1520
     1521                if (dbts[i].data)
     1522                {
     1523                    memcpy(dbts[i].data, data, size);
     1524                    dbts[i].size = size;
     1525                    dbts[i].ulen = dbts[i].size;
     1526                    dbts[i].flags = DB_DBT_APPMALLOC;  /* DB will free */
     1527                }
     1528                else
     1529                {
     1530                    PyErr_SetString(PyExc_MemoryError,
     1531                        "malloc failed in _db_associateCallback (list)");
     1532                    PyErr_Print();
     1533                }
     1534            }
     1535
     1536            CLEAR_DBT(*secKey);
     1537
     1538            secKey->data = dbts;
     1539            secKey->size = listlen;
     1540            secKey->flags = DB_DBT_APPMALLOC | DB_DBT_MULTIPLE;
     1541            retval = 0;
     1542        }
     1543#endif
    14201544        else {
    14211545            PyErr_SetString(
    14221546               PyExc_TypeError,
    1423                "DB associate callback should return DB_DONOTINDEX or string.");
     1547#if (PY_VERSION_HEX < 0x03000000)
     1548"DB associate callback should return DB_DONOTINDEX/string/list of strings.");
     1549#else
     1550"DB associate callback should return DB_DONOTINDEX/bytes/list of bytes.");
     1551#endif
    14241552            PyErr_Print();
    14251553        }
     
    14401568    DBObject* secondaryDB;
    14411569    PyObject* callback;
    1442 #if (DBVER >= 41)
    14431570    PyObject *txnobj = NULL;
    14441571    DB_TXN *txn = NULL;
    14451572    static char* kwnames[] = {"secondaryDB", "callback", "flags", "txn",
    14461573                                    NULL};
    1447 #else
    1448     static char* kwnames[] = {"secondaryDB", "callback", "flags", NULL};
    1449 #endif
    1450 
    1451 #if (DBVER >= 41)
     1574
    14521575    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iO:associate", kwnames,
    14531576                                     &secondaryDB, &callback, &flags,
    14541577                                     &txnobj)) {
    1455 #else
    1456     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:associate", kwnames,
    1457                                      &secondaryDB, &callback, &flags)) {
    1458 #endif
    1459         return NULL;
    1460     }
    1461 
    1462 #if (DBVER >= 41)
     1578        return NULL;
     1579    }
     1580
    14631581    if (!checkTxnObj(txnobj, &txn)) return NULL;
    1464 #endif
    14651582
    14661583    CHECK_DB_NOT_CLOSED(self);
     
    14981615#endif
    14991616    MYDB_BEGIN_ALLOW_THREADS;
    1500 #if (DBVER >= 41)
    15011617    err = self->db->associate(self->db,
    1502                               txn,
     1618                              txn,
    15031619                              secondaryDB->db,
    15041620                              _db_associateCallback,
    15051621                              flags);
    1506 #else
    1507     err = self->db->associate(self->db,
    1508                               secondaryDB->db,
    1509                               _db_associateCallback,
    1510                               flags);
    1511 #endif
    15121622    MYDB_END_ALLOW_THREADS;
    15131623
     
    16181728
    16191729    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
    1620             && self->moduleFlags.getReturnsNone) {
     1730            && self->moduleFlags.getReturnsNone) {
    16211731        err = 0;
    16221732        Py_INCREF(Py_None);
     
    17021812
    17031813
     1814#if (DBVER >= 47)
     1815/*
     1816** This function is available since Berkeley DB 4.4,
     1817** but 4.6 version is so buggy that we only support
     1818** it from BDB 4.7 and newer.
     1819*/
     1820static PyObject*
     1821DB_compact(DBObject* self, PyObject* args, PyObject* kwargs)
     1822{
     1823    PyObject* txnobj = NULL;
     1824    PyObject *startobj = NULL, *stopobj = NULL;
     1825    int flags = 0;
     1826    DB_TXN *txn = NULL;
     1827    DBT *start_p = NULL, *stop_p = NULL;
     1828    DBT start, stop;
     1829    int err;
     1830    DB_COMPACT c_data = { 0 };
     1831    static char* kwnames[] = { "txn", "start", "stop", "flags",
     1832                               "compact_fillpercent", "compact_pages",
     1833                               "compact_timeout", NULL };
     1834
     1835
     1836    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOiiiI:compact", kwnames,
     1837                                     &txnobj, &startobj, &stopobj, &flags,
     1838                                     &c_data.compact_fillpercent,
     1839                                     &c_data.compact_pages,
     1840                                     &c_data.compact_timeout))
     1841        return NULL;
     1842
     1843    CHECK_DB_NOT_CLOSED(self);
     1844    if (!checkTxnObj(txnobj, &txn)) {
     1845        return NULL;
     1846    }
     1847
     1848    if (startobj && make_key_dbt(self, startobj, &start, NULL)) {
     1849        start_p = &start;
     1850    }
     1851    if (stopobj && make_key_dbt(self, stopobj, &stop, NULL)) {
     1852        stop_p = &stop;
     1853    }
     1854
     1855    MYDB_BEGIN_ALLOW_THREADS;
     1856    err = self->db->compact(self->db, txn, start_p, stop_p, &c_data,
     1857                            flags, NULL);
     1858    MYDB_END_ALLOW_THREADS;
     1859
     1860    if (startobj)
     1861        FREE_DBT(start);
     1862    if (stopobj)
     1863        FREE_DBT(stop);
     1864
     1865    RETURN_IF_ERR();
     1866
     1867    return PyLong_FromUnsignedLong(c_data.compact_pages_truncated);
     1868}
     1869#endif
     1870
     1871
    17041872static PyObject*
    17051873DB_fd(DBObject* self)
     
    17161884}
    17171885
     1886
     1887#if (DBVER >= 46)
     1888static PyObject*
     1889DB_exists(DBObject* self, PyObject* args, PyObject* kwargs)
     1890{
     1891    int err, flags=0;
     1892    PyObject* txnobj = NULL;
     1893    PyObject* keyobj;
     1894    DBT key;
     1895    DB_TXN *txn;
     1896
     1897    static char* kwnames[] = {"key", "txn", "flags", NULL};
     1898
     1899    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:exists", kwnames,
     1900                &keyobj, &txnobj, &flags))
     1901        return NULL;
     1902
     1903    CHECK_DB_NOT_CLOSED(self);
     1904    if (!make_key_dbt(self, keyobj, &key, NULL))
     1905        return NULL;
     1906    if (!checkTxnObj(txnobj, &txn)) {
     1907        FREE_DBT(key);
     1908        return NULL;
     1909    }
     1910
     1911    MYDB_BEGIN_ALLOW_THREADS;
     1912    err = self->db->exists(self->db, txn, &key, flags);
     1913    MYDB_END_ALLOW_THREADS;
     1914
     1915    FREE_DBT(key);
     1916
     1917    if (!err) {
     1918        Py_INCREF(Py_True);
     1919        return Py_True;
     1920    }
     1921    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)) {
     1922        Py_INCREF(Py_False);
     1923        return Py_False;
     1924    }
     1925
     1926    /*
     1927    ** If we reach there, there was an error. The
     1928    ** "return" should be unreachable.
     1929    */
     1930    RETURN_IF_ERR();
     1931    assert(0);  /* This coude SHOULD be unreachable */
     1932    return NULL;
     1933}
     1934#endif
    17181935
    17191936static PyObject*
     
    17651982    }
    17661983    else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
    1767              && self->moduleFlags.getReturnsNone) {
     1984             && self->moduleFlags.getReturnsNone) {
    17681985        err = 0;
    17691986        Py_INCREF(Py_None);
     
    18342051    }
    18352052    else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
    1836              && self->moduleFlags.getReturnsNone) {
     2053             && self->moduleFlags.getReturnsNone) {
    18372054        err = 0;
    18382055        Py_INCREF(Py_None);
     
    19692186
    19702187    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
    1971             && self->moduleFlags.getReturnsNone) {
     2188            && self->moduleFlags.getReturnsNone) {
    19722189        err = 0;
    19732190        Py_INCREF(Py_None);
     
    20432260    cursors = malloc((length+1) * sizeof(DBC*));
    20442261    if (!cursors) {
    2045         PyErr_NoMemory();
    2046         return NULL;
     2262        PyErr_NoMemory();
     2263        return NULL;
    20472264    }
    20482265
     
    21152332    char* filename = NULL;
    21162333    char* dbname = NULL;
    2117 #if (DBVER >= 41)
    21182334    PyObject *txnobj = NULL;
    21192335    DB_TXN *txn = NULL;
     
    21242340    static char* kwnames_basic[] = {
    21252341        "filename", "dbtype", "flags", "mode", "txn", NULL};
    2126 #else
    2127     /* with dbname */
    2128     static char* kwnames[] = {
    2129         "filename", "dbname", "dbtype", "flags", "mode", NULL};
    2130     /* without dbname */
    2131     static char* kwnames_basic[] = {
    2132         "filename", "dbtype", "flags", "mode", NULL};
    2133 #endif
    2134 
    2135 #if (DBVER >= 41)
     2342
    21362343    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziiiO:open", kwnames,
    2137                                      &filename, &dbname, &type, &flags, &mode,
     2344                                     &filename, &dbname, &type, &flags, &mode,
    21382345                                     &txnobj))
    2139 #else
    2140     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziii:open", kwnames,
    2141                                      &filename, &dbname, &type, &flags,
    2142                                      &mode))
    2143 #endif
    21442346    {
    2145         PyErr_Clear();
    2146         type = DB_UNKNOWN; flags = 0; mode = 0660;
    2147         filename = NULL; dbname = NULL;
    2148 #if (DBVER >= 41)
    2149         if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iiiO:open",
     2347        PyErr_Clear();
     2348        type = DB_UNKNOWN; flags = 0; mode = 0660;
     2349        filename = NULL; dbname = NULL;
     2350        if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iiiO:open",
    21502351                                         kwnames_basic,
    2151                                         &filename, &type, &flags, &mode,
     2352                                        &filename, &type, &flags, &mode,
    21522353                                         &txnobj))
    2153             return NULL;
    2154 #else
    2155         if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iii:open",
    2156                                          kwnames_basic,
    2157                                          &filename, &type, &flags, &mode))
    2158             return NULL;
    2159 #endif
    2160     }
    2161 
    2162 #if (DBVER >= 41)
     2354            return NULL;
     2355    }
     2356
    21632357    if (!checkTxnObj(txnobj, &txn)) return NULL;
    2164 #endif
    21652358
    21662359    if (NULL == self->db) {
     
    21742367    }
    21752368
    2176 #if (DBVER >= 41)
    21772369    if (txn) {  /* Can't use 'txnobj' because could be 'txnobj==Py_None' */
    21782370        INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_dbs,self);
     
    21812373        self->txn=NULL;
    21822374    }
    2183 #else
    2184     self->txn=NULL;
    2185 #endif
    2186 
    2187     MYDB_BEGIN_ALLOW_THREADS;
    2188 #if (DBVER >= 41)
     2375
     2376    MYDB_BEGIN_ALLOW_THREADS;
    21892377    err = self->db->open(self->db, txn, filename, dbname, type, flags, mode);
    2190 #else
    2191     err = self->db->open(self->db, filename, dbname, type, flags, mode);
    2192 #endif
    2193     MYDB_END_ALLOW_THREADS;
     2378    MYDB_END_ALLOW_THREADS;
     2379
    21942380    if (makeDBError(err)) {
    21952381        PyObject *dummy;
     
    23202506}
    23212507
     2508#if (DBVER >= 46)
     2509static PyObject*
     2510DB_set_priority(DBObject* self, PyObject* args)
     2511{
     2512    int err, priority;
     2513
     2514    if (!PyArg_ParseTuple(args,"i:set_priority", &priority))
     2515        return NULL;
     2516    CHECK_DB_NOT_CLOSED(self);
     2517
     2518    MYDB_BEGIN_ALLOW_THREADS;
     2519    err = self->db->set_priority(self->db, priority);
     2520    MYDB_END_ALLOW_THREADS;
     2521    RETURN_IF_ERR();
     2522    RETURN_NONE();
     2523}
     2524
     2525static PyObject*
     2526DB_get_priority(DBObject* self)
     2527{
     2528    int err = 0;
     2529    DB_CACHE_PRIORITY priority;
     2530
     2531    CHECK_DB_NOT_CLOSED(self);
     2532
     2533    MYDB_BEGIN_ALLOW_THREADS;
     2534    err = self->db->get_priority(self->db, &priority);
     2535    MYDB_END_ALLOW_THREADS;
     2536    RETURN_IF_ERR();
     2537    return NUMBER_FromLong(priority);
     2538}
     2539#endif
     2540
     2541static PyObject*
     2542DB_set_q_extentsize(DBObject* self, PyObject* args)
     2543{
     2544    int err;
     2545    u_int32_t extentsize;
     2546
     2547    if (!PyArg_ParseTuple(args,"i:set_q_extentsize", &extentsize))
     2548        return NULL;
     2549    CHECK_DB_NOT_CLOSED(self);
     2550
     2551    MYDB_BEGIN_ALLOW_THREADS;
     2552    err = self->db->set_q_extentsize(self->db, extentsize);
     2553    MYDB_END_ALLOW_THREADS;
     2554    RETURN_IF_ERR();
     2555    RETURN_NONE();
     2556}
     2557
     2558#if (DBVER >= 42)
     2559static PyObject*
     2560DB_get_q_extentsize(DBObject* self)
     2561{
     2562    int err = 0;
     2563    u_int32_t extentsize;
     2564
     2565    CHECK_DB_NOT_CLOSED(self);
     2566
     2567    MYDB_BEGIN_ALLOW_THREADS;
     2568    err = self->db->get_q_extentsize(self->db, &extentsize);
     2569    MYDB_END_ALLOW_THREADS;
     2570    RETURN_IF_ERR();
     2571    return NUMBER_FromLong(extentsize);
     2572}
     2573#endif
    23222574
    23232575static PyObject*
     
    23262578    int err, minkey;
    23272579
    2328     if (!PyArg_ParseTuple(args,"i:set_bt_minkey", &minkey ))
     2580    if (!PyArg_ParseTuple(args,"i:set_bt_minkey", &minkey))
    23292581        return NULL;
    23302582    CHECK_DB_NOT_CLOSED(self);
     
    23362588    RETURN_NONE();
    23372589}
     2590
     2591#if (DBVER >= 42)
     2592static PyObject*
     2593DB_get_bt_minkey(DBObject* self)
     2594{
     2595    int err;
     2596    u_int32_t bt_minkey;
     2597
     2598    CHECK_DB_NOT_CLOSED(self);
     2599
     2600    MYDB_BEGIN_ALLOW_THREADS;
     2601    err = self->db->get_bt_minkey(self->db, &bt_minkey);
     2602    MYDB_END_ALLOW_THREADS;
     2603    RETURN_IF_ERR();
     2604    return NUMBER_FromLong(bt_minkey);
     2605}
     2606#endif
    23382607
    23392608static int
    23402609_default_cmp(const DBT *leftKey,
    2341              const DBT *rightKey)
     2610             const DBT *rightKey)
    23422611{
    23432612  int res;
     
    23452614
    23462615  res = memcmp(leftKey->data, rightKey->data,
    2347                lsize < rsize ? lsize : rsize);
     2616               lsize < rsize ? lsize : rsize);
    23482617
    23492618  if (res == 0) {
    23502619      if (lsize < rsize) {
    2351           res = -1;
     2620          res = -1;
    23522621      }
    23532622      else if (lsize > rsize) {
    2354           res = 1;
     2623          res = 1;
    23552624      }
    23562625  }
     
    23602629static int
    23612630_db_compareCallback(DB* db,
    2362                     const DBT *leftKey,
    2363                     const DBT *rightKey)
     2631                    const DBT *leftKey,
     2632                    const DBT *rightKey)
    23642633{
    23652634    int res = 0;
     
    23692638
    23702639    if (self == NULL || self->btCompareCallback == NULL) {
    2371         MYDB_BEGIN_BLOCK_THREADS;
    2372         PyErr_SetString(PyExc_TypeError,
    2373                         (self == 0
    2374                         ? "DB_bt_compare db is NULL."
    2375                         : "DB_bt_compare callback is NULL."));
    2376         /* we're in a callback within the DB code, we can't raise */
    2377         PyErr_Print();
    2378         res = _default_cmp(leftKey, rightKey);
    2379         MYDB_END_BLOCK_THREADS;
     2640        MYDB_BEGIN_BLOCK_THREADS;
     2641        PyErr_SetString(PyExc_TypeError,
     2642                        (self == 0
     2643                        ? "DB_bt_compare db is NULL."
     2644                        : "DB_bt_compare callback is NULL."));
     2645        /* we're in a callback within the DB code, we can't raise */
     2646        PyErr_Print();
     2647        res = _default_cmp(leftKey, rightKey);
     2648        MYDB_END_BLOCK_THREADS;
    23802649    } else {
    2381         MYDB_BEGIN_BLOCK_THREADS;
    2382 
    2383         args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
    2384         if (args != NULL) {
    2385                 result = PyEval_CallObject(self->btCompareCallback, args);
    2386         }
    2387         if (args == NULL || result == NULL) {
    2388             /* we're in a callback within the DB code, we can't raise */
    2389             PyErr_Print();
    2390             res = _default_cmp(leftKey, rightKey);
    2391         } else if (NUMBER_Check(result)) {
    2392             res = NUMBER_AsLong(result);
    2393         } else {
    2394             PyErr_SetString(PyExc_TypeError,
    2395                             "DB_bt_compare callback MUST return an int.");
    2396             /* we're in a callback within the DB code, we can't raise */
    2397             PyErr_Print();
    2398             res = _default_cmp(leftKey, rightKey);
    2399         }
    2400 
    2401         Py_XDECREF(args);
    2402         Py_XDECREF(result);
    2403 
    2404         MYDB_END_BLOCK_THREADS;
     2650        MYDB_BEGIN_BLOCK_THREADS;
     2651
     2652        args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
     2653        if (args != NULL) {
     2654                result = PyEval_CallObject(self->btCompareCallback, args);
     2655        }
     2656        if (args == NULL || result == NULL) {
     2657            /* we're in a callback within the DB code, we can't raise */
     2658            PyErr_Print();
     2659            res = _default_cmp(leftKey, rightKey);
     2660        } else if (NUMBER_Check(result)) {
     2661            res = NUMBER_AsLong(result);
     2662        } else {
     2663            PyErr_SetString(PyExc_TypeError,
     2664                            "DB_bt_compare callback MUST return an int.");
     2665            /* we're in a callback within the DB code, we can't raise */
     2666            PyErr_Print();
     2667            res = _default_cmp(leftKey, rightKey);
     2668        }
     2669
     2670        Py_XDECREF(args);
     2671        Py_XDECREF(result);
     2672
     2673        MYDB_END_BLOCK_THREADS;
    24052674    }
    24062675    return res;
     
    24162685
    24172686    if (!PyCallable_Check(comparator)) {
    2418         makeTypeError("Callable", comparator);
    2419         return NULL;
     2687        makeTypeError("Callable", comparator);
     2688        return NULL;
    24202689    }
    24212690
     
    24312700        return NULL;
    24322701    if (!NUMBER_Check(result)) {
    2433         Py_DECREF(result);
    2434         PyErr_SetString(PyExc_TypeError,
    2435                         "callback MUST return an int");
    2436         return NULL;
     2702        Py_DECREF(result);
     2703        PyErr_SetString(PyExc_TypeError,
     2704                        "callback MUST return an int");
     2705        return NULL;
    24372706    } else if (NUMBER_AsLong(result) != 0) {
    2438         Py_DECREF(result);
    2439         PyErr_SetString(PyExc_TypeError,
    2440                         "callback failed to return 0 on two empty strings");
    2441         return NULL;
     2707        Py_DECREF(result);
     2708        PyErr_SetString(PyExc_TypeError,
     2709                        "callback failed to return 0 on two empty strings");
     2710        return NULL;
    24422711    }
    24432712    Py_DECREF(result);
     
    24472716     * change the function once the db is opened anyway */
    24482717    if (self->btCompareCallback != NULL) {
    2449         PyErr_SetString(PyExc_RuntimeError, "set_bt_compare() cannot be called more than once");
    2450         return NULL;
     2718        PyErr_SetString(PyExc_RuntimeError, "set_bt_compare() cannot be called more than once");
     2719        return NULL;
    24512720    }
    24522721
     
    24632732
    24642733    if (err) {
    2465         /* restore the old state in case of error */
    2466         Py_DECREF(comparator);
    2467         self->btCompareCallback = NULL;
     2734        /* restore the old state in case of error */
     2735        Py_DECREF(comparator);
     2736        self->btCompareCallback = NULL;
    24682737    }
    24692738
     
    24912760}
    24922761
     2762#if (DBVER >= 42)
     2763static PyObject*
     2764DB_get_cachesize(DBObject* self)
     2765{
     2766    int err;
     2767    u_int32_t gbytes, bytes;
     2768    int ncache;
     2769
     2770    CHECK_DB_NOT_CLOSED(self);
     2771
     2772    MYDB_BEGIN_ALLOW_THREADS;
     2773    err = self->db->get_cachesize(self->db, &gbytes, &bytes, &ncache);
     2774    MYDB_END_ALLOW_THREADS;
     2775
     2776    RETURN_IF_ERR();
     2777
     2778    return Py_BuildValue("(iii)", gbytes, bytes, ncache);
     2779}
     2780#endif
    24932781
    24942782static PyObject*
     
    25102798}
    25112799
     2800#if (DBVER >= 42)
     2801static PyObject*
     2802DB_get_flags(DBObject* self)
     2803{
     2804    int err;
     2805    u_int32_t flags;
     2806
     2807    CHECK_DB_NOT_CLOSED(self);
     2808
     2809    MYDB_BEGIN_ALLOW_THREADS;
     2810    err = self->db->get_flags(self->db, &flags);
     2811    MYDB_END_ALLOW_THREADS;
     2812    RETURN_IF_ERR();
     2813    return NUMBER_FromLong(flags);
     2814}
     2815#endif
    25122816
    25132817static PyObject*
     
    25272831}
    25282832
     2833#if (DBVER >= 42)
     2834static PyObject*
     2835DB_get_h_ffactor(DBObject* self)
     2836{
     2837    int err;
     2838    u_int32_t ffactor;
     2839
     2840    CHECK_DB_NOT_CLOSED(self);
     2841
     2842    MYDB_BEGIN_ALLOW_THREADS;
     2843    err = self->db->get_h_ffactor(self->db, &ffactor);
     2844    MYDB_END_ALLOW_THREADS;
     2845    RETURN_IF_ERR();
     2846    return NUMBER_FromLong(ffactor);
     2847}
     2848#endif
    25292849
    25302850static PyObject*
     
    25442864}
    25452865
     2866#if (DBVER >= 42)
     2867static PyObject*
     2868DB_get_h_nelem(DBObject* self)
     2869{
     2870    int err;
     2871    u_int32_t nelem;
     2872
     2873    CHECK_DB_NOT_CLOSED(self);
     2874
     2875    MYDB_BEGIN_ALLOW_THREADS;
     2876    err = self->db->get_h_nelem(self->db, &nelem);
     2877    MYDB_END_ALLOW_THREADS;
     2878    RETURN_IF_ERR();
     2879    return NUMBER_FromLong(nelem);
     2880}
     2881#endif
    25462882
    25472883static PyObject*
     
    25612897}
    25622898
     2899#if (DBVER >= 42)
     2900static PyObject*
     2901DB_get_lorder(DBObject* self)
     2902{
     2903    int err;
     2904    int lorder;
     2905
     2906    CHECK_DB_NOT_CLOSED(self);
     2907
     2908    MYDB_BEGIN_ALLOW_THREADS;
     2909    err = self->db->get_lorder(self->db, &lorder);
     2910    MYDB_END_ALLOW_THREADS;
     2911    RETURN_IF_ERR();
     2912    return NUMBER_FromLong(lorder);
     2913}
     2914#endif
    25632915
    25642916static PyObject*
     
    25782930}
    25792931
     2932#if (DBVER >= 42)
     2933static PyObject*
     2934DB_get_pagesize(DBObject* self)
     2935{
     2936    int err;
     2937    u_int32_t pagesize;
     2938
     2939    CHECK_DB_NOT_CLOSED(self);
     2940
     2941    MYDB_BEGIN_ALLOW_THREADS;
     2942    err = self->db->get_pagesize(self->db, &pagesize);
     2943    MYDB_END_ALLOW_THREADS;
     2944    RETURN_IF_ERR();
     2945    return NUMBER_FromLong(pagesize);
     2946}
     2947#endif
    25802948
    25812949static PyObject*
     
    26002968}
    26012969
     2970#if (DBVER >= 42)
     2971static PyObject*
     2972DB_get_re_delim(DBObject* self)
     2973{
     2974    int err, re_delim;
     2975
     2976    CHECK_DB_NOT_CLOSED(self);
     2977
     2978    MYDB_BEGIN_ALLOW_THREADS;
     2979    err = self->db->get_re_delim(self->db, &re_delim);
     2980    MYDB_END_ALLOW_THREADS;
     2981    RETURN_IF_ERR();
     2982    return NUMBER_FromLong(re_delim);
     2983}
     2984#endif
     2985
    26022986static PyObject*
    26032987DB_set_re_len(DBObject* self, PyObject* args)
     
    26163000}
    26173001
     3002#if (DBVER >= 42)
     3003static PyObject*
     3004DB_get_re_len(DBObject* self)
     3005{
     3006    int err;
     3007    u_int32_t re_len;
     3008
     3009    CHECK_DB_NOT_CLOSED(self);
     3010
     3011    MYDB_BEGIN_ALLOW_THREADS;
     3012    err = self->db->get_re_len(self->db, &re_len);
     3013    MYDB_END_ALLOW_THREADS;
     3014    RETURN_IF_ERR();
     3015    return NUMBER_FromLong(re_len);
     3016}
     3017#endif
    26183018
    26193019static PyObject*
     
    26373037}
    26383038
     3039#if (DBVER >= 42)
     3040static PyObject*
     3041DB_get_re_pad(DBObject* self)
     3042{
     3043    int err, re_pad;
     3044
     3045    CHECK_DB_NOT_CLOSED(self);
     3046
     3047    MYDB_BEGIN_ALLOW_THREADS;
     3048    err = self->db->get_re_pad(self->db, &re_pad);
     3049    MYDB_END_ALLOW_THREADS;
     3050    RETURN_IF_ERR();
     3051    return NUMBER_FromLong(re_pad);
     3052}
     3053#endif
    26393054
    26403055static PyObject*
     
    26423057{
    26433058    int err;
    2644     char *re_source;
    2645 
    2646     if (!PyArg_ParseTuple(args,"s:set_re_source", &re_source))
     3059    char *source;
     3060
     3061    if (!PyArg_ParseTuple(args,"s:set_re_source", &source))
    26473062        return NULL;
    26483063    CHECK_DB_NOT_CLOSED(self);
    26493064
    26503065    MYDB_BEGIN_ALLOW_THREADS;
    2651     err = self->db->set_re_source(self->db, re_source);
    2652     MYDB_END_ALLOW_THREADS;
    2653     RETURN_IF_ERR();
    2654     RETURN_NONE();
    2655 }
    2656 
    2657 
    2658 static PyObject*
    2659 DB_set_q_extentsize(DBObject* self, PyObject* args)
    2660 {
    2661     int err;
    2662     int extentsize;
    2663 
    2664     if (!PyArg_ParseTuple(args,"i:set_q_extentsize", &extentsize))
    2665         return NULL;
     3066    err = self->db->set_re_source(self->db, source);
     3067    MYDB_END_ALLOW_THREADS;
     3068    RETURN_IF_ERR();
     3069    RETURN_NONE();
     3070}
     3071
     3072#if (DBVER >= 42)
     3073static PyObject*
     3074DB_get_re_source(DBObject* self)
     3075{
     3076    int err;
     3077    const char *source;
     3078
    26663079    CHECK_DB_NOT_CLOSED(self);
    26673080
    26683081    MYDB_BEGIN_ALLOW_THREADS;
    2669     err = self->db->set_q_extentsize(self->db, extentsize);
    2670     MYDB_END_ALLOW_THREADS;
    2671     RETURN_IF_ERR();
    2672     RETURN_NONE();
    2673 }
     3082    err = self->db->get_re_source(self->db, &source);
     3083    MYDB_END_ALLOW_THREADS;
     3084    RETURN_IF_ERR();
     3085    return PyBytes_FromString(source);
     3086}
     3087#endif
    26743088
    26753089static PyObject*
     
    27083122    RETURN_IF_ERR();
    27093123
    2710     self->haveStat = 1;
    2711 
    27123124    /* Turn the stat structure into a dictionary */
    27133125    type = _DB_get_type(self);
     
    27313143#endif
    27323144        MAKE_HASH_ENTRY(pagesize);
    2733 #if (DBVER < 41)
    2734         MAKE_HASH_ENTRY(nelem);
    2735 #endif
    27363145        MAKE_HASH_ENTRY(ffactor);
    27373146        MAKE_HASH_ENTRY(buckets);
     
    27803189        MAKE_QUEUE_ENTRY(ndata);
    27813190        MAKE_QUEUE_ENTRY(pagesize);
    2782 #if (DBVER >= 41)
    27833191        MAKE_QUEUE_ENTRY(extentsize);
    2784 #endif
    27853192        MAKE_QUEUE_ENTRY(pages);
    27863193        MAKE_QUEUE_ENTRY(re_len);
     
    28073214    return d;
    28083215}
     3216
     3217#if (DBVER >= 43)
     3218static PyObject*
     3219DB_stat_print(DBObject* self, PyObject* args, PyObject *kwargs)
     3220{
     3221    int err;
     3222    int flags=0;
     3223    static char* kwnames[] = { "flags", NULL };
     3224
     3225    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
     3226                kwnames, &flags))
     3227    {
     3228        return NULL;
     3229    }
     3230    CHECK_DB_NOT_CLOSED(self);
     3231    MYDB_BEGIN_ALLOW_THREADS;
     3232    err = self->db->stat_print(self->db, flags);
     3233    MYDB_END_ALLOW_THREADS;
     3234    RETURN_IF_ERR();
     3235    RETURN_NONE();
     3236}
     3237#endif
     3238
    28093239
    28103240static PyObject*
     
    28863316    if (outFileName)
    28873317        outFile = fopen(outFileName, "w");
    2888         /* XXX(nnorwitz): it should probably be an exception if outFile
    2889            can't be opened. */
     3318        /* XXX(nnorwitz): it should probably be an exception if outFile
     3319           can't be opened. */
    28903320
    28913321    {  /* DB.verify acts as a DB handle destructor (like close) */
     
    28933323
    28943324        error=DB_close_internal(self, 0, 1);
    2895         if (error ) {
     3325        if (error) {
    28963326          return error;
    28973327        }
     
    29313361}
    29323362
    2933 #if (DBVER >= 41)
    29343363static PyObject*
    29353364DB_set_encrypt(DBObject* self, PyObject* args, PyObject* kwargs)
     
    29413370
    29423371    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
    2943                 &passwd, &flags)) {
    2944         return NULL;
     3372                &passwd, &flags)) {
     3373        return NULL;
    29453374    }
    29463375
     
    29523381    RETURN_NONE();
    29533382}
    2954 #endif /* DBVER >= 41 */
     3383
     3384#if (DBVER >= 42)
     3385static PyObject*
     3386DB_get_encrypt_flags(DBObject* self)
     3387{
     3388    int err;
     3389    u_int32_t flags;
     3390
     3391    MYDB_BEGIN_ALLOW_THREADS;
     3392    err = self->db->get_encrypt_flags(self->db, &flags);
     3393    MYDB_END_ALLOW_THREADS;
     3394
     3395    RETURN_IF_ERR();
     3396
     3397    return NUMBER_FromLong(flags);
     3398}
     3399#endif
     3400
    29553401
    29563402
     
    29623408    int err;
    29633409    Py_ssize_t size = 0;
    2964     int flags = 0;
    29653410    void* sp;
    29663411    DBObject* self = (DBObject*)_self;
     
    29753420    }
    29763421
    2977     if (self->haveStat) {  /* Has the stat function been called recently?  If
    2978                               so, we can use the cached value. */
    2979         flags = DB_FAST_STAT;
    2980     }
    2981 
    2982     MYDB_BEGIN_ALLOW_THREADS;
    2983 redo_stat_for_length:
     3422    MYDB_BEGIN_ALLOW_THREADS;
    29843423#if (DBVER >= 43)
    2985     err = self->db->stat(self->db, /*txnid*/ NULL, &sp, flags);
     3424    err = self->db->stat(self->db, /*txnid*/ NULL, &sp, 0);
    29863425#else
    2987     err = self->db->stat(self->db, &sp, flags);
    2988 #endif
     3426    err = self->db->stat(self->db, &sp, 0);
     3427#endif
     3428    MYDB_END_ALLOW_THREADS;
    29893429
    29903430    /* All the stat structures have matching fields upto the ndata field,
     
    29923432    size = ((DB_BTREE_STAT*)sp)->bt_ndata;
    29933433
    2994     /* A size of 0 could mean that Berkeley DB no longer had the stat values cached.
    2995      * redo a full stat to make sure.
    2996      *   Fixes SF python bug 1493322, pybsddb bug 1184012
    2997      */
    2998     if (size == 0 && (flags & DB_FAST_STAT)) {
    2999         flags = 0;
    3000         if (!err)
    3001             free(sp);
    3002         goto redo_stat_for_length;
    3003     }
    3004 
    3005     MYDB_END_ALLOW_THREADS;
    3006 
    30073434    if (err)
    30083435        return -1;
    3009 
    3010     self->haveStat = 1;
    30113436
    30123437    free(sp);
     
    30983523
    30993524static PyObject*
    3100 DB_has_key(DBObject* self, PyObject* args, PyObject* kwargs)
    3101 {
    3102     int err;
    3103     PyObject* keyobj;
    3104     DBT key, data;
    3105     PyObject* txnobj = NULL;
     3525_DB_has_key(DBObject* self, PyObject* keyobj, PyObject* txnobj)
     3526{
     3527    int err;
     3528    DBT key;
    31063529    DB_TXN *txn = NULL;
    3107     static char* kwnames[] = {"key","txn", NULL};
    3108 
    3109     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:has_key", kwnames,
    3110                 &keyobj, &txnobj))
    3111         return NULL;
    31123530
    31133531    CHECK_DB_NOT_CLOSED(self);
     
    31193537    }
    31203538
     3539#if (DBVER < 46)
    31213540    /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
    31223541       it has a record but can't allocate a buffer for the data.  This saves
    31233542       having to deal with data we won't be using.
    31243543     */
    3125     CLEAR_DBT(data);
    3126     data.flags = DB_DBT_USERMEM;
    3127 
    3128     MYDB_BEGIN_ALLOW_THREADS;
    3129     err = self->db->get(self->db, txn, &key, &data, 0);
    3130     MYDB_END_ALLOW_THREADS;
     3544    {
     3545        DBT data ;
     3546        CLEAR_DBT(data);
     3547        data.flags = DB_DBT_USERMEM;
     3548
     3549        MYDB_BEGIN_ALLOW_THREADS;
     3550        err = self->db->get(self->db, txn, &key, &data, 0);
     3551        MYDB_END_ALLOW_THREADS;
     3552    }
     3553#else
     3554    MYDB_BEGIN_ALLOW_THREADS;
     3555    err = self->db->exists(self->db, txn, &key, 0);
     3556    MYDB_END_ALLOW_THREADS;
     3557#endif
     3558
    31313559    FREE_DBT(key);
    31323560
     3561    /*
     3562    ** DB_BUFFER_SMALL is only used if we use "get".
     3563    ** We can drop it when we only use "exists",
     3564    ** when we drop suport for Berkeley DB < 4.6.
     3565    */
    31333566    if (err == DB_BUFFER_SMALL || err == 0) {
    3134         return NUMBER_FromLong(1);
     3567        Py_INCREF(Py_True);
     3568        return Py_True;
    31353569    } else if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
    3136         return NUMBER_FromLong(0);
     3570        Py_INCREF(Py_False);
     3571        return Py_False;
    31373572    }
    31383573
    31393574    makeDBError(err);
    31403575    return NULL;
     3576}
     3577
     3578static PyObject*
     3579DB_has_key(DBObject* self, PyObject* args, PyObject* kwargs)
     3580{
     3581    PyObject* keyobj;
     3582    PyObject* txnobj = NULL;
     3583    static char* kwnames[] = {"key","txn", NULL};
     3584
     3585    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:has_key", kwnames,
     3586                &keyobj, &txnobj))
     3587        return NULL;
     3588
     3589    return _DB_has_key(self, keyobj, txnobj);
     3590}
     3591
     3592
     3593static int DB_contains(DBObject* self, PyObject* keyobj)
     3594{
     3595    PyObject* result;
     3596    int result2 = 0;
     3597
     3598    result = _DB_has_key(self, keyobj, NULL) ;
     3599    if (result == NULL) {
     3600        return -1; /* Propague exception */
     3601    }
     3602    if (result != Py_False) {
     3603        result2 = 1;
     3604    }
     3605
     3606    Py_DECREF(result);
     3607    return result2;
    31413608}
    31423609
     
    32943761
    32953762/* --------------------------------------------------------------------- */
     3763/* DBLogCursor methods */
     3764
     3765
     3766static PyObject*
     3767DBLogCursor_close_internal(DBLogCursorObject* self)
     3768{
     3769    int err = 0;
     3770
     3771    if (self->logc != NULL) {
     3772        EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
     3773
     3774        MYDB_BEGIN_ALLOW_THREADS;
     3775        err = self->logc->close(self->logc, 0);
     3776        MYDB_END_ALLOW_THREADS;
     3777        self->logc = NULL;
     3778    }
     3779    RETURN_IF_ERR();
     3780    RETURN_NONE();
     3781}
     3782
     3783static PyObject*
     3784DBLogCursor_close(DBLogCursorObject* self)
     3785{
     3786    return DBLogCursor_close_internal(self);
     3787}
     3788
     3789
     3790static PyObject*
     3791_DBLogCursor_get(DBLogCursorObject* self, int flag, DB_LSN *lsn2)
     3792{
     3793    int err;
     3794    DBT data;
     3795    DB_LSN lsn = {0, 0};
     3796    PyObject *dummy, *retval;
     3797
     3798    CLEAR_DBT(data);
     3799    data.flags = DB_DBT_MALLOC; /* Berkeley DB must do the malloc */
     3800
     3801    CHECK_LOGCURSOR_NOT_CLOSED(self);
     3802
     3803    if (lsn2)
     3804        lsn = *lsn2;
     3805
     3806    MYDB_BEGIN_ALLOW_THREADS;
     3807    err = self->logc->get(self->logc, &lsn, &data, flag);
     3808    MYDB_END_ALLOW_THREADS;
     3809
     3810    if (err == DB_NOTFOUND) {
     3811        Py_INCREF(Py_None);
     3812        retval = Py_None;
     3813    }
     3814    else if (makeDBError(err)) {
     3815        retval = NULL;
     3816    }
     3817    else {
     3818        retval = dummy = BuildValue_S(data.data, data.size);
     3819        if (dummy) {
     3820            retval = Py_BuildValue("(ii)O", lsn.file, lsn.offset, dummy);
     3821            Py_DECREF(dummy);
     3822        }
     3823    }
     3824
     3825    FREE_DBT(data);
     3826    return retval;
     3827}
     3828
     3829static PyObject*
     3830DBLogCursor_current(DBLogCursorObject* self)
     3831{
     3832    return _DBLogCursor_get(self, DB_CURRENT, NULL);
     3833}
     3834
     3835static PyObject*
     3836DBLogCursor_first(DBLogCursorObject* self)
     3837{
     3838    return _DBLogCursor_get(self, DB_FIRST, NULL);
     3839}
     3840
     3841static PyObject*
     3842DBLogCursor_last(DBLogCursorObject* self)
     3843{
     3844    return _DBLogCursor_get(self, DB_LAST, NULL);
     3845}
     3846
     3847static PyObject*
     3848DBLogCursor_next(DBLogCursorObject* self)
     3849{
     3850    return _DBLogCursor_get(self, DB_NEXT, NULL);
     3851}
     3852
     3853static PyObject*
     3854DBLogCursor_prev(DBLogCursorObject* self)
     3855{
     3856    return _DBLogCursor_get(self, DB_PREV, NULL);
     3857}
     3858
     3859static PyObject*
     3860DBLogCursor_set(DBLogCursorObject* self, PyObject* args)
     3861{
     3862    DB_LSN lsn;
     3863
     3864    if (!PyArg_ParseTuple(args, "(ii):set", &lsn.file, &lsn.offset))
     3865        return NULL;
     3866
     3867    return _DBLogCursor_get(self, DB_SET, &lsn);
     3868}
     3869
     3870
     3871
     3872/* --------------------------------------------------------------------- */
    32963873/* DBCursor methods */
    32973874
     
    33683945    RETURN_IF_ERR();
    33693946
    3370     self->mydb->haveStat = 0;
    33713947    RETURN_NONE();
    33723948}
     
    34153991    CLEAR_DBT(data);
    34163992    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:get", &kwnames[2],
    3417                                      &flags, &dlen, &doff))
     3993                                     &flags, &dlen, &doff))
    34183994    {
    34193995        PyErr_Clear();
    34203996        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:get",
    34213997                                         &kwnames[1],
    3422                                         &keyobj, &flags, &dlen, &doff))
     3998                                        &keyobj, &flags, &dlen, &doff))
    34233999        {
    34244000            PyErr_Clear();
     
    34284004            {
    34294005                return NULL;
    3430             }
    3431         }
     4006            }
     4007        }
    34324008    }
    34334009
     
    34484024
    34494025    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
    3450             && self->mydb->moduleFlags.getReturnsNone) {
     4026            && self->mydb->moduleFlags.getReturnsNone) {
    34514027        Py_INCREF(Py_None);
    34524028        retval = Py_None;
     
    34914067    CLEAR_DBT(data);
    34924068    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:pget", &kwnames[2],
    3493                                      &flags, &dlen, &doff))
     4069                                     &flags, &dlen, &doff))
    34944070    {
    34954071        PyErr_Clear();
    34964072        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:pget",
    3497                                          kwnames_keyOnly, 
    3498                                         &keyobj, &flags, &dlen, &doff))
     4073                                         kwnames_keyOnly,
     4074                                        &keyobj, &flags, &dlen, &doff))
    34994075        {
    35004076            PyErr_Clear();
     
    35044080            {
    35054081                return NULL;
    3506             }
    3507         }
     4082            }
     4083        }
    35084084    }
    35094085
     
    35264102
    35274103    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
    3528             && self->mydb->moduleFlags.getReturnsNone) {
     4104            && self->mydb->moduleFlags.getReturnsNone) {
    35294105        Py_INCREF(Py_None);
    35304106        retval = Py_None;
     
    36374213
    36384214    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iii:put", kwnames,
    3639                                      &keyobj, &dataobj, &flags, &dlen, &doff))
     4215                                     &keyobj, &dataobj, &flags, &dlen, &doff))
    36404216        return NULL;
    36414217
     
    36564232    FREE_DBT(key);  /* 'make_key_dbt' could do a 'malloc' */
    36574233    RETURN_IF_ERR();
    3658     self->mydb->haveStat = 0;
    36594234    RETURN_NONE();
    36604235}
     
    36724247
    36734248    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set", kwnames,
    3674                                      &keyobj, &flags, &dlen, &doff))
     4249                                     &keyobj, &flags, &dlen, &doff))
    36754250        return NULL;
    36764251
     
    36904265    MYDB_END_ALLOW_THREADS;
    36914266    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
    3692             && self->mydb->moduleFlags.cursorSetReturnsNone) {
     4267            && self->mydb->moduleFlags.cursorSetReturnsNone) {
    36934268        Py_INCREF(Py_None);
    36944269        retval = Py_None;
     
    37354310
    37364311    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set_range", kwnames,
    3737                                      &keyobj, &flags, &dlen, &doff))
     4312                                     &keyobj, &flags, &dlen, &doff))
    37384313        return NULL;
    37394314
     
    37524327    MYDB_END_ALLOW_THREADS;
    37534328    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
    3754             && self->mydb->moduleFlags.cursorSetReturnsNone) {
     4329            && self->mydb->moduleFlags.cursorSetReturnsNone) {
    37554330        Py_INCREF(Py_None);
    37564331        retval = Py_None;
     
    39064481
    39074482    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|iii:set_recno", kwnames,
    3908                                      &irecno, &flags, &dlen, &doff))
     4483                                     &irecno, &flags, &dlen, &doff))
    39094484      return NULL;
    39104485
     
    39354510    MYDB_END_ALLOW_THREADS;
    39364511    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
    3937             && self->mydb->moduleFlags.cursorSetReturnsNone) {
     4512            && self->mydb->moduleFlags.cursorSetReturnsNone) {
    39384513        Py_INCREF(Py_None);
    39394514        retval = Py_None;
     
    39714546}
    39724547
     4548#if (DBVER >= 46)
     4549static PyObject*
     4550DBC_prev_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
     4551{
     4552    return _DBCursor_get(self,DB_PREV_DUP,args,kwargs,"|iii:prev_dup");
     4553}
     4554#endif
    39734555
    39744556static PyObject*
     
    39984580    MYDB_END_ALLOW_THREADS;
    39994581    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
    4000             && self->mydb->moduleFlags.getReturnsNone) {
     4582            && self->mydb->moduleFlags.getReturnsNone) {
    40014583        Py_INCREF(Py_None);
    40024584        retval = Py_None;
     
    40134595
    40144596
     4597#if (DBVER >= 46)
     4598static PyObject*
     4599DBC_set_priority(DBCursorObject* self, PyObject* args, PyObject* kwargs)
     4600{
     4601    int err, priority;
     4602    static char* kwnames[] = { "priority", NULL };
     4603
     4604    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:set_priority", kwnames,
     4605                                     &priority))
     4606        return NULL;
     4607
     4608    CHECK_CURSOR_NOT_CLOSED(self);
     4609
     4610    MYDB_BEGIN_ALLOW_THREADS;
     4611    err = self->dbc->set_priority(self->dbc, priority);
     4612    MYDB_END_ALLOW_THREADS;
     4613    RETURN_IF_ERR();
     4614    RETURN_NONE();
     4615}
     4616
     4617
     4618static PyObject*
     4619DBC_get_priority(DBCursorObject* self)
     4620{
     4621    int err;
     4622    DB_CACHE_PRIORITY priority;
     4623
     4624    CHECK_CURSOR_NOT_CLOSED(self);
     4625
     4626    MYDB_BEGIN_ALLOW_THREADS;
     4627    err = self->dbc->get_priority(self->dbc, &priority);
     4628    MYDB_END_ALLOW_THREADS;
     4629    RETURN_IF_ERR();
     4630    return NUMBER_FromLong(priority);
     4631}
     4632#endif
     4633
     4634
    40154635
    40164636/* --------------------------------------------------------------------- */
     
    40264646    if (!self->closed) {      /* Don't close more than once */
    40274647        while(self->children_txns) {
    4028           dummy=DBTxn_abort_discard_internal(self->children_txns,0);
    4029           Py_XDECREF(dummy);
     4648            dummy = DBTxn_abort_discard_internal(self->children_txns, 0);
     4649            Py_XDECREF(dummy);
    40304650        }
    40314651        while(self->children_dbs) {
    4032           dummy=DB_close_internal(self->children_dbs, 0, 0);
    4033           Py_XDECREF(dummy);
     4652            dummy = DB_close_internal(self->children_dbs, 0, 0);
     4653            Py_XDECREF(dummy);
     4654        }
     4655        while(self->children_logcursors) {
     4656            dummy = DBLogCursor_close_internal(self->children_logcursors);
     4657            Py_XDECREF(dummy);
    40344658        }
    40354659    }
     
    40814705
    40824706static PyObject*
     4707DBEnv_memp_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
     4708{
     4709    int err;
     4710    DB_MPOOL_STAT *gsp;
     4711    DB_MPOOL_FSTAT **fsp, **fsp2;
     4712    PyObject* d = NULL, *d2, *d3, *r;
     4713    u_int32_t flags = 0;
     4714    static char* kwnames[] = { "flags", NULL };
     4715
     4716    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:memp_stat",
     4717                kwnames, &flags))
     4718        return NULL;
     4719
     4720    CHECK_ENV_NOT_CLOSED(self);
     4721
     4722    MYDB_BEGIN_ALLOW_THREADS;
     4723    err = self->db_env->memp_stat(self->db_env, &gsp, &fsp, flags);
     4724    MYDB_END_ALLOW_THREADS;
     4725    RETURN_IF_ERR();
     4726
     4727    /* Turn the stat structure into a dictionary */
     4728    d = PyDict_New();
     4729    if (d == NULL) {
     4730        if (gsp)
     4731            free(gsp);
     4732        return NULL;
     4733    }
     4734
     4735#define MAKE_ENTRY(name)  _addIntToDict(d, #name, gsp->st_##name)
     4736
     4737    MAKE_ENTRY(gbytes);
     4738    MAKE_ENTRY(ncache);
     4739#if (DBVER >= 46)
     4740    MAKE_ENTRY(max_ncache);
     4741#endif
     4742    MAKE_ENTRY(regsize);
     4743#if (DBVER >= 43)
     4744    MAKE_ENTRY(mmapsize);
     4745    MAKE_ENTRY(maxopenfd);
     4746    MAKE_ENTRY(maxwrite);
     4747    MAKE_ENTRY(maxwrite_sleep);
     4748#endif
     4749    MAKE_ENTRY(map);
     4750    MAKE_ENTRY(cache_hit);
     4751    MAKE_ENTRY(cache_miss);
     4752    MAKE_ENTRY(page_create);
     4753    MAKE_ENTRY(page_in);
     4754    MAKE_ENTRY(page_out);
     4755    MAKE_ENTRY(ro_evict);
     4756    MAKE_ENTRY(rw_evict);
     4757    MAKE_ENTRY(page_trickle);
     4758    MAKE_ENTRY(pages);
     4759    MAKE_ENTRY(page_clean);
     4760    MAKE_ENTRY(page_dirty);
     4761    MAKE_ENTRY(hash_buckets);
     4762    MAKE_ENTRY(hash_searches);
     4763    MAKE_ENTRY(hash_longest);
     4764    MAKE_ENTRY(hash_examined);
     4765    MAKE_ENTRY(hash_nowait);
     4766    MAKE_ENTRY(hash_wait);
     4767#if (DBVER >= 45)
     4768    MAKE_ENTRY(hash_max_nowait);
     4769#endif
     4770    MAKE_ENTRY(hash_max_wait);
     4771    MAKE_ENTRY(region_wait);
     4772    MAKE_ENTRY(region_nowait);
     4773#if (DBVER >= 45)
     4774    MAKE_ENTRY(mvcc_frozen);
     4775    MAKE_ENTRY(mvcc_thawed);
     4776    MAKE_ENTRY(mvcc_freed);
     4777#endif
     4778    MAKE_ENTRY(alloc);
     4779    MAKE_ENTRY(alloc_buckets);
     4780    MAKE_ENTRY(alloc_max_buckets);
     4781    MAKE_ENTRY(alloc_pages);
     4782    MAKE_ENTRY(alloc_max_pages);
     4783#if (DBVER >= 45)
     4784    MAKE_ENTRY(io_wait);
     4785#endif
     4786#if (DBVER >= 48)
     4787    MAKE_ENTRY(sync_interrupted);
     4788#endif
     4789
     4790#undef MAKE_ENTRY
     4791    free(gsp);
     4792
     4793    d2 = PyDict_New();
     4794    if (d2 == NULL) {
     4795        Py_DECREF(d);
     4796        if (fsp)
     4797            free(fsp);
     4798        return NULL;
     4799    }
     4800#define MAKE_ENTRY(name)  _addIntToDict(d3, #name, (*fsp2)->st_##name)
     4801    for(fsp2=fsp;*fsp2; fsp2++) {
     4802        d3 = PyDict_New();
     4803        if (d3 == NULL) {
     4804            Py_DECREF(d);
     4805            Py_DECREF(d2);
     4806            if (fsp)
     4807                free(fsp);
     4808            return NULL;
     4809        }
     4810        MAKE_ENTRY(pagesize);
     4811        MAKE_ENTRY(cache_hit);
     4812        MAKE_ENTRY(cache_miss);
     4813        MAKE_ENTRY(map);
     4814        MAKE_ENTRY(page_create);
     4815        MAKE_ENTRY(page_in);
     4816        MAKE_ENTRY(page_out);
     4817        if(PyDict_SetItemString(d2, (*fsp2)->file_name, d3)) {
     4818            Py_DECREF(d);
     4819            Py_DECREF(d2);
     4820            Py_DECREF(d3);
     4821            if (fsp)
     4822                free(fsp);
     4823            return NULL;
     4824        }
     4825        Py_DECREF(d3);
     4826    }
     4827
     4828#undef MAKE_ENTRY
     4829    free(fsp);
     4830
     4831    r = Py_BuildValue("(OO)", d, d2);
     4832    Py_DECREF(d);
     4833    Py_DECREF(d2);
     4834    return r;
     4835}
     4836
     4837#if (DBVER >= 43)
     4838static PyObject*
     4839DBEnv_memp_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
     4840{
     4841    int err;
     4842    int flags=0;
     4843    static char* kwnames[] = { "flags", NULL };
     4844
     4845    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:memp_stat_print",
     4846                kwnames, &flags))
     4847    {
     4848        return NULL;
     4849    }
     4850    CHECK_ENV_NOT_CLOSED(self);
     4851    MYDB_BEGIN_ALLOW_THREADS;
     4852    err = self->db_env->memp_stat_print(self->db_env, flags);
     4853    MYDB_END_ALLOW_THREADS;
     4854    RETURN_IF_ERR();
     4855    RETURN_NONE();
     4856}
     4857#endif
     4858
     4859
     4860static PyObject*
     4861DBEnv_memp_trickle(DBEnvObject* self, PyObject* args)
     4862{
     4863    int err, percent, nwrotep;
     4864
     4865    if (!PyArg_ParseTuple(args, "i:memp_trickle", &percent))
     4866        return NULL;
     4867    CHECK_ENV_NOT_CLOSED(self);
     4868    MYDB_BEGIN_ALLOW_THREADS;
     4869    err = self->db_env->memp_trickle(self->db_env, percent, &nwrotep);
     4870    MYDB_END_ALLOW_THREADS;
     4871    RETURN_IF_ERR();
     4872    return NUMBER_FromLong(nwrotep);
     4873}
     4874
     4875static PyObject*
     4876DBEnv_memp_sync(DBEnvObject* self, PyObject* args)
     4877{
     4878    int err;
     4879    DB_LSN lsn = {0, 0};
     4880    DB_LSN *lsn_p = NULL;
     4881
     4882    if (!PyArg_ParseTuple(args, "|(ii):memp_sync", &lsn.file, &lsn.offset))
     4883        return NULL;
     4884    if ((lsn.file!=0) || (lsn.offset!=0)) {
     4885        lsn_p = &lsn;
     4886    }
     4887    CHECK_ENV_NOT_CLOSED(self);
     4888    MYDB_BEGIN_ALLOW_THREADS;
     4889    err = self->db_env->memp_sync(self->db_env, lsn_p);
     4890    MYDB_END_ALLOW_THREADS;
     4891    RETURN_IF_ERR();
     4892    RETURN_NONE();
     4893}
     4894
     4895static PyObject*
    40834896DBEnv_remove(DBEnvObject* self, PyObject* args)
    40844897{
     
    40964909}
    40974910
    4098 #if (DBVER >= 41)
    40994911static PyObject*
    41004912DBEnv_dbremove(DBEnvObject* self, PyObject* args, PyObject* kwargs)
     
    41104922
    41114923    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zOi:dbremove", kwnames,
    4112                 &file, &database, &txnobj, &flags)) {
    4113         return NULL;
     4924                &file, &database, &txnobj, &flags)) {
     4925        return NULL;
    41144926    }
    41154927    if (!checkTxnObj(txnobj, &txn)) {
     
    41384950
    41394951    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "szs|Oi:dbrename", kwnames,
    4140                 &file, &database, &newname, &txnobj, &flags)) {
    4141         return NULL;
     4952                &file, &database, &newname, &txnobj, &flags)) {
     4953        return NULL;
    41424954    }
    41434955    if (!checkTxnObj(txnobj, &txn)) {
     
    41524964    RETURN_NONE();
    41534965}
     4966
     4967
    41544968
    41554969static PyObject*
     
    41624976
    41634977    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
    4164                 &passwd, &flags)) {
    4165         return NULL;
     4978                &passwd, &flags)) {
     4979        return NULL;
    41664980    }
    41674981
     
    41734987    RETURN_NONE();
    41744988}
    4175 #endif /* DBVER >= 41 */
     4989
     4990#if (DBVER >= 42)
     4991static PyObject*
     4992DBEnv_get_encrypt_flags(DBEnvObject* self)
     4993{
     4994    int err;
     4995    u_int32_t flags;
     4996
     4997    CHECK_ENV_NOT_CLOSED(self);
     4998
     4999    MYDB_BEGIN_ALLOW_THREADS;
     5000    err = self->db_env->get_encrypt_flags(self->db_env, &flags);
     5001    MYDB_END_ALLOW_THREADS;
     5002
     5003    RETURN_IF_ERR();
     5004
     5005    return NUMBER_FromLong(flags);
     5006}
     5007
     5008static PyObject*
     5009DBEnv_get_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
     5010{
     5011    int err;
     5012    int flag;
     5013    u_int32_t timeout;
     5014    static char* kwnames[] = {"flag", NULL };
     5015
     5016    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:get_timeout", kwnames,
     5017                &flag)) {
     5018        return NULL;
     5019    }
     5020    CHECK_ENV_NOT_CLOSED(self);
     5021
     5022    MYDB_BEGIN_ALLOW_THREADS;
     5023    err = self->db_env->get_timeout(self->db_env, &timeout, flag);
     5024    MYDB_END_ALLOW_THREADS;
     5025    RETURN_IF_ERR();
     5026    return NUMBER_FromLong(timeout);
     5027}
     5028#endif
     5029
    41765030
    41775031static PyObject*
     
    41845038
    41855039    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
    4186                 &timeout, &flags)) {
    4187         return NULL;
     5040                &timeout, &flags)) {
     5041        return NULL;
    41885042    }
    41895043
     
    42105064    RETURN_NONE();
    42115065}
     5066
     5067#if (DBVER >= 42)
     5068static PyObject*
     5069DBEnv_get_shm_key(DBEnvObject* self)
     5070{
     5071    int err;
     5072    long shm_key;
     5073
     5074    CHECK_ENV_NOT_CLOSED(self);
     5075
     5076    MYDB_BEGIN_ALLOW_THREADS;
     5077    err = self->db_env->get_shm_key(self->db_env, &shm_key);
     5078    MYDB_END_ALLOW_THREADS;
     5079
     5080    RETURN_IF_ERR();
     5081
     5082    return NUMBER_FromLong(shm_key);
     5083}
     5084#endif
     5085
     5086#if (DBVER >= 46)
     5087static PyObject*
     5088DBEnv_set_cache_max(DBEnvObject* self, PyObject* args)
     5089{
     5090    int err, gbytes, bytes;
     5091
     5092    if (!PyArg_ParseTuple(args, "ii:set_cache_max",
     5093                          &gbytes, &bytes))
     5094        return NULL;
     5095    CHECK_ENV_NOT_CLOSED(self);
     5096
     5097    MYDB_BEGIN_ALLOW_THREADS;
     5098    err = self->db_env->set_cache_max(self->db_env, gbytes, bytes);
     5099    MYDB_END_ALLOW_THREADS;
     5100    RETURN_IF_ERR();
     5101    RETURN_NONE();
     5102}
     5103
     5104static PyObject*
     5105DBEnv_get_cache_max(DBEnvObject* self)
     5106{
     5107    int err;
     5108    u_int32_t gbytes, bytes;
     5109
     5110    CHECK_ENV_NOT_CLOSED(self);
     5111
     5112    MYDB_BEGIN_ALLOW_THREADS;
     5113    err = self->db_env->get_cache_max(self->db_env, &gbytes, &bytes);
     5114    MYDB_END_ALLOW_THREADS;
     5115
     5116    RETURN_IF_ERR();
     5117
     5118    return Py_BuildValue("(ii)", gbytes, bytes);
     5119}
     5120#endif
     5121
     5122#if (DBVER >= 46)
     5123static PyObject*
     5124DBEnv_set_thread_count(DBEnvObject* self, PyObject* args)
     5125{
     5126    int err;
     5127    u_int32_t count;
     5128
     5129    if (!PyArg_ParseTuple(args, "i:set_thread_count", &count))
     5130        return NULL;
     5131    CHECK_ENV_NOT_CLOSED(self);
     5132
     5133    MYDB_BEGIN_ALLOW_THREADS;
     5134    err = self->db_env->set_thread_count(self->db_env, count);
     5135    MYDB_END_ALLOW_THREADS;
     5136    RETURN_IF_ERR();
     5137    RETURN_NONE();
     5138}
     5139
     5140static PyObject*
     5141DBEnv_get_thread_count(DBEnvObject* self)
     5142{
     5143    int err;
     5144    u_int32_t count;
     5145
     5146    CHECK_ENV_NOT_CLOSED(self);
     5147
     5148    MYDB_BEGIN_ALLOW_THREADS;
     5149    err = self->db_env->get_thread_count(self->db_env, &count);
     5150    MYDB_END_ALLOW_THREADS;
     5151    RETURN_IF_ERR();
     5152    return NUMBER_FromLong(count);
     5153}
     5154#endif
    42125155
    42135156static PyObject*
     
    42285171}
    42295172
     5173#if (DBVER >= 42)
     5174static PyObject*
     5175DBEnv_get_cachesize(DBEnvObject* self)
     5176{
     5177    int err;
     5178    u_int32_t gbytes, bytes;
     5179    int ncache;
     5180
     5181    CHECK_ENV_NOT_CLOSED(self);
     5182
     5183    MYDB_BEGIN_ALLOW_THREADS;
     5184    err = self->db_env->get_cachesize(self->db_env, &gbytes, &bytes, &ncache);
     5185    MYDB_END_ALLOW_THREADS;
     5186
     5187    RETURN_IF_ERR();
     5188
     5189    return Py_BuildValue("(iii)", gbytes, bytes, ncache);
     5190}
     5191#endif
     5192
    42305193
    42315194static PyObject*
     
    42465209}
    42475210
     5211#if (DBVER >= 42)
     5212static PyObject*
     5213DBEnv_get_flags(DBEnvObject* self)
     5214{
     5215    int err;
     5216    u_int32_t flags;
     5217
     5218    CHECK_ENV_NOT_CLOSED(self);
     5219
     5220    MYDB_BEGIN_ALLOW_THREADS;
     5221    err = self->db_env->get_flags(self->db_env, &flags);
     5222    MYDB_END_ALLOW_THREADS;
     5223    RETURN_IF_ERR();
     5224    return NUMBER_FromLong(flags);
     5225}
     5226#endif
    42485227
    42495228#if (DBVER >= 47)
     
    42645243    RETURN_NONE();
    42655244}
     5245
     5246static PyObject*
     5247DBEnv_log_get_config(DBEnvObject* self, PyObject* args)
     5248{
     5249    int err, flag, onoff;
     5250
     5251    if (!PyArg_ParseTuple(args, "i:log_get_config", &flag))
     5252        return NULL;
     5253    CHECK_ENV_NOT_CLOSED(self);
     5254
     5255    MYDB_BEGIN_ALLOW_THREADS;
     5256    err = self->db_env->log_get_config(self->db_env, flag, &onoff);
     5257    MYDB_END_ALLOW_THREADS;
     5258    RETURN_IF_ERR();
     5259    return PyBool_FromLong(onoff);
     5260}
    42665261#endif /* DBVER >= 47 */
    42675262
     5263#if (DBVER >= 44)
     5264static PyObject*
     5265DBEnv_mutex_set_max(DBEnvObject* self, PyObject* args)
     5266{
     5267    int err;
     5268    int value;
     5269
     5270    if (!PyArg_ParseTuple(args, "i:mutex_set_max", &value))
     5271        return NULL;
     5272
     5273    CHECK_ENV_NOT_CLOSED(self);
     5274
     5275    MYDB_BEGIN_ALLOW_THREADS;
     5276    err = self->db_env->mutex_set_max(self->db_env, value);
     5277    MYDB_END_ALLOW_THREADS;
     5278
     5279    RETURN_IF_ERR();
     5280    RETURN_NONE();
     5281}
     5282
     5283static PyObject*
     5284DBEnv_mutex_get_max(DBEnvObject* self)
     5285{
     5286    int err;
     5287    u_int32_t value;
     5288
     5289    CHECK_ENV_NOT_CLOSED(self);
     5290
     5291    MYDB_BEGIN_ALLOW_THREADS;
     5292    err = self->db_env->mutex_get_max(self->db_env, &value);
     5293    MYDB_END_ALLOW_THREADS;
     5294
     5295    RETURN_IF_ERR();
     5296
     5297    return NUMBER_FromLong(value);
     5298}
     5299
     5300static PyObject*
     5301DBEnv_mutex_set_align(DBEnvObject* self, PyObject* args)
     5302{
     5303    int err;
     5304    int align;
     5305
     5306    if (!PyArg_ParseTuple(args, "i:mutex_set_align", &align))
     5307        return NULL;
     5308
     5309    CHECK_ENV_NOT_CLOSED(self);
     5310
     5311    MYDB_BEGIN_ALLOW_THREADS;
     5312    err = self->db_env->mutex_set_align(self->db_env, align);
     5313    MYDB_END_ALLOW_THREADS;
     5314
     5315    RETURN_IF_ERR();
     5316    RETURN_NONE();
     5317}
     5318
     5319static PyObject*
     5320DBEnv_mutex_get_align(DBEnvObject* self)
     5321{
     5322    int err;
     5323    u_int32_t align;
     5324
     5325    CHECK_ENV_NOT_CLOSED(self);
     5326
     5327    MYDB_BEGIN_ALLOW_THREADS;
     5328    err = self->db_env->mutex_get_align(self->db_env, &align);
     5329    MYDB_END_ALLOW_THREADS;
     5330
     5331    RETURN_IF_ERR();
     5332
     5333    return NUMBER_FromLong(align);
     5334}
     5335
     5336static PyObject*
     5337DBEnv_mutex_set_increment(DBEnvObject* self, PyObject* args)
     5338{
     5339    int err;
     5340    int increment;
     5341
     5342    if (!PyArg_ParseTuple(args, "i:mutex_set_increment", &increment))
     5343        return NULL;
     5344
     5345    CHECK_ENV_NOT_CLOSED(self);
     5346
     5347    MYDB_BEGIN_ALLOW_THREADS;
     5348    err = self->db_env->mutex_set_increment(self->db_env, increment);
     5349    MYDB_END_ALLOW_THREADS;
     5350
     5351    RETURN_IF_ERR();
     5352    RETURN_NONE();
     5353}
     5354
     5355static PyObject*
     5356DBEnv_mutex_get_increment(DBEnvObject* self)
     5357{
     5358    int err;
     5359    u_int32_t increment;
     5360
     5361    CHECK_ENV_NOT_CLOSED(self);
     5362
     5363    MYDB_BEGIN_ALLOW_THREADS;
     5364    err = self->db_env->mutex_get_increment(self->db_env, &increment);
     5365    MYDB_END_ALLOW_THREADS;
     5366
     5367    RETURN_IF_ERR();
     5368
     5369    return NUMBER_FromLong(increment);
     5370}
     5371
     5372static PyObject*
     5373DBEnv_mutex_set_tas_spins(DBEnvObject* self, PyObject* args)
     5374{
     5375    int err;
     5376    int tas_spins;
     5377
     5378    if (!PyArg_ParseTuple(args, "i:mutex_set_tas_spins", &tas_spins))
     5379        return NULL;
     5380
     5381    CHECK_ENV_NOT_CLOSED(self);
     5382
     5383    MYDB_BEGIN_ALLOW_THREADS;
     5384    err = self->db_env->mutex_set_tas_spins(self->db_env, tas_spins);
     5385    MYDB_END_ALLOW_THREADS;
     5386
     5387    RETURN_IF_ERR();
     5388    RETURN_NONE();
     5389}
     5390
     5391static PyObject*
     5392DBEnv_mutex_get_tas_spins(DBEnvObject* self)
     5393{
     5394    int err;
     5395    u_int32_t tas_spins;
     5396
     5397    CHECK_ENV_NOT_CLOSED(self);
     5398
     5399    MYDB_BEGIN_ALLOW_THREADS;
     5400    err = self->db_env->mutex_get_tas_spins(self->db_env, &tas_spins);
     5401    MYDB_END_ALLOW_THREADS;
     5402
     5403    RETURN_IF_ERR();
     5404
     5405    return NUMBER_FromLong(tas_spins);
     5406}
     5407#endif
    42685408
    42695409static PyObject*
     
    42845424}
    42855425
     5426#if (DBVER >= 42)
     5427static PyObject*
     5428DBEnv_get_data_dirs(DBEnvObject* self)
     5429{
     5430    int err;
     5431    PyObject *tuple;
     5432    PyObject *item;
     5433    const char **dirpp;
     5434    int size, i;
     5435
     5436    CHECK_ENV_NOT_CLOSED(self);
     5437
     5438    MYDB_BEGIN_ALLOW_THREADS;
     5439    err = self->db_env->get_data_dirs(self->db_env, &dirpp);
     5440    MYDB_END_ALLOW_THREADS;
     5441
     5442    RETURN_IF_ERR();
     5443
     5444    /*
     5445    ** Calculate size. Python C API
     5446    ** actually allows for tuple resizing,
     5447    ** but this is simple enough.
     5448    */
     5449    for (size=0; *(dirpp+size) ; size++);
     5450
     5451    tuple = PyTuple_New(size);
     5452    if (!tuple)
     5453        return NULL;
     5454
     5455    for (i=0; i<size; i++) {
     5456        item = PyBytes_FromString (*(dirpp+i));
     5457        if (item == NULL) {
     5458            Py_DECREF(tuple);
     5459            tuple = NULL;
     5460            break;
     5461        }
     5462        PyTuple_SET_ITEM(tuple, i, item);
     5463    }
     5464    return tuple;
     5465}
     5466#endif
     5467
     5468#if (DBVER >= 44)
     5469static PyObject*
     5470DBEnv_set_lg_filemode(DBEnvObject* self, PyObject* args)
     5471{
     5472    int err, filemode;
     5473
     5474    if (!PyArg_ParseTuple(args, "i:set_lg_filemode", &filemode))
     5475        return NULL;
     5476    CHECK_ENV_NOT_CLOSED(self);
     5477
     5478    MYDB_BEGIN_ALLOW_THREADS;
     5479    err = self->db_env->set_lg_filemode(self->db_env, filemode);
     5480    MYDB_END_ALLOW_THREADS;
     5481    RETURN_IF_ERR();
     5482    RETURN_NONE();
     5483}
     5484
     5485static PyObject*
     5486DBEnv_get_lg_filemode(DBEnvObject* self)
     5487{
     5488    int err, filemode;
     5489
     5490    CHECK_ENV_NOT_CLOSED(self);
     5491
     5492    MYDB_BEGIN_ALLOW_THREADS;
     5493    err = self->db_env->get_lg_filemode(self->db_env, &filemode);
     5494    MYDB_END_ALLOW_THREADS;
     5495    RETURN_IF_ERR();
     5496    return NUMBER_FromLong(filemode);
     5497}
     5498#endif
    42865499
    42875500static PyObject*
     
    43015514}
    43025515
     5516#if (DBVER >= 42)
     5517static PyObject*
     5518DBEnv_get_lg_bsize(DBEnvObject* self)
     5519{
     5520    int err;
     5521    u_int32_t lg_bsize;
     5522
     5523    CHECK_ENV_NOT_CLOSED(self);
     5524
     5525    MYDB_BEGIN_ALLOW_THREADS;
     5526    err = self->db_env->get_lg_bsize(self->db_env, &lg_bsize);
     5527    MYDB_END_ALLOW_THREADS;
     5528    RETURN_IF_ERR();
     5529    return NUMBER_FromLong(lg_bsize);
     5530}
     5531#endif
    43035532
    43045533static PyObject*
     
    43195548}
    43205549
     5550#if (DBVER >= 42)
     5551static PyObject*
     5552DBEnv_get_lg_dir(DBEnvObject* self)
     5553{
     5554    int err;
     5555    const char *dirp;
     5556
     5557    CHECK_ENV_NOT_CLOSED(self);
     5558
     5559    MYDB_BEGIN_ALLOW_THREADS;
     5560    err = self->db_env->get_lg_dir(self->db_env, &dirp);
     5561    MYDB_END_ALLOW_THREADS;
     5562    RETURN_IF_ERR();
     5563    return PyBytes_FromString(dirp);
     5564}
     5565#endif
     5566
    43215567static PyObject*
    43225568DBEnv_set_lg_max(DBEnvObject* self, PyObject* args)
     
    43695615}
    43705616
     5617#if (DBVER >= 42)
     5618static PyObject*
     5619DBEnv_get_lg_regionmax(DBEnvObject* self)
     5620{
     5621    int err;
     5622    u_int32_t lg_regionmax;
     5623
     5624    CHECK_ENV_NOT_CLOSED(self);
     5625
     5626    MYDB_BEGIN_ALLOW_THREADS;
     5627    err = self->db_env->get_lg_regionmax(self->db_env, &lg_regionmax);
     5628    MYDB_END_ALLOW_THREADS;
     5629    RETURN_IF_ERR();
     5630    return NUMBER_FromLong(lg_regionmax);
     5631}
     5632#endif
     5633
     5634#if (DBVER >= 47)
     5635static PyObject*
     5636DBEnv_set_lk_partitions(DBEnvObject* self, PyObject* args)
     5637{
     5638    int err, lk_partitions;
     5639
     5640    if (!PyArg_ParseTuple(args, "i:set_lk_partitions", &lk_partitions))
     5641        return NULL;
     5642    CHECK_ENV_NOT_CLOSED(self);
     5643
     5644    MYDB_BEGIN_ALLOW_THREADS;
     5645    err = self->db_env->set_lk_partitions(self->db_env, lk_partitions);
     5646    MYDB_END_ALLOW_THREADS;
     5647    RETURN_IF_ERR();
     5648    RETURN_NONE();
     5649}
     5650
     5651static PyObject*
     5652DBEnv_get_lk_partitions(DBEnvObject* self)
     5653{
     5654    int err;
     5655    u_int32_t lk_partitions;
     5656
     5657    CHECK_ENV_NOT_CLOSED(self);
     5658
     5659    MYDB_BEGIN_ALLOW_THREADS;
     5660    err = self->db_env->get_lk_partitions(self->db_env, &lk_partitions);
     5661    MYDB_END_ALLOW_THREADS;
     5662    RETURN_IF_ERR();
     5663    return NUMBER_FromLong(lk_partitions);
     5664}
     5665#endif
    43715666
    43725667static PyObject*
     
    43865681}
    43875682
     5683#if (DBVER >= 42)
     5684static PyObject*
     5685DBEnv_get_lk_detect(DBEnvObject* self)
     5686{
     5687    int err;
     5688    u_int32_t lk_detect;
     5689
     5690    CHECK_ENV_NOT_CLOSED(self);
     5691
     5692    MYDB_BEGIN_ALLOW_THREADS;
     5693    err = self->db_env->get_lk_detect(self->db_env, &lk_detect);
     5694    MYDB_END_ALLOW_THREADS;
     5695    RETURN_IF_ERR();
     5696    return NUMBER_FromLong(lk_detect);
     5697}
     5698#endif
     5699
    43885700
    43895701#if (DBVER < 45)
     
    44235735}
    44245736
     5737#if (DBVER >= 42)
     5738static PyObject*
     5739DBEnv_get_lk_max_locks(DBEnvObject* self)
     5740{
     5741    int err;
     5742    u_int32_t lk_max;
     5743
     5744    CHECK_ENV_NOT_CLOSED(self);
     5745
     5746    MYDB_BEGIN_ALLOW_THREADS;
     5747    err = self->db_env->get_lk_max_locks(self->db_env, &lk_max);
     5748    MYDB_END_ALLOW_THREADS;
     5749    RETURN_IF_ERR();
     5750    return NUMBER_FromLong(lk_max);
     5751}
     5752#endif
    44255753
    44265754static PyObject*
     
    44405768}
    44415769
     5770#if (DBVER >= 42)
     5771static PyObject*
     5772DBEnv_get_lk_max_lockers(DBEnvObject* self)
     5773{
     5774    int err;
     5775    u_int32_t lk_max;
     5776
     5777    CHECK_ENV_NOT_CLOSED(self);
     5778
     5779    MYDB_BEGIN_ALLOW_THREADS;
     5780    err = self->db_env->get_lk_max_lockers(self->db_env, &lk_max);
     5781    MYDB_END_ALLOW_THREADS;
     5782    RETURN_IF_ERR();
     5783    return NUMBER_FromLong(lk_max);
     5784}
     5785#endif
    44425786
    44435787static PyObject*
     
    44575801}
    44585802
     5803#if (DBVER >= 42)
     5804static PyObject*
     5805DBEnv_get_lk_max_objects(DBEnvObject* self)
     5806{
     5807    int err;
     5808    u_int32_t lk_max;
     5809
     5810    CHECK_ENV_NOT_CLOSED(self);
     5811
     5812    MYDB_BEGIN_ALLOW_THREADS;
     5813    err = self->db_env->get_lk_max_objects(self->db_env, &lk_max);
     5814    MYDB_END_ALLOW_THREADS;
     5815    RETURN_IF_ERR();
     5816    return NUMBER_FromLong(lk_max);
     5817}
     5818#endif
     5819
     5820#if (DBVER >= 42)
     5821static PyObject*
     5822DBEnv_get_mp_mmapsize(DBEnvObject* self)
     5823{
     5824    int err;
     5825    size_t mmapsize;
     5826
     5827    CHECK_ENV_NOT_CLOSED(self);
     5828
     5829    MYDB_BEGIN_ALLOW_THREADS;
     5830    err = self->db_env->get_mp_mmapsize(self->db_env, &mmapsize);
     5831    MYDB_END_ALLOW_THREADS;
     5832    RETURN_IF_ERR();
     5833    return NUMBER_FromLong(mmapsize);
     5834}
     5835#endif
     5836
    44595837
    44605838static PyObject*
     
    44915869    RETURN_NONE();
    44925870}
     5871
     5872
     5873#if (DBVER >= 42)
     5874static PyObject*
     5875DBEnv_get_tmp_dir(DBEnvObject* self)
     5876{
     5877    int err;
     5878    const char *dirpp;
     5879
     5880    CHECK_ENV_NOT_CLOSED(self);
     5881
     5882    MYDB_BEGIN_ALLOW_THREADS;
     5883    err = self->db_env->get_tmp_dir(self->db_env, &dirpp);
     5884    MYDB_END_ALLOW_THREADS;
     5885
     5886    RETURN_IF_ERR();
     5887
     5888    return PyBytes_FromString(dirpp);
     5889}
     5890#endif
    44935891
    44945892
     
    45025900#define PREPLIST_LEN 16
    45035901    DB_PREPLIST preplist[PREPLIST_LEN];
     5902#if (DBVER < 48)
    45045903    long retp;
     5904#else
     5905    u_int32_t retp;
     5906#endif
    45055907
    45065908    CHECK_ENV_NOT_CLOSED(self);
     
    45235925        for (i=0; i<retp; i++) {
    45245926            gid=PyBytes_FromStringAndSize((char *)(preplist[i].gid),
    4525                                 DB_XIDDATASIZE);
     5927                                DB_GID_SIZE);
    45265928            if (!gid) {
    45275929                Py_DECREF(list);
    45285930                return NULL;
    45295931            }
    4530             txn=newDBTxnObject(self, NULL, preplist[i].txn, flags);
     5932            txn=newDBTxnObject(self, NULL, preplist[i].txn, 0);
    45315933            if (!txn) {
    45325934                Py_DECREF(list);
     
    46036005
    46046006
     6007#if (DBVER >= 42)
     6008static PyObject*
     6009DBEnv_get_tx_max(DBEnvObject* self)
     6010{
     6011    int err;
     6012    u_int32_t max;
     6013
     6014    CHECK_ENV_NOT_CLOSED(self);
     6015
     6016    MYDB_BEGIN_ALLOW_THREADS;
     6017    err = self->db_env->get_tx_max(self->db_env, &max);
     6018    MYDB_END_ALLOW_THREADS;
     6019    RETURN_IF_ERR();
     6020    return PyLong_FromUnsignedLong(max);
     6021}
     6022#endif
     6023
     6024
    46056025static PyObject*
    46066026DBEnv_set_tx_max(DBEnvObject* self, PyObject* args)
     
    46126032    CHECK_ENV_NOT_CLOSED(self);
    46136033
     6034    MYDB_BEGIN_ALLOW_THREADS;
    46146035    err = self->db_env->set_tx_max(self->db_env, max);
    4615     RETURN_IF_ERR();
    4616     RETURN_NONE();
    4617 }
    4618 
     6036    MYDB_END_ALLOW_THREADS;
     6037    RETURN_IF_ERR();
     6038    RETURN_NONE();
     6039}
     6040
     6041
     6042#if (DBVER >= 42)
     6043static PyObject*
     6044DBEnv_get_tx_timestamp(DBEnvObject* self)
     6045{
     6046    int err;
     6047    time_t timestamp;
     6048
     6049    CHECK_ENV_NOT_CLOSED(self);
     6050
     6051    MYDB_BEGIN_ALLOW_THREADS;
     6052    err = self->db_env->get_tx_timestamp(self->db_env, &timestamp);
     6053    MYDB_END_ALLOW_THREADS;
     6054    RETURN_IF_ERR();
     6055    return NUMBER_FromLong(timestamp);
     6056}
     6057#endif
    46196058
    46206059static PyObject*
     
    46296068    CHECK_ENV_NOT_CLOSED(self);
    46306069    timestamp = (time_t)stamp;
     6070    MYDB_BEGIN_ALLOW_THREADS;
    46316071    err = self->db_env->set_tx_timestamp(self->db_env, &timestamp);
     6072    MYDB_END_ALLOW_THREADS;
    46326073    RETURN_IF_ERR();
    46336074    RETURN_NONE();
     
    47236164#if (DBVER >= 44)
    47246165static PyObject*
    4725 DBEnv_lsn_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
     6166DBEnv_fileid_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
    47266167{
    47276168    int err;
     
    47306171    static char* kwnames[] = { "file", "flags", NULL};
    47316172
     6173    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:fileid_reset", kwnames,
     6174                                     &file, &flags))
     6175        return NULL;
     6176    CHECK_ENV_NOT_CLOSED(self);
     6177
     6178    MYDB_BEGIN_ALLOW_THREADS;
     6179    err = self->db_env->fileid_reset(self->db_env, file, flags);
     6180    MYDB_END_ALLOW_THREADS;
     6181    RETURN_IF_ERR();
     6182    RETURN_NONE();
     6183}
     6184
     6185static PyObject*
     6186DBEnv_lsn_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
     6187{
     6188    int err;
     6189    char *file;
     6190    u_int32_t flags = 0;
     6191    static char* kwnames[] = { "file", "flags", NULL};
     6192
    47326193    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:lsn_reset", kwnames,
    47336194                                     &file, &flags))
     
    47426203}
    47436204#endif /* DBVER >= 4.4 */
     6205
     6206
     6207#if (DBVER >= 43)
     6208static PyObject*
     6209DBEnv_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
     6210{
     6211    int err;
     6212    int flags=0;
     6213    static char* kwnames[] = { "flags", NULL };
     6214
     6215    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
     6216                kwnames, &flags))
     6217    {
     6218        return NULL;
     6219    }
     6220    CHECK_ENV_NOT_CLOSED(self);
     6221    MYDB_BEGIN_ALLOW_THREADS;
     6222    err = self->db_env->stat_print(self->db_env, flags);
     6223    MYDB_END_ALLOW_THREADS;
     6224    RETURN_IF_ERR();
     6225    RETURN_NONE();
     6226}
     6227#endif
     6228
    47446229
    47456230static PyObject*
     
    47776262    MAKE_ENTRY(lg_size);
    47786263    MAKE_ENTRY(record);
    4779 #endif
    4780 #if (DBVER < 41)
    4781     MAKE_ENTRY(lg_max);
    47826264#endif
    47836265    MAKE_ENTRY(w_mbytes);
     
    48076289
    48086290
     6291#if (DBVER >= 43)
     6292static PyObject*
     6293DBEnv_log_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
     6294{
     6295    int err;
     6296    int flags=0;
     6297    static char* kwnames[] = { "flags", NULL };
     6298
     6299    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:log_stat_print",
     6300                kwnames, &flags))
     6301    {
     6302        return NULL;
     6303    }
     6304    CHECK_ENV_NOT_CLOSED(self);
     6305    MYDB_BEGIN_ALLOW_THREADS;
     6306    err = self->db_env->log_stat_print(self->db_env, flags);
     6307    MYDB_END_ALLOW_THREADS;
     6308    RETURN_IF_ERR();
     6309    RETURN_NONE();
     6310}
     6311#endif
     6312
     6313
    48096314static PyObject*
    48106315DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
     
    48336338#define MAKE_ENTRY(name)  _addIntToDict(d, #name, sp->st_##name)
    48346339
    4835 #if (DBVER < 41)
    4836     MAKE_ENTRY(lastid);
    4837 #endif
    4838 #if (DBVER >=41)
    48396340    MAKE_ENTRY(id);
    48406341    MAKE_ENTRY(cur_maxid);
    4841 #endif
    48426342    MAKE_ENTRY(nmodes);
    48436343    MAKE_ENTRY(maxlocks);
     
    48646364#endif
    48656365    MAKE_ENTRY(ndeadlocks);
    4866 #if (DBVER >= 41)
    48676366    MAKE_ENTRY(locktimeout);
    48686367    MAKE_ENTRY(txntimeout);
    4869 #endif
    48706368    MAKE_ENTRY(nlocktimeouts);
    48716369    MAKE_ENTRY(ntxntimeouts);
     
    48936391}
    48946392
     6393#if (DBVER >= 43)
     6394static PyObject*
     6395DBEnv_lock_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
     6396{
     6397    int err;
     6398    int flags=0;
     6399    static char* kwnames[] = { "flags", NULL };
     6400
     6401    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:lock_stat_print",
     6402                kwnames, &flags))
     6403    {
     6404        return NULL;
     6405    }
     6406    CHECK_ENV_NOT_CLOSED(self);
     6407    MYDB_BEGIN_ALLOW_THREADS;
     6408    err = self->db_env->lock_stat_print(self->db_env, flags);
     6409    MYDB_END_ALLOW_THREADS;
     6410    RETURN_IF_ERR();
     6411    RETURN_NONE();
     6412}
     6413#endif
     6414
     6415
     6416static PyObject*
     6417DBEnv_log_cursor(DBEnvObject* self)
     6418{
     6419    int err;
     6420    DB_LOGC* dblogc;
     6421
     6422    CHECK_ENV_NOT_CLOSED(self);
     6423
     6424    MYDB_BEGIN_ALLOW_THREADS;
     6425    err = self->db_env->log_cursor(self->db_env, &dblogc, 0);
     6426    MYDB_END_ALLOW_THREADS;
     6427    RETURN_IF_ERR();
     6428    return (PyObject*) newDBLogCursorObject(dblogc, self);
     6429}
     6430
     6431
    48956432static PyObject*
    48966433DBEnv_log_flush(DBEnvObject* self)
     
    49076444    RETURN_NONE();
    49086445}
     6446
     6447static PyObject*
     6448DBEnv_log_file(DBEnvObject* self, PyObject* args)
     6449{
     6450    int err;
     6451    DB_LSN lsn = {0, 0};
     6452    int size = 20;
     6453    char *name = NULL;
     6454    PyObject *retval;
     6455
     6456    if (!PyArg_ParseTuple(args, "(ii):log_file", &lsn.file, &lsn.offset))
     6457        return NULL;
     6458
     6459    CHECK_ENV_NOT_CLOSED(self);
     6460
     6461    do {
     6462        name = malloc(size);
     6463        if (!name) {
     6464            PyErr_NoMemory();
     6465            return NULL;
     6466        }
     6467        MYDB_BEGIN_ALLOW_THREADS;
     6468        err = self->db_env->log_file(self->db_env, &lsn, name, size);
     6469        MYDB_END_ALLOW_THREADS;
     6470        if (err == EINVAL) {
     6471            free(name);
     6472            size *= 2;
     6473        } else if (err) {
     6474            free(name);
     6475            RETURN_IF_ERR();
     6476            assert(0);  /* Unreachable... supposely */
     6477            return NULL;
     6478        }
     6479/*
     6480** If the final buffer we try is too small, we will
     6481** get this exception:
     6482** DBInvalidArgError:
     6483**    (22, 'Invalid argument -- DB_ENV->log_file: name buffer is too short')
     6484*/
     6485    } while ((err == EINVAL) && (size<(1<<17)));
     6486
     6487    RETURN_IF_ERR();  /* Maybe the size is not the problem */
     6488
     6489    retval = Py_BuildValue("s", name);
     6490    free(name);
     6491    return retval;
     6492}
     6493
     6494
     6495#if (DBVER >= 44)
     6496static PyObject*
     6497DBEnv_log_printf(DBEnvObject* self, PyObject* args, PyObject *kwargs)
     6498{
     6499    int err;
     6500    char *string;
     6501    PyObject *txnobj = NULL;
     6502    DB_TXN *txn = NULL;
     6503    static char* kwnames[] = {"string", "txn", NULL };
     6504
     6505    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|O:log_printf", kwnames,
     6506                &string, &txnobj))
     6507        return NULL;
     6508
     6509    CHECK_ENV_NOT_CLOSED(self);
     6510
     6511    if (!checkTxnObj(txnobj, &txn))
     6512        return NULL;
     6513
     6514    /*
     6515    ** Do not use the format string directly, to avoid attacks.
     6516    */
     6517    MYDB_BEGIN_ALLOW_THREADS;
     6518    err = self->db_env->log_printf(self->db_env, txn, "%s", string);
     6519    MYDB_END_ALLOW_THREADS;
     6520
     6521    RETURN_IF_ERR();
     6522    RETURN_NONE();
     6523}
     6524#endif
     6525
    49096526
    49106527static PyObject*
     
    49566573
    49576574
     6575#if (DBVER >= 44)
     6576static PyObject*
     6577DBEnv_mutex_stat(DBEnvObject* self, PyObject* args)
     6578{
     6579    int err;
     6580    DB_MUTEX_STAT* statp = NULL;
     6581    PyObject* d = NULL;
     6582    u_int32_t flags = 0;
     6583
     6584    if (!PyArg_ParseTuple(args, "|i:mutex_stat", &flags))
     6585        return NULL;
     6586    CHECK_ENV_NOT_CLOSED(self);
     6587
     6588    MYDB_BEGIN_ALLOW_THREADS;
     6589    err = self->db_env->mutex_stat(self->db_env, &statp, flags);
     6590    MYDB_END_ALLOW_THREADS;
     6591    RETURN_IF_ERR();
     6592
     6593    /* Turn the stat structure into a dictionary */
     6594    d = PyDict_New();
     6595    if (d == NULL) {
     6596        if (statp)
     6597            free(statp);
     6598        return NULL;
     6599    }
     6600
     6601#define MAKE_ENTRY(name)  _addIntToDict(d, #name, statp->st_##name)
     6602
     6603    MAKE_ENTRY(mutex_align);
     6604    MAKE_ENTRY(mutex_tas_spins);
     6605    MAKE_ENTRY(mutex_cnt);
     6606    MAKE_ENTRY(mutex_free);
     6607    MAKE_ENTRY(mutex_inuse);
     6608    MAKE_ENTRY(mutex_inuse_max);
     6609    MAKE_ENTRY(regsize);
     6610    MAKE_ENTRY(region_wait);
     6611    MAKE_ENTRY(region_nowait);
     6612
     6613#undef MAKE_ENTRY
     6614    free(statp);
     6615    return d;
     6616}
     6617#endif
     6618
     6619
     6620#if (DBVER >= 44)
     6621static PyObject*
     6622DBEnv_mutex_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
     6623{
     6624    int err;
     6625    int flags=0;
     6626    static char* kwnames[] = { "flags", NULL };
     6627
     6628    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:mutex_stat_print",
     6629                kwnames, &flags))
     6630    {
     6631        return NULL;
     6632    }
     6633    CHECK_ENV_NOT_CLOSED(self);
     6634    MYDB_BEGIN_ALLOW_THREADS;
     6635    err = self->db_env->mutex_stat_print(self->db_env, flags);
     6636    MYDB_END_ALLOW_THREADS;
     6637    RETURN_IF_ERR();
     6638    RETURN_NONE();
     6639}
     6640#endif
     6641
     6642
     6643#if (DBVER >= 43)
     6644static PyObject*
     6645DBEnv_txn_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
     6646{
     6647    int err;
     6648    int flags=0;
     6649    static char* kwnames[] = { "flags", NULL };
     6650
     6651    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
     6652                kwnames, &flags))
     6653    {
     6654        return NULL;
     6655    }
     6656
     6657    CHECK_ENV_NOT_CLOSED(self);
     6658
     6659    MYDB_BEGIN_ALLOW_THREADS;
     6660    err = self->db_env->txn_stat_print(self->db_env, flags);
     6661    MYDB_END_ALLOW_THREADS;
     6662    RETURN_IF_ERR();
     6663    RETURN_NONE();
     6664}
     6665#endif
     6666
     6667
    49586668static PyObject*
    49596669DBEnv_txn_stat(DBEnvObject* self, PyObject* args)
     
    50486758
    50496759
     6760#if (DBVER < 48)
    50506761static PyObject*
    50516762DBEnv_set_rpc_server(DBEnvObject* self, PyObject* args, PyObject* kwargs)
     
    50696780    RETURN_NONE();
    50706781}
     6782#endif
     6783
     6784#if (DBVER >= 43)
     6785static PyObject*
     6786DBEnv_set_mp_max_openfd(DBEnvObject* self, PyObject* args)
     6787{
     6788    int err;
     6789    int maxopenfd;
     6790
     6791    if (!PyArg_ParseTuple(args, "i:set_mp_max_openfd", &maxopenfd)) {
     6792        return NULL;
     6793    }
     6794    CHECK_ENV_NOT_CLOSED(self);
     6795    MYDB_BEGIN_ALLOW_THREADS;
     6796    err = self->db_env->set_mp_max_openfd(self->db_env, maxopenfd);
     6797    MYDB_END_ALLOW_THREADS;
     6798    RETURN_IF_ERR();
     6799    RETURN_NONE();
     6800}
     6801
     6802static PyObject*
     6803DBEnv_get_mp_max_openfd(DBEnvObject* self)
     6804{
     6805    int err;
     6806    int maxopenfd;
     6807
     6808    CHECK_ENV_NOT_CLOSED(self);
     6809
     6810    MYDB_BEGIN_ALLOW_THREADS;
     6811    err = self->db_env->get_mp_max_openfd(self->db_env, &maxopenfd);
     6812    MYDB_END_ALLOW_THREADS;
     6813    RETURN_IF_ERR();
     6814    return NUMBER_FromLong(maxopenfd);
     6815}
     6816
     6817
     6818static PyObject*
     6819DBEnv_set_mp_max_write(DBEnvObject* self, PyObject* args)
     6820{
     6821    int err;
     6822    int maxwrite, maxwrite_sleep;
     6823
     6824    if (!PyArg_ParseTuple(args, "ii:set_mp_max_write", &maxwrite,
     6825                &maxwrite_sleep)) {
     6826        return NULL;
     6827    }
     6828    CHECK_ENV_NOT_CLOSED(self);
     6829    MYDB_BEGIN_ALLOW_THREADS;
     6830    err = self->db_env->set_mp_max_write(self->db_env, maxwrite,
     6831            maxwrite_sleep);
     6832    MYDB_END_ALLOW_THREADS;
     6833    RETURN_IF_ERR();
     6834    RETURN_NONE();
     6835}
     6836
     6837static PyObject*
     6838DBEnv_get_mp_max_write(DBEnvObject* self)
     6839{
     6840    int err;
     6841    int maxwrite;
     6842#if (DBVER >= 46)
     6843    db_timeout_t maxwrite_sleep;
     6844#else
     6845    int maxwrite_sleep;
     6846#endif
     6847
     6848    CHECK_ENV_NOT_CLOSED(self);
     6849
     6850    MYDB_BEGIN_ALLOW_THREADS;
     6851    err = self->db_env->get_mp_max_write(self->db_env, &maxwrite,
     6852            &maxwrite_sleep);
     6853    MYDB_END_ALLOW_THREADS;
     6854    RETURN_IF_ERR();
     6855
     6856    return Py_BuildValue("(ii)", maxwrite, (int)maxwrite_sleep);
     6857}
     6858#endif
     6859
    50716860
    50726861static PyObject*
     
    51476936
    51486937    if (!PyCallable_Check(notifyFunc)) {
    5149             makeTypeError("Callable", notifyFunc);
    5150             return NULL;
     6938            makeTypeError("Callable", notifyFunc);
     6939            return NULL;
    51516940    }
    51526941
     
    51666955
    51676956    if (err) {
    5168             Py_DECREF(notifyFunc);
    5169             self->event_notifyCallback = NULL;
     6957            Py_DECREF(notifyFunc);
     6958            self->event_notifyCallback = NULL;
    51706959    }
    51716960
     
    54887277                "i|O:rep_start", kwnames, &flags, &cdata_py))
    54897278    {
    5490             return NULL;
     7279            return NULL;
    54917280    }
    54927281    CHECK_ENV_NOT_CLOSED(self);
     
    56267415#endif
    56277416
     7417
     7418#if (DBVER >= 47)
     7419static PyObject*
     7420DBEnv_rep_set_clockskew(DBEnvObject* self, PyObject* args)
     7421{
     7422    int err;
     7423    unsigned int fast, slow;
     7424
     7425#if (PY_VERSION_HEX >= 0x02040000)
     7426    if (!PyArg_ParseTuple(args,"II:rep_set_clockskew", &fast, &slow))
     7427        return NULL;
     7428#else
     7429    if (!PyArg_ParseTuple(args,"ii:rep_set_clockskew", &fast, &slow))
     7430        return NULL;
     7431#endif
     7432
     7433    CHECK_ENV_NOT_CLOSED(self);
     7434
     7435    MYDB_BEGIN_ALLOW_THREADS;
     7436    err = self->db_env->rep_set_clockskew(self->db_env, fast, slow);
     7437    MYDB_END_ALLOW_THREADS;
     7438    RETURN_IF_ERR();
     7439    RETURN_NONE();
     7440}
     7441
     7442static PyObject*
     7443DBEnv_rep_get_clockskew(DBEnvObject* self)
     7444{
     7445    int err;
     7446    unsigned int fast, slow;
     7447
     7448    CHECK_ENV_NOT_CLOSED(self);
     7449    MYDB_BEGIN_ALLOW_THREADS;
     7450    err = self->db_env->rep_get_clockskew(self->db_env, &fast, &slow);
     7451    MYDB_END_ALLOW_THREADS;
     7452    RETURN_IF_ERR();
     7453#if (PY_VERSION_HEX >= 0x02040000)
     7454    return Py_BuildValue("(II)", fast, slow);
     7455#else
     7456    return Py_BuildValue("(ii)", fast, slow);
     7457#endif
     7458}
     7459#endif
     7460
     7461#if (DBVER >= 43)
     7462static PyObject*
     7463DBEnv_rep_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
     7464{
     7465    int err;
     7466    int flags=0;
     7467    static char* kwnames[] = { "flags", NULL };
     7468
     7469    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat_print",
     7470                kwnames, &flags))
     7471    {
     7472        return NULL;
     7473    }
     7474    CHECK_ENV_NOT_CLOSED(self);
     7475    MYDB_BEGIN_ALLOW_THREADS;
     7476    err = self->db_env->rep_stat_print(self->db_env, flags);
     7477    MYDB_END_ALLOW_THREADS;
     7478    RETURN_IF_ERR();
     7479    RETURN_NONE();
     7480}
     7481#endif
     7482
     7483static PyObject*
     7484DBEnv_rep_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
     7485{
     7486    int err;
     7487    int flags=0;
     7488    DB_REP_STAT *statp;
     7489    PyObject *stats;
     7490    static char* kwnames[] = { "flags", NULL };
     7491
     7492    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat",
     7493                kwnames, &flags))
     7494    {
     7495        return NULL;
     7496    }
     7497    CHECK_ENV_NOT_CLOSED(self);
     7498    MYDB_BEGIN_ALLOW_THREADS;
     7499    err = self->db_env->rep_stat(self->db_env, &statp, flags);
     7500    MYDB_END_ALLOW_THREADS;
     7501    RETURN_IF_ERR();
     7502
     7503    stats=PyDict_New();
     7504    if (stats == NULL) {
     7505        free(statp);
     7506        return NULL;
     7507    }
     7508
     7509#define MAKE_ENTRY(name)  _addIntToDict(stats, #name, statp->st_##name)
     7510#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(stats , #name, statp->st_##name)
     7511
     7512#if (DBVER >= 44)
     7513    MAKE_ENTRY(bulk_fills);
     7514    MAKE_ENTRY(bulk_overflows);
     7515    MAKE_ENTRY(bulk_records);
     7516    MAKE_ENTRY(bulk_transfers);
     7517    MAKE_ENTRY(client_rerequests);
     7518    MAKE_ENTRY(client_svc_miss);
     7519    MAKE_ENTRY(client_svc_req);
     7520#endif
     7521    MAKE_ENTRY(dupmasters);
     7522#if (DBVER >= 43)
     7523    MAKE_ENTRY(egen);
     7524    MAKE_ENTRY(election_nvotes);
     7525    MAKE_ENTRY(startup_complete);
     7526    MAKE_ENTRY(pg_duplicated);
     7527    MAKE_ENTRY(pg_records);
     7528    MAKE_ENTRY(pg_requested);
     7529    MAKE_ENTRY(next_pg);
     7530    MAKE_ENTRY(waiting_pg);
     7531#endif
     7532    MAKE_ENTRY(election_cur_winner);
     7533    MAKE_ENTRY(election_gen);
     7534    MAKE_DB_LSN_ENTRY(election_lsn);
     7535    MAKE_ENTRY(election_nsites);
     7536    MAKE_ENTRY(election_priority);
     7537#if (DBVER >= 44)
     7538    MAKE_ENTRY(election_sec);
     7539    MAKE_ENTRY(election_usec);
     7540#endif
     7541    MAKE_ENTRY(election_status);
     7542    MAKE_ENTRY(election_tiebreaker);
     7543    MAKE_ENTRY(election_votes);
     7544    MAKE_ENTRY(elections);
     7545    MAKE_ENTRY(elections_won);
     7546    MAKE_ENTRY(env_id);
     7547    MAKE_ENTRY(env_priority);
     7548    MAKE_ENTRY(gen);
     7549    MAKE_ENTRY(log_duplicated);
     7550    MAKE_ENTRY(log_queued);
     7551    MAKE_ENTRY(log_queued_max);
     7552    MAKE_ENTRY(log_queued_total);
     7553    MAKE_ENTRY(log_records);
     7554    MAKE_ENTRY(log_requested);
     7555    MAKE_ENTRY(master);
     7556    MAKE_ENTRY(master_changes);
     7557#if (DBVER >= 47)
     7558    MAKE_ENTRY(max_lease_sec);
     7559    MAKE_ENTRY(max_lease_usec);
     7560    MAKE_DB_LSN_ENTRY(max_perm_lsn);
     7561#endif
     7562    MAKE_ENTRY(msgs_badgen);
     7563    MAKE_ENTRY(msgs_processed);
     7564    MAKE_ENTRY(msgs_recover);
     7565    MAKE_ENTRY(msgs_send_failures);
     7566    MAKE_ENTRY(msgs_sent);
     7567    MAKE_ENTRY(newsites);
     7568    MAKE_DB_LSN_ENTRY(next_lsn);
     7569    MAKE_ENTRY(nsites);
     7570    MAKE_ENTRY(nthrottles);
     7571    MAKE_ENTRY(outdated);
     7572#if (DBVER >= 46)
     7573    MAKE_ENTRY(startsync_delayed);
     7574#endif
     7575    MAKE_ENTRY(status);
     7576    MAKE_ENTRY(txns_applied);
     7577    MAKE_DB_LSN_ENTRY(waiting_lsn);
     7578
     7579#undef MAKE_DB_LSN_ENTRY
     7580#undef MAKE_ENTRY
     7581
     7582    free(statp);
     7583    return stats;
     7584}
     7585
    56287586/* --------------------------------------------------------------------- */
    56297587/* REPLICATION METHODS: Replication Manager */
     
    56417599                "ii:repmgr_start", kwnames, &nthreads, &flags))
    56427600    {
    5643             return NULL;
     7601            return NULL;
    56447602    }
    56457603    CHECK_ENV_NOT_CLOSED(self);
     
    56647622                "si|i:repmgr_set_local_site", kwnames, &host, &port, &flags))
    56657623    {
    5666             return NULL;
     7624            return NULL;
    56677625    }
    56687626    CHECK_ENV_NOT_CLOSED(self);
     
    56887646                "si|i:repmgr_add_remote_site", kwnames, &host, &port, &flags))
    56897647    {
    5690             return NULL;
     7648            return NULL;
    56917649    }
    56927650    CHECK_ENV_NOT_CLOSED(self);
     
    57067664    if (!PyArg_ParseTuple(args, "i:repmgr_set_ack_policy", &ack_policy))
    57077665    {
    5708             return NULL;
     7666            return NULL;
    57097667    }
    57107668    CHECK_ENV_NOT_CLOSED(self);
     
    58817839            ** so nothing to do.
    58827840            */
    5883             db->txn=NULL; 
     7841            db->txn=NULL;
    58847842        }
    58857843    }
     
    59507908        return NULL;
    59517909
    5952     if (gid_size != DB_XIDDATASIZE) {
     7910    if (gid_size != DB_GID_SIZE) {
    59537911        PyErr_SetString(PyExc_TypeError,
    5954                         "gid must be DB_XIDDATASIZE bytes long");
     7912                        "gid must be DB_GID_SIZE bytes long");
    59557913        return NULL;
    59567914    }
     
    60668024    return NUMBER_FromLong(id);
    60678025}
     8026
     8027
     8028static PyObject*
     8029DBTxn_set_timeout(DBTxnObject* self, PyObject* args, PyObject* kwargs)
     8030{
     8031    int err;
     8032    u_int32_t flags=0;
     8033    u_int32_t timeout = 0;
     8034    static char* kwnames[] = { "timeout", "flags", NULL };
     8035
     8036    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
     8037                &timeout, &flags)) {
     8038        return NULL;
     8039    }
     8040
     8041    MYDB_BEGIN_ALLOW_THREADS;
     8042    err = self->txn->set_timeout(self->txn, (db_timeout_t)timeout, flags);
     8043    MYDB_END_ALLOW_THREADS;
     8044
     8045    RETURN_IF_ERR();
     8046    RETURN_NONE();
     8047}
     8048
     8049
     8050#if (DBVER >= 44)
     8051static PyObject*
     8052DBTxn_set_name(DBTxnObject* self, PyObject* args)
     8053{
     8054    int err;
     8055    const char *name;
     8056
     8057    if (!PyArg_ParseTuple(args, "s:set_name", &name))
     8058        return NULL;
     8059
     8060    MYDB_BEGIN_ALLOW_THREADS;
     8061    err = self->txn->set_name(self->txn, name);
     8062    MYDB_END_ALLOW_THREADS;
     8063
     8064    RETURN_IF_ERR();
     8065    RETURN_NONE();
     8066}
     8067#endif
     8068
     8069
     8070#if (DBVER >= 44)
     8071static PyObject*
     8072DBTxn_get_name(DBTxnObject* self)
     8073{
     8074    int err;
     8075    const char *name;
     8076
     8077    MYDB_BEGIN_ALLOW_THREADS;
     8078    err = self->txn->get_name(self->txn, &name);
     8079    MYDB_END_ALLOW_THREADS;
     8080
     8081    RETURN_IF_ERR();
     8082#if (PY_VERSION_HEX < 0x03000000)
     8083    if (!name) {
     8084        return PyString_FromString("");
     8085    }
     8086    return PyString_FromString(name);
     8087#else
     8088    if (!name) {
     8089        return PyUnicode_FromString("");
     8090    }
     8091    return PyUnicode_FromString(name);
     8092#endif
     8093}
     8094#endif
     8095
    60688096
    60698097#if (DBVER >= 43)
     
    61708198
    61718199static PyObject*
    6172 DBSequence_init_value(DBSequenceObject* self, PyObject* args)
     8200DBSequence_initial_value(DBSequenceObject* self, PyObject* args)
    61738201{
    61748202    int err;
    61758203    PY_LONG_LONG value;
    61768204    db_seq_t value2;
    6177     if (!PyArg_ParseTuple(args,"L:init_value", &value))
     8205    if (!PyArg_ParseTuple(args,"L:initial_value", &value))
    61788206        return NULL;
    61798207    CHECK_SEQUENCE_NOT_CLOSED(self)
     
    63518379    max=max2;
    63528380    return Py_BuildValue("(LL)", min, max);
     8381}
     8382
     8383
     8384static PyObject*
     8385DBSequence_stat_print(DBSequenceObject* self, PyObject* args, PyObject *kwargs)
     8386{
     8387    int err;
     8388    int flags=0;
     8389    static char* kwnames[] = { "flags", NULL };
     8390
     8391    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
     8392                kwnames, &flags))
     8393    {
     8394        return NULL;
     8395    }
     8396
     8397    CHECK_SEQUENCE_NOT_CLOSED(self);
     8398
     8399    MYDB_BEGIN_ALLOW_THREADS;
     8400    err = self->sequence->stat_print(self->sequence, flags);
     8401    MYDB_END_ALLOW_THREADS;
     8402    RETURN_IF_ERR();
     8403    RETURN_NONE();
    63538404}
    63548405
     
    64048455    {"associate",       (PyCFunction)DB_associate,      METH_VARARGS|METH_KEYWORDS},
    64058456    {"close",           (PyCFunction)DB_close,          METH_VARARGS},
     8457#if (DBVER >= 47)
     8458    {"compact",         (PyCFunction)DB_compact,        METH_VARARGS|METH_KEYWORDS},
     8459#endif
    64068460    {"consume",         (PyCFunction)DB_consume,        METH_VARARGS|METH_KEYWORDS},
    64078461    {"consume_wait",    (PyCFunction)DB_consume_wait,   METH_VARARGS|METH_KEYWORDS},
     
    64098463    {"delete",          (PyCFunction)DB_delete,         METH_VARARGS|METH_KEYWORDS},
    64108464    {"fd",              (PyCFunction)DB_fd,             METH_NOARGS},
     8465#if (DBVER >= 46)
     8466    {"exists",          (PyCFunction)DB_exists,
     8467        METH_VARARGS|METH_KEYWORDS},
     8468#endif
    64118469    {"get",             (PyCFunction)DB_get,            METH_VARARGS|METH_KEYWORDS},
    64128470    {"pget",            (PyCFunction)DB_pget,           METH_VARARGS|METH_KEYWORDS},
     
    64258483    {"rename",          (PyCFunction)DB_rename,         METH_VARARGS},
    64268484    {"set_bt_minkey",   (PyCFunction)DB_set_bt_minkey,  METH_VARARGS},
     8485#if (DBVER >= 42)
     8486    {"get_bt_minkey",   (PyCFunction)DB_get_bt_minkey,  METH_NOARGS},
     8487#endif
    64278488    {"set_bt_compare",  (PyCFunction)DB_set_bt_compare, METH_O},
    64288489    {"set_cachesize",   (PyCFunction)DB_set_cachesize,  METH_VARARGS},
    6429 #if (DBVER >= 41)
     8490#if (DBVER >= 42)
     8491    {"get_cachesize",   (PyCFunction)DB_get_cachesize,  METH_NOARGS},
     8492#endif
    64308493    {"set_encrypt",     (PyCFunction)DB_set_encrypt,    METH_VARARGS|METH_KEYWORDS},
    6431 #endif
     8494#if (DBVER >= 42)
     8495    {"get_encrypt_flags", (PyCFunction)DB_get_encrypt_flags, METH_NOARGS},
     8496#endif
     8497
    64328498    {"set_flags",       (PyCFunction)DB_set_flags,      METH_VARARGS},
     8499#if (DBVER >= 42)
     8500    {"get_flags",       (PyCFunction)DB_get_flags,      METH_NOARGS},
     8501#endif
    64338502    {"set_h_ffactor",   (PyCFunction)DB_set_h_ffactor,  METH_VARARGS},
     8503#if (DBVER >= 42)
     8504    {"get_h_ffactor",   (PyCFunction)DB_get_h_ffactor,  METH_NOARGS},
     8505#endif
    64348506    {"set_h_nelem",     (PyCFunction)DB_set_h_nelem,    METH_VARARGS},
     8507#if (DBVER >= 42)
     8508    {"get_h_nelem",     (PyCFunction)DB_get_h_nelem,    METH_NOARGS},
     8509#endif
    64358510    {"set_lorder",      (PyCFunction)DB_set_lorder,     METH_VARARGS},
     8511#if (DBVER >= 42)
     8512    {"get_lorder",      (PyCFunction)DB_get_lorder,     METH_NOARGS},
     8513#endif
    64368514    {"set_pagesize",    (PyCFunction)DB_set_pagesize,   METH_VARARGS},
     8515#if (DBVER >= 42)
     8516    {"get_pagesize",    (PyCFunction)DB_get_pagesize,   METH_NOARGS},
     8517#endif
    64378518    {"set_re_delim",    (PyCFunction)DB_set_re_delim,   METH_VARARGS},
     8519#if (DBVER >= 42)
     8520    {"get_re_delim",    (PyCFunction)DB_get_re_delim,   METH_NOARGS},
     8521#endif
    64388522    {"set_re_len",      (PyCFunction)DB_set_re_len,     METH_VARARGS},
     8523#if (DBVER >= 42)
     8524    {"get_re_len",      (PyCFunction)DB_get_re_len,     METH_NOARGS},
     8525#endif
    64398526    {"set_re_pad",      (PyCFunction)DB_set_re_pad,     METH_VARARGS},
     8527#if (DBVER >= 42)
     8528    {"get_re_pad",      (PyCFunction)DB_get_re_pad,     METH_NOARGS},
     8529#endif
    64408530    {"set_re_source",   (PyCFunction)DB_set_re_source,  METH_VARARGS},
     8531#if (DBVER >= 42)
     8532    {"get_re_source",   (PyCFunction)DB_get_re_source,  METH_NOARGS},
     8533#endif
    64418534    {"set_q_extentsize",(PyCFunction)DB_set_q_extentsize, METH_VARARGS},
     8535#if (DBVER >= 42)
     8536    {"get_q_extentsize",(PyCFunction)DB_get_q_extentsize, METH_NOARGS},
     8537#endif
    64428538    {"set_private",     (PyCFunction)DB_set_private,    METH_O},
    64438539    {"get_private",     (PyCFunction)DB_get_private,    METH_NOARGS},
     8540#if (DBVER >= 46)
     8541    {"set_priority",    (PyCFunction)DB_set_priority,   METH_VARARGS},
     8542    {"get_priority",    (PyCFunction)DB_get_priority,   METH_NOARGS},
     8543#endif
    64448544    {"stat",            (PyCFunction)DB_stat,           METH_VARARGS|METH_KEYWORDS},
     8545#if (DBVER >= 43)
     8546    {"stat_print",      (PyCFunction)DB_stat_print,
     8547        METH_VARARGS|METH_KEYWORDS},
     8548#endif
    64458549    {"sync",            (PyCFunction)DB_sync,           METH_VARARGS},
    64468550    {"truncate",        (PyCFunction)DB_truncate,       METH_VARARGS|METH_KEYWORDS},
     
    64538557};
    64548558
     8559
     8560/* We need this to support __contains__() */
     8561static PySequenceMethods DB_sequence = {
     8562    0, /* sq_length, mapping wins here */
     8563    0, /* sq_concat */
     8564    0, /* sq_repeat */
     8565    0, /* sq_item */
     8566    0, /* sq_slice */
     8567    0, /* sq_ass_item */
     8568    0, /* sq_ass_slice */
     8569    (objobjproc)DB_contains, /* sq_contains */
     8570    0, /* sq_inplace_concat */
     8571    0, /* sq_inplace_repeat */
     8572};
    64558573
    64568574static PyMappingMethods DB_mapping = {
     
    64848602    {"next_dup",        (PyCFunction)DBC_next_dup,      METH_VARARGS|METH_KEYWORDS},
    64858603    {"next_nodup",      (PyCFunction)DBC_next_nodup,    METH_VARARGS|METH_KEYWORDS},
     8604#if (DBVER >= 46)
     8605    {"prev_dup",        (PyCFunction)DBC_prev_dup,
     8606        METH_VARARGS|METH_KEYWORDS},
     8607#endif
    64868608    {"prev_nodup",      (PyCFunction)DBC_prev_nodup,    METH_VARARGS|METH_KEYWORDS},
    64878609    {"join_item",       (PyCFunction)DBC_join_item,     METH_VARARGS},
     8610#if (DBVER >= 46)
     8611    {"set_priority",    (PyCFunction)DBC_set_priority,
     8612        METH_VARARGS|METH_KEYWORDS},
     8613    {"get_priority",    (PyCFunction)DBC_get_priority, METH_NOARGS},
     8614#endif
     8615    {NULL,      NULL}       /* sentinel */
     8616};
     8617
     8618
     8619static PyMethodDef DBLogCursor_methods[] = {
     8620    {"close",   (PyCFunction)DBLogCursor_close,     METH_NOARGS},
     8621    {"current", (PyCFunction)DBLogCursor_current,   METH_NOARGS},
     8622    {"first",   (PyCFunction)DBLogCursor_first,     METH_NOARGS},
     8623    {"last",    (PyCFunction)DBLogCursor_last,      METH_NOARGS},
     8624    {"next",    (PyCFunction)DBLogCursor_next,      METH_NOARGS},
     8625    {"prev",    (PyCFunction)DBLogCursor_prev,      METH_NOARGS},
     8626    {"set",     (PyCFunction)DBLogCursor_set,       METH_VARARGS},
    64888627    {NULL,      NULL}       /* sentinel */
    64898628};
     
    64948633    {"open",            (PyCFunction)DBEnv_open,             METH_VARARGS},
    64958634    {"remove",          (PyCFunction)DBEnv_remove,           METH_VARARGS},
    6496 #if (DBVER >= 41)
    64978635    {"dbremove",        (PyCFunction)DBEnv_dbremove,         METH_VARARGS|METH_KEYWORDS},
    64988636    {"dbrename",        (PyCFunction)DBEnv_dbrename,         METH_VARARGS|METH_KEYWORDS},
     8637#if (DBVER >= 46)
     8638    {"set_thread_count", (PyCFunction)DBEnv_set_thread_count, METH_VARARGS},
     8639    {"get_thread_count", (PyCFunction)DBEnv_get_thread_count, METH_NOARGS},
     8640#endif
    64998641    {"set_encrypt",     (PyCFunction)DBEnv_set_encrypt,      METH_VARARGS|METH_KEYWORDS},
    6500 #endif
    6501     {"set_timeout",     (PyCFunction)DBEnv_set_timeout,      METH_VARARGS|METH_KEYWORDS},
    6502     {"set_shm_key",     (PyCFunction)DBEnv_set_shm_key,      METH_VARARGS},
    6503     {"set_cachesize",   (PyCFunction)DBEnv_set_cachesize,    METH_VARARGS},
    6504     {"set_data_dir",    (PyCFunction)DBEnv_set_data_dir,     METH_VARARGS},
    6505     {"set_flags",       (PyCFunction)DBEnv_set_flags,        METH_VARARGS},
     8642#if (DBVER >= 42)
     8643    {"get_encrypt_flags", (PyCFunction)DBEnv_get_encrypt_flags, METH_NOARGS},
     8644    {"get_timeout",     (PyCFunction)DBEnv_get_timeout,
     8645        METH_VARARGS|METH_KEYWORDS},
     8646#endif
     8647    {"set_timeout",     (PyCFunction)DBEnv_set_timeout,     METH_VARARGS|METH_KEYWORDS},
     8648    {"set_shm_key",     (PyCFunction)DBEnv_set_shm_key,     METH_VARARGS},
     8649#if (DBVER >= 42)
     8650    {"get_shm_key",     (PyCFunction)DBEnv_get_shm_key,     METH_NOARGS},
     8651#endif
     8652#if (DBVER >= 46)
     8653    {"set_cache_max",   (PyCFunction)DBEnv_set_cache_max,   METH_VARARGS},
     8654    {"get_cache_max",   (PyCFunction)DBEnv_get_cache_max,   METH_NOARGS},
     8655#endif
     8656    {"set_cachesize",   (PyCFunction)DBEnv_set_cachesize,   METH_VARARGS},
     8657#if (DBVER >= 42)
     8658    {"get_cachesize",   (PyCFunction)DBEnv_get_cachesize,   METH_NOARGS},
     8659#endif
     8660    {"memp_trickle",    (PyCFunction)DBEnv_memp_trickle,    METH_VARARGS},
     8661    {"memp_sync",       (PyCFunction)DBEnv_memp_sync,       METH_VARARGS},
     8662    {"memp_stat",       (PyCFunction)DBEnv_memp_stat,
     8663        METH_VARARGS|METH_KEYWORDS},
     8664#if (DBVER >= 43)
     8665    {"memp_stat_print", (PyCFunction)DBEnv_memp_stat_print,
     8666        METH_VARARGS|METH_KEYWORDS},
     8667#endif
     8668#if (DBVER >= 44)
     8669    {"mutex_set_max",   (PyCFunction)DBEnv_mutex_set_max,   METH_VARARGS},
     8670    {"mutex_get_max",   (PyCFunction)DBEnv_mutex_get_max,   METH_NOARGS},
     8671    {"mutex_set_align", (PyCFunction)DBEnv_mutex_set_align, METH_VARARGS},
     8672    {"mutex_get_align", (PyCFunction)DBEnv_mutex_get_align, METH_NOARGS},
     8673    {"mutex_set_increment", (PyCFunction)DBEnv_mutex_set_increment,
     8674        METH_VARARGS},
     8675    {"mutex_get_increment", (PyCFunction)DBEnv_mutex_get_increment,
     8676        METH_NOARGS},
     8677    {"mutex_set_tas_spins", (PyCFunction)DBEnv_mutex_set_tas_spins,
     8678        METH_VARARGS},
     8679    {"mutex_get_tas_spins", (PyCFunction)DBEnv_mutex_get_tas_spins,
     8680        METH_NOARGS},
     8681    {"mutex_stat",      (PyCFunction)DBEnv_mutex_stat,      METH_VARARGS},
     8682#if (DBVER >= 44)
     8683    {"mutex_stat_print", (PyCFunction)DBEnv_mutex_stat_print,
     8684                                         METH_VARARGS|METH_KEYWORDS},
     8685#endif
     8686#endif
     8687    {"set_data_dir",    (PyCFunction)DBEnv_set_data_dir,    METH_VARARGS},
     8688#if (DBVER >= 42)
     8689    {"get_data_dirs",   (PyCFunction)DBEnv_get_data_dirs,   METH_NOARGS},
     8690#endif
     8691#if (DBVER >= 42)
     8692    {"get_flags",       (PyCFunction)DBEnv_get_flags,       METH_NOARGS},
     8693#endif
     8694    {"set_flags",       (PyCFunction)DBEnv_set_flags,       METH_VARARGS},
    65068695#if (DBVER >= 47)
    6507     {"log_set_config",  (PyCFunction)DBEnv_log_set_config,   METH_VARARGS},
    6508 #endif
    6509     {"set_lg_bsize",    (PyCFunction)DBEnv_set_lg_bsize,     METH_VARARGS},
    6510     {"set_lg_dir",      (PyCFunction)DBEnv_set_lg_dir,       METH_VARARGS},
    6511     {"set_lg_max",      (PyCFunction)DBEnv_set_lg_max,       METH_VARARGS},
     8696    {"log_set_config",  (PyCFunction)DBEnv_log_set_config,  METH_VARARGS},
     8697    {"log_get_config",  (PyCFunction)DBEnv_log_get_config,  METH_VARARGS},
     8698#endif
     8699    {"set_lg_bsize",    (PyCFunction)DBEnv_set_lg_bsize,    METH_VARARGS},
    65128700#if (DBVER >= 42)
    6513     {"get_lg_max",      (PyCFunction)DBEnv_get_lg_max,       METH_NOARGS},
     8701    {"get_lg_bsize",    (PyCFunction)DBEnv_get_lg_bsize,    METH_NOARGS},
     8702#endif
     8703    {"set_lg_dir",      (PyCFunction)DBEnv_set_lg_dir,      METH_VARARGS},
     8704#if (DBVER >= 42)
     8705    {"get_lg_dir",      (PyCFunction)DBEnv_get_lg_dir,      METH_NOARGS},
     8706#endif
     8707    {"set_lg_max",      (PyCFunction)DBEnv_set_lg_max,      METH_VARARGS},
     8708#if (DBVER >= 42)
     8709    {"get_lg_max",      (PyCFunction)DBEnv_get_lg_max,      METH_NOARGS},
    65148710#endif
    65158711    {"set_lg_regionmax",(PyCFunction)DBEnv_set_lg_regionmax, METH_VARARGS},
    6516     {"set_lk_detect",   (PyCFunction)DBEnv_set_lk_detect,    METH_VARARGS},
     8712#if (DBVER >= 42)
     8713    {"get_lg_regionmax",(PyCFunction)DBEnv_get_lg_regionmax, METH_NOARGS},
     8714#endif
     8715#if (DBVER >= 44)
     8716    {"set_lg_filemode", (PyCFunction)DBEnv_set_lg_filemode, METH_VARARGS},
     8717    {"get_lg_filemode", (PyCFunction)DBEnv_get_lg_filemode, METH_NOARGS},
     8718#endif
     8719#if (DBVER >= 47)
     8720    {"set_lk_partitions", (PyCFunction)DBEnv_set_lk_partitions, METH_VARARGS},
     8721    {"get_lk_partitions", (PyCFunction)DBEnv_get_lk_partitions, METH_NOARGS},
     8722#endif
     8723    {"set_lk_detect",   (PyCFunction)DBEnv_set_lk_detect,   METH_VARARGS},
     8724#if (DBVER >= 42)
     8725    {"get_lk_detect",   (PyCFunction)DBEnv_get_lk_detect,   METH_NOARGS},
     8726#endif
    65178727#if (DBVER < 45)
    6518     {"set_lk_max",      (PyCFunction)DBEnv_set_lk_max,       METH_VARARGS},
     8728    {"set_lk_max",      (PyCFunction)DBEnv_set_lk_max,      METH_VARARGS},
    65198729#endif
    65208730    {"set_lk_max_locks", (PyCFunction)DBEnv_set_lk_max_locks, METH_VARARGS},
     8731#if (DBVER >= 42)
     8732    {"get_lk_max_locks", (PyCFunction)DBEnv_get_lk_max_locks, METH_NOARGS},
     8733#endif
    65218734    {"set_lk_max_lockers", (PyCFunction)DBEnv_set_lk_max_lockers, METH_VARARGS},
     8735#if (DBVER >= 42)
     8736    {"get_lk_max_lockers", (PyCFunction)DBEnv_get_lk_max_lockers, METH_NOARGS},
     8737#endif
    65228738    {"set_lk_max_objects", (PyCFunction)DBEnv_set_lk_max_objects, METH_VARARGS},
    6523     {"set_mp_mmapsize", (PyCFunction)DBEnv_set_mp_mmapsize,  METH_VARARGS},
    6524     {"set_tmp_dir",     (PyCFunction)DBEnv_set_tmp_dir,      METH_VARARGS},
    6525     {"txn_begin",       (PyCFunction)DBEnv_txn_begin,        METH_VARARGS|METH_KEYWORDS},
    6526     {"txn_checkpoint",  (PyCFunction)DBEnv_txn_checkpoint,   METH_VARARGS},
    6527     {"txn_stat",        (PyCFunction)DBEnv_txn_stat,         METH_VARARGS},
    6528     {"set_tx_max",      (PyCFunction)DBEnv_set_tx_max,       METH_VARARGS},
     8739#if (DBVER >= 42)
     8740    {"get_lk_max_objects", (PyCFunction)DBEnv_get_lk_max_objects, METH_NOARGS},
     8741#endif
     8742#if (DBVER >= 43)
     8743    {"stat_print",          (PyCFunction)DBEnv_stat_print,
     8744        METH_VARARGS|METH_KEYWORDS},
     8745#endif
     8746    {"set_mp_mmapsize", (PyCFunction)DBEnv_set_mp_mmapsize, METH_VARARGS},
     8747#if (DBVER >= 42)
     8748    {"get_mp_mmapsize", (PyCFunction)DBEnv_get_mp_mmapsize, METH_NOARGS},
     8749#endif
     8750    {"set_tmp_dir",     (PyCFunction)DBEnv_set_tmp_dir,     METH_VARARGS},
     8751#if (DBVER >= 42)
     8752    {"get_tmp_dir",     (PyCFunction)DBEnv_get_tmp_dir,     METH_NOARGS},
     8753#endif
     8754    {"txn_begin",       (PyCFunction)DBEnv_txn_begin,       METH_VARARGS|METH_KEYWORDS},
     8755    {"txn_checkpoint",  (PyCFunction)DBEnv_txn_checkpoint,  METH_VARARGS},
     8756    {"txn_stat",        (PyCFunction)DBEnv_txn_stat,        METH_VARARGS},
     8757#if (DBVER >= 43)
     8758    {"txn_stat_print",  (PyCFunction)DBEnv_txn_stat_print,
     8759        METH_VARARGS|METH_KEYWORDS},
     8760#endif
     8761#if (DBVER >= 42)
     8762    {"get_tx_max",      (PyCFunction)DBEnv_get_tx_max,      METH_NOARGS},
     8763    {"get_tx_timestamp", (PyCFunction)DBEnv_get_tx_timestamp, METH_NOARGS},
     8764#endif
     8765    {"set_tx_max",      (PyCFunction)DBEnv_set_tx_max,      METH_VARARGS},
    65298766    {"set_tx_timestamp", (PyCFunction)DBEnv_set_tx_timestamp, METH_VARARGS},
    6530     {"lock_detect",     (PyCFunction)DBEnv_lock_detect,      METH_VARARGS},
    6531     {"lock_get",        (PyCFunction)DBEnv_lock_get,         METH_VARARGS},
    6532     {"lock_id",         (PyCFunction)DBEnv_lock_id,          METH_NOARGS},
    6533     {"lock_id_free",    (PyCFunction)DBEnv_lock_id_free,     METH_VARARGS},
    6534     {"lock_put",        (PyCFunction)DBEnv_lock_put,         METH_VARARGS},
    6535     {"lock_stat",       (PyCFunction)DBEnv_lock_stat,        METH_VARARGS},
    6536     {"log_archive",     (PyCFunction)DBEnv_log_archive,      METH_VARARGS},
    6537     {"log_flush",       (PyCFunction)DBEnv_log_flush,        METH_NOARGS},
    6538     {"log_stat",        (PyCFunction)DBEnv_log_stat,         METH_VARARGS},
     8767    {"lock_detect",     (PyCFunction)DBEnv_lock_detect,     METH_VARARGS},
     8768    {"lock_get",        (PyCFunction)DBEnv_lock_get,        METH_VARARGS},
     8769    {"lock_id",         (PyCFunction)DBEnv_lock_id,         METH_NOARGS},
     8770    {"lock_id_free",    (PyCFunction)DBEnv_lock_id_free,    METH_VARARGS},
     8771    {"lock_put",        (PyCFunction)DBEnv_lock_put,        METH_VARARGS},
     8772    {"lock_stat",       (PyCFunction)DBEnv_lock_stat,       METH_VARARGS},
     8773#if (DBVER >= 43)
     8774    {"lock_stat_print", (PyCFunction)DBEnv_lock_stat_print,
     8775        METH_VARARGS|METH_KEYWORDS},
     8776#endif
     8777    {"log_cursor",      (PyCFunction)DBEnv_log_cursor,      METH_NOARGS},
     8778    {"log_file",        (PyCFunction)DBEnv_log_file,        METH_VARARGS},
    65398779#if (DBVER >= 44)
    6540     {"lsn_reset",       (PyCFunction)DBEnv_lsn_reset,        METH_VARARGS|METH_KEYWORDS},
     8780    {"log_printf",      (PyCFunction)DBEnv_log_printf,
     8781        METH_VARARGS|METH_KEYWORDS},
     8782#endif
     8783    {"log_archive",     (PyCFunction)DBEnv_log_archive,     METH_VARARGS},
     8784    {"log_flush",       (PyCFunction)DBEnv_log_flush,       METH_NOARGS},
     8785    {"log_stat",        (PyCFunction)DBEnv_log_stat,        METH_VARARGS},
     8786#if (DBVER >= 43)
     8787    {"log_stat_print",  (PyCFunction)DBEnv_log_stat_print,
     8788        METH_VARARGS|METH_KEYWORDS},
     8789#endif
     8790#if (DBVER >= 44)
     8791    {"fileid_reset",    (PyCFunction)DBEnv_fileid_reset,    METH_VARARGS|METH_KEYWORDS},
     8792    {"lsn_reset",       (PyCFunction)DBEnv_lsn_reset,       METH_VARARGS|METH_KEYWORDS},
    65418793#endif
    65428794    {"set_get_returns_none",(PyCFunction)DBEnv_set_get_returns_none, METH_VARARGS},
    6543     {"txn_recover",     (PyCFunction)DBEnv_txn_recover,       METH_NOARGS},
     8795    {"txn_recover",     (PyCFunction)DBEnv_txn_recover,     METH_NOARGS},
     8796#if (DBVER < 48)
    65448797    {"set_rpc_server",  (PyCFunction)DBEnv_set_rpc_server,
    65458798        METH_VARARGS||METH_KEYWORDS},
    6546     {"set_verbose",     (PyCFunction)DBEnv_set_verbose,       METH_VARARGS},
     8799#endif
     8800#if (DBVER >= 43)
     8801    {"set_mp_max_openfd", (PyCFunction)DBEnv_set_mp_max_openfd, METH_VARARGS},
     8802    {"get_mp_max_openfd", (PyCFunction)DBEnv_get_mp_max_openfd, METH_NOARGS},
     8803    {"set_mp_max_write", (PyCFunction)DBEnv_set_mp_max_write, METH_VARARGS},
     8804    {"get_mp_max_write", (PyCFunction)DBEnv_get_mp_max_write, METH_NOARGS},
     8805#endif
     8806    {"set_verbose",     (PyCFunction)DBEnv_set_verbose,     METH_VARARGS},
    65478807#if (DBVER >= 42)
    65488808    {"get_verbose",     (PyCFunction)DBEnv_get_verbose,       METH_VARARGS},
     
    65828842    {"rep_get_timeout", (PyCFunction)DBEnv_rep_get_timeout, METH_VARARGS},
    65838843#endif
     8844#if (DBVER >= 47)
     8845    {"rep_set_clockskew", (PyCFunction)DBEnv_rep_set_clockskew, METH_VARARGS},
     8846    {"rep_get_clockskew", (PyCFunction)DBEnv_rep_get_clockskew, METH_VARARGS},
     8847#endif
     8848    {"rep_stat", (PyCFunction)DBEnv_rep_stat,
     8849        METH_VARARGS|METH_KEYWORDS},
     8850#if (DBVER >= 43)
     8851    {"rep_stat_print", (PyCFunction)DBEnv_rep_stat_print,
     8852        METH_VARARGS|METH_KEYWORDS},
     8853#endif
     8854
    65848855#if (DBVER >= 45)
    65858856    {"repmgr_start", (PyCFunction)DBEnv_repmgr_start,
     
    66128883    {"abort",           (PyCFunction)DBTxn_abort,       METH_NOARGS},
    66138884    {"id",              (PyCFunction)DBTxn_id,          METH_NOARGS},
     8885    {"set_timeout",     (PyCFunction)DBTxn_set_timeout,
     8886        METH_VARARGS|METH_KEYWORDS},
     8887#if (DBVER >= 44)
     8888    {"set_name",        (PyCFunction)DBTxn_set_name, METH_VARARGS},
     8889    {"get_name",        (PyCFunction)DBTxn_get_name, METH_NOARGS},
     8890#endif
    66148891    {NULL,      NULL}       /* sentinel */
    66158892};
     
    66228899    {"get_dbp",         (PyCFunction)DBSequence_get_dbp,        METH_NOARGS},
    66238900    {"get_key",         (PyCFunction)DBSequence_get_key,        METH_NOARGS},
    6624     {"init_value",      (PyCFunction)DBSequence_init_value,     METH_VARARGS},
     8901    {"initial_value",   (PyCFunction)DBSequence_initial_value,  METH_VARARGS},
    66258902    {"open",            (PyCFunction)DBSequence_open,           METH_VARARGS|METH_KEYWORDS},
    66268903    {"remove",          (PyCFunction)DBSequence_remove,         METH_VARARGS|METH_KEYWORDS},
     
    66328909    {"get_range",       (PyCFunction)DBSequence_get_range,      METH_NOARGS},
    66338910    {"stat",            (PyCFunction)DBSequence_stat,           METH_VARARGS|METH_KEYWORDS},
     8911    {"stat_print",      (PyCFunction)DBSequence_stat_print,
     8912        METH_VARARGS|METH_KEYWORDS},
    66348913    {NULL,      NULL}       /* sentinel */
    66358914};
     
    66458924
    66468925#if (DBVER >= 42)
     8926    MYDB_BEGIN_ALLOW_THREADS;
    66478927    self->db_env->get_home(self->db_env, &home);
     8928    MYDB_END_ALLOW_THREADS;
    66488929#else
    66498930    home=self->db_env->db_home;
     
    66808961    0,          /*tp_repr*/
    66818962    0,          /*tp_as_number*/
    6682     0,          /*tp_as_sequence*/
     8963    &DB_sequence,/*tp_as_sequence*/
    66838964    &DB_mapping,/*tp_as_mapping*/
    66848965    0,          /*tp_hash*/
    6685     0,                  /* tp_call */
    6686     0,                  /* tp_str */
    6687     0,                  /* tp_getattro */
     8966    0,                  /* tp_call */
     8967    0,                  /* tp_str */
     8968    0,                  /* tp_getattro */
    66888969    0,          /* tp_setattro */
    6689     0,                  /* tp_as_buffer */
     8970    0,                  /* tp_as_buffer */
    66908971#if (PY_VERSION_HEX < 0x03000000)
    66918972    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS,      /* tp_flags */
     
    66948975#endif
    66958976    0,          /* tp_doc */
    6696     0,              /* tp_traverse */
    6697     0,                  /* tp_clear */
    6698     0,                  /* tp_richcompare */
     8977    0,              /* tp_traverse */
     8978    0,                  /* tp_clear */
     8979    0,                  /* tp_richcompare */
    66998980    offsetof(DBObject, in_weakreflist),   /* tp_weaklistoffset */
    67008981    0,          /*tp_iter*/
     
    67489029
    67499030
     9031statichere PyTypeObject DBLogCursor_Type = {
     9032#if (PY_VERSION_HEX < 0x03000000)
     9033    PyObject_HEAD_INIT(NULL)
     9034    0,                  /*ob_size*/
     9035#else
     9036    PyVarObject_HEAD_INIT(NULL, 0)
     9037#endif
     9038    "DBLogCursor",         /*tp_name*/
     9039    sizeof(DBLogCursorObject),  /*tp_basicsize*/
     9040    0,          /*tp_itemsize*/
     9041    /* methods */
     9042    (destructor)DBLogCursor_dealloc,/*tp_dealloc*/
     9043    0,          /*tp_print*/
     9044    0,          /*tp_getattr*/
     9045    0,          /*tp_setattr*/
     9046    0,          /*tp_compare*/
     9047    0,          /*tp_repr*/
     9048    0,          /*tp_as_number*/
     9049    0,          /*tp_as_sequence*/
     9050    0,          /*tp_as_mapping*/
     9051    0,          /*tp_hash*/
     9052    0,          /*tp_call*/
     9053    0,          /*tp_str*/
     9054    0,          /*tp_getattro*/
     9055    0,          /*tp_setattro*/
     9056    0,          /*tp_as_buffer*/
     9057#if (PY_VERSION_HEX < 0x03000000)
     9058    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS,      /* tp_flags */
     9059#else
     9060    Py_TPFLAGS_DEFAULT,      /* tp_flags */
     9061#endif
     9062    0,          /* tp_doc */
     9063    0,          /* tp_traverse */
     9064    0,          /* tp_clear */
     9065    0,          /* tp_richcompare */
     9066    offsetof(DBLogCursorObject, in_weakreflist),   /* tp_weaklistoffset */
     9067    0,          /*tp_iter*/
     9068    0,          /*tp_iternext*/
     9069    DBLogCursor_methods, /*tp_methods*/
     9070    0,          /*tp_members*/
     9071};
     9072
     9073
    67509074statichere PyTypeObject DBEnv_Type = {
    67519075#if (PY_VERSION_HEX < 0x03000000)
     
    67699093    0,          /*tp_as_mapping*/
    67709094    0,          /*tp_hash*/
    6771     0,                  /* tp_call */
    6772     0,                  /* tp_str */
    6773     0,                  /* tp_getattro */
     9095    0,                  /* tp_call */
     9096    0,                  /* tp_str */
     9097    0,                  /* tp_getattro */
    67749098    0,          /* tp_setattro */
    6775     0,                  /* tp_as_buffer */
     9099    0,                  /* tp_as_buffer */
    67769100#if (PY_VERSION_HEX < 0x03000000)
    67779101    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS,      /* tp_flags */
     
    67809104#endif
    67819105    0,          /* tp_doc */
    6782     0,              /* tp_traverse */
    6783     0,                  /* tp_clear */
    6784     0,                  /* tp_richcompare */
     9106    0,              /* tp_traverse */
     9107    0,                  /* tp_clear */
     9108    0,                  /* tp_richcompare */
    67859109    offsetof(DBEnvObject, in_weakreflist),   /* tp_weaklistoffset */
    67869110    0,          /* tp_iter */
     
    68129136    0,          /*tp_as_mapping*/
    68139137    0,          /*tp_hash*/
    6814     0,                  /* tp_call */
    6815     0,                  /* tp_str */
    6816     0,                  /* tp_getattro */
     9138    0,                  /* tp_call */
     9139    0,                  /* tp_str */
     9140    0,                  /* tp_getattro */
    68179141    0,          /* tp_setattro */
    6818     0,                  /* tp_as_buffer */
     9142    0,                  /* tp_as_buffer */
    68199143#if (PY_VERSION_HEX < 0x03000000)
    68209144    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS,      /* tp_flags */
     
    68239147#endif
    68249148    0,          /* tp_doc */
    6825     0,          /* tp_traverse */
    6826     0,                  /* tp_clear */
    6827     0,                  /* tp_richcompare */
     9149    0,          /* tp_traverse */
     9150    0,                  /* tp_clear */
     9151    0,                  /* tp_richcompare */
    68289152    offsetof(DBTxnObject, in_weakreflist),   /* tp_weaklistoffset */
    68299153    0,          /*tp_iter*/
     
    68559179    0,          /*tp_as_mapping*/
    68569180    0,          /*tp_hash*/
    6857     0,                  /* tp_call */
    6858     0,                  /* tp_str */
    6859     0,                  /* tp_getattro */
     9181    0,                  /* tp_call */
     9182    0,                  /* tp_str */
     9183    0,                  /* tp_getattro */
    68609184    0,          /* tp_setattro */
    6861     0,                  /* tp_as_buffer */
     9185    0,                  /* tp_as_buffer */
    68629186#if (PY_VERSION_HEX < 0x03000000)
    68639187    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS,      /* tp_flags */
     
    68669190#endif
    68679191    0,          /* tp_doc */
    6868     0,              /* tp_traverse */
    6869     0,                  /* tp_clear */
    6870     0,                  /* tp_richcompare */
     9192    0,              /* tp_traverse */
     9193    0,                  /* tp_clear */
     9194    0,                  /* tp_richcompare */
    68719195    offsetof(DBLockObject, in_weakreflist),   /* tp_weaklistoffset */
    68729196};
     
    68949218    0,          /*tp_as_mapping*/
    68959219    0,          /*tp_hash*/
    6896     0,                  /* tp_call */
    6897     0,                  /* tp_str */
    6898     0,                  /* tp_getattro */
     9220    0,                  /* tp_call */
     9221    0,                  /* tp_str */
     9222    0,                  /* tp_getattro */
    68999223    0,          /* tp_setattro */
    6900     0,                  /* tp_as_buffer */
     9224    0,                  /* tp_as_buffer */
    69019225#if (PY_VERSION_HEX < 0x03000000)
    69029226    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS,      /* tp_flags */
     
    69059229#endif
    69069230    0,          /* tp_doc */
    6907     0,              /* tp_traverse */
    6908     0,                  /* tp_clear */
    6909     0,                  /* tp_richcompare */
     9231    0,              /* tp_traverse */
     9232    0,                  /* tp_clear */
     9233    0,                  /* tp_richcompare */
    69109234    offsetof(DBSequenceObject, in_weakreflist),   /* tp_weaklistoffset */
    69119235    0,          /*tp_iter*/
     
    70329356    PyObject* m;
    70339357    PyObject* d;
    7034     PyObject* pybsddb_version_s = PyBytes_FromString( PY_BSDDB_VERSION );
    7035     PyObject* db_version_s = PyBytes_FromString( DB_VERSION_STRING );
    7036     PyObject* cvsid_s = PyBytes_FromString( rcs_id );
    70379358    PyObject* py_api;
     9359    PyObject* pybsddb_version_s;
     9360    PyObject* db_version_s;
     9361    PyObject* cvsid_s;
     9362
     9363#if (PY_VERSION_HEX < 0x03000000)
     9364    pybsddb_version_s = PyString_FromString(PY_BSDDB_VERSION);
     9365    db_version_s = PyString_FromString(DB_VERSION_STRING);
     9366    cvsid_s = PyString_FromString(rcs_id);
     9367#else
     9368    /* This data should be ascii, so UTF-8 conversion is fine */
     9369    pybsddb_version_s = PyUnicode_FromString(PY_BSDDB_VERSION);
     9370    db_version_s = PyUnicode_FromString(DB_VERSION_STRING);
     9371    cvsid_s = PyUnicode_FromString(rcs_id);
     9372#endif
    70389373
    70399374    /* Initialize object types */
    70409375    if ((PyType_Ready(&DB_Type) < 0)
    70419376        || (PyType_Ready(&DBCursor_Type) < 0)
     9377        || (PyType_Ready(&DBLogCursor_Type) < 0)
    70429378        || (PyType_Ready(&DBEnv_Type) < 0)
    70439379        || (PyType_Ready(&DBTxn_Type) < 0)
     
    70699405        return;
    70709406#else
    7071         return NULL;
     9407        return NULL;
    70729408#endif
    70739409    }
     
    70929428    ADD_INT(d, DB_MAX_RECORDS);
    70939429
     9430#if (DBVER < 48)
    70949431#if (DBVER >= 42)
    70959432    ADD_INT(d, DB_RPCCLIENT);
     
    70999436    _addIntToDict(d, "DB_RPCCLIENT", DB_CLIENT);
    71009437#endif
     9438#endif
     9439
     9440#if (DBVER < 48)
    71019441    ADD_INT(d, DB_XA_CREATE);
     9442#endif
    71029443
    71039444    ADD_INT(d, DB_CREATE);
     
    71169457    ADD_INT(d, DB_JOINENV);
    71179458
     9459#if (DBVER >= 48)
     9460    ADD_INT(d, DB_GID_SIZE);
     9461#else
    71189462    ADD_INT(d, DB_XIDDATASIZE);
     9463    /* Allow new code to work in old BDB releases */
     9464    _addIntToDict(d, "DB_GID_SIZE", DB_XIDDATASIZE);
     9465#endif
    71199466
    71209467    ADD_INT(d, DB_RECOVER);
     
    71309477    ADD_INT(d, DB_TXN_SYNC);
    71319478    ADD_INT(d, DB_TXN_NOWAIT);
     9479
     9480#if (DBVER >= 46)
     9481    ADD_INT(d, DB_TXN_WAIT);
     9482#endif
    71329483
    71339484    ADD_INT(d, DB_EXCL);
     
    71429493    ADD_INT(d, DB_UPGRADE);
    71439494
     9495    ADD_INT(d, DB_PRINTABLE);
    71449496    ADD_INT(d, DB_AGGRESSIVE);
    71459497    ADD_INT(d, DB_NOORDERCHK);
     
    72279579    ADD_INT(d, DB_SNAPSHOT);
    72289580
     9581#if (DBVER >= 43)
     9582    ADD_INT(d, DB_INORDER);
     9583#endif
     9584
    72299585    ADD_INT(d, DB_JOIN_NOSORT);
    72309586
     
    72369592#endif
    72379593
    7238 #if (DBVER >= 41)
    7239     _addIntToDict(d, "DB_CHECKPOINT", 0);
    7240 #else
    7241     ADD_INT(d, DB_CHECKPOINT);
    7242     ADD_INT(d, DB_CURLSN);
    7243 #endif
    72449594#if (DBVER <= 41)
    72459595    ADD_INT(d, DB_COMMIT);
     
    72529602    ADD_INT(d, DB_FLUSH);
    72539603    ADD_INT(d, DB_GET_BOTH);
     9604    ADD_INT(d, DB_GET_BOTH_RANGE);
    72549605    ADD_INT(d, DB_GET_RECNO);
    72559606    ADD_INT(d, DB_JOIN_ITEM);
     
    72669617    ADD_INT(d, DB_PREV);
    72679618    ADD_INT(d, DB_PREV_NODUP);
     9619#if (DBVER >= 46)
     9620    ADD_INT(d, DB_PREV_DUP);
     9621#endif
    72689622#if (DBVER < 45)
    72699623    ADD_INT(d, DB_RECORDCOUNT);
     
    72819635
    72829636#if (DBVER >= 44)
     9637    ADD_INT(d, DB_IMMUTABLE_KEY);
    72839638    ADD_INT(d, DB_READ_UNCOMMITTED);    /* replaces DB_DIRTY_READ in 4.4 */
    72849639    ADD_INT(d, DB_READ_COMMITTED);
    72859640#endif
    72869641
     9642#if (DBVER >= 44)
     9643    ADD_INT(d, DB_FREELIST_ONLY);
     9644    ADD_INT(d, DB_FREE_SPACE);
     9645#endif
     9646
    72879647    ADD_INT(d, DB_DONOTINDEX);
    72889648
    7289 #if (DBVER >= 41)
    7290     _addIntToDict(d, "DB_INCOMPLETE", 0);
    7291 #else
    7292     ADD_INT(d, DB_INCOMPLETE);
    7293 #endif
    72949649    ADD_INT(d, DB_KEYEMPTY);
    72959650    ADD_INT(d, DB_KEYEXIST);
     
    73129667    ADD_INT(d, DB_NOPANIC);
    73139668
    7314 #if (DBVER >= 41)
    73159669    ADD_INT(d, DB_OVERWRITE);
    7316 #endif
    7317 
    7318 #ifdef DB_REGISTER
     9670
     9671#if (DBVER >= 43)
     9672    ADD_INT(d, DB_STAT_SUBSYSTEM);
     9673    ADD_INT(d, DB_STAT_MEMP_HASH);
     9674#endif
     9675
     9676#if (DBVER >= 48)
     9677    ADD_INT(d, DB_OVERWRITE_DUP);
     9678#endif
     9679
     9680#if (DBVER >= 47)
     9681    ADD_INT(d, DB_FOREIGN_ABORT);
     9682    ADD_INT(d, DB_FOREIGN_CASCADE);
     9683    ADD_INT(d, DB_FOREIGN_NULLIFY);
     9684#endif
     9685
     9686#if (DBVER >= 44)
    73199687    ADD_INT(d, DB_REGISTER);
    73209688#endif
     9689
     9690    ADD_INT(d, DB_EID_INVALID);
     9691    ADD_INT(d, DB_EID_BROADCAST);
    73219692
    73229693#if (DBVER >= 42)
     
    73929763    ADD_INT(d, DB_REP_MASTER);
    73939764    ADD_INT(d, DB_REP_CLIENT);
     9765
     9766    ADD_INT(d, DB_REP_PERMANENT);
     9767
     9768#if (DBVER >= 44)
     9769    ADD_INT(d, DB_REP_CONF_NOAUTOINIT);
     9770    ADD_INT(d, DB_REP_CONF_DELAYCLIENT);
     9771    ADD_INT(d, DB_REP_CONF_BULK);
     9772    ADD_INT(d, DB_REP_CONF_NOWAIT);
     9773    ADD_INT(d, DB_REP_ANYWHERE);
     9774    ADD_INT(d, DB_REP_REREQUEST);
     9775#endif
     9776
     9777#if (DBVER >= 42)
     9778    ADD_INT(d, DB_REP_NOBUFFER);
     9779#endif
     9780
     9781#if (DBVER >= 46)
     9782    ADD_INT(d, DB_REP_LEASE_EXPIRED);
     9783    ADD_INT(d, DB_IGNORE_LEASE);
     9784#endif
     9785
     9786#if (DBVER >= 47)
     9787    ADD_INT(d, DB_REP_CONF_LEASE);
     9788    ADD_INT(d, DB_REPMGR_CONF_2SITE_STRICT);
     9789#endif
     9790
    73949791#if (DBVER >= 45)
    73959792    ADD_INT(d, DB_REP_ELECTION);
     
    74039800    ADD_INT(d, DB_REP_CHECKPOINT_DELAY);
    74049801    ADD_INT(d, DB_REP_FULL_ELECTION_TIMEOUT);
     9802    ADD_INT(d, DB_REP_LEASE_TIMEOUT);
     9803#endif
     9804#if (DBVER >= 47)
     9805    ADD_INT(d, DB_REP_HEARTBEAT_MONITOR);
     9806    ADD_INT(d, DB_REP_HEARTBEAT_SEND);
    74059807#endif
    74069808
     
    74159817    ADD_INT(d, DB_REPMGR_CONNECTED);
    74169818    ADD_INT(d, DB_REPMGR_DISCONNECTED);
    7417     ADD_INT(d, DB_STAT_CLEAR);
    74189819    ADD_INT(d, DB_STAT_ALL);
    74199820#endif
     
    74319832#endif
    74329833
    7433 #if (DBVER >= 41)
    74349834    ADD_INT(d, DB_ENCRYPT_AES);
    74359835    ADD_INT(d, DB_AUTO_COMMIT);
    7436 #else
    7437     /* allow Berkeley DB 4.1 aware apps to run on older versions */
    7438     _addIntToDict(d, "DB_AUTO_COMMIT", 0);
     9836    ADD_INT(d, DB_PRIORITY_VERY_LOW);
     9837    ADD_INT(d, DB_PRIORITY_LOW);
     9838    ADD_INT(d, DB_PRIORITY_DEFAULT);
     9839    ADD_INT(d, DB_PRIORITY_HIGH);
     9840    ADD_INT(d, DB_PRIORITY_VERY_HIGH);
     9841
     9842#if (DBVER >= 46)
     9843    ADD_INT(d, DB_PRIORITY_UNCHANGED);
    74399844#endif
    74409845
     
    74749879    PyDict_SetItemString(d, "KeyError", PyExc_KeyError);
    74759880    PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
    7476                  "class DBKeyEmptyError(DBError, KeyError): pass",
     9881                 "class DBKeyEmptyError(DBError, KeyError): pass",
    74779882                 Py_file_input, d, d);
    74789883    DBNotFoundError = PyDict_GetItemString(d, "DBNotFoundError");
     
    75009905#endif
    75019906
    7502 
    7503 #if !INCOMPLETE_IS_WARNING
    7504     MAKE_EX(DBIncompleteError);
    7505 #endif
    75069907    MAKE_EX(DBCursorClosedError);
    7507     MAKE_EX(DBKeyEmptyError);
    75089908    MAKE_EX(DBKeyExistError);
    75099909    MAKE_EX(DBLockDeadlockError);
     
    75319931    MAKE_EX(DBRepHandleDeadError);
    75329932#endif
     9933#if (DBVER >= 44)
     9934    MAKE_EX(DBRepLockoutError);
     9935#endif
    75339936
    75349937    MAKE_EX(DBRepUnavailError);
    75359938
     9939#if (DBVER >= 46)
     9940    MAKE_EX(DBRepLeaseExpiredError);
     9941#endif
     9942
     9943#if (DBVER >= 47)
     9944        MAKE_EX(DBForeignConflictError);
     9945#endif
     9946
    75369947#undef MAKE_EX
    75379948
    7538     /* Initiliase the C API structure and add it to the module */
    7539     bsddb_api.db_type         = &DB_Type;
    7540     bsddb_api.dbcursor_type   = &DBCursor_Type;
    7541     bsddb_api.dbenv_type      = &DBEnv_Type;
    7542     bsddb_api.dbtxn_type      = &DBTxn_Type;
    7543     bsddb_api.dblock_type     = &DBLock_Type;
     9949    /* Initialise the C API structure and add it to the module */
     9950    bsddb_api.db_type          = &DB_Type;
     9951    bsddb_api.dbcursor_type    = &DBCursor_Type;
     9952    bsddb_api.dblogcursor_type = &DBLogCursor_Type;
     9953    bsddb_api.dbenv_type       = &DBEnv_Type;
     9954    bsddb_api.dbtxn_type       = &DBTxn_Type;
     9955    bsddb_api.dblock_type      = &DBLock_Type;
    75449956#if (DBVER >= 43)
    7545     bsddb_api.dbsequence_type = &DBSequence_Type;
    7546 #endif
    7547     bsddb_api.makeDBError     = makeDBError;
    7548 
     9957    bsddb_api.dbsequence_type  = &DBSequence_Type;
     9958#endif
     9959    bsddb_api.makeDBError      = makeDBError;
     9960
     9961    /*
     9962    ** Capsules exist from Python 3.1, but I
     9963    ** don't want to break the API compatibility
     9964    ** for already published Python versions.
     9965    */
     9966#if (PY_VERSION_HEX < 0x03020000)
    75499967    py_api = PyCObject_FromVoidPtr((void*)&bsddb_api, NULL);
     9968#else
     9969    {
     9970        char py_api_name[250];
     9971
     9972        strcpy(py_api_name, _bsddbModuleName);
     9973        strcat(py_api_name, ".api");
     9974
     9975        py_api = PyCapsule_New((void*)&bsddb_api, py_api_name, NULL);
     9976    }
     9977#endif
     9978
    75509979    PyDict_SetItemString(d, "api", py_api);
    75519980    Py_DECREF(py_api);
  • python/trunk/Modules/bsddb.h

    r2 r132  
    7171 * DBSequence   (Sequence)
    7272 *
     73 * New datatypes:
     74 *
     75 * DBLogCursor  (Log Cursor)
     76 *
    7377 */
    7478
     
    106110#endif
    107111
    108 #define PY_BSDDB_VERSION "4.7.3"
     112#define PY_BSDDB_VERSION "4.8.4"
    109113
    110114/* Python object definitions */
     
    123127struct DBObject;          /* Forward declaration */
    124128struct DBCursorObject;    /* Forward declaration */
     129struct DBLogCursorObject; /* Forward declaration */
    125130struct DBTxnObject;       /* Forward declaration */
    126131struct DBSequenceObject;  /* Forward declaration */
     
    135140    struct DBObject *children_dbs;
    136141    struct DBTxnObject *children_txns;
     142    struct DBLogCursorObject *children_logcursors;
    137143    PyObject        *private_obj;
    138144    PyObject        *rep_transport;
     
    146152    u_int32_t       flags;     /* saved flags from open() */
    147153    u_int32_t       setflags;  /* saved flags from set_flags() */
    148     int             haveStat;
    149154    struct behaviourFlags moduleFlags;
    150155    struct DBTxnObject *txn;
     
    194199
    195200
     201typedef struct DBLogCursorObject {
     202    PyObject_HEAD
     203    DB_LOGC*        logc;
     204    DBEnvObject*    env;
     205    struct DBLogCursorObject **sibling_prev_p;
     206    struct DBLogCursorObject *sibling_next;
     207    PyObject        *in_weakreflist; /* List of weak references */
     208} DBLogCursorObject;
     209
     210
    196211typedef struct {
    197212    PyObject_HEAD
    198213    DB_LOCK         lock;
     214    int             lock_initialized;  /* Signal if we actually have a lock */
    199215    PyObject        *in_weakreflist; /* List of weak references */
    200216} DBLockObject;
     
    221237   following (error checking missed out for clarity):
    222238
     239     // If you are using Python before 3.2:
    223240     BSDDB_api* bsddb_api;
    224241     PyObject*  mod;
     
    232249     Py_DECREF(mod);
    233250
     251
     252     // If you are using Python 3.2 or up:
     253     BSDDB_api* bsddb_api;
     254
     255     // Use "bsddb3._pybsddb.api" if you're using
     256     // the standalone pybsddb add-on.
     257     bsddb_api = (void **)PyCapsule_Import("bsddb._bsddb.api", 1);
     258
     259
    234260   The structure's members must not be changed.
    235261*/
     
    239265    PyTypeObject* db_type;
    240266    PyTypeObject* dbcursor_type;
     267    PyTypeObject* dblogcursor_type;
    241268    PyTypeObject* dbenv_type;
    242269    PyTypeObject* dbtxn_type;
     
    248275    /* Functions */
    249276    int (*makeDBError)(int err);
    250 
    251277} BSDDB_api;
    252278
  • python/trunk/Modules/bsddbmodule.c

    r2 r132  
    3131
    3232typedef struct {
    33         PyObject_HEAD
    34         DB *di_bsddb;
    35         int di_size;    /* -1 means recompute */
    36         int di_type;
    37 #ifdef WITH_THREAD
    38         PyThread_type_lock di_lock;
     33    PyObject_HEAD
     34    DB *di_bsddb;
     35    int di_size;        /* -1 means recompute */
     36    int di_type;
     37#ifdef WITH_THREAD
     38    PyThread_type_lock di_lock;
    3939#endif
    4040} bsddbobject;
     
    4545#define check_bsddbobject_open(v, r) if ((v)->di_bsddb == NULL) \
    4646               { PyErr_SetString(BsddbError, \
    47                                 "BSDDB object has already been closed"); \
     47                                "BSDDB object has already been closed"); \
    4848                 return r; }
    4949
     
    5252static PyObject *
    5353newdbhashobject(char *file, int flags, int mode,
    54                 int bsize, int ffactor, int nelem, int cachesize,
    55                 int hash, int lorder)
    56 {
    57         bsddbobject *dp;
    58         HASHINFO info;
    59 
    60         if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
    61                 return NULL;
    62 
    63         info.bsize = bsize;
    64         info.ffactor = ffactor;
    65         info.nelem = nelem;
    66         info.cachesize = cachesize;
    67         info.hash = NULL; /* XXX should derive from hash argument */
    68         info.lorder = lorder;
     54                int bsize, int ffactor, int nelem, int cachesize,
     55                int hash, int lorder)
     56{
     57    bsddbobject *dp;
     58    HASHINFO info;
     59
     60    if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
     61        return NULL;
     62
     63    info.bsize = bsize;
     64    info.ffactor = ffactor;
     65    info.nelem = nelem;
     66    info.cachesize = cachesize;
     67    info.hash = NULL; /* XXX should derive from hash argument */
     68    info.lorder = lorder;
    6969
    7070#ifdef O_BINARY
    71         flags |= O_BINARY;
    72 #endif
    73         Py_BEGIN_ALLOW_THREADS
    74         dp->di_bsddb = dbopen(file, flags, mode, DB_HASH, &info);
    75         Py_END_ALLOW_THREADS
    76         if (dp->di_bsddb == NULL) {
    77                 PyErr_SetFromErrno(BsddbError);
    78 #ifdef WITH_THREAD
    79                 dp->di_lock = NULL;
    80 #endif
    81                 Py_DECREF(dp);
    82                 return NULL;
    83         }
    84 
    85         dp->di_size = -1;
    86         dp->di_type = DB_HASH;
    87 
    88 #ifdef WITH_THREAD
    89         dp->di_lock = PyThread_allocate_lock();
    90         if (dp->di_lock == NULL) {
    91                 PyErr_SetString(BsddbError, "can't allocate lock");
    92                 Py_DECREF(dp);
    93                 return NULL;
    94         }
    95 #endif
    96 
    97         return (PyObject *)dp;
     71    flags |= O_BINARY;
     72#endif
     73    Py_BEGIN_ALLOW_THREADS
     74    dp->di_bsddb = dbopen(file, flags, mode, DB_HASH, &info);
     75    Py_END_ALLOW_THREADS
     76    if (dp->di_bsddb == NULL) {
     77        PyErr_SetFromErrno(BsddbError);
     78#ifdef WITH_THREAD
     79        dp->di_lock = NULL;
     80#endif
     81        Py_DECREF(dp);
     82        return NULL;
     83    }
     84
     85    dp->di_size = -1;
     86    dp->di_type = DB_HASH;
     87
     88#ifdef WITH_THREAD
     89    dp->di_lock = PyThread_allocate_lock();
     90    if (dp->di_lock == NULL) {
     91        PyErr_SetString(BsddbError, "can't allocate lock");
     92        Py_DECREF(dp);
     93        return NULL;
     94    }
     95#endif
     96
     97    return (PyObject *)dp;
    9898}
    9999
    100100static PyObject *
    101101newdbbtobject(char *file, int flags, int mode,
    102               int btflags, int cachesize, int maxkeypage,
    103               int minkeypage, int psize, int lorder)
    104 {
    105         bsddbobject *dp;
    106         BTREEINFO info;
    107 
    108         if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
    109                 return NULL;
    110 
    111         info.flags = btflags;
    112         info.cachesize = cachesize;
    113         info.maxkeypage = maxkeypage;
    114         info.minkeypage = minkeypage;
    115         info.psize = psize;
    116         info.lorder = lorder;
    117         info.compare = 0; /* Use default comparison functions, for now..*/
    118         info.prefix = 0;
     102              int btflags, int cachesize, int maxkeypage,
     103              int minkeypage, int psize, int lorder)
     104{
     105    bsddbobject *dp;
     106    BTREEINFO info;
     107
     108    if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
     109        return NULL;
     110
     111    info.flags = btflags;
     112    info.cachesize = cachesize;
     113    info.maxkeypage = maxkeypage;
     114    info.minkeypage = minkeypage;
     115    info.psize = psize;
     116    info.lorder = lorder;
     117    info.compare = 0; /* Use default comparison functions, for now..*/
     118    info.prefix = 0;
    119119
    120120#ifdef O_BINARY
    121         flags |= O_BINARY;
    122 #endif
    123         Py_BEGIN_ALLOW_THREADS
    124         dp->di_bsddb = dbopen(file, flags, mode, DB_BTREE, &info);
    125         Py_END_ALLOW_THREADS
    126         if (dp->di_bsddb == NULL) {
    127                 PyErr_SetFromErrno(BsddbError);
    128 #ifdef WITH_THREAD
    129                 dp->di_lock = NULL;
    130 #endif
    131                 Py_DECREF(dp);
    132                 return NULL;
    133         }
    134 
    135         dp->di_size = -1;
    136         dp->di_type = DB_BTREE;
    137 
    138 #ifdef WITH_THREAD
    139         dp->di_lock = PyThread_allocate_lock();
    140         if (dp->di_lock == NULL) {
    141                 PyErr_SetString(BsddbError, "can't allocate lock");
    142                 Py_DECREF(dp);
    143                 return NULL;
    144         }
    145 #endif
    146 
    147         return (PyObject *)dp;
     121    flags |= O_BINARY;
     122#endif
     123    Py_BEGIN_ALLOW_THREADS
     124    dp->di_bsddb = dbopen(file, flags, mode, DB_BTREE, &info);
     125    Py_END_ALLOW_THREADS
     126    if (dp->di_bsddb == NULL) {
     127        PyErr_SetFromErrno(BsddbError);
     128#ifdef WITH_THREAD
     129        dp->di_lock = NULL;
     130#endif
     131        Py_DECREF(dp);
     132        return NULL;
     133    }
     134
     135    dp->di_size = -1;
     136    dp->di_type = DB_BTREE;
     137
     138#ifdef WITH_THREAD
     139    dp->di_lock = PyThread_allocate_lock();
     140    if (dp->di_lock == NULL) {
     141        PyErr_SetString(BsddbError, "can't allocate lock");
     142        Py_DECREF(dp);
     143        return NULL;
     144    }
     145#endif
     146
     147    return (PyObject *)dp;
    148148}
    149149
    150150static PyObject *
    151151newdbrnobject(char *file, int flags, int mode,
    152               int rnflags, int cachesize, int psize, int lorder,
    153               size_t reclen, u_char bval, char *bfname)
    154 {
    155         bsddbobject *dp;
    156         RECNOINFO info;
    157         int fd;
    158 
    159         if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
    160                 return NULL;
    161 
    162         info.flags = rnflags;
    163         info.cachesize = cachesize;
    164         info.psize = psize;
    165         info.lorder = lorder;
    166         info.reclen = reclen;
    167         info.bval = bval;
    168         info.bfname = bfname;
     152              int rnflags, int cachesize, int psize, int lorder,
     153              size_t reclen, u_char bval, char *bfname)
     154{
     155    bsddbobject *dp;
     156    RECNOINFO info;
     157    int fd;
     158
     159    if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL)
     160        return NULL;
     161
     162    info.flags = rnflags;
     163    info.cachesize = cachesize;
     164    info.psize = psize;
     165    info.lorder = lorder;
     166    info.reclen = reclen;
     167    info.bval = bval;
     168    info.bfname = bfname;
    169169
    170170#ifdef O_BINARY
    171         flags |= O_BINARY;
    172 #endif
    173         /* This is a hack to avoid a dbopen() bug that happens when
    174         * it fails. */
    175         fd = open(file, flags);
    176         if (fd == -1) {
    177                 dp->di_bsddb = NULL;
    178         }
    179         else {
    180                 close(fd);
    181                 Py_BEGIN_ALLOW_THREADS
    182                 dp->di_bsddb = dbopen(file, flags, mode, DB_RECNO, &info);
    183                 Py_END_ALLOW_THREADS
    184         }
    185         if (dp->di_bsddb == NULL) {
    186                 PyErr_SetFromErrno(BsddbError);
    187 #ifdef WITH_THREAD
    188                 dp->di_lock = NULL;
    189 #endif
    190                 Py_DECREF(dp);
    191                 return NULL;
    192         }
    193 
    194         dp->di_size = -1;
    195         dp->di_type = DB_RECNO;
    196 
    197 #ifdef WITH_THREAD
    198         dp->di_lock = PyThread_allocate_lock();
    199         if (dp->di_lock == NULL) {
    200                 PyErr_SetString(BsddbError, "can't allocate lock");
    201                 Py_DECREF(dp);
    202                 return NULL;
    203         }
    204 #endif
    205 
    206         return (PyObject *)dp;
     171    flags |= O_BINARY;
     172#endif
     173    /* This is a hack to avoid a dbopen() bug that happens when
     174    * it fails. */
     175    fd = open(file, flags);
     176    if (fd == -1) {
     177        dp->di_bsddb = NULL;
     178    }
     179    else {
     180        close(fd);
     181        Py_BEGIN_ALLOW_THREADS
     182        dp->di_bsddb = dbopen(file, flags, mode, DB_RECNO, &info);
     183        Py_END_ALLOW_THREADS
     184    }
     185    if (dp->di_bsddb == NULL) {
     186        PyErr_SetFromErrno(BsddbError);
     187#ifdef WITH_THREAD
     188        dp->di_lock = NULL;
     189#endif
     190        Py_DECREF(dp);
     191        return NULL;
     192    }
     193
     194    dp->di_size = -1;
     195    dp->di_type = DB_RECNO;
     196
     197#ifdef WITH_THREAD
     198    dp->di_lock = PyThread_allocate_lock();
     199    if (dp->di_lock == NULL) {
     200        PyErr_SetString(BsddbError, "can't allocate lock");
     201        Py_DECREF(dp);
     202        return NULL;
     203    }
     204#endif
     205
     206    return (PyObject *)dp;
    207207}
    208208
     
    211211{
    212212#ifdef WITH_THREAD
    213         if (dp->di_lock) {
    214                 PyThread_acquire_lock(dp->di_lock, 0);
    215                 PyThread_release_lock(dp->di_lock);
    216                 PyThread_free_lock(dp->di_lock);
    217                 dp->di_lock = NULL;
    218         }
    219 #endif
    220         if (dp->di_bsddb != NULL) {
    221                 int status;
    222                 Py_BEGIN_ALLOW_THREADS
    223                 status = (dp->di_bsddb->close)(dp->di_bsddb);
    224                 Py_END_ALLOW_THREADS
    225                 if (status != 0)
    226                         fprintf(stderr,
    227                                 "Python bsddb: close errno %d in dealloc\n",
    228                                 errno);
    229         }
    230         PyObject_Del(dp);
     213    if (dp->di_lock) {
     214        PyThread_acquire_lock(dp->di_lock, 0);
     215        PyThread_release_lock(dp->di_lock);
     216        PyThread_free_lock(dp->di_lock);
     217        dp->di_lock = NULL;
     218    }
     219#endif
     220    if (dp->di_bsddb != NULL) {
     221        int status;
     222        Py_BEGIN_ALLOW_THREADS
     223        status = (dp->di_bsddb->close)(dp->di_bsddb);
     224        Py_END_ALLOW_THREADS
     225        if (status != 0)
     226            fprintf(stderr,
     227                "Python bsddb: close errno %d in dealloc\n",
     228                errno);
     229    }
     230    PyObject_Del(dp);
    231231}
    232232
    233233#ifdef WITH_THREAD
    234234#define BSDDB_BGN_SAVE(_dp) \
    235         Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(_dp->di_lock,1);
     235    Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(_dp->di_lock,1);
    236236#define BSDDB_END_SAVE(_dp) \
    237         PyThread_release_lock(_dp->di_lock); Py_END_ALLOW_THREADS
     237    PyThread_release_lock(_dp->di_lock); Py_END_ALLOW_THREADS
    238238#else
    239 #define BSDDB_BGN_SAVE(_dp) Py_BEGIN_ALLOW_THREADS 
     239#define BSDDB_BGN_SAVE(_dp) Py_BEGIN_ALLOW_THREADS
    240240#define BSDDB_END_SAVE(_dp) Py_END_ALLOW_THREADS
    241241#endif
     
    244244bsddb_length(bsddbobject *dp)
    245245{
    246         check_bsddbobject_open(dp, -1);
    247         if (dp->di_size < 0) {
    248                 DBT krec, drec;
    249                 int status;
    250                 int size = 0;
    251                 BSDDB_BGN_SAVE(dp)
    252                 for (status = (dp->di_bsddb->seq)(dp->di_bsddb,
    253                                                   &krec, &drec,R_FIRST);
    254                      status == 0;
    255                      status = (dp->di_bsddb->seq)(dp->di_bsddb,
    256                                                   &krec, &drec, R_NEXT))
    257                         size++;
    258                 BSDDB_END_SAVE(dp)
    259                 if (status < 0) {
    260                         PyErr_SetFromErrno(BsddbError);
    261                         return -1;
    262                 }
    263                 dp->di_size = size;
    264         }
    265         return dp->di_size;
     246    check_bsddbobject_open(dp, -1);
     247    if (dp->di_size < 0) {
     248        DBT krec, drec;
     249        int status;
     250        int size = 0;
     251        BSDDB_BGN_SAVE(dp)
     252        for (status = (dp->di_bsddb->seq)(dp->di_bsddb,
     253                                          &krec, &drec,R_FIRST);
     254             status == 0;
     255             status = (dp->di_bsddb->seq)(dp->di_bsddb,
     256                                          &krec, &drec, R_NEXT))
     257            size++;
     258        BSDDB_END_SAVE(dp)
     259        if (status < 0) {
     260            PyErr_SetFromErrno(BsddbError);
     261            return -1;
     262        }
     263        dp->di_size = size;
     264    }
     265    return dp->di_size;
    266266}
    267267
     
    269269bsddb_subscript(bsddbobject *dp, PyObject *key)
    270270{
    271         int status;
    272         DBT krec, drec;
    273         char *data,buf[4096];
    274         int size;
    275         PyObject *result;
    276         recno_t recno;
    277        
    278         if (dp->di_type == DB_RECNO) {
    279                 if (!PyArg_Parse(key, "i", &recno)) {
    280                         PyErr_SetString(PyExc_TypeError,
    281                                         "key type must be integer");
    282                         return NULL;
    283                 }
    284                 krec.data = &recno;
    285                 krec.size = sizeof(recno);
    286         }
    287         else {
    288                 if (!PyArg_Parse(key, "s#", &data, &size)) {
    289                         PyErr_SetString(PyExc_TypeError,
    290                                         "key type must be string");
    291                         return NULL;
    292                 }
    293                 krec.data = data;
    294                 krec.size = size;
    295         }
    296         check_bsddbobject_open(dp, NULL);
    297 
    298         BSDDB_BGN_SAVE(dp)
    299         status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
    300         if (status == 0) {
    301                 if (drec.size > sizeof(buf)) data = malloc(drec.size);
    302                 else data = buf;
    303                 if (data!=NULL) memcpy(data,drec.data,drec.size);
    304         }
    305         BSDDB_END_SAVE(dp)
    306         if (data==NULL) return PyErr_NoMemory();
    307         if (status != 0) {
    308                 if (status < 0)
    309                         PyErr_SetFromErrno(BsddbError);
    310                 else
    311                         PyErr_SetObject(PyExc_KeyError, key);
    312                 return NULL;
    313         }
    314 
    315         result = PyString_FromStringAndSize(data, (int)drec.size);
    316         if (data != buf) free(data);
    317         return result;
     271    int status;
     272    DBT krec, drec;
     273    char *data = NULL;
     274    char buf[4096];
     275    int size;
     276    PyObject *result;
     277    recno_t recno;
     278
     279    if (dp->di_type == DB_RECNO) {
     280        if (!PyArg_Parse(key, "i", &recno)) {
     281            PyErr_SetString(PyExc_TypeError,
     282                            "key type must be integer");
     283            return NULL;
     284        }
     285        krec.data = &recno;
     286        krec.size = sizeof(recno);
     287    }
     288    else {
     289        if (!PyArg_Parse(key, "s#", &data, &size)) {
     290            PyErr_SetString(PyExc_TypeError,
     291                            "key type must be string");
     292            return NULL;
     293        }
     294        krec.data = data;
     295        krec.size = size;
     296    }
     297    check_bsddbobject_open(dp, NULL);
     298
     299    BSDDB_BGN_SAVE(dp)
     300    status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
     301    if (status == 0) {
     302        if (drec.size > sizeof(buf)) data = malloc(drec.size);
     303        else data = buf;
     304        if (data!=NULL) memcpy(data,drec.data,drec.size);
     305    }
     306    BSDDB_END_SAVE(dp)
     307    if (data==NULL) return PyErr_NoMemory();
     308    if (status != 0) {
     309        if (status < 0)
     310            PyErr_SetFromErrno(BsddbError);
     311        else
     312            PyErr_SetObject(PyExc_KeyError, key);
     313        return NULL;
     314    }
     315
     316    result = PyString_FromStringAndSize(data, (int)drec.size);
     317    if (data != buf) free(data);
     318    return result;
    318319}
    319320
     
    321322bsddb_ass_sub(bsddbobject *dp, PyObject *key, PyObject *value)
    322323{
    323         int status;
    324         DBT krec, drec;
    325         char *data;
    326         int size;
    327         recno_t recno;
    328 
    329         if (dp->di_type == DB_RECNO) {
    330                 if (!PyArg_Parse(key, "i", &recno)) {
    331                         PyErr_SetString(PyExc_TypeError,
    332                                         "bsddb key type must be integer");
    333                         return -1;
    334                 }
    335                 krec.data = &recno;
    336                 krec.size = sizeof(recno);
    337         }
    338         else {
    339                 if (!PyArg_Parse(key, "s#", &data, &size)) {
    340                         PyErr_SetString(PyExc_TypeError,
    341                                         "bsddb key type must be string");
    342                         return -1;
    343                 }
    344                 krec.data = data;
    345                 krec.size = size;
    346         }
    347         check_bsddbobject_open(dp, -1);
    348         dp->di_size = -1;
    349         if (value == NULL) {
    350                 BSDDB_BGN_SAVE(dp)
    351                 status = (dp->di_bsddb->del)(dp->di_bsddb, &krec, 0);
    352                 BSDDB_END_SAVE(dp)
    353         }
    354         else {
    355                 if (!PyArg_Parse(value, "s#", &data, &size)) {
    356                         PyErr_SetString(PyExc_TypeError,
    357                                         "bsddb value type must be string");
    358                         return -1;
    359                 }
    360                 drec.data = data;
    361                 drec.size = size;
    362                 BSDDB_BGN_SAVE(dp)
    363                 status = (dp->di_bsddb->put)(dp->di_bsddb, &krec, &drec, 0);
    364                 BSDDB_END_SAVE(dp)
    365         }
    366         if (status != 0) {
    367                 if (status < 0)
    368                         PyErr_SetFromErrno(BsddbError);
    369                 else
    370                         PyErr_SetObject(PyExc_KeyError, key);
    371                 return -1;
    372         }
    373         return 0;
     324    int status;
     325    DBT krec, drec;
     326    char *data;
     327    int size;
     328    recno_t recno;
     329
     330    if (dp->di_type == DB_RECNO) {
     331        if (!PyArg_Parse(key, "i", &recno)) {
     332            PyErr_SetString(PyExc_TypeError,
     333                            "bsddb key type must be integer");
     334            return -1;
     335        }
     336        krec.data = &recno;
     337        krec.size = sizeof(recno);
     338    }
     339    else {
     340        if (!PyArg_Parse(key, "s#", &data, &size)) {
     341            PyErr_SetString(PyExc_TypeError,
     342                            "bsddb key type must be string");
     343            return -1;
     344        }
     345        krec.data = data;
     346        krec.size = size;
     347    }
     348    check_bsddbobject_open(dp, -1);
     349    dp->di_size = -1;
     350    if (value == NULL) {
     351        BSDDB_BGN_SAVE(dp)
     352        status = (dp->di_bsddb->del)(dp->di_bsddb, &krec, 0);
     353        BSDDB_END_SAVE(dp)
     354    }
     355    else {
     356        if (!PyArg_Parse(value, "s#", &data, &size)) {
     357            PyErr_SetString(PyExc_TypeError,
     358                            "bsddb value type must be string");
     359            return -1;
     360        }
     361        drec.data = data;
     362        drec.size = size;
     363        BSDDB_BGN_SAVE(dp)
     364        status = (dp->di_bsddb->put)(dp->di_bsddb, &krec, &drec, 0);
     365        BSDDB_END_SAVE(dp)
     366    }
     367    if (status != 0) {
     368        if (status < 0)
     369            PyErr_SetFromErrno(BsddbError);
     370        else
     371            PyErr_SetObject(PyExc_KeyError, key);
     372        return -1;
     373    }
     374    return 0;
    374375}
    375376
    376377static PyMappingMethods bsddb_as_mapping = {
    377         (lenfunc)bsddb_length,          /*mp_length*/
    378         (binaryfunc)bsddb_subscript,    /*mp_subscript*/
    379         (objobjargproc)bsddb_ass_sub,   /*mp_ass_subscript*/
     378    (lenfunc)bsddb_length,              /*mp_length*/
     379    (binaryfunc)bsddb_subscript,        /*mp_subscript*/
     380    (objobjargproc)bsddb_ass_sub,       /*mp_ass_subscript*/
    380381};
    381382
     
    383384bsddb_close(bsddbobject *dp)
    384385{
    385         if (dp->di_bsddb != NULL) {
    386                 int status;
    387                 BSDDB_BGN_SAVE(dp)
    388                 status = (dp->di_bsddb->close)(dp->di_bsddb);
    389                 BSDDB_END_SAVE(dp)
    390                 if (status != 0) {
    391                         dp->di_bsddb = NULL;
    392                         PyErr_SetFromErrno(BsddbError);
    393                         return NULL;
    394                 }
    395         }
    396         dp->di_bsddb = NULL;
    397         Py_INCREF(Py_None);
    398         return Py_None;
     386    if (dp->di_bsddb != NULL) {
     387        int status;
     388        BSDDB_BGN_SAVE(dp)
     389        status = (dp->di_bsddb->close)(dp->di_bsddb);
     390        BSDDB_END_SAVE(dp)
     391        if (status != 0) {
     392            dp->di_bsddb = NULL;
     393            PyErr_SetFromErrno(BsddbError);
     394            return NULL;
     395        }
     396    }
     397    dp->di_bsddb = NULL;
     398    Py_INCREF(Py_None);
     399    return Py_None;
    399400}
    400401
     
    402403bsddb_keys(bsddbobject *dp)
    403404{
    404         PyObject *list, *item=NULL;
    405         DBT krec, drec;
    406         char *data=NULL,buf[4096];
    407         int status;
    408         int err;
    409 
    410         check_bsddbobject_open(dp, NULL);
    411         list = PyList_New(0);
    412         if (list == NULL)
    413                 return NULL;
    414         BSDDB_BGN_SAVE(dp)
    415         status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_FIRST);
    416         if (status == 0) {
    417                 if (krec.size > sizeof(buf)) data = malloc(krec.size);
    418                 else data = buf;
    419                 if (data != NULL) memcpy(data,krec.data,krec.size);
    420         }
    421         BSDDB_END_SAVE(dp)
    422         if (status == 0 && data==NULL) return PyErr_NoMemory();
    423         while (status == 0) {
    424                 if (dp->di_type == DB_RECNO)
    425                         item = PyInt_FromLong(*((int*)data));
    426                 else
    427                         item = PyString_FromStringAndSize(data,
    428                                                           (int)krec.size);
    429                 if (data != buf) free(data);
    430                 if (item == NULL) {
    431                         Py_DECREF(list);
    432                         return NULL;
    433                 }
    434                 err = PyList_Append(list, item);
    435                 Py_DECREF(item);
    436                 if (err != 0) {
    437                         Py_DECREF(list);
    438                         return NULL;
    439                 }
    440                 BSDDB_BGN_SAVE(dp)
    441                 status = (dp->di_bsddb->seq)
    442                         (dp->di_bsddb, &krec, &drec, R_NEXT);
    443                 if (status == 0) {
    444                         if (krec.size > sizeof(buf))
    445                                 data = malloc(krec.size);
    446                         else data = buf;
    447                         if (data != NULL)
    448                                 memcpy(data,krec.data,krec.size);
    449                 }
    450                 BSDDB_END_SAVE(dp)
    451                 if (data == NULL) return PyErr_NoMemory();
    452         }
    453         if (status < 0) {
    454                 PyErr_SetFromErrno(BsddbError);
    455                 Py_DECREF(list);
    456                 return NULL;
    457         }
    458         if (dp->di_size < 0)
    459                 dp->di_size = PyList_Size(list); /* We just did the work */
    460         return list;
     405    PyObject *list, *item=NULL;
     406    DBT krec, drec;
     407    char *data=NULL,buf[4096];
     408    int status;
     409    int err;
     410
     411    check_bsddbobject_open(dp, NULL);
     412    list = PyList_New(0);
     413    if (list == NULL)
     414        return NULL;
     415    BSDDB_BGN_SAVE(dp)
     416    status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_FIRST);
     417    if (status == 0) {
     418        if (krec.size > sizeof(buf)) data = malloc(krec.size);
     419        else data = buf;
     420        if (data != NULL) memcpy(data,krec.data,krec.size);
     421    }
     422    BSDDB_END_SAVE(dp)
     423    if (status == 0 && data==NULL) return PyErr_NoMemory();
     424    while (status == 0) {
     425        if (dp->di_type == DB_RECNO)
     426            item = PyInt_FromLong(*((int*)data));
     427        else
     428            item = PyString_FromStringAndSize(data,
     429                                              (int)krec.size);
     430        if (data != buf) free(data);
     431        if (item == NULL) {
     432            Py_DECREF(list);
     433            return NULL;
     434        }
     435        err = PyList_Append(list, item);
     436        Py_DECREF(item);
     437        if (err != 0) {
     438            Py_DECREF(list);
     439            return NULL;
     440        }
     441        BSDDB_BGN_SAVE(dp)
     442        status = (dp->di_bsddb->seq)
     443            (dp->di_bsddb, &krec, &drec, R_NEXT);
     444        if (status == 0) {
     445            if (krec.size > sizeof(buf))
     446                data = malloc(krec.size);
     447            else data = buf;
     448            if (data != NULL)
     449                memcpy(data,krec.data,krec.size);
     450        }
     451        BSDDB_END_SAVE(dp)
     452        if (data == NULL) return PyErr_NoMemory();
     453    }
     454    if (status < 0) {
     455        PyErr_SetFromErrno(BsddbError);
     456        Py_DECREF(list);
     457        return NULL;
     458    }
     459    if (dp->di_size < 0)
     460        dp->di_size = PyList_Size(list); /* We just did the work */
     461    return list;
    461462}
    462463
     
    464465bsddb_has_key(bsddbobject *dp, PyObject *args)
    465466{
    466         DBT krec, drec;
    467         int status;
    468         char *data;
    469         int size;
    470         recno_t recno;
    471 
    472         if (dp->di_type == DB_RECNO) {
    473                 if (!PyArg_ParseTuple(args, "i;key type must be integer",
    474                                       &recno)) {
    475                         return NULL;
    476                 }
    477                 krec.data = &recno;
    478                 krec.size = sizeof(recno);
    479         }
    480         else {
    481                 if (!PyArg_ParseTuple(args, "s#;key type must be string",
    482                                       &data, &size)) {
    483                         return NULL;
    484                 }
    485                 krec.data = data;
    486                 krec.size = size;
    487         }
    488         check_bsddbobject_open(dp, NULL);
    489 
    490         BSDDB_BGN_SAVE(dp)
    491         status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
    492         BSDDB_END_SAVE(dp)
    493         if (status < 0) {
    494                 PyErr_SetFromErrno(BsddbError);
    495                 return NULL;
    496         }
    497 
    498         return PyInt_FromLong(status == 0);
     467    DBT krec, drec;
     468    int status;
     469    char *data;
     470    int size;
     471    recno_t recno;
     472
     473    if (dp->di_type == DB_RECNO) {
     474        if (!PyArg_ParseTuple(args, "i;key type must be integer",
     475                              &recno)) {
     476            return NULL;
     477        }
     478        krec.data = &recno;
     479        krec.size = sizeof(recno);
     480    }
     481    else {
     482        if (!PyArg_ParseTuple(args, "s#;key type must be string",
     483                              &data, &size)) {
     484            return NULL;
     485        }
     486        krec.data = data;
     487        krec.size = size;
     488    }
     489    check_bsddbobject_open(dp, NULL);
     490
     491    BSDDB_BGN_SAVE(dp)
     492    status = (dp->di_bsddb->get)(dp->di_bsddb, &krec, &drec, 0);
     493    BSDDB_END_SAVE(dp)
     494    if (status < 0) {
     495        PyErr_SetFromErrno(BsddbError);
     496        return NULL;
     497    }
     498
     499    return PyInt_FromLong(status == 0);
    499500}
    500501
     
    502503bsddb_set_location(bsddbobject *dp, PyObject *key)
    503504{
    504         int status;
    505         DBT krec, drec;
    506         char *data,buf[4096];
    507         int size;
    508         PyObject *result;
    509         recno_t recno;
    510 
    511         if (dp->di_type == DB_RECNO) {
    512                 if (!PyArg_ParseTuple(key, "i;key type must be integer",
    513                                       &recno)) {
    514                         return NULL;
    515                 }
    516                 krec.data = &recno;
    517                 krec.size = sizeof(recno);
    518         }
    519         else {
    520                 if (!PyArg_ParseTuple(key, "s#;key type must be string",
    521                                       &data, &size)) {
    522                         return NULL;
    523                 }
    524                 krec.data = data;
    525                 krec.size = size;
    526         }
    527         check_bsddbobject_open(dp, NULL);
    528 
    529         BSDDB_BGN_SAVE(dp)
    530         status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_CURSOR);
    531         if (status == 0) {
    532                 if (drec.size > sizeof(buf)) data = malloc(drec.size);
    533                 else data = buf;
    534                 if (data!=NULL) memcpy(data,drec.data,drec.size);
    535         }
    536         BSDDB_END_SAVE(dp)
    537         if (data==NULL) return PyErr_NoMemory();
    538         if (status != 0) {
    539                 if (status < 0)
    540                         PyErr_SetFromErrno(BsddbError);
    541                 else
    542                         PyErr_SetObject(PyExc_KeyError, key);
    543                 return NULL;
    544         }
    545 
    546         if (dp->di_type == DB_RECNO)
    547                 result = Py_BuildValue("is#", *((int*)krec.data),
    548                                        data, drec.size);
    549         else
    550                 result = Py_BuildValue("s#s#", krec.data, krec.size,
    551                                        data, drec.size);
    552         if (data != buf) free(data);
    553         return result;
     505    int status;
     506    DBT krec, drec;
     507    char *data = NULL;
     508    char buf[4096];
     509    int size;
     510    PyObject *result;
     511    recno_t recno;
     512
     513    if (dp->di_type == DB_RECNO) {
     514        if (!PyArg_ParseTuple(key, "i;key type must be integer",
     515                              &recno)) {
     516            return NULL;
     517        }
     518        krec.data = &recno;
     519        krec.size = sizeof(recno);
     520    }
     521    else {
     522        if (!PyArg_ParseTuple(key, "s#;key type must be string",
     523                              &data, &size)) {
     524            return NULL;
     525        }
     526        krec.data = data;
     527        krec.size = size;
     528    }
     529    check_bsddbobject_open(dp, NULL);
     530
     531    BSDDB_BGN_SAVE(dp)
     532    status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec, &drec, R_CURSOR);
     533    if (status == 0) {
     534        if (drec.size > sizeof(buf)) data = malloc(drec.size);
     535        else data = buf;
     536        if (data!=NULL) memcpy(data,drec.data,drec.size);
     537    }
     538    BSDDB_END_SAVE(dp)
     539    if (data==NULL) return PyErr_NoMemory();
     540    if (status != 0) {
     541        if (status < 0)
     542            PyErr_SetFromErrno(BsddbError);
     543        else
     544            PyErr_SetObject(PyExc_KeyError, key);
     545        return NULL;
     546    }
     547
     548    if (dp->di_type == DB_RECNO)
     549        result = Py_BuildValue("is#", *((int*)krec.data),
     550                               data, drec.size);
     551    else
     552        result = Py_BuildValue("s#s#", krec.data, krec.size,
     553                               data, drec.size);
     554    if (data != buf) free(data);
     555    return result;
    554556}
    555557
     
    557559bsddb_seq(bsddbobject *dp, int sequence_request)
    558560{
    559         int status;
    560         DBT krec, drec;
    561         char *kdata=NULL,kbuf[4096];
    562         char *ddata=NULL,dbuf[4096];
    563         PyObject *result;
    564 
    565         check_bsddbobject_open(dp, NULL);
    566         krec.data = 0;
    567         krec.size = 0;
    568 
    569         BSDDB_BGN_SAVE(dp)
    570         status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec,
    571                                      &drec, sequence_request);
    572         if (status == 0) {
    573                 if (krec.size > sizeof(kbuf)) kdata = malloc(krec.size);
    574                 else kdata = kbuf;
    575                 if (kdata != NULL) memcpy(kdata,krec.data,krec.size);
    576                 if (drec.size > sizeof(dbuf)) ddata = malloc(drec.size);
    577                 else ddata = dbuf;
    578                 if (ddata != NULL) memcpy(ddata,drec.data,drec.size);
    579         }
    580         BSDDB_END_SAVE(dp)
    581         if (status == 0) {
    582                 if ((kdata == NULL) || (ddata == NULL))
    583                         return PyErr_NoMemory();
    584         }
    585         else {
    586                 /* (status != 0) */ 
    587                 if (status < 0)
    588                         PyErr_SetFromErrno(BsddbError);
    589                 else
    590                         PyErr_SetString(PyExc_KeyError, "no key/data pairs");
    591                 return NULL;
    592         }
    593 
    594         if (dp->di_type == DB_RECNO)
    595                 result = Py_BuildValue("is#", *((int*)kdata),
    596                                        ddata, drec.size);
    597         else
    598                 result = Py_BuildValue("s#s#", kdata, krec.size,
    599                                        ddata, drec.size);
    600         if (kdata != kbuf) free(kdata);
    601         if (ddata != dbuf) free(ddata);
    602         return result;
     561    int status;
     562    DBT krec, drec;
     563    char *kdata=NULL,kbuf[4096];
     564    char *ddata=NULL,dbuf[4096];
     565    PyObject *result;
     566
     567    check_bsddbobject_open(dp, NULL);
     568    krec.data = 0;
     569    krec.size = 0;
     570
     571    BSDDB_BGN_SAVE(dp)
     572    status = (dp->di_bsddb->seq)(dp->di_bsddb, &krec,
     573                                 &drec, sequence_request);
     574    if (status == 0) {
     575        if (krec.size > sizeof(kbuf)) kdata = malloc(krec.size);
     576        else kdata = kbuf;
     577        if (kdata != NULL) memcpy(kdata,krec.data,krec.size);
     578        if (drec.size > sizeof(dbuf)) ddata = malloc(drec.size);
     579        else ddata = dbuf;
     580        if (ddata != NULL) memcpy(ddata,drec.data,drec.size);
     581    }
     582    BSDDB_END_SAVE(dp)
     583    if (status == 0) {
     584        if ((kdata == NULL) || (ddata == NULL))
     585            return PyErr_NoMemory();
     586    }
     587    else {
     588        /* (status != 0) */
     589        if (status < 0)
     590            PyErr_SetFromErrno(BsddbError);
     591        else
     592            PyErr_SetString(PyExc_KeyError, "no key/data pairs");
     593        return NULL;
     594    }
     595
     596    if (dp->di_type == DB_RECNO)
     597        result = Py_BuildValue("is#", *((int*)kdata),
     598                               ddata, drec.size);
     599    else
     600        result = Py_BuildValue("s#s#", kdata, krec.size,
     601                               ddata, drec.size);
     602    if (kdata != kbuf) free(kdata);
     603    if (ddata != dbuf) free(ddata);
     604    return result;
    603605}
    604606
     
    606608bsddb_next(bsddbobject *dp)
    607609{
    608         return bsddb_seq(dp, R_NEXT);
     610    return bsddb_seq(dp, R_NEXT);
    609611}
    610612static PyObject *
    611613bsddb_previous(bsddbobject *dp)
    612614{
    613         return bsddb_seq(dp, R_PREV);
     615    return bsddb_seq(dp, R_PREV);
    614616}
    615617static PyObject *
    616618bsddb_first(bsddbobject *dp)
    617619{
    618         return bsddb_seq(dp, R_FIRST);
     620    return bsddb_seq(dp, R_FIRST);
    619621}
    620622static PyObject *
    621623bsddb_last(bsddbobject *dp)
    622624{
    623         return bsddb_seq(dp, R_LAST);
     625    return bsddb_seq(dp, R_LAST);
    624626}
    625627static PyObject *
    626628bsddb_sync(bsddbobject *dp)
    627629{
    628         int status;
    629 
    630         check_bsddbobject_open(dp, NULL);
    631         BSDDB_BGN_SAVE(dp)
    632         status = (dp->di_bsddb->sync)(dp->di_bsddb, 0);
    633         BSDDB_END_SAVE(dp)
    634         if (status != 0) {
    635                 PyErr_SetFromErrno(BsddbError);
    636                 return NULL;
    637         }
    638         return PyInt_FromLong(status = 0);
     630    int status;
     631
     632    check_bsddbobject_open(dp, NULL);
     633    BSDDB_BGN_SAVE(dp)
     634    status = (dp->di_bsddb->sync)(dp->di_bsddb, 0);
     635    BSDDB_END_SAVE(dp)
     636    if (status != 0) {
     637        PyErr_SetFromErrno(BsddbError);
     638        return NULL;
     639    }
     640    return PyInt_FromLong(0);
    639641}
    640642static PyMethodDef bsddb_methods[] = {
    641         {"close",               (PyCFunction)bsddb_close, METH_NOARGS},
    642         {"keys",                (PyCFunction)bsddb_keys, METH_NOARGS},
    643         {"has_key",             (PyCFunction)bsddb_has_key, METH_VARARGS},
    644         {"set_location",        (PyCFunction)bsddb_set_location, METH_VARARGS},
    645         {"next",                (PyCFunction)bsddb_next, METH_NOARGS},
    646         {"previous",    (PyCFunction)bsddb_previous, METH_NOARGS},
    647         {"first",               (PyCFunction)bsddb_first, METH_NOARGS},
    648         {"last",                (PyCFunction)bsddb_last, METH_NOARGS},
    649         {"sync",                (PyCFunction)bsddb_sync, METH_NOARGS},
    650         {NULL,          NULL}           /* sentinel */
     643    {"close",                   (PyCFunction)bsddb_close, METH_NOARGS},
     644    {"keys",                    (PyCFunction)bsddb_keys, METH_NOARGS},
     645    {"has_key",                 (PyCFunction)bsddb_has_key, METH_VARARGS},
     646    {"set_location",            (PyCFunction)bsddb_set_location, METH_VARARGS},
     647    {"next",                    (PyCFunction)bsddb_next, METH_NOARGS},
     648    {"previous",        (PyCFunction)bsddb_previous, METH_NOARGS},
     649    {"first",                   (PyCFunction)bsddb_first, METH_NOARGS},
     650    {"last",                    (PyCFunction)bsddb_last, METH_NOARGS},
     651    {"sync",                    (PyCFunction)bsddb_sync, METH_NOARGS},
     652    {NULL,              NULL}           /* sentinel */
    651653};
    652654
     
    654656bsddb_getattr(PyObject *dp, char *name)
    655657{
    656         return Py_FindMethod(bsddb_methods, dp, name);
     658    return Py_FindMethod(bsddb_methods, dp, name);
    657659}
    658660
    659661static PyTypeObject Bsddbtype = {
    660         PyObject_HEAD_INIT(NULL)
    661         0,
    662         "bsddb.bsddb",
    663         sizeof(bsddbobject),
    664         0,
    665         (destructor)bsddb_dealloc, /*tp_dealloc*/
    666         0,                      /*tp_print*/
    667         (getattrfunc)bsddb_getattr, /*tp_getattr*/
    668         0,                      /*tp_setattr*/
    669         0,                      /*tp_compare*/
    670         0,                      /*tp_repr*/
    671         0,                      /*tp_as_number*/
    672         0,                      /*tp_as_sequence*/
    673         &bsddb_as_mapping,      /*tp_as_mapping*/
     662    PyObject_HEAD_INIT(NULL)
     663    0,
     664    "bsddb.bsddb",
     665    sizeof(bsddbobject),
     666    0,
     667    (destructor)bsddb_dealloc, /*tp_dealloc*/
     668    0,                          /*tp_print*/
     669    (getattrfunc)bsddb_getattr, /*tp_getattr*/
     670    0,                          /*tp_setattr*/
     671    0,                          /*tp_compare*/
     672    0,                          /*tp_repr*/
     673    0,                          /*tp_as_number*/
     674    0,                          /*tp_as_sequence*/
     675    &bsddb_as_mapping,          /*tp_as_mapping*/
    674676};
    675677
     
    677679bsdhashopen(PyObject *self, PyObject *args)
    678680{
    679         char *file;
    680         char *flag = NULL;
    681         int flags = O_RDONLY;
    682         int mode = 0666;
    683         int bsize = 0;
    684         int ffactor = 0;
    685         int nelem = 0;
    686         int cachesize = 0;
    687         int hash = 0; /* XXX currently ignored */
    688         int lorder = 0;
    689 
    690         if (!PyArg_ParseTuple(args, "z|siiiiiii:hashopen",
    691                               &file, &flag, &mode,
    692                               &bsize, &ffactor, &nelem, &cachesize,
    693                               &hash, &lorder))
    694                 return NULL;
    695         if (flag != NULL) {
    696                 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
    697                 if (flag[0] == 'r')
    698                         flags = O_RDONLY;
    699                 else if (flag[0] == 'w')
    700                         flags = O_RDWR;
    701                 else if (flag[0] == 'c')
    702                         flags = O_RDWR|O_CREAT;
    703                 else if (flag[0] == 'n')
    704                         flags = O_RDWR|O_CREAT|O_TRUNC;
    705                 else {
    706                         PyErr_SetString(BsddbError,
    707                                 "Flag should begin with 'r', 'w', 'c' or 'n'");
    708                         return NULL;
    709                 }
    710                 if (flag[1] == 'l') {
     681    char *file;
     682    char *flag = NULL;
     683    int flags = O_RDONLY;
     684    int mode = 0666;
     685    int bsize = 0;
     686    int ffactor = 0;
     687    int nelem = 0;
     688    int cachesize = 0;
     689    int hash = 0; /* XXX currently ignored */
     690    int lorder = 0;
     691
     692    if (!PyArg_ParseTuple(args, "z|siiiiiii:hashopen",
     693                          &file, &flag, &mode,
     694                          &bsize, &ffactor, &nelem, &cachesize,
     695                          &hash, &lorder))
     696        return NULL;
     697    if (flag != NULL) {
     698        /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
     699        if (flag[0] == 'r')
     700            flags = O_RDONLY;
     701        else if (flag[0] == 'w')
     702            flags = O_RDWR;
     703        else if (flag[0] == 'c')
     704            flags = O_RDWR|O_CREAT;
     705        else if (flag[0] == 'n')
     706            flags = O_RDWR|O_CREAT|O_TRUNC;
     707        else {
     708            PyErr_SetString(BsddbError,
     709                "Flag should begin with 'r', 'w', 'c' or 'n'");
     710            return NULL;
     711        }
     712        if (flag[1] == 'l') {
    711713#if defined(O_EXLOCK) && defined(O_SHLOCK)
    712                         if (flag[0] == 'r')
    713                                 flags |= O_SHLOCK;
    714                         else
    715                                 flags |= O_EXLOCK;
     714            if (flag[0] == 'r')
     715                flags |= O_SHLOCK;
     716            else
     717                flags |= O_EXLOCK;
    716718#else
    717                         PyErr_SetString(BsddbError,
    718                                      "locking not supported on this platform");
    719                         return NULL;
    720 #endif
    721                 }
    722         }
    723         return newdbhashobject(file, flags, mode,
    724                                bsize, ffactor, nelem, cachesize, hash, lorder);
     719            PyErr_SetString(BsddbError,
     720                         "locking not supported on this platform");
     721            return NULL;
     722#endif
     723        }
     724    }
     725    return newdbhashobject(file, flags, mode,
     726                           bsize, ffactor, nelem, cachesize, hash, lorder);
    725727}
    726728
     
    728730bsdbtopen(PyObject *self, PyObject *args)
    729731{
    730         char *file;
    731         char *flag = NULL;
    732         int flags = O_RDONLY;
    733         int mode = 0666;
    734         int cachesize = 0;
    735         int maxkeypage = 0;
    736         int minkeypage = 0;
    737         int btflags = 0;
    738         unsigned int psize = 0;
    739         int lorder = 0;
    740 
    741         if (!PyArg_ParseTuple(args, "z|siiiiiii:btopen",
    742                               &file, &flag, &mode,
    743                               &btflags, &cachesize, &maxkeypage, &minkeypage,
    744                               &psize, &lorder))
    745                 return NULL;
    746         if (flag != NULL) {
    747                 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
    748                 if (flag[0] == 'r')
    749                         flags = O_RDONLY;
    750                 else if (flag[0] == 'w')
    751                         flags = O_RDWR;
    752                 else if (flag[0] == 'c')
    753                         flags = O_RDWR|O_CREAT;
    754                 else if (flag[0] == 'n')
    755                         flags = O_RDWR|O_CREAT|O_TRUNC;
    756                 else {
    757                         PyErr_SetString(BsddbError,
    758                                "Flag should begin with 'r', 'w', 'c' or 'n'");
    759                         return NULL;
    760                 }
    761                 if (flag[1] == 'l') {
     732    char *file;
     733    char *flag = NULL;
     734    int flags = O_RDONLY;
     735    int mode = 0666;
     736    int cachesize = 0;
     737    int maxkeypage = 0;
     738    int minkeypage = 0;
     739    int btflags = 0;
     740    unsigned int psize = 0;
     741    int lorder = 0;
     742
     743    if (!PyArg_ParseTuple(args, "z|siiiiiii:btopen",
     744                          &file, &flag, &mode,
     745                          &btflags, &cachesize, &maxkeypage, &minkeypage,
     746                          &psize, &lorder))
     747        return NULL;
     748    if (flag != NULL) {
     749        /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
     750        if (flag[0] == 'r')
     751            flags = O_RDONLY;
     752        else if (flag[0] == 'w')
     753            flags = O_RDWR;
     754        else if (flag[0] == 'c')
     755            flags = O_RDWR|O_CREAT;
     756        else if (flag[0] == 'n')
     757            flags = O_RDWR|O_CREAT|O_TRUNC;
     758        else {
     759            PyErr_SetString(BsddbError,
     760                   "Flag should begin with 'r', 'w', 'c' or 'n'");
     761            return NULL;
     762        }
     763        if (flag[1] == 'l') {
    762764#if defined(O_EXLOCK) && defined(O_SHLOCK)
    763                         if (flag[0] == 'r')
    764                                 flags |= O_SHLOCK;
    765                         else
    766                                 flags |= O_EXLOCK;
     765            if (flag[0] == 'r')
     766                flags |= O_SHLOCK;
     767            else
     768                flags |= O_EXLOCK;
    767769#else
    768                         PyErr_SetString(BsddbError,
    769                                     "locking not supported on this platform");
    770                         return NULL;
    771 #endif
    772                 }
    773         }
    774         return newdbbtobject(file, flags, mode,
    775                              btflags, cachesize, maxkeypage, minkeypage,
    776                              psize, lorder);
     770            PyErr_SetString(BsddbError,
     771                        "locking not supported on this platform");
     772            return NULL;
     773#endif
     774        }
     775    }
     776    return newdbbtobject(file, flags, mode,
     777                         btflags, cachesize, maxkeypage, minkeypage,
     778                         psize, lorder);
    777779}
    778780
     
    780782bsdrnopen(PyObject *self, PyObject *args)
    781783{
    782         char *file;
    783         char *flag = NULL;
    784         int flags = O_RDONLY;
    785         int mode = 0666;
    786         int cachesize = 0;
    787         int rnflags = 0;
    788         unsigned int psize = 0;
    789         int lorder = 0;
    790         size_t reclen = 0;
    791         char  *bval = "";
    792         char *bfname = NULL;
    793 
    794         if (!PyArg_ParseTuple(args, "z|siiiiiiss:rnopen",
    795                               &file, &flag, &mode,
    796                               &rnflags, &cachesize, &psize, &lorder,
    797                               &reclen, &bval, &bfname))
    798                 return NULL;
    799 
    800         if (flag != NULL) {
    801                 /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
    802                 if (flag[0] == 'r')
    803                         flags = O_RDONLY;
    804                 else if (flag[0] == 'w')
    805                         flags = O_RDWR;
    806                 else if (flag[0] == 'c')
    807                         flags = O_RDWR|O_CREAT;
    808                 else if (flag[0] == 'n')
    809                         flags = O_RDWR|O_CREAT|O_TRUNC;
    810                 else {
    811                         PyErr_SetString(BsddbError,
    812                                "Flag should begin with 'r', 'w', 'c' or 'n'");
    813                         return NULL;
    814                 }
    815                 if (flag[1] == 'l') {
     784    char *file;
     785    char *flag = NULL;
     786    int flags = O_RDONLY;
     787    int mode = 0666;
     788    int cachesize = 0;
     789    int rnflags = 0;
     790    unsigned int psize = 0;
     791    int lorder = 0;
     792    size_t reclen = 0;
     793    char  *bval = "";
     794    char *bfname = NULL;
     795
     796    if (!PyArg_ParseTuple(args, "z|siiiiiiss:rnopen",
     797                          &file, &flag, &mode,
     798                          &rnflags, &cachesize, &psize, &lorder,
     799                          &reclen, &bval, &bfname))
     800        return NULL;
     801
     802    if (flag != NULL) {
     803        /* XXX need to pass O_EXCL, O_EXLOCK, O_NONBLOCK, O_SHLOCK */
     804        if (flag[0] == 'r')
     805            flags = O_RDONLY;
     806        else if (flag[0] == 'w')
     807            flags = O_RDWR;
     808        else if (flag[0] == 'c')
     809            flags = O_RDWR|O_CREAT;
     810        else if (flag[0] == 'n')
     811            flags = O_RDWR|O_CREAT|O_TRUNC;
     812        else {
     813            PyErr_SetString(BsddbError,
     814                   "Flag should begin with 'r', 'w', 'c' or 'n'");
     815            return NULL;
     816        }
     817        if (flag[1] == 'l') {
    816818#if defined(O_EXLOCK) && defined(O_SHLOCK)
    817                         if (flag[0] == 'r')
    818                                 flags |= O_SHLOCK;
    819                         else
    820                                 flags |= O_EXLOCK;
     819            if (flag[0] == 'r')
     820                flags |= O_SHLOCK;
     821            else
     822                flags |= O_EXLOCK;
    821823#else
    822                         PyErr_SetString(BsddbError,
    823                                     "locking not supported on this platform");
    824                         return NULL;
    825 #endif
    826                 }
    827                 else if (flag[1] != '\0') {
    828                         PyErr_SetString(BsddbError,
    829                                        "Flag char 2 should be 'l' or absent");
    830                         return NULL;
    831                 }
    832         }
    833         return newdbrnobject(file, flags, mode, rnflags, cachesize,
    834                              psize, lorder, reclen, bval[0], bfname);
     824            PyErr_SetString(BsddbError,
     825                        "locking not supported on this platform");
     826            return NULL;
     827#endif
     828        }
     829        else if (flag[1] != '\0') {
     830            PyErr_SetString(BsddbError,
     831                           "Flag char 2 should be 'l' or absent");
     832            return NULL;
     833        }
     834    }
     835    return newdbrnobject(file, flags, mode, rnflags, cachesize,
     836                         psize, lorder, reclen, bval[0], bfname);
    835837}
    836838
    837839static PyMethodDef bsddbmodule_methods[] = {
    838         {"hashopen",    (PyCFunction)bsdhashopen, METH_VARARGS},
    839         {"btopen",      (PyCFunction)bsdbtopen, METH_VARARGS},
    840         {"rnopen",      (PyCFunction)bsdrnopen, METH_VARARGS},
    841         /* strictly for use by dbhhash!!! */
    842         {"open",        (PyCFunction)bsdhashopen, METH_VARARGS},
    843         {0,             0},
     840    {"hashopen",        (PyCFunction)bsdhashopen, METH_VARARGS},
     841    {"btopen",          (PyCFunction)bsdbtopen, METH_VARARGS},
     842    {"rnopen",          (PyCFunction)bsdrnopen, METH_VARARGS},
     843    /* strictly for use by dbhhash!!! */
     844    {"open",            (PyCFunction)bsdhashopen, METH_VARARGS},
     845    {0,                 0},
    844846};
    845847
    846848PyMODINIT_FUNC
    847849initbsddb185(void) {
    848         PyObject *m, *d;
     850    PyObject *m, *d;
    849851
    850852    if (PyErr_WarnPy3k("the bsddb185 module has been removed in "
    851853                       "Python 3.0", 2) < 0)
    852         return;   
    853 
    854         Bsddbtype.ob_type = &PyType_Type;
    855         m = Py_InitModule("bsddb185", bsddbmodule_methods);
    856         if (m == NULL)
    857                 return;
    858         d = PyModule_GetDict(m);
    859         BsddbError = PyErr_NewException("bsddb.error", NULL, NULL);
    860         if (BsddbError != NULL)
    861                 PyDict_SetItemString(d, "error", BsddbError);
    862 }
     854    return;
     855
     856    Bsddbtype.ob_type = &PyType_Type;
     857    m = Py_InitModule("bsddb185", bsddbmodule_methods);
     858    if (m == NULL)
     859        return;
     860    d = PyModule_GetDict(m);
     861    BsddbError = PyErr_NewException("bsddb.error", NULL, NULL);
     862    if (BsddbError != NULL)
     863        PyDict_SetItemString(d, "error", BsddbError);
     864}
  • python/trunk/setup.py

    r27 r132  
    713713        # versions of BerkeleyDB already installed.
    714714
    715         max_db_ver = (4, 7)
     715        max_db_ver = (4, 8)
    716716        min_db_ver = (3, 3)
    717         db_setup_debug = False   # verbose debug prints from this script?
     717        db_setup_debug = True   # verbose debug prints from this script?
    718718
    719719        def allow_db_ver(db_ver):
Note: See TracChangeset for help on using the changeset viewer.