Python-checkins
Threads by month
- ----- 2024 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
June 2008
- 23 participants
- 889 discussions
21 Jul '08
Author: jesus.cea
Date: Tue May 13 20:45:46 2008
New Revision: 63207
Log:
bsddb module updated to version 4.6.4
Modified:
python/trunk/Misc/NEWS
python/trunk/Modules/_bsddb.c
python/trunk/Modules/bsddb.h
Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS (original)
+++ python/trunk/Misc/NEWS Tue May 13 20:45:46 2008
@@ -25,6 +25,8 @@
- Support for Windows9x has been removed from the winsound module.
+- bsddb module updated to version 4.6.4.
+
Library
-------
Modified: python/trunk/Modules/_bsddb.c
==============================================================================
--- python/trunk/Modules/_bsddb.c (original)
+++ python/trunk/Modules/_bsddb.c Tue May 13 20:45:46 2008
@@ -36,7 +36,7 @@
/*
* Handwritten code to wrap version 3.x of the Berkeley DB library,
* written to replace a SWIG-generated file. It has since been updated
- * to compile with BerkeleyDB versions 3.2 through 4.2.
+ * to compile with Berkeley DB versions 3.2 through 4.2.
*
* This module was started by Andrew Kuchling to remove the dependency
* on SWIG in a package by Gregory P. Smith who based his work on a
@@ -48,7 +48,10 @@
* the DB 3.x API and to build a solid unit test suite. Robin has
* since gone onto other projects (wxPython).
*
- * Gregory P. Smith <greg(a)krypto.org> is once again the maintainer.
+ * Gregory P. Smith <greg(a)krypto.org> was once again the maintainer.
+ *
+ * Since January 2008, new maintainer is Jesus Cea <jcea(a)argo.es>.
+ * Jesus Cea licenses this code to PSF under a Contributor Agreement.
*
* Use the pybsddb-users(a)lists.sf.net mailing list for all questions.
* Things can change faster than the header of this file is updated. This
@@ -183,6 +186,10 @@
static PyObject* DBNoSuchFileError; /* ENOENT */
static PyObject* DBPermissionsError; /* EPERM */
+#if (DBVER >= 42)
+static PyObject* DBRepHandleDeadError; /* DB_REP_HANDLE_DEAD */
+#endif
+
#if (DBVER < 43)
#define DB_BUFFER_SMALL ENOMEM
#endif
@@ -202,6 +209,9 @@
staticforward PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type, DBLock_Type;
+#if (DBVER >= 43)
+staticforward PyTypeObject DBSequence_Type;
+#endif
#ifndef Py_TYPE
/* for compatibility with Python 2.5 and earlier */
@@ -217,10 +227,77 @@
#define DBSequenceObject_Check(v) (Py_TYPE(v) == &DBSequence_Type)
#endif
+#if (DBVER < 46)
+ #define _DBC_close(dbc) dbc->c_close(dbc)
+ #define _DBC_count(dbc,a,b) dbc->c_count(dbc,a,b)
+ #define _DBC_del(dbc,a) dbc->c_del(dbc,a)
+ #define _DBC_dup(dbc,a,b) dbc->c_dup(dbc,a,b)
+ #define _DBC_get(dbc,a,b,c) dbc->c_get(dbc,a,b,c)
+ #define _DBC_pget(dbc,a,b,c,d) dbc->c_pget(dbc,a,b,c,d)
+ #define _DBC_put(dbc,a,b,c) dbc->c_put(dbc,a,b,c)
+#else
+ #define _DBC_close(dbc) dbc->close(dbc)
+ #define _DBC_count(dbc,a,b) dbc->count(dbc,a,b)
+ #define _DBC_del(dbc,a) dbc->del(dbc,a)
+ #define _DBC_dup(dbc,a,b) dbc->dup(dbc,a,b)
+ #define _DBC_get(dbc,a,b,c) dbc->get(dbc,a,b,c)
+ #define _DBC_pget(dbc,a,b,c,d) dbc->pget(dbc,a,b,c,d)
+ #define _DBC_put(dbc,a,b,c) dbc->put(dbc,a,b,c)
+#endif
+
/* --------------------------------------------------------------------- */
/* Utility macros and functions */
+#define INSERT_IN_DOUBLE_LINKED_LIST(backlink,object) \
+ { \
+ object->sibling_next=backlink; \
+ object->sibling_prev_p=&(backlink); \
+ backlink=object; \
+ if (object->sibling_next) { \
+ object->sibling_next->sibling_prev_p=&(object->sibling_next); \
+ } \
+ }
+
+#define EXTRACT_FROM_DOUBLE_LINKED_LIST(object) \
+ { \
+ if (object->sibling_next) { \
+ object->sibling_next->sibling_prev_p=object->sibling_prev_p; \
+ } \
+ *(object->sibling_prev_p)=object->sibling_next; \
+ }
+
+#define EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(object) \
+ { \
+ if (object->sibling_next) { \
+ object->sibling_next->sibling_prev_p=object->sibling_prev_p; \
+ } \
+ if (object->sibling_prev_p) { \
+ *(object->sibling_prev_p)=object->sibling_next; \
+ } \
+ }
+
+#define INSERT_IN_DOUBLE_LINKED_LIST_TXN(backlink,object) \
+ { \
+ object->sibling_next_txn=backlink; \
+ object->sibling_prev_p_txn=&(backlink); \
+ backlink=object; \
+ if (object->sibling_next_txn) { \
+ object->sibling_next_txn->sibling_prev_p_txn= \
+ &(object->sibling_next_txn); \
+ } \
+ }
+
+#define EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(object) \
+ { \
+ if (object->sibling_next_txn) { \
+ object->sibling_next_txn->sibling_prev_p_txn= \
+ object->sibling_prev_p_txn; \
+ } \
+ *(object->sibling_prev_p_txn)=object->sibling_next_txn; \
+ }
+
+
#define RETURN_IF_ERR() \
if (makeDBError(err)) { \
return NULL; \
@@ -443,6 +520,66 @@
}
+/*
+** We need these functions because some results
+** are undefined if pointer is NULL. Some other
+** give None instead of "".
+**
+** This functions are static and will be
+** -I hope- inlined.
+*/
+static const char *DummyString = "This string is a simple placeholder";
+static PyObject *Build_PyString(const char *p,int s)
+{
+ if (!p) {
+ p=DummyString;
+ assert(s==0);
+ }
+ return PyString_FromStringAndSize(p,s);
+}
+
+static PyObject *BuildValue_S(const void *p,int s)
+{
+ if (!p) {
+ p=DummyString;
+ assert(s==0);
+ }
+ return Py_BuildValue("s#",p,s);
+}
+
+static PyObject *BuildValue_SS(const void *p1,int s1,const void *p2,int s2)
+{
+ if (!p1) {
+ p1=DummyString;
+ assert(s1==0);
+ }
+ if (!p2) {
+ p2=DummyString;
+ assert(s2==0);
+ }
+ return Py_BuildValue("s#s#",p1,s1,p2,s2);
+}
+
+static PyObject *BuildValue_IS(int i,const void *p,int s)
+{
+ if (!p) {
+ p=DummyString;
+ assert(s==0);
+ }
+ return Py_BuildValue("is#",i,p,s);
+}
+
+static PyObject *BuildValue_LS(long i,const void *p,int s)
+{
+ if (!p) {
+ p=DummyString;
+ assert(s==0);
+ }
+ return Py_BuildValue("ls#",i,p,s);
+}
+
+
+
/* make a nice exception object to raise for errors. */
static int makeDBError(int err)
{
@@ -505,6 +642,10 @@
case ENOENT: errObj = DBNoSuchFileError; break;
case EPERM : errObj = DBPermissionsError; break;
+#if (DBVER >= 42)
+ case DB_REP_HANDLE_DEAD : errObj = DBRepHandleDeadError; break;
+#endif
+
default: errObj = DBError; break;
}
@@ -608,16 +749,11 @@
flags |= extra_flags;
CLEAR_DBT(key);
CLEAR_DBT(data);
- if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
- /* Tell BerkeleyDB to malloc the return value (thread safe) */
- data.flags = DB_DBT_MALLOC;
- key.flags = DB_DBT_MALLOC;
- }
if (!add_partial_dbt(&data, dlen, doff))
return NULL;
MYDB_BEGIN_ALLOW_THREADS;
- err = self->dbc->c_get(self->dbc, &key, &data, flags);
+ err = _DBC_get(self->dbc, &key, &data, flags);
MYDB_END_ALLOW_THREADS;
if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
@@ -638,21 +774,15 @@
case DB_RECNO:
case DB_QUEUE:
- retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
- data.data, data.size);
+ retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
break;
case DB_HASH:
case DB_BTREE:
default:
- retval = Py_BuildValue("s#s#", key.data, key.size,
- data.data, data.size);
+ retval = BuildValue_SS(key.data, key.size, data.data, data.size);
break;
}
}
- if (!err) {
- FREE_DBT(key);
- FREE_DBT(data);
- }
return retval;
}
@@ -672,7 +802,7 @@
{
PyObject* v;
/* if the value fits in regular int, use that. */
-#ifdef HAVE_LONG_LONG
+#ifdef PY_LONG_LONG
if (sizeof(time_t) > sizeof(long))
v = PyLong_FromLongLong((PY_LONG_LONG) value);
else
@@ -696,7 +826,16 @@
}
#endif
+#if (DBVER >= 40)
+static void _addDB_lsnToDict(PyObject* dict, char *name, DB_LSN value)
+{
+ PyObject *v = Py_BuildValue("(ll)",value.file,value.offset);
+ if (!v || PyDict_SetItemString(dict, name, v))
+ PyErr_Clear();
+ Py_XDECREF(v);
+}
+#endif
/* --------------------------------------------------------------------- */
/* Allocators and deallocators */
@@ -716,6 +855,10 @@
self->flags = 0;
self->setflags = 0;
self->myenvobj = NULL;
+ self->children_cursors = NULL;
+#if (DBVER >=43)
+ self->children_sequences = NULL;
+#endif
#if (DBVER >= 33)
self->associateCallback = NULL;
self->btCompareCallback = NULL;
@@ -728,7 +871,14 @@
Py_INCREF(arg);
self->myenvobj = arg;
db_env = arg->db_env;
+ INSERT_IN_DOUBLE_LINKED_LIST(self->myenvobj->children_dbs,self);
+ } else {
+ self->sibling_prev_p=NULL;
+ self->sibling_next=NULL;
}
+ self->txn=NULL;
+ self->sibling_prev_p_txn=NULL;
+ self->sibling_next_txn=NULL;
if (self->myenvobj)
self->moduleFlags = self->myenvobj->moduleFlags;
@@ -760,23 +910,17 @@
}
+/* Forward declaration */
+static PyObject *DB_close_internal(DBObject* self, int flags);
+
static void
DB_dealloc(DBObject* self)
{
+ PyObject *dummy;
+
if (self->db != NULL) {
- /* avoid closing a DB when its DBEnv has been closed out from under
- * it */
- if (!self->myenvobj ||
- (self->myenvobj && self->myenvobj->db_env))
- {
- MYDB_BEGIN_ALLOW_THREADS;
- self->db->close(self->db, 0);
- MYDB_END_ALLOW_THREADS;
- } else {
- PyErr_Warn(PyExc_RuntimeWarning,
- "DB could not be closed in destructor: DBEnv already closed");
- }
- self->db = NULL;
+ dummy=DB_close_internal(self,0);
+ Py_XDECREF(dummy);
}
if (self->in_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *) self);
@@ -798,9 +942,8 @@
PyObject_Del(self);
}
-
static DBCursorObject*
-newDBCursorObject(DBC* dbc, DBObject* db)
+newDBCursorObject(DBC* dbc, DBTxnObject *txn, DBObject* db)
{
DBCursorObject* self = PyObject_New(DBCursorObject, &DBCursor_Type);
if (self == NULL)
@@ -808,40 +951,37 @@
self->dbc = dbc;
self->mydb = db;
+
+ INSERT_IN_DOUBLE_LINKED_LIST(self->mydb->children_cursors,self);
+ if (txn && ((PyObject *)txn!=Py_None)) {
+ INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->children_cursors,self);
+ self->txn=txn;
+ } else {
+ self->txn=NULL;
+ }
+
self->in_weakreflist = NULL;
Py_INCREF(self->mydb);
return self;
}
+/* Forward declaration */
+static PyObject *DBC_close_internal(DBCursorObject* self);
+
static void
DBCursor_dealloc(DBCursorObject* self)
{
- int err;
+ PyObject *dummy;
+ if (self->dbc != NULL) {
+ dummy=DBC_close_internal(self);
+ Py_XDECREF(dummy);
+ }
if (self->in_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *) self);
}
-
- if (self->dbc != NULL) {
- /* If the underlying database has been closed, we don't
- need to do anything. If the environment has been closed
- we need to leak, as BerkeleyDB will crash trying to access
- the environment. There was an exception when the
- user closed the environment even though there still was
- a database open. */
- if (self->mydb->db && self->mydb->myenvobj &&
- !self->mydb->myenvobj->closed)
- /* test for: open db + no environment or non-closed environment */
- if (self->mydb->db && (!self->mydb->myenvobj || (self->mydb->myenvobj &&
- !self->mydb->myenvobj->closed))) {
- MYDB_BEGIN_ALLOW_THREADS;
- err = self->dbc->c_close(self->dbc);
- MYDB_END_ALLOW_THREADS;
- }
- self->dbc = NULL;
- }
- Py_XDECREF( self->mydb );
+ Py_DECREF(self->mydb);
PyObject_Del(self);
}
@@ -858,8 +998,14 @@
self->flags = flags;
self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
+ self->children_dbs = NULL;
+ self->children_txns = NULL;
self->in_weakreflist = NULL;
+#if (DBVER >= 40)
+ self->event_notifyCallback = NULL;
+#endif
+
MYDB_BEGIN_ALLOW_THREADS;
err = db_env_create(&self->db_env, flags);
MYDB_END_ALLOW_THREADS;
@@ -869,75 +1015,119 @@
}
else {
self->db_env->set_errcall(self->db_env, _db_errorCallback);
+ self->db_env->app_private=self;
}
return self;
}
+/* Forward declaration */
+static PyObject *DBEnv_close_internal(DBEnvObject* self, int flags);
static void
DBEnv_dealloc(DBEnvObject* self)
{
+ PyObject *dummy;
+
+ if (self->db_env && !self->closed) {
+ dummy=DBEnv_close_internal(self,0);
+ Py_XDECREF(dummy);
+ }
+
+#if (DBVER >= 40)
+ Py_XDECREF(self->event_notifyCallback);
+ self->event_notifyCallback = NULL;
+#endif
+
if (self->in_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *) self);
}
- if (self->db_env && !self->closed) {
- MYDB_BEGIN_ALLOW_THREADS;
- self->db_env->close(self->db_env, 0);
- MYDB_END_ALLOW_THREADS;
- }
PyObject_Del(self);
}
static DBTxnObject*
-newDBTxnObject(DBEnvObject* myenv, DB_TXN *parent, int flags)
+newDBTxnObject(DBEnvObject* myenv, DBTxnObject *parent, DB_TXN *txn, int flags)
{
int err;
+ DB_TXN *parent_txn=NULL;
+
DBTxnObject* self = PyObject_New(DBTxnObject, &DBTxn_Type);
if (self == NULL)
return NULL;
- Py_INCREF(myenv);
- self->env = (PyObject*)myenv;
+
self->in_weakreflist = NULL;
- MYDB_BEGIN_ALLOW_THREADS;
+ if (parent && ((PyObject *)parent!=Py_None)) {
+ parent_txn=parent->txn;
+ }
+
+ if (txn) {
+ self->txn=txn;
+ } else {
+ MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
- err = myenv->db_env->txn_begin(myenv->db_env, parent, &(self->txn), flags);
+ err = myenv->db_env->txn_begin(myenv->db_env, parent_txn, &(self->txn), flags);
#else
- err = txn_begin(myenv->db_env, parent, &(self->txn), flags);
+ err = txn_begin(myenv->db_env, parent->txn, &(self_txn), flags);
#endif
- MYDB_END_ALLOW_THREADS;
- if (makeDBError(err)) {
- Py_DECREF(self->env);
- PyObject_Del(self);
- self = NULL;
+ MYDB_END_ALLOW_THREADS;
+
+ if (makeDBError(err)) {
+ PyObject_Del(self);
+ return NULL;
+ }
}
+
+ if (parent_txn) { /* Can't use 'parent' because could be 'parent==Py_None' */
+ self->parent_txn=parent;
+ Py_INCREF(parent);
+ self->env = NULL;
+ INSERT_IN_DOUBLE_LINKED_LIST(parent->children_txns,self);
+ } else {
+ self->parent_txn=NULL;
+ Py_INCREF(myenv);
+ self->env = myenv;
+ INSERT_IN_DOUBLE_LINKED_LIST(myenv->children_txns,self);
+ }
+
+ self->children_txns=NULL;
+ self->children_dbs=NULL;
+ self->children_cursors=NULL;
+ self->children_sequences=NULL;
+ self->flag_prepare=0;
+
return self;
}
+/* Forward declaration */
+static PyObject *
+DBTxn_abort_discard_internal(DBTxnObject* self, int discard);
static void
DBTxn_dealloc(DBTxnObject* self)
{
+ PyObject *dummy;
+
+ if (self->txn) {
+ int flag_prepare = self->flag_prepare;
+ dummy=DBTxn_abort_discard_internal(self,0);
+ Py_XDECREF(dummy);
+ if (!flag_prepare) {
+ PyErr_Warn(PyExc_RuntimeWarning,
+ "DBTxn aborted in destructor. No prior commit() or abort().");
+ }
+ }
+
if (self->in_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *) self);
}
- if (self->txn) {
- /* it hasn't been finalized, abort it! */
- MYDB_BEGIN_ALLOW_THREADS;
-#if (DBVER >= 40)
- self->txn->abort(self->txn);
-#else
- txn_abort(self->txn);
-#endif
- MYDB_END_ALLOW_THREADS;
- PyErr_Warn(PyExc_RuntimeWarning,
- "DBTxn aborted in destructor. No prior commit() or abort().");
+ if (self->env) {
+ Py_DECREF(self->env);
+ } else {
+ Py_DECREF(self->parent_txn);
}
-
- Py_DECREF(self->env);
PyObject_Del(self);
}
@@ -991,8 +1181,11 @@
return NULL;
Py_INCREF(mydb);
self->mydb = mydb;
- self->in_weakreflist = NULL;
+ INSERT_IN_DOUBLE_LINKED_LIST(self->mydb->children_sequences,self);
+ self->txn=NULL;
+
+ self->in_weakreflist = NULL;
MYDB_BEGIN_ALLOW_THREADS;
err = db_sequence_create(&self->sequence, self->mydb->db, flags);
@@ -1006,10 +1199,20 @@
return self;
}
+/* Forward declaration */
+static PyObject
+*DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close);
static void
DBSequence_dealloc(DBSequenceObject* self)
{
+ PyObject *dummy;
+
+ if (self->sequence != NULL) {
+ dummy=DBSequence_close_internal(self,0,0);
+ Py_XDECREF(dummy);
+ }
+
if (self->in_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *) self);
}
@@ -1072,11 +1275,9 @@
MYDB_BEGIN_BLOCK_THREADS;
if (type == DB_RECNO || type == DB_QUEUE)
- args = Py_BuildValue("(ls#)", *((db_recno_t*)priKey->data),
- priData->data, priData->size);
+ args = BuildValue_LS(*((db_recno_t*)priKey->data), priData->data, priData->size);
else
- args = Py_BuildValue("(s#s#)", priKey->data, priKey->size,
- priData->data, priData->size);
+ args = BuildValue_SS(priKey->data, priKey->size, priData->data, priData->size);
if (args != NULL) {
result = PyEval_CallObject(callback, args);
}
@@ -1217,21 +1418,49 @@
static PyObject*
-DB_close(DBObject* self, PyObject* args)
+DB_close_internal(DBObject* self, int flags)
{
- int err, flags=0;
- if (!PyArg_ParseTuple(args,"|i:close", &flags))
- return NULL;
+ PyObject *dummy;
+ int err;
+
if (self->db != NULL) {
- if (self->myenvobj)
- CHECK_ENV_NOT_CLOSED(self->myenvobj);
+ /* Can be NULL if db is not in an environment */
+ EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
+ if (self->txn) {
+ EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
+ self->txn=NULL;
+ }
+
+ while(self->children_cursors) {
+ dummy=DBC_close_internal(self->children_cursors);
+ Py_XDECREF(dummy);
+ }
+
+#if (DBVER >= 43)
+ while(self->children_sequences) {
+ dummy=DBSequence_close_internal(self->children_sequences,0,0);
+ Py_XDECREF(dummy);
+ }
+#endif
+
+ MYDB_BEGIN_ALLOW_THREADS;
err = self->db->close(self->db, flags);
+ MYDB_END_ALLOW_THREADS;
self->db = NULL;
RETURN_IF_ERR();
}
RETURN_NONE();
}
+static PyObject*
+DB_close(DBObject* self, PyObject* args)
+{
+ int flags=0;
+ if (!PyArg_ParseTuple(args,"|i:close", &flags))
+ return NULL;
+ return DB_close_internal(self,flags);
+}
+
static PyObject*
_DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
@@ -1262,7 +1491,7 @@
CLEAR_DBT(key);
CLEAR_DBT(data);
if (CHECK_DBFLAG(self, DB_THREAD)) {
- /* Tell BerkeleyDB to malloc the return value (thread safe) */
+ /* Tell Berkeley DB to malloc the return value (thread safe) */
data.flags = DB_DBT_MALLOC;
key.flags = DB_DBT_MALLOC;
}
@@ -1278,8 +1507,7 @@
retval = Py_None;
}
else if (!err) {
- retval = Py_BuildValue("s#s#", key.data, key.size, data.data,
- data.size);
+ retval = BuildValue_SS(key.data, key.size, data.data, data.size);
FREE_DBT(key);
FREE_DBT(data);
}
@@ -1322,7 +1550,7 @@
err = self->db->cursor(self->db, txn, &dbc, flags);
MYDB_END_ALLOW_THREADS;
RETURN_IF_ERR();
- return (PyObject*) newDBCursorObject(dbc, self);
+ return (PyObject*) newDBCursorObject(dbc, (DBTxnObject *)txnobj, self);
}
@@ -1404,7 +1632,7 @@
CLEAR_DBT(data);
if (CHECK_DBFLAG(self, DB_THREAD)) {
- /* Tell BerkeleyDB to malloc the return value (thread safe) */
+ /* Tell Berkeley DB to malloc the return value (thread safe) */
data.flags = DB_DBT_MALLOC;
}
if (!add_partial_dbt(&data, dlen, doff)) {
@@ -1429,10 +1657,9 @@
}
else if (!err) {
if (flags & DB_SET_RECNO) /* return both key and data */
- retval = Py_BuildValue("s#s#", key.data, key.size, data.data,
- data.size);
+ retval = BuildValue_SS(key.data, key.size, data.data, data.size);
else /* return just the data */
- retval = PyString_FromStringAndSize((char*)data.data, data.size);
+ retval = Build_PyString(data.data, data.size);
FREE_DBT(data);
}
FREE_DBT(key);
@@ -1472,7 +1699,7 @@
CLEAR_DBT(data);
if (CHECK_DBFLAG(self, DB_THREAD)) {
- /* Tell BerkeleyDB to malloc the return value (thread safe) */
+ /* Tell Berkeley DB to malloc the return value (thread safe) */
data.flags = DB_DBT_MALLOC;
}
if (!add_partial_dbt(&data, dlen, doff)) {
@@ -1501,13 +1728,13 @@
else if (!err) {
PyObject *pkeyObj;
PyObject *dataObj;
- dataObj = PyString_FromStringAndSize(data.data, data.size);
+ dataObj = Build_PyString(data.data, data.size);
if (self->primaryDBType == DB_RECNO ||
self->primaryDBType == DB_QUEUE)
pkeyObj = PyInt_FromLong(*(int *)pkey.data);
else
- pkeyObj = PyString_FromStringAndSize(pkey.data, pkey.size);
+ pkeyObj = Build_PyString(pkey.data, pkey.size);
if (flags & DB_SET_RECNO) /* return key , pkey and data */
{
@@ -1516,7 +1743,7 @@
if (type == DB_RECNO || type == DB_QUEUE)
keyObj = PyInt_FromLong(*(int *)key.data);
else
- keyObj = PyString_FromStringAndSize(key.data, key.size);
+ keyObj = Build_PyString(key.data, key.size);
#if (PY_VERSION_HEX >= 0x02040000)
retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
#else
@@ -1620,7 +1847,7 @@
orig_data = data.data;
if (CHECK_DBFLAG(self, DB_THREAD)) {
- /* Tell BerkeleyDB to malloc the return value (thread safe) */
+ /* Tell Berkeley DB to malloc the return value (thread safe) */
/* XXX(nnorwitz): At least 4.4.20 and 4.5.20 require this flag. */
data.flags = DB_DBT_MALLOC;
}
@@ -1637,7 +1864,7 @@
}
else if (!err) {
/* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */
- retval = PyString_FromStringAndSize((char*)data.data, data.size);
+ retval = Build_PyString(data.data, data.size);
/* Even though the flags require DB_DBT_MALLOC, data is not always
allocated. 4.4: allocated, 4.5: *not* allocated. :-( */
@@ -1748,7 +1975,7 @@
but does not hold python references to them or prevent
them from being closed prematurely. This can cause
python to crash when things are done in the wrong order. */
- return (PyObject*) newDBCursorObject(dbc, self);
+ return (PyObject*) newDBCursorObject(dbc, NULL, self);
}
@@ -1845,6 +2072,17 @@
return NULL;
}
+#if (DBVER >= 41)
+ if (txn) { /* Can't use 'txnobj' because could be 'txnobj==Py_None' */
+ INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_dbs,self);
+ self->txn=(DBTxnObject *)txnobj;
+ } else {
+ self->txn=NULL;
+ }
+#else
+ self->txn=NULL;
+#endif
+
MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 41)
err = self->db->open(self->db, txn, filename, dbname, type, flags, mode);
@@ -1853,8 +2091,10 @@
#endif
MYDB_END_ALLOW_THREADS;
if (makeDBError(err)) {
- self->db->close(self->db, 0);
- self->db = NULL;
+ PyObject *dummy;
+
+ dummy=DB_close_internal(self,0);
+ Py_XDECREF(dummy);
return NULL;
}
@@ -1863,6 +2103,7 @@
#endif
self->flags = flags;
+
RETURN_NONE();
}
@@ -1993,7 +2234,7 @@
}
static int
-_db_compareCallback(DB* db,
+_db_compareCallback(DB* db,
const DBT *leftKey,
const DBT *rightKey)
{
@@ -2015,8 +2256,7 @@
} else {
MYDB_BEGIN_BLOCK_THREADS;
- args = Py_BuildValue("s#s#", leftKey->data, leftKey->size,
- rightKey->data, rightKey->size);
+ args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
if (args != NULL) {
/* XXX(twouters) I highly doubt this INCREF is correct */
Py_INCREF(self);
@@ -2369,6 +2609,9 @@
MAKE_HASH_ENTRY(version);
MAKE_HASH_ENTRY(nkeys);
MAKE_HASH_ENTRY(ndata);
+#if (DBVER >= 46)
+ MAKE_HASH_ENTRY(pagecnt);
+#endif
MAKE_HASH_ENTRY(pagesize);
#if (DBVER < 41)
MAKE_HASH_ENTRY(nelem);
@@ -2391,6 +2634,9 @@
MAKE_BT_ENTRY(version);
MAKE_BT_ENTRY(nkeys);
MAKE_BT_ENTRY(ndata);
+#if (DBVER >= 46)
+ MAKE_BT_ENTRY(pagecnt);
+#endif
MAKE_BT_ENTRY(pagesize);
MAKE_BT_ENTRY(minkey);
MAKE_BT_ENTRY(re_len);
@@ -2400,6 +2646,9 @@
MAKE_BT_ENTRY(leaf_pg);
MAKE_BT_ENTRY(dup_pg);
MAKE_BT_ENTRY(over_pg);
+#if (DBVER >= 43)
+ MAKE_BT_ENTRY(empty_pg);
+#endif
MAKE_BT_ENTRY(free);
MAKE_BT_ENTRY(int_pgfree);
MAKE_BT_ENTRY(leaf_pgfree);
@@ -2413,6 +2662,9 @@
MAKE_QUEUE_ENTRY(nkeys);
MAKE_QUEUE_ENTRY(ndata);
MAKE_QUEUE_ENTRY(pagesize);
+#if (DBVER > 40)
+ MAKE_QUEUE_ENTRY(extentsize);
+#endif
MAKE_QUEUE_ENTRY(pages);
MAKE_QUEUE_ENTRY(re_len);
MAKE_QUEUE_ENTRY(re_pad);
@@ -2527,15 +2779,14 @@
if (outFile)
fclose(outFile);
- /* DB.verify acts as a DB handle destructor (like close); this was
- * documented in BerkeleyDB 4.2 but had the undocumented effect
- * of not being safe in prior versions while still requiring an explicit
- * DB.close call afterwards. Lets call close for the user to emulate
- * the safe 4.2 behaviour. */
-#if (DBVER <= 41)
- self->db->close(self->db, 0);
-#endif
- self->db = NULL;
+ { /* DB.verify acts as a DB handle destructor (like close) */
+ PyObject *error;
+
+ error=DB_close_internal(self,0);
+ if (error ) {
+ return error;
+ }
+ }
RETURN_IF_ERR();
RETURN_NONE();
@@ -2622,7 +2873,7 @@
so we can use any of them for the type cast */
size = ((DB_BTREE_STAT*)sp)->bt_ndata;
- /* A size of 0 could mean that BerkeleyDB no longer had the stat values cached.
+ /* A size of 0 could mean that Berkeley DB no longer had the stat values cached.
* redo a full stat to make sure.
* Fixes SF python bug 1493322, pybsddb bug 1184012
*/
@@ -2658,7 +2909,7 @@
CLEAR_DBT(data);
if (CHECK_DBFLAG(self, DB_THREAD)) {
- /* Tell BerkeleyDB to malloc the return value (thread safe) */
+ /* Tell Berkeley DB to malloc the return value (thread safe) */
data.flags = DB_DBT_MALLOC;
}
MYDB_BEGIN_ALLOW_THREADS;
@@ -2672,7 +2923,7 @@
retval = NULL;
}
else {
- retval = PyString_FromStringAndSize((char*)data.data, data.size);
+ retval = Build_PyString(data.data, data.size);
FREE_DBT(data);
}
@@ -2802,14 +3053,9 @@
return NULL;
}
- if (CHECK_DBFLAG(self, DB_THREAD)) {
- key.flags = DB_DBT_REALLOC;
- data.flags = DB_DBT_REALLOC;
- }
-
while (1) { /* use the cursor to traverse the DB, collecting items */
MYDB_BEGIN_ALLOW_THREADS;
- err = cursor->c_get(cursor, &key, &data, DB_NEXT);
+ err = _DBC_get(cursor, &key, &data, DB_NEXT);
MYDB_END_ALLOW_THREADS;
if (err) {
@@ -2823,7 +3069,7 @@
case DB_BTREE:
case DB_HASH:
default:
- item = PyString_FromStringAndSize((char*)key.data, key.size);
+ item = Build_PyString(key.data, key.size);
break;
case DB_RECNO:
case DB_QUEUE:
@@ -2833,7 +3079,7 @@
break;
case _VALUES_LIST:
- item = PyString_FromStringAndSize((char*)data.data, data.size);
+ item = Build_PyString(data.data, data.size);
break;
case _ITEMS_LIST:
@@ -2841,13 +3087,11 @@
case DB_BTREE:
case DB_HASH:
default:
- item = Py_BuildValue("s#s#", key.data, key.size, data.data,
- data.size);
+ item = BuildValue_SS(key.data, key.size, data.data, data.size);
break;
case DB_RECNO:
case DB_QUEUE:
- item = Py_BuildValue("is#", *((db_recno_t*)key.data),
- data.data, data.size);
+ item = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
break;
}
break;
@@ -2872,10 +3116,8 @@
}
done:
- FREE_DBT(key);
- FREE_DBT(data);
MYDB_BEGIN_ALLOW_THREADS;
- cursor->c_close(cursor);
+ _DBC_close(cursor);
MYDB_END_ALLOW_THREADS;
return list;
}
@@ -2927,23 +3169,35 @@
static PyObject*
-DBC_close(DBCursorObject* self, PyObject* args)
+DBC_close_internal(DBCursorObject* self)
{
int err = 0;
- if (!PyArg_ParseTuple(args, ":close"))
- return NULL;
-
if (self->dbc != NULL) {
+ EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
+ if (self->txn) {
+ EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
+ self->txn=NULL;
+ }
+
MYDB_BEGIN_ALLOW_THREADS;
- err = self->dbc->c_close(self->dbc);
- self->dbc = NULL;
+ err = _DBC_close(self->dbc);
MYDB_END_ALLOW_THREADS;
+ self->dbc = NULL;
}
RETURN_IF_ERR();
RETURN_NONE();
}
+static PyObject*
+DBC_close(DBCursorObject* self, PyObject* args)
+{
+ if (!PyArg_ParseTuple(args, ":close"))
+ return NULL;
+
+ return DBC_close_internal(self);
+}
+
static PyObject*
DBC_count(DBCursorObject* self, PyObject* args)
@@ -2958,7 +3212,7 @@
CHECK_CURSOR_NOT_CLOSED(self);
MYDB_BEGIN_ALLOW_THREADS;
- err = self->dbc->c_count(self->dbc, &count, flags);
+ err = _DBC_count(self->dbc, &count, flags);
MYDB_END_ALLOW_THREADS;
RETURN_IF_ERR();
@@ -2984,7 +3238,7 @@
CHECK_CURSOR_NOT_CLOSED(self);
MYDB_BEGIN_ALLOW_THREADS;
- err = self->dbc->c_del(self->dbc, flags);
+ err = _DBC_del(self->dbc, flags);
MYDB_END_ALLOW_THREADS;
RETURN_IF_ERR();
@@ -3005,11 +3259,11 @@
CHECK_CURSOR_NOT_CLOSED(self);
MYDB_BEGIN_ALLOW_THREADS;
- err = self->dbc->c_dup(self->dbc, &dbc, flags);
+ err = _DBC_dup(self->dbc, &dbc, flags);
MYDB_END_ALLOW_THREADS;
RETURN_IF_ERR();
- return (PyObject*) newDBCursorObject(dbc, self->mydb);
+ return (PyObject*) newDBCursorObject(dbc, self->txn, self->mydb);
}
static PyObject*
@@ -3059,19 +3313,12 @@
if ( (dataobj && !make_dbt(dataobj, &data)) ||
(!add_partial_dbt(&data, dlen, doff)) )
{
- FREE_DBT(key);
+ FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
return NULL;
}
- if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
- data.flags = DB_DBT_MALLOC;
- if (!(key.flags & DB_DBT_REALLOC)) {
- key.flags |= DB_DBT_MALLOC;
- }
- }
-
MYDB_BEGIN_ALLOW_THREADS;
- err = self->dbc->c_get(self->dbc, &key, &data, flags);
+ err = _DBC_get(self->dbc, &key, &data, flags);
MYDB_END_ALLOW_THREADS;
if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
@@ -3090,18 +3337,15 @@
case DB_BTREE:
case DB_HASH:
default:
- retval = Py_BuildValue("s#s#", key.data, key.size,
- data.data, data.size);
+ retval = BuildValue_SS(key.data, key.size, data.data, data.size);
break;
case DB_RECNO:
case DB_QUEUE:
- retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
- data.data, data.size);
+ retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
break;
}
- FREE_DBT(data);
}
- FREE_DBT(key);
+ FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
return retval;
}
@@ -3145,22 +3389,15 @@
return NULL;
if ( (dataobj && !make_dbt(dataobj, &data)) ||
(!add_partial_dbt(&data, dlen, doff)) ) {
- FREE_DBT(key);
+ FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
return NULL;
}
- if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
- data.flags = DB_DBT_MALLOC;
- if (!(key.flags & DB_DBT_REALLOC)) {
- key.flags |= DB_DBT_MALLOC;
- }
- }
-
CLEAR_DBT(pkey);
pkey.flags = DB_DBT_MALLOC;
MYDB_BEGIN_ALLOW_THREADS;
- err = self->dbc->c_pget(self->dbc, &key, &pkey, &data, flags);
+ err = _DBC_pget(self->dbc, &key, &pkey, &data, flags);
MYDB_END_ALLOW_THREADS;
if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
@@ -3174,13 +3411,13 @@
else {
PyObject *pkeyObj;
PyObject *dataObj;
- dataObj = PyString_FromStringAndSize(data.data, data.size);
+ dataObj = Build_PyString(data.data, data.size);
if (self->mydb->primaryDBType == DB_RECNO ||
self->mydb->primaryDBType == DB_QUEUE)
pkeyObj = PyInt_FromLong(*(int *)pkey.data);
else
- pkeyObj = PyString_FromStringAndSize(pkey.data, pkey.size);
+ pkeyObj = Build_PyString(pkey.data, pkey.size);
if (key.data && key.size) /* return key, pkey and data */
{
@@ -3189,14 +3426,14 @@
if (type == DB_RECNO || type == DB_QUEUE)
keyObj = PyInt_FromLong(*(int *)key.data);
else
- keyObj = PyString_FromStringAndSize(key.data, key.size);
+ keyObj = Build_PyString(key.data, key.size);
#if (PY_VERSION_HEX >= 0x02040000)
retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
#else
retval = Py_BuildValue("OOO", keyObj, pkeyObj, dataObj);
#endif
Py_DECREF(keyObj);
- FREE_DBT(key);
+ FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
}
else /* return just the pkey and data */
{
@@ -3209,11 +3446,10 @@
Py_DECREF(dataObj);
Py_DECREF(pkeyObj);
FREE_DBT(pkey);
- FREE_DBT(data);
}
/* the only time REALLOC should be set is if we used an integer
* key that make_key_dbt malloc'd for us. always free these. */
- if (key.flags & DB_DBT_REALLOC) {
+ if (key.flags & DB_DBT_REALLOC) { /* 'make_key_dbt' could do a 'malloc' */
FREE_DBT(key);
}
return retval;
@@ -3236,20 +3472,13 @@
CLEAR_DBT(key);
CLEAR_DBT(data);
- if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
- /* Tell BerkeleyDB to malloc the return value (thread safe) */
- data.flags = DB_DBT_MALLOC;
- key.flags = DB_DBT_MALLOC;
- }
MYDB_BEGIN_ALLOW_THREADS;
- err = self->dbc->c_get(self->dbc, &key, &data, DB_GET_RECNO);
+ err = _DBC_get(self->dbc, &key, &data, DB_GET_RECNO);
MYDB_END_ALLOW_THREADS;
RETURN_IF_ERR();
recno = *((db_recno_t*)data.data);
- FREE_DBT(key);
- FREE_DBT(data);
return PyInt_FromLong(recno);
}
@@ -3297,14 +3526,14 @@
if (!make_dbt(dataobj, &data) ||
!add_partial_dbt(&data, dlen, doff) )
{
- FREE_DBT(key);
+ FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
return NULL;
}
MYDB_BEGIN_ALLOW_THREADS;
- err = self->dbc->c_put(self->dbc, &key, &data, flags);
+ err = _DBC_put(self->dbc, &key, &data, flags);
MYDB_END_ALLOW_THREADS;
- FREE_DBT(key);
+ FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
RETURN_IF_ERR();
self->mydb->haveStat = 0;
RETURN_NONE();
@@ -3331,17 +3560,13 @@
return NULL;
CLEAR_DBT(data);
- if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
- /* Tell BerkeleyDB to malloc the return value (thread safe) */
- data.flags = DB_DBT_MALLOC;
- }
if (!add_partial_dbt(&data, dlen, doff)) {
- FREE_DBT(key);
+ FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
return NULL;
}
MYDB_BEGIN_ALLOW_THREADS;
- err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET);
+ err = _DBC_get(self->dbc, &key, &data, flags|DB_SET);
MYDB_END_ALLOW_THREADS;
if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
&& self->mydb->moduleFlags.cursorSetReturnsNone) {
@@ -3359,22 +3584,19 @@
case DB_BTREE:
case DB_HASH:
default:
- retval = Py_BuildValue("s#s#", key.data, key.size,
- data.data, data.size);
+ retval = BuildValue_SS(key.data, key.size, data.data, data.size);
break;
case DB_RECNO:
case DB_QUEUE:
- retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
- data.data, data.size);
+ retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
break;
}
- FREE_DBT(data);
- FREE_DBT(key);
+ FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
}
/* the only time REALLOC should be set is if we used an integer
* key that make_key_dbt malloc'd for us. always free these. */
if (key.flags & DB_DBT_REALLOC) {
- FREE_DBT(key);
+ FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
}
return retval;
@@ -3402,19 +3624,11 @@
CLEAR_DBT(data);
if (!add_partial_dbt(&data, dlen, doff)) {
- FREE_DBT(key);
+ FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
return NULL;
}
- if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
- /* Tell BerkeleyDB to malloc the return value (thread safe) */
- data.flags |= DB_DBT_MALLOC;
- /* only BTREE databases will return anything in the key */
- if (!(key.flags & DB_DBT_REALLOC) && _DB_get_type(self->mydb) == DB_BTREE) {
- key.flags |= DB_DBT_MALLOC;
- }
- }
MYDB_BEGIN_ALLOW_THREADS;
- err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET_RANGE);
+ err = _DBC_get(self->dbc, &key, &data, flags|DB_SET_RANGE);
MYDB_END_ALLOW_THREADS;
if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
&& self->mydb->moduleFlags.cursorSetReturnsNone) {
@@ -3432,22 +3646,19 @@
case DB_BTREE:
case DB_HASH:
default:
- retval = Py_BuildValue("s#s#", key.data, key.size,
- data.data, data.size);
+ retval = BuildValue_SS(key.data, key.size, data.data, data.size);
break;
case DB_RECNO:
case DB_QUEUE:
- retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
- data.data, data.size);
+ retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
break;
}
- FREE_DBT(key);
- FREE_DBT(data);
+ FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
}
/* the only time REALLOC should be set is if we used an integer
* key that make_key_dbt malloc'd for us. always free these. */
if (key.flags & DB_DBT_REALLOC) {
- FREE_DBT(key);
+ FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
}
return retval;
@@ -3465,12 +3676,12 @@
if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
return NULL;
if (!make_dbt(dataobj, &data)) {
- FREE_DBT(key);
+ FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
return NULL;
}
MYDB_BEGIN_ALLOW_THREADS;
- err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_GET_BOTH);
+ err = _DBC_get(self->dbc, &key, &data, flags|DB_GET_BOTH);
MYDB_END_ALLOW_THREADS;
if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && returnsNone) {
Py_INCREF(Py_None);
@@ -3487,18 +3698,16 @@
case DB_BTREE:
case DB_HASH:
default:
- retval = Py_BuildValue("s#s#", key.data, key.size,
- data.data, data.size);
+ retval = BuildValue_SS(key.data, key.size, data.data, data.size);
break;
case DB_RECNO:
case DB_QUEUE:
- retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
- data.data, data.size);
+ retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
break;
}
}
- FREE_DBT(key);
+ FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
return retval;
}
@@ -3537,7 +3746,7 @@
data.flags = DB_DBT_USERMEM;
data.ulen = 0;
MYDB_BEGIN_ALLOW_THREADS;
- err = self->dbc->c_get(self->dbc, &key, &data, flags);
+ err = _DBC_get(self->dbc, &key, &data, flags);
MYDB_END_ALLOW_THREADS;
if (err == DB_BUFFER_SMALL || !err) {
/* DB_BUFFER_SMALL means positive size, !err means zero length value */
@@ -3545,8 +3754,6 @@
err = 0;
}
- FREE_DBT(key);
- FREE_DBT(data);
RETURN_IF_ERR();
return retval;
}
@@ -3600,17 +3807,13 @@
key.flags = DB_DBT_REALLOC;
CLEAR_DBT(data);
- if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
- /* Tell BerkeleyDB to malloc the return value (thread safe) */
- data.flags = DB_DBT_MALLOC;
- }
if (!add_partial_dbt(&data, dlen, doff)) {
FREE_DBT(key);
return NULL;
}
MYDB_BEGIN_ALLOW_THREADS;
- err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET_RECNO);
+ err = _DBC_get(self->dbc, &key, &data, flags|DB_SET_RECNO);
MYDB_END_ALLOW_THREADS;
if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
&& self->mydb->moduleFlags.cursorSetReturnsNone) {
@@ -3621,9 +3824,7 @@
retval = NULL;
}
else { /* Can only be used for BTrees, so no need to return int key */
- retval = Py_BuildValue("s#s#", key.data, key.size,
- data.data, data.size);
- FREE_DBT(data);
+ retval = BuildValue_SS(key.data, key.size, data.data, data.size);
}
FREE_DBT(key);
@@ -3673,13 +3874,9 @@
CLEAR_DBT(key);
CLEAR_DBT(data);
- if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
- /* Tell BerkeleyDB to malloc the return value (thread safe) */
- key.flags = DB_DBT_MALLOC;
- }
MYDB_BEGIN_ALLOW_THREADS;
- err = self->dbc->c_get(self->dbc, &key, &data, flags | DB_JOIN_ITEM);
+ err = _DBC_get(self->dbc, &key, &data, flags | DB_JOIN_ITEM);
MYDB_END_ALLOW_THREADS;
if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
&& self->mydb->moduleFlags.getReturnsNone) {
@@ -3690,8 +3887,7 @@
retval = NULL;
}
else {
- retval = Py_BuildValue("s#", key.data, key.size);
- FREE_DBT(key);
+ retval = BuildValue_S(key.data, key.size);
}
return retval;
@@ -3704,18 +3900,26 @@
static PyObject*
-DBEnv_close(DBEnvObject* self, PyObject* args)
+DBEnv_close_internal(DBEnvObject* self, int flags)
{
- int err, flags = 0;
+ PyObject *dummy;
+ int err;
- if (!PyArg_ParseTuple(args, "|i:close", &flags))
- return NULL;
if (!self->closed) { /* Don't close more than once */
+ while(self->children_txns) {
+ dummy=DBTxn_abort_discard_internal(self->children_txns,0);
+ Py_XDECREF(dummy);
+ }
+ while(self->children_dbs) {
+ dummy=DB_close_internal(self->children_dbs,0);
+ Py_XDECREF(dummy);
+ }
+
MYDB_BEGIN_ALLOW_THREADS;
err = self->db_env->close(self->db_env, flags);
MYDB_END_ALLOW_THREADS;
/* after calling DBEnv->close, regardless of error, this DBEnv
- * may not be accessed again (BerkeleyDB docs). */
+ * may not be accessed again (Berkeley DB docs). */
self->closed = 1;
self->db_env = NULL;
RETURN_IF_ERR();
@@ -3723,6 +3927,16 @@
RETURN_NONE();
}
+static PyObject*
+DBEnv_close(DBEnvObject* self, PyObject* args)
+{
+ int flags = 0;
+
+ if (!PyArg_ParseTuple(args, "|i:close", &flags))
+ return NULL;
+ return DBEnv_close_internal(self,flags);
+}
+
static PyObject*
DBEnv_open(DBEnvObject* self, PyObject* args)
@@ -3982,8 +4196,27 @@
RETURN_NONE();
}
-
-#if (DBVER >= 33)
+#if (DBVER >= 42)
+static PyObject*
+DBEnv_get_lg_max(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ u_int32_t lg_max;
+
+ if (!PyArg_ParseTuple(args, ":get_lg_max"))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->get_lg_max(self->db_env, &lg_max);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ return PyInt_FromLong(lg_max);
+}
+#endif
+
+
+#if (DBVER >= 33)
static PyObject*
DBEnv_set_lg_regionmax(DBEnvObject* self, PyObject* args)
{
@@ -4125,6 +4358,84 @@
}
+#if (DBVER >= 40)
+static PyObject*
+DBEnv_txn_recover(DBEnvObject* self, PyObject* args)
+{
+ int flags = DB_FIRST;
+ int err, i;
+ PyObject *list, *tuple, *gid;
+ DBTxnObject *txn;
+#define PREPLIST_LEN 16
+ DB_PREPLIST preplist[PREPLIST_LEN];
+ long retp;
+
+ if (!PyArg_ParseTuple(args, ":txn_recover"))
+ return NULL;
+
+ CHECK_ENV_NOT_CLOSED(self);
+
+ list=PyList_New(0);
+ if (!list)
+ return NULL;
+ while (!0) {
+ MYDB_BEGIN_ALLOW_THREADS
+ err=self->db_env->txn_recover(self->db_env,
+ preplist, PREPLIST_LEN, &retp, flags);
+#undef PREPLIST_LEN
+ MYDB_END_ALLOW_THREADS
+ if (err) {
+ Py_DECREF(list);
+ RETURN_IF_ERR();
+ }
+ if (!retp) break;
+ flags=DB_NEXT; /* Prepare for next loop pass */
+ for (i=0; i<retp; i++) {
+ gid=PyString_FromStringAndSize((char *)(preplist[i].gid),
+ DB_XIDDATASIZE);
+ if (!gid) {
+ Py_DECREF(list);
+ return NULL;
+ }
+ txn=newDBTxnObject(self, NULL, preplist[i].txn, flags);
+ if (!txn) {
+ Py_DECREF(list);
+ Py_DECREF(gid);
+ return NULL;
+ }
+ txn->flag_prepare=1; /* Recover state */
+ tuple=PyTuple_New(2);
+ if (!tuple) {
+ Py_DECREF(list);
+ Py_DECREF(gid);
+ Py_DECREF(txn);
+ return NULL;
+ }
+ if (PyTuple_SetItem(tuple, 0, gid)) {
+ Py_DECREF(list);
+ Py_DECREF(gid);
+ Py_DECREF(txn);
+ Py_DECREF(tuple);
+ return NULL;
+ }
+ if (PyTuple_SetItem(tuple, 1, (PyObject *)txn)) {
+ Py_DECREF(list);
+ Py_DECREF(txn);
+ Py_DECREF(tuple); /* This delete the "gid" also */
+ return NULL;
+ }
+ if (PyList_Append(list, tuple)) {
+ Py_DECREF(list);
+ Py_DECREF(tuple);/* This delete the "gid" and the "txn" also */
+ return NULL;
+ }
+ Py_DECREF(tuple);
+ }
+ }
+ return list;
+}
+#endif
+
static PyObject*
DBEnv_txn_begin(DBEnvObject* self, PyObject* args, PyObject* kwargs)
{
@@ -4141,7 +4452,7 @@
return NULL;
CHECK_ENV_NOT_CLOSED(self);
- return (PyObject*)newDBTxnObject(self, txn, flags);
+ return (PyObject*)newDBTxnObject(self, (DBTxnObject *)txnobj, NULL, flags);
}
@@ -4426,6 +4737,10 @@
#if (DBVER < 41)
MAKE_ENTRY(lastid);
#endif
+#if (DBVER >=41)
+ MAKE_ENTRY(id);
+ MAKE_ENTRY(cur_maxid);
+#endif
MAKE_ENTRY(nmodes);
MAKE_ENTRY(maxlocks);
MAKE_ENTRY(maxlockers);
@@ -4438,6 +4753,10 @@
MAKE_ENTRY(maxnobjects);
MAKE_ENTRY(nrequests);
MAKE_ENTRY(nreleases);
+#if (DBVER >= 44)
+ MAKE_ENTRY(nupgrade);
+ MAKE_ENTRY(ndowngrade);
+#endif
#if (DBVER < 44)
MAKE_ENTRY(nnowaits); /* these were renamed in 4.4 */
MAKE_ENTRY(nconflicts);
@@ -4446,6 +4765,23 @@
MAKE_ENTRY(lock_wait);
#endif
MAKE_ENTRY(ndeadlocks);
+#if (DBVER >= 41)
+ MAKE_ENTRY(locktimeout);
+ MAKE_ENTRY(txntimeout);
+#endif
+#if (DBVER >= 40)
+ MAKE_ENTRY(nlocktimeouts);
+ MAKE_ENTRY(ntxntimeouts);
+#endif
+#if (DBVER >= 46)
+ MAKE_ENTRY(objs_wait);
+ MAKE_ENTRY(objs_nowait);
+ MAKE_ENTRY(lockers_wait);
+ MAKE_ENTRY(lockers_nowait);
+ MAKE_ENTRY(locks_wait);
+ MAKE_ENTRY(locks_nowait);
+ MAKE_ENTRY(hash_len);
+#endif
MAKE_ENTRY(regsize);
MAKE_ENTRY(region_wait);
MAKE_ENTRY(region_nowait);
@@ -4455,130 +4791,653 @@
return d;
}
+#if (DBVER >= 40)
+static PyObject*
+DBEnv_log_flush(DBEnvObject* self, PyObject* args)
+{
+ int err;
+
+ if (!PyArg_ParseTuple(args, ":log_flush"))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS
+ err = self->db_env->log_flush(self->db_env, NULL);
+ MYDB_END_ALLOW_THREADS
+
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+#endif
static PyObject*
DBEnv_log_archive(DBEnvObject* self, PyObject* args)
{
- int flags=0;
+ int flags=0;
+ int err;
+ char **log_list = NULL;
+ PyObject* list;
+ PyObject* item = NULL;
+
+ if (!PyArg_ParseTuple(args, "|i:log_archive", &flags))
+ return NULL;
+
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+ err = self->db_env->log_archive(self->db_env, &log_list, flags);
+#elif (DBVER == 33)
+ err = log_archive(self->db_env, &log_list, flags);
+#else
+ err = log_archive(self->db_env, &log_list, flags, NULL);
+#endif
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+
+ list = PyList_New(0);
+ if (list == NULL) {
+ if (log_list)
+ free(log_list);
+ return NULL;
+ }
+
+ if (log_list) {
+ char **log_list_start;
+ for (log_list_start = log_list; *log_list != NULL; ++log_list) {
+ item = PyString_FromString (*log_list);
+ if (item == NULL) {
+ Py_DECREF(list);
+ list = NULL;
+ break;
+ }
+ PyList_Append(list, item);
+ Py_DECREF(item);
+ }
+ free(log_list_start);
+ }
+ return list;
+}
+
+
+static PyObject*
+DBEnv_txn_stat(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ DB_TXN_STAT* sp;
+ PyObject* d = NULL;
+ u_int32_t flags=0;
+
+ if (!PyArg_ParseTuple(args, "|i:txn_stat", &flags))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ MYDB_BEGIN_ALLOW_THREADS;
+#if (DBVER >= 40)
+ err = self->db_env->txn_stat(self->db_env, &sp, flags);
+#elif (DBVER == 33)
+ err = txn_stat(self->db_env, &sp);
+#else
+ err = txn_stat(self->db_env, &sp, NULL);
+#endif
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+
+ /* Turn the stat structure into a dictionary */
+ d = PyDict_New();
+ if (d == NULL) {
+ free(sp);
+ return NULL;
+ }
+
+#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
+#define MAKE_TIME_T_ENTRY(name) _addTimeTToDict(d, #name, sp->st_##name)
+#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(d, #name, sp->st_##name)
+
+#if (DBVER >= 40)
+ MAKE_DB_LSN_ENTRY(last_ckp);
+#endif
+ MAKE_TIME_T_ENTRY(time_ckp);
+ MAKE_ENTRY(last_txnid);
+ MAKE_ENTRY(maxtxns);
+ MAKE_ENTRY(nactive);
+ MAKE_ENTRY(maxnactive);
+#if (DBVER >= 45)
+ MAKE_ENTRY(nsnapshot);
+ MAKE_ENTRY(maxnsnapshot);
+#endif
+ MAKE_ENTRY(nbegins);
+ MAKE_ENTRY(naborts);
+ MAKE_ENTRY(ncommits);
+#if (DBVER >= 40)
+ MAKE_ENTRY(nrestores);
+#endif
+ MAKE_ENTRY(regsize);
+ MAKE_ENTRY(region_wait);
+ MAKE_ENTRY(region_nowait);
+
+#undef MAKE_DB_LSN_ENTRY
+#undef MAKE_ENTRY
+#undef MAKE_TIME_T_ENTRY
+ free(sp);
+ return d;
+}
+
+
+static PyObject*
+DBEnv_set_get_returns_none(DBEnvObject* self, PyObject* args)
+{
+ int flags=0;
+ int oldValue=0;
+
+ if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
+ return NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+
+ if (self->moduleFlags.getReturnsNone)
+ ++oldValue;
+ if (self->moduleFlags.cursorSetReturnsNone)
+ ++oldValue;
+ self->moduleFlags.getReturnsNone = (flags >= 1);
+ self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
+ return PyInt_FromLong(oldValue);
+}
+
+#if (DBVER >= 40)
+static PyObject*
+DBEnv_set_verbose(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ int which, onoff;
+
+ if (!PyArg_ParseTuple(args, "ii:set_verbose", &which, &onoff)) {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->set_verbose(self->db_env, which, onoff);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+#if (DBVER >= 42)
+static PyObject*
+DBEnv_get_verbose(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ int which;
+ int verbose;
+
+ if (!PyArg_ParseTuple(args, "i:get_verbose", &which)) {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->get_verbose(self->db_env, which, &verbose);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ return PyBool_FromLong(verbose);
+}
+#endif
+#endif
+
+#if (DBVER >= 45)
+static void
+_dbenv_event_notifyCallback(DB_ENV* db_env, u_int32_t event, void *event_info)
+{
+ DBEnvObject *dbenv;
+ PyObject* callback;
+ PyObject* args;
+ PyObject* result = NULL;
+
+ MYDB_BEGIN_BLOCK_THREADS;
+ dbenv = (DBEnvObject *)db_env->app_private;
+ callback = dbenv->event_notifyCallback;
+ if (callback) {
+ if (event == DB_EVENT_REP_NEWMASTER) {
+ args = Py_BuildValue("(Oii)", dbenv, event, *((int *)event_info));
+ } else {
+ args = Py_BuildValue("(OiO)", dbenv, event, Py_None);
+ }
+ if (args) {
+ result = PyEval_CallObject(callback, args);
+ }
+ if ((!args) || (!result)) {
+ PyErr_Print();
+ }
+ Py_XDECREF(args);
+ Py_XDECREF(result);
+ }
+ MYDB_END_BLOCK_THREADS;
+}
+#endif
+
+#if (DBVER >= 45)
+static PyObject*
+DBEnv_set_event_notify(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ PyObject *notifyFunc;
+
+ if (!PyArg_ParseTuple(args, "O:set_event_notify", ¬ifyFunc)) {
+ return NULL;
+ }
+
+ CHECK_ENV_NOT_CLOSED(self);
+
+ if (!PyCallable_Check(notifyFunc)) {
+ makeTypeError("Callable", notifyFunc);
+ return NULL;
+ }
+
+ Py_XDECREF(self->event_notifyCallback);
+ Py_INCREF(notifyFunc);
+ self->event_notifyCallback = notifyFunc;
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->set_event_notify(self->db_env, _dbenv_event_notifyCallback);
+ MYDB_END_ALLOW_THREADS;
+
+ if (err) {
+ Py_DECREF(notifyFunc);
+ self->event_notifyCallback = NULL;
+ }
+
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+#endif
+
+
+/* --------------------------------------------------------------------- */
+/* REPLICATION METHODS: Base Replication */
+
+#if (DBVER >= 45)
+static PyObject*
+DBEnv_rep_set_nsites(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ int nsites;
+
+ if (!PyArg_ParseTuple(args, "i:rep_set_nsites", &nsites)) {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->rep_set_nsites(self->db_env, nsites);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DBEnv_rep_get_nsites(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ int nsites;
+
+ if (!PyArg_ParseTuple(args, ":rep_get_nsites")) {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->rep_get_nsites(self->db_env, &nsites);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ return PyInt_FromLong(nsites);
+}
+
+static PyObject*
+DBEnv_rep_set_priority(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ int priority;
+
+ if (!PyArg_ParseTuple(args, "i:rep_set_priority", &priority)) {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->rep_set_priority(self->db_env, priority);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DBEnv_rep_get_priority(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ int priority;
+
+ if (!PyArg_ParseTuple(args, ":rep_get_priority")) {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->rep_get_priority(self->db_env, &priority);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ return PyInt_FromLong(priority);
+}
+
+static PyObject*
+DBEnv_rep_set_timeout(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ int which, timeout;
+
+ if (!PyArg_ParseTuple(args, "ii:rep_set_timeout", &which, &timeout)) {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->rep_set_timeout(self->db_env, which, timeout);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DBEnv_rep_get_timeout(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ int which;
+ u_int32_t timeout;
+
+ if (!PyArg_ParseTuple(args, "i:rep_get_timeout", &which)) {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->rep_get_timeout(self->db_env, which, &timeout);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ return PyInt_FromLong(timeout);
+}
+#endif
+
+/* --------------------------------------------------------------------- */
+/* REPLICATION METHODS: Replication Manager */
+
+#if (DBVER >= 45)
+static PyObject*
+DBEnv_repmgr_start(DBEnvObject* self, PyObject* args, PyObject*
+ kwargs)
+{
+ int err;
+ int nthreads, flags;
+ static char* kwnames[] = {"nthreads","flags", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "ii:repmgr_start", kwnames, &nthreads, &flags))
+ {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->repmgr_start(self->db_env, nthreads, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DBEnv_repmgr_set_local_site(DBEnvObject* self, PyObject* args, PyObject*
+ kwargs)
+{
+ int err;
+ char *host;
+ int port;
+ int flags = 0;
+ static char* kwnames[] = {"host", "port", "flags", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "si|i:repmgr_set_local_site", kwnames, &host, &port, &flags))
+ {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->repmgr_set_local_site(self->db_env, host, port, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DBEnv_repmgr_add_remote_site(DBEnvObject* self, PyObject* args, PyObject*
+ kwargs)
+{
+ int err;
+ char *host;
+ int port;
+ int flags = 0;
+ int eidp;
+ static char* kwnames[] = {"host", "port", "flags", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "si|i:repmgr_add_remote_site", kwnames, &host, &port, &flags))
+ {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->repmgr_add_remote_site(self->db_env, host, port, &eidp, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ return PyInt_FromLong(eidp);
+}
+
+static PyObject*
+DBEnv_repmgr_set_ack_policy(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ int ack_policy;
+
+ if (!PyArg_ParseTuple(args, "i:repmgr_set_ack_policy", &ack_policy))
+ {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->repmgr_set_ack_policy(self->db_env, ack_policy);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DBEnv_repmgr_get_ack_policy(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ int ack_policy;
+
+ if (!PyArg_ParseTuple(args, ":repmgr_get_ack_policy"))
+ {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->repmgr_get_ack_policy(self->db_env, &ack_policy);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ return PyInt_FromLong(ack_policy);
+}
+
+static PyObject*
+DBEnv_repmgr_site_list(DBEnvObject* self, PyObject* args)
+{
int err;
- char **log_list = NULL;
- PyObject* list;
- PyObject* item = NULL;
+ unsigned int countp;
+ DB_REPMGR_SITE *listp;
+ PyObject *stats, *key, *tuple;
- if (!PyArg_ParseTuple(args, "|i:log_archive", &flags))
+ if (!PyArg_ParseTuple(args, ":repmgr_site_list"))
+ {
return NULL;
-
+ }
CHECK_ENV_NOT_CLOSED(self);
MYDB_BEGIN_ALLOW_THREADS;
-#if (DBVER >= 40)
- err = self->db_env->log_archive(self->db_env, &log_list, flags);
-#elif (DBVER == 33)
- err = log_archive(self->db_env, &log_list, flags);
-#else
- err = log_archive(self->db_env, &log_list, flags, NULL);
-#endif
+ err = self->db_env->repmgr_site_list(self->db_env, &countp, &listp);
MYDB_END_ALLOW_THREADS;
RETURN_IF_ERR();
- list = PyList_New(0);
- if (list == NULL) {
- if (log_list)
- free(log_list);
+ stats=PyDict_New();
+ if (stats == NULL) {
+ free(listp);
return NULL;
}
- if (log_list) {
- char **log_list_start;
- for (log_list_start = log_list; *log_list != NULL; ++log_list) {
- item = PyString_FromString (*log_list);
- if (item == NULL) {
- Py_DECREF(list);
- list = NULL;
- break;
- }
- PyList_Append(list, item);
- Py_DECREF(item);
+ for(;countp--;) {
+ key=PyInt_FromLong(listp[countp].eid);
+ if(!key) {
+ Py_DECREF(stats);
+ free(listp);
+ return NULL;
+ }
+#if (PY_VERSION_HEX >= 0x02040000)
+ tuple=Py_BuildValue("(sII)", listp[countp].host,
+ listp[countp].port, listp[countp].status);
+#else
+ tuple=Py_BuildValue("(sii)", listp[countp].host,
+ listp[countp].port, listp[countp].status);
+#endif
+ if(!tuple) {
+ Py_DECREF(key);
+ Py_DECREF(stats);
+ free(listp);
+ return NULL;
+ }
+ if(PyDict_SetItem(stats, key, tuple)) {
+ Py_DECREF(key);
+ Py_DECREF(tuple);
+ Py_DECREF(stats);
+ free(listp);
+ return NULL;
}
- free(log_list_start);
}
- return list;
+ free(listp);
+ return stats;
}
+#endif
-
+#if (DBVER >= 46)
static PyObject*
-DBEnv_txn_stat(DBEnvObject* self, PyObject* args)
+DBEnv_repmgr_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
{
int err;
- DB_TXN_STAT* sp;
- PyObject* d = NULL;
- u_int32_t flags=0;
+ int flags=0;
+ static char* kwnames[] = { "flags", NULL };
- if (!PyArg_ParseTuple(args, "|i:txn_stat", &flags))
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat_print",
+ kwnames, &flags))
+ {
return NULL;
+ }
CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->repmgr_stat_print(self->db_env, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+static PyObject*
+DBEnv_repmgr_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
+{
+ int err;
+ int flags=0;
+ DB_REPMGR_STAT *statp;
+ PyObject *stats;
+ static char* kwnames[] = { "flags", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat",
+ kwnames, &flags))
+ {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
MYDB_BEGIN_ALLOW_THREADS;
-#if (DBVER >= 40)
- err = self->db_env->txn_stat(self->db_env, &sp, flags);
-#elif (DBVER == 33)
- err = txn_stat(self->db_env, &sp);
-#else
- err = txn_stat(self->db_env, &sp, NULL);
-#endif
+ err = self->db_env->repmgr_stat(self->db_env, &statp, flags);
MYDB_END_ALLOW_THREADS;
RETURN_IF_ERR();
- /* Turn the stat structure into a dictionary */
- d = PyDict_New();
- if (d == NULL) {
- free(sp);
+ stats=PyDict_New();
+ if (stats == NULL) {
+ free(statp);
return NULL;
}
-#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
-#define MAKE_TIME_T_ENTRY(name)_addTimeTToDict(d, #name, sp->st_##name)
+#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
- MAKE_TIME_T_ENTRY(time_ckp);
- MAKE_ENTRY(last_txnid);
- MAKE_ENTRY(maxtxns);
- MAKE_ENTRY(nactive);
- MAKE_ENTRY(maxnactive);
- MAKE_ENTRY(nbegins);
- MAKE_ENTRY(naborts);
- MAKE_ENTRY(ncommits);
- MAKE_ENTRY(regsize);
- MAKE_ENTRY(region_wait);
- MAKE_ENTRY(region_nowait);
+ MAKE_ENTRY(perm_failed);
+ MAKE_ENTRY(msgs_queued);
+ MAKE_ENTRY(msgs_dropped);
+ MAKE_ENTRY(connection_drop);
+ MAKE_ENTRY(connect_fail);
#undef MAKE_ENTRY
-#undef MAKE_TIME_T_ENTRY
- free(sp);
- return d;
+
+ free(statp);
+ return stats;
}
+#endif
-static PyObject*
-DBEnv_set_get_returns_none(DBEnvObject* self, PyObject* args)
-{
- int flags=0;
- int oldValue=0;
+/* --------------------------------------------------------------------- */
+/* DBTxn methods */
- if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
- return NULL;
- CHECK_ENV_NOT_CLOSED(self);
- if (self->moduleFlags.getReturnsNone)
- ++oldValue;
- if (self->moduleFlags.cursorSetReturnsNone)
- ++oldValue;
- self->moduleFlags.getReturnsNone = (flags >= 1);
- self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
- return PyInt_FromLong(oldValue);
+static void _close_transaction_cursors(DBTxnObject* txn)
+{
+ PyObject *dummy;
+
+ while(txn->children_cursors) {
+ PyErr_Warn(PyExc_RuntimeWarning,
+ "Must close cursors before resolving a transaction.");
+ dummy=DBC_close_internal(txn->children_cursors);
+ Py_XDECREF(dummy);
+ }
}
+static void _promote_transaction_dbs_and_sequences(DBTxnObject *txn)
+{
+ DBObject *db;
+#if (DBVER >= 43)
+ DBSequenceObject *dbs;
+#endif
-/* --------------------------------------------------------------------- */
-/* DBTxn methods */
+ while (txn->children_dbs) {
+ db=txn->children_dbs;
+ EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(db);
+ if (txn->parent_txn) {
+ INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_dbs,db);
+ db->txn=txn->parent_txn;
+ } else {
+ /* The db is already linked to its environment,
+ ** so nothing to do.
+ */
+ db->txn=NULL;
+ }
+ }
+
+#if (DBVER >= 43)
+ while (txn->children_sequences) {
+ dbs=txn->children_sequences;
+ EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(dbs);
+ if (txn->parent_txn) {
+ INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_sequences,dbs);
+ dbs->txn=txn->parent_txn;
+ } else {
+ /* The sequence is already linked to its
+ ** parent db. Nothing to do.
+ */
+ dbs->txn=NULL;
+ }
+ }
+#endif
+}
static PyObject*
@@ -4590,15 +5449,22 @@
if (!PyArg_ParseTuple(args, "|i:commit", &flags))
return NULL;
+ _close_transaction_cursors(self);
+
if (!self->txn) {
PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
- "after txn_commit or txn_abort");
+ "after txn_commit, txn_abort "
+ "or txn_discard");
PyErr_SetObject(DBError, t);
Py_DECREF(t);
return NULL;
}
+ self->flag_prepare=0;
txn = self->txn;
self->txn = NULL; /* this DB_TXN is no longer valid after this call */
+
+ EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
+
MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
err = txn->commit(txn, flags);
@@ -4606,6 +5472,9 @@
err = txn_commit(txn, flags);
#endif
MYDB_END_ALLOW_THREADS;
+
+ _promote_transaction_dbs_and_sequences(self);
+
RETURN_IF_ERR();
RETURN_NONE();
}
@@ -4629,11 +5498,13 @@
if (!self->txn) {
PyObject *t = Py_BuildValue("(is)", 0,"DBTxn must not be used "
- "after txn_commit or txn_abort");
+ "after txn_commit, txn_abort "
+ "or txn_discard");
PyErr_SetObject(DBError, t);
Py_DECREF(t);
return NULL;
}
+ self->flag_prepare=1; /* Prepare state */
MYDB_BEGIN_ALLOW_THREADS;
#if (DBVER >= 40)
err = self->txn->prepare(self->txn, (u_int8_t*)gid);
@@ -4651,7 +5522,8 @@
if (!self->txn) {
PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
- "after txn_commit or txn_abort");
+ "after txn_commit, txn_abort "
+ "or txn_discard");
PyErr_SetObject(DBError, t);
Py_DECREF(t);
return NULL;
@@ -4666,34 +5538,87 @@
static PyObject*
-DBTxn_abort(DBTxnObject* self, PyObject* args)
+DBTxn_abort_discard_internal(DBTxnObject* self, int discard)
{
- int err;
+ PyObject *dummy;
+ int err=0;
DB_TXN *txn;
- if (!PyArg_ParseTuple(args, ":abort"))
- return NULL;
-
if (!self->txn) {
PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
- "after txn_commit or txn_abort");
+ "after txn_commit, txn_abort "
+ "or txn_discard");
PyErr_SetObject(DBError, t);
Py_DECREF(t);
return NULL;
}
txn = self->txn;
self->txn = NULL; /* this DB_TXN is no longer valid after this call */
+
+ _close_transaction_cursors(self);
+#if (DBVER >= 43)
+ while (self->children_sequences) {
+ dummy=DBSequence_close_internal(self->children_sequences,0,0);
+ Py_XDECREF(dummy);
+ }
+#endif
+ while (self->children_dbs) {
+ dummy=DB_close_internal(self->children_dbs,0);
+ Py_XDECREF(dummy);
+ }
+
+ EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
+
MYDB_BEGIN_ALLOW_THREADS;
+ if (discard) {
+ assert(!self->flag_prepare);
+#if (DBVER >= 40)
+ err = txn->discard(txn,0);
+#else
+ err = txn_discard(txn);
+#endif
+ } else {
+ /*
+ ** If the transaction is in the "prepare" or "recover" state,
+ ** we better do not implicitly abort it.
+ */
+ if (!self->flag_prepare) {
#if (DBVER >= 40)
- err = txn->abort(txn);
+ err = txn->abort(txn);
#else
- err = txn_abort(txn);
+ err = txn_abort(txn);
#endif
+ }
+ }
MYDB_END_ALLOW_THREADS;
RETURN_IF_ERR();
RETURN_NONE();
}
+static PyObject*
+DBTxn_abort(DBTxnObject* self, PyObject* args)
+{
+ if (!PyArg_ParseTuple(args, ":abort"))
+ return NULL;
+
+ self->flag_prepare=0;
+ _close_transaction_cursors(self);
+
+ return DBTxn_abort_discard_internal(self,0);
+}
+
+static PyObject*
+DBTxn_discard(DBTxnObject* self, PyObject* args)
+{
+ if (!PyArg_ParseTuple(args, ":discard"))
+ return NULL;
+
+ self->flag_prepare=0;
+ _close_transaction_cursors(self);
+
+ return DBTxn_abort_discard_internal(self,1);
+}
+
static PyObject*
DBTxn_id(DBTxnObject* self, PyObject* args)
@@ -4705,7 +5630,8 @@
if (!self->txn) {
PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
- "after txn_commit or txn_abort");
+ "after txn_commit, txn_abort "
+ "or txn_discard");
PyErr_SetObject(DBError, t);
Py_DECREF(t);
return NULL;
@@ -4726,24 +5652,41 @@
static PyObject*
-DBSequence_close(DBSequenceObject* self, PyObject* args)
+DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close)
{
- int err, flags=0;
- if (!PyArg_ParseTuple(args,"|i:close", &flags))
- return NULL;
- CHECK_SEQUENCE_NOT_CLOSED(self)
+ int err=0;
- MYDB_BEGIN_ALLOW_THREADS
- err = self->sequence->close(self->sequence, flags);
- self->sequence = NULL;
- MYDB_END_ALLOW_THREADS
+ if (self->sequence!=NULL) {
+ EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
+ if (self->txn) {
+ EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
+ self->txn=NULL;
+ }
- RETURN_IF_ERR();
+ if (!do_not_close) {
+ MYDB_BEGIN_ALLOW_THREADS
+ err = self->sequence->close(self->sequence, flags);
+ MYDB_END_ALLOW_THREADS
+ }
+ self->sequence = NULL;
+
+ RETURN_IF_ERR();
+ }
RETURN_NONE();
}
static PyObject*
+DBSequence_close(DBSequenceObject* self, PyObject* args)
+{
+ int flags=0;
+ if (!PyArg_ParseTuple(args,"|i:close", &flags))
+ return NULL;
+
+ return DBSequence_close_internal(self,flags,0);
+}
+
+static PyObject*
DBSequence_get(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
{
int err, flags = 0;
@@ -4765,7 +5708,6 @@
RETURN_IF_ERR();
return PyLong_FromLongLong(value);
-
}
static PyObject*
@@ -4784,6 +5726,10 @@
int err;
DBT key;
PyObject *retval = NULL;
+
+ if (!PyArg_ParseTuple(args,":get_key"))
+ return NULL;
+
key.flags = DB_DBT_MALLOC;
CHECK_SEQUENCE_NOT_CLOSED(self)
MYDB_BEGIN_ALLOW_THREADS
@@ -4791,7 +5737,7 @@
MYDB_END_ALLOW_THREADS
if (!err)
- retval = PyString_FromStringAndSize(key.data, key.size);
+ retval = Build_PyString(key.data, key.size);
FREE_DBT(key);
RETURN_IF_ERR();
@@ -4803,13 +5749,15 @@
DBSequence_init_value(DBSequenceObject* self, PyObject* args)
{
int err;
- db_seq_t value;
+ PY_LONG_LONG value;
+ db_seq_t value2;
if (!PyArg_ParseTuple(args,"L:init_value", &value))
return NULL;
CHECK_SEQUENCE_NOT_CLOSED(self)
+ value2=value; /* If truncation, compiler should show a warning */
MYDB_BEGIN_ALLOW_THREADS
- err = self->sequence->initial_value(self->sequence, value);
+ err = self->sequence->initial_value(self->sequence, value2);
MYDB_END_ALLOW_THREADS
RETURN_IF_ERR();
@@ -4843,12 +5791,18 @@
CLEAR_DBT(key);
RETURN_IF_ERR();
+ if (txn) {
+ INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_sequences,self);
+ self->txn=(DBTxnObject *)txnobj;
+ }
+
RETURN_NONE();
}
static PyObject*
DBSequence_remove(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
{
+ PyObject *dummy;
int err, flags = 0;
PyObject *txnobj = NULL;
DB_TXN *txn = NULL;
@@ -4866,6 +5820,9 @@
err = self->sequence->remove(self->sequence, txn, flags);
MYDB_END_ALLOW_THREADS
+ dummy=DBSequence_close_internal(self,flags,1);
+ Py_XDECREF(dummy);
+
RETURN_IF_ERR();
RETURN_NONE();
}
@@ -4916,7 +5873,6 @@
RETURN_IF_ERR();
RETURN_NONE();
-
}
static PyObject*
@@ -4940,13 +5896,16 @@
DBSequence_set_range(DBSequenceObject* self, PyObject* args)
{
int err;
- db_seq_t min, max;
+ PY_LONG_LONG min, max;
+ db_seq_t min2, max2;
if (!PyArg_ParseTuple(args,"(LL):set_range", &min, &max))
return NULL;
CHECK_SEQUENCE_NOT_CLOSED(self)
+ min2=min; /* If truncation, compiler should show a warning */
+ max2=max;
MYDB_BEGIN_ALLOW_THREADS
- err = self->sequence->set_range(self->sequence, min, max);
+ err = self->sequence->set_range(self->sequence, min2, max2);
MYDB_END_ALLOW_THREADS
RETURN_IF_ERR();
@@ -4957,16 +5916,19 @@
DBSequence_get_range(DBSequenceObject* self, PyObject* args)
{
int err;
- db_seq_t min, max;
+ PY_LONG_LONG min, max;
+ db_seq_t min2, max2;
if (!PyArg_ParseTuple(args,":get_range"))
return NULL;
CHECK_SEQUENCE_NOT_CLOSED(self)
MYDB_BEGIN_ALLOW_THREADS
- err = self->sequence->get_range(self->sequence, &min, &max);
+ err = self->sequence->get_range(self->sequence, &min2, &max2);
MYDB_END_ALLOW_THREADS
RETURN_IF_ERR();
+ min=min2; /* If truncation, compiler should show a warning */
+ max=max2;
return Py_BuildValue("(LL)", min, max);
}
@@ -5134,6 +6096,9 @@
{"set_lg_bsize", (PyCFunction)DBEnv_set_lg_bsize, METH_VARARGS},
{"set_lg_dir", (PyCFunction)DBEnv_set_lg_dir, METH_VARARGS},
{"set_lg_max", (PyCFunction)DBEnv_set_lg_max, METH_VARARGS},
+#if (DBVER >= 42)
+ {"get_lg_max", (PyCFunction)DBEnv_get_lg_max, METH_VARARGS},
+#endif
#if (DBVER >= 33)
{"set_lg_regionmax",(PyCFunction)DBEnv_set_lg_regionmax, METH_VARARGS},
#endif
@@ -5161,12 +6126,55 @@
{"lock_stat", (PyCFunction)DBEnv_lock_stat, METH_VARARGS},
{"log_archive", (PyCFunction)DBEnv_log_archive, METH_VARARGS},
#if (DBVER >= 40)
+ {"log_flush", (PyCFunction)DBEnv_log_flush, METH_VARARGS},
+#endif
+#if (DBVER >= 40)
{"log_stat", (PyCFunction)DBEnv_log_stat, METH_VARARGS},
#endif
#if (DBVER >= 44)
{"lsn_reset", (PyCFunction)DBEnv_lsn_reset, METH_VARARGS|METH_KEYWORDS},
#endif
{"set_get_returns_none",(PyCFunction)DBEnv_set_get_returns_none, METH_VARARGS},
+#if (DBVER >= 40)
+ {"txn_recover", (PyCFunction)DBEnv_txn_recover, METH_VARARGS},
+#endif
+#if (DBVER >= 40)
+ {"set_verbose", (PyCFunction)DBEnv_set_verbose, METH_VARARGS},
+#if (DBVER >= 42)
+ {"get_verbose", (PyCFunction)DBEnv_get_verbose, METH_VARARGS},
+#endif
+#endif
+#if (DBVER >= 45)
+ {"set_event_notify", (PyCFunction)DBEnv_set_event_notify, METH_VARARGS},
+#endif
+#if (DBVER >= 45)
+ {"rep_set_nsites", (PyCFunction)DBEnv_rep_set_nsites, METH_VARARGS},
+ {"rep_get_nsites", (PyCFunction)DBEnv_rep_get_nsites, METH_VARARGS},
+ {"rep_set_priority", (PyCFunction)DBEnv_rep_set_priority, METH_VARARGS},
+ {"rep_get_priority", (PyCFunction)DBEnv_rep_get_priority, METH_VARARGS},
+ {"rep_set_timeout", (PyCFunction)DBEnv_rep_set_timeout, METH_VARARGS},
+ {"rep_get_timeout", (PyCFunction)DBEnv_rep_get_timeout, METH_VARARGS},
+#endif
+#if (DBVER >= 45)
+ {"repmgr_start", (PyCFunction)DBEnv_repmgr_start,
+ METH_VARARGS|METH_KEYWORDS},
+ {"repmgr_set_local_site", (PyCFunction)DBEnv_repmgr_set_local_site,
+ METH_VARARGS|METH_KEYWORDS},
+ {"repmgr_add_remote_site", (PyCFunction)DBEnv_repmgr_add_remote_site,
+ METH_VARARGS|METH_KEYWORDS},
+ {"repmgr_set_ack_policy", (PyCFunction)DBEnv_repmgr_set_ack_policy,
+ METH_VARARGS},
+ {"repmgr_get_ack_policy", (PyCFunction)DBEnv_repmgr_get_ack_policy,
+ METH_VARARGS},
+ {"repmgr_site_list", (PyCFunction)DBEnv_repmgr_site_list,
+ METH_VARARGS},
+#endif
+#if (DBVER >= 46)
+ {"repmgr_stat", (PyCFunction)DBEnv_repmgr_stat,
+ METH_VARARGS|METH_KEYWORDS},
+ {"repmgr_stat_print", (PyCFunction)DBEnv_repmgr_stat_print,
+ METH_VARARGS|METH_KEYWORDS},
+#endif
{NULL, NULL} /* sentinel */
};
@@ -5174,6 +6182,7 @@
static PyMethodDef DBTxn_methods[] = {
{"commit", (PyCFunction)DBTxn_commit, METH_VARARGS},
{"prepare", (PyCFunction)DBTxn_prepare, METH_VARARGS},
+ {"discard", (PyCFunction)DBTxn_discard, METH_VARARGS},
{"abort", (PyCFunction)DBTxn_abort, METH_VARARGS},
{"id", (PyCFunction)DBTxn_id, METH_VARARGS},
{NULL, NULL} /* sentinel */
@@ -5212,11 +6221,17 @@
DBEnv_getattr(DBEnvObject* self, char *name)
{
if (!strcmp(name, "db_home")) {
- CHECK_ENV_NOT_CLOSED(self);
- if (self->db_env->db_home == NULL) {
- RETURN_NONE();
- }
- return PyString_FromString(self->db_env->db_home);
+ const char *home = NULL;
+ CHECK_ENV_NOT_CLOSED(self);
+#if (DBVER >= 42)
+ self->db_env->get_home(self->db_env, &home);
+#else
+ home=self->db_env->db_home;
+#endif
+ if (home == NULL) {
+ RETURN_NONE();
+ }
+ return PyString_FromString(home);
}
return Py_FindMethod(DBEnv_methods, (PyObject* )self, name);
@@ -5582,7 +6597,7 @@
ADD_INT(d, DB_RPCCLIENT);
#else
ADD_INT(d, DB_CLIENT);
- /* allow apps to be written using DB_RPCCLIENT on older BerkeleyDB */
+ /* allow apps to be written using DB_RPCCLIENT on older Berkeley DB */
_addIntToDict(d, "DB_RPCCLIENT", DB_CLIENT);
#endif
ADD_INT(d, DB_XA_CREATE);
@@ -5590,6 +6605,9 @@
ADD_INT(d, DB_CREATE);
ADD_INT(d, DB_NOMMAP);
ADD_INT(d, DB_THREAD);
+#if (DBVER >= 45)
+ ADD_INT(d, DB_MULTIVERSION);
+#endif
ADD_INT(d, DB_FORCE);
ADD_INT(d, DB_INIT_CDB);
@@ -5599,6 +6617,10 @@
ADD_INT(d, DB_INIT_TXN);
ADD_INT(d, DB_JOINENV);
+#if (DBVER >= 40)
+ ADD_INT(d, DB_XIDDATASIZE);
+#endif
+
ADD_INT(d, DB_RECOVER);
ADD_INT(d, DB_RECOVER_FATAL);
ADD_INT(d, DB_TXN_NOSYNC);
@@ -5645,6 +6667,13 @@
ADD_INT(d, DB_LOCK_MINWRITE);
#endif
+#if (DBVER >= 40)
+ ADD_INT(d, DB_LOCK_EXPIRE);
+#endif
+#if (DBVER >= 43)
+ ADD_INT(d, DB_LOCK_MAXWRITE);
+#endif
+
#if (DBVER >= 33)
/* docs say to use zero instead */
@@ -5816,6 +6845,10 @@
ADD_INT(d, DB_NOPANIC);
#endif
+#if (DBVER >= 41)
+ ADD_INT(d, DB_OVERWRITE);
+#endif
+
#ifdef DB_REGISTER
ADD_INT(d, DB_REGISTER);
#endif
@@ -5832,7 +6865,76 @@
ADD_INT(d, DB_CHKSUM);
#endif
+#if (DBVER >= 44)
+ ADD_INT(d, DB_DSYNC_DB);
+#endif
+
+#if (DBVER >= 45)
+ ADD_INT(d, DB_TXN_SNAPSHOT);
+#endif
+
+#if (DBVER >= 40)
+ ADD_INT(d, DB_VERB_DEADLOCK);
+#if (DBVER >= 46)
+ ADD_INT(d, DB_VERB_FILEOPS);
+ ADD_INT(d, DB_VERB_FILEOPS_ALL);
+#endif
+ ADD_INT(d, DB_VERB_RECOVERY);
+#if (DBVER >= 44)
+ ADD_INT(d, DB_VERB_REGISTER);
+#endif
+ ADD_INT(d, DB_VERB_REPLICATION);
+ ADD_INT(d, DB_VERB_WAITSFOR);
+#endif
+
+#if (DBVER >= 45)
+ ADD_INT(d, DB_EVENT_PANIC);
+ ADD_INT(d, DB_EVENT_REP_CLIENT);
+#if (DBVER >= 46)
+ ADD_INT(d, DB_EVENT_REP_ELECTED);
+#endif
+ ADD_INT(d, DB_EVENT_REP_MASTER);
+ ADD_INT(d, DB_EVENT_REP_NEWMASTER);
+#if (DBVER >= 46)
+ ADD_INT(d, DB_EVENT_REP_PERM_FAILED);
+#endif
+ ADD_INT(d, DB_EVENT_REP_STARTUPDONE);
+ ADD_INT(d, DB_EVENT_WRITE_FAILED);
+#endif
+
+#if (DBVER >= 40)
+ ADD_INT(d, DB_REP_MASTER);
+ ADD_INT(d, DB_REP_CLIENT);
+#if (DBVER >= 45)
+ ADD_INT(d, DB_REP_ELECTION);
+
+ ADD_INT(d, DB_REP_ACK_TIMEOUT);
+ ADD_INT(d, DB_REP_CONNECTION_RETRY);
+ ADD_INT(d, DB_REP_ELECTION_TIMEOUT);
+ ADD_INT(d, DB_REP_ELECTION_RETRY);
+#endif
+#if (DBVER >= 46)
+ ADD_INT(d, DB_REP_CHECKPOINT_DELAY);
+ ADD_INT(d, DB_REP_FULL_ELECTION_TIMEOUT);
+#endif
+#endif
+
+#if (DBVER >= 45)
+ ADD_INT(d, DB_REPMGR_PEER);
+ ADD_INT(d, DB_REPMGR_ACKS_ALL);
+ ADD_INT(d, DB_REPMGR_ACKS_ALL_PEERS);
+ ADD_INT(d, DB_REPMGR_ACKS_NONE);
+ ADD_INT(d, DB_REPMGR_ACKS_ONE);
+ ADD_INT(d, DB_REPMGR_ACKS_ONE_PEER);
+ ADD_INT(d, DB_REPMGR_ACKS_QUORUM);
+ ADD_INT(d, DB_REPMGR_CONNECTED);
+ ADD_INT(d, DB_REPMGR_DISCONNECTED);
+ ADD_INT(d, DB_STAT_CLEAR);
+ ADD_INT(d, DB_STAT_ALL);
+#endif
+
#if (DBVER >= 43)
+ ADD_INT(d, DB_DSYNC_LOG);
ADD_INT(d, DB_LOG_INMEMORY);
ADD_INT(d, DB_BUFFER_SMALL);
ADD_INT(d, DB_SEQ_DEC);
@@ -5844,7 +6946,7 @@
ADD_INT(d, DB_ENCRYPT_AES);
ADD_INT(d, DB_AUTO_COMMIT);
#else
- /* allow berkeleydb 4.1 aware apps to run on older versions */
+ /* allow Berkeley DB 4.1 aware apps to run on older versions */
_addIntToDict(d, "DB_AUTO_COMMIT", 0);
#endif
@@ -5920,6 +7022,10 @@
MAKE_EX(DBNoSuchFileError);
MAKE_EX(DBPermissionsError);
+#if (DBVER >= 42)
+ MAKE_EX(DBRepHandleDeadError);
+#endif
+
#undef MAKE_EX
/* Initiliase the C API structure and add it to the module */
Modified: python/trunk/Modules/bsddb.h
==============================================================================
--- python/trunk/Modules/bsddb.h (original)
+++ python/trunk/Modules/bsddb.h Tue May 13 20:45:46 2008
@@ -36,7 +36,7 @@
/*
* Handwritten code to wrap version 3.x of the Berkeley DB library,
* written to replace a SWIG-generated file. It has since been updated
- * to compile with BerkeleyDB versions 3.2 through 4.2.
+ * to compile with Berkeley DB versions 3.2 through 4.2.
*
* This module was started by Andrew Kuchling to remove the dependency
* on SWIG in a package by Gregory P. Smith who based his work on a
@@ -105,7 +105,7 @@
#error "eek! DBVER can't handle minor versions > 9"
#endif
-#define PY_BSDDB_VERSION "4.6.0"
+#define PY_BSDDB_VERSION "4.6.5devel2"
/* Python object definitions */
@@ -119,17 +119,27 @@
};
+
+struct DBObject; /* Forward declaration */
+struct DBCursorObject; /* Forward declaration */
+struct DBTxnObject; /* Forward declaration */
+struct DBSequenceObject; /* Forward declaration */
+
typedef struct {
PyObject_HEAD
DB_ENV* db_env;
u_int32_t flags; /* saved flags from open() */
int closed;
struct behaviourFlags moduleFlags;
+#if (DBVER >= 40)
+ PyObject* event_notifyCallback;
+#endif
+ struct DBObject *children_dbs;
+ struct DBTxnObject *children_txns;
PyObject *in_weakreflist; /* List of weak references */
} DBEnvObject;
-
-typedef struct {
+typedef struct DBObject {
PyObject_HEAD
DB* db;
DBEnvObject* myenvobj; /* PyObject containing the DB_ENV */
@@ -137,6 +147,15 @@
u_int32_t setflags; /* saved flags from set_flags() */
int haveStat;
struct behaviourFlags moduleFlags;
+ struct DBTxnObject *txn;
+ struct DBCursorObject *children_cursors;
+#if (DBVER >=43)
+ struct DBSequenceObject *children_sequences;
+#endif
+ struct DBObject **sibling_prev_p;
+ struct DBObject *sibling_next;
+ struct DBObject **sibling_prev_p_txn;
+ struct DBObject *sibling_next_txn;
#if (DBVER >= 33)
PyObject* associateCallback;
PyObject* btCompareCallback;
@@ -146,18 +165,31 @@
} DBObject;
-typedef struct {
+typedef struct DBCursorObject {
PyObject_HEAD
DBC* dbc;
+ struct DBCursorObject **sibling_prev_p;
+ struct DBCursorObject *sibling_next;
+ struct DBCursorObject **sibling_prev_p_txn;
+ struct DBCursorObject *sibling_next_txn;
DBObject* mydb;
+ struct DBTxnObject *txn;
PyObject *in_weakreflist; /* List of weak references */
} DBCursorObject;
-typedef struct {
+typedef struct DBTxnObject {
PyObject_HEAD
DB_TXN* txn;
- PyObject *env;
+ DBEnvObject* env;
+ int flag_prepare;
+ struct DBTxnObject *parent_txn;
+ struct DBTxnObject **sibling_prev_p;
+ struct DBTxnObject *sibling_next;
+ struct DBTxnObject *children_txns;
+ struct DBObject *children_dbs;
+ struct DBSequenceObject *children_sequences;
+ struct DBCursorObject *children_cursors;
PyObject *in_weakreflist; /* List of weak references */
} DBTxnObject;
@@ -170,13 +202,17 @@
#if (DBVER >= 43)
-typedef struct {
+typedef struct DBSequenceObject {
PyObject_HEAD
DB_SEQUENCE* sequence;
DBObject* mydb;
+ struct DBTxnObject *txn;
+ struct DBSequenceObject **sibling_prev_p;
+ struct DBSequenceObject *sibling_next;
+ struct DBSequenceObject **sibling_prev_p_txn;
+ struct DBSequenceObject *sibling_next_txn;
PyObject *in_weakreflist; /* List of weak references */
} DBSequenceObject;
-staticforward PyTypeObject DBSequence_Type;
#endif
3
2
The Buildbot has detected a new failure of i386 Ubuntu 3.0.
Full details are available at:
http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.0/builds/113
Buildbot URL: http://www.python.org/dev/buildbot/all/
Buildslave for this Build: klose-ubuntu-i386
Build Reason:
Build Source Stamp: [branch branches/py3k] HEAD
Blamelist: benjamin.peterson
BUILD FAILED: failed test
Excerpt from the test logfile:
1 test failed:
test_urllib2
======================================================================
ERROR: test_badly_named_methods (test.test_urllib2.OpenerDirectorTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/pybot/buildarea/3.0.klose-ubuntu-i386/build/Lib/test/test_urllib2.py", line 408, in test_badly_named_methods
self.assertRaises(URLError, o.open, scheme+"://example.com/")
File "/home/pybot/buildarea/3.0.klose-ubuntu-i386/build/Lib/unittest.py", line 311, in failUnlessRaises
callableObj(*args, **kwargs)
File "/home/pybot/buildarea/3.0.klose-ubuntu-i386/build/Lib/urllib/request.py", line 352, in open
response = self._open(req, data)
File "/home/pybot/buildarea/3.0.klose-ubuntu-i386/build/Lib/urllib/request.py", line 375, in _open
'unknown_open', req)
File "/home/pybot/buildarea/3.0.klose-ubuntu-i386/build/Lib/urllib/request.py", line 330, in _call_chain
result = func(*args)
File "/home/pybot/buildarea/3.0.klose-ubuntu-i386/build/Lib/urllib/request.py", line 1100, in unknown_open
raise urllib.error.URLError('unknown url type: %s' % type)
urllib.error.URLError: <urlopen error unknown url type: do>
make: *** [buildbottest] Error 1
sincerely,
-The Buildbot
1
0
r64601 - in python/trunk: Lib/test/test_threading_local.py Misc/NEWS Modules/threadmodule.c
by amaury.forgeotdarc 30 Jun '08
by amaury.forgeotdarc 30 Jun '08
30 Jun '08
Author: amaury.forgeotdarc
Date: Tue Jul 1 00:42:40 2008
New Revision: 64601
Log:
#Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
When a thread touches such an object for the first time, a new thread-local __dict__ is created,
and the __init__ method is run.
But a thread switch can occur here; if the other thread touches the same object, it installs another
__dict__; when the first thread resumes, it updates the dictionary of the second...
This is the deep cause of the failures in test_multiprocessing involving "managers" objects.
Also a 2.5 backport candidate.
Modified:
python/trunk/Lib/test/test_threading_local.py
python/trunk/Misc/NEWS
python/trunk/Modules/threadmodule.c
Modified: python/trunk/Lib/test/test_threading_local.py
==============================================================================
--- python/trunk/Lib/test/test_threading_local.py (original)
+++ python/trunk/Lib/test/test_threading_local.py Tue Jul 1 00:42:40 2008
@@ -42,6 +42,32 @@
deadlist = [weak for weak in weaklist if weak() is None]
self.assert_(len(deadlist) in (n-1, n), (n, len(deadlist)))
+ def test_derived(self):
+ # Issue 3088: if there is a threads switch inside the __init__
+ # of a threading.local derived class, the per-thread dictionary
+ # is created but not correctly set on the object.
+ # The first member set may be bogus.
+ import time
+ class Local(threading.local):
+ def __init__(self):
+ time.sleep(0.01)
+ local = Local()
+
+ def f(i):
+ local.x = i
+ # Simply check that the variable is correctly set
+ self.assertEqual(local.x, i)
+
+ threads= []
+ for i in range(10):
+ t = threading.Thread(target=f, args=(i,))
+ t.start()
+ threads.append(t)
+
+ for t in threads:
+ t.join()
+
+
def test_main():
suite = unittest.TestSuite()
suite.addTest(DocTestSuite('_threading_local'))
Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS (original)
+++ python/trunk/Misc/NEWS Tue Jul 1 00:42:40 2008
@@ -10,6 +10,10 @@
Core and Builtins
-----------------
+- Issue #3088: Corrected a race condition in classes derived from
+ threading.local: the first member set by a thread could be saved in
+ another thread's dictionary.
+
- Issue #3004: Minor change to slice.indices(): the start and stop
arguments are now treated identically, making the behaviour easier
to describe and understand. For example, slice(None, -10,
Modified: python/trunk/Modules/threadmodule.c
==============================================================================
--- python/trunk/Modules/threadmodule.c (original)
+++ python/trunk/Modules/threadmodule.c Tue Jul 1 00:42:40 2008
@@ -293,7 +293,10 @@
}
}
- else if (self->dict != ldict) {
+
+ /* The call to tp_init above may have caused another thread to run.
+ Install our ldict again. */
+ if (self->dict != ldict) {
Py_CLEAR(self->dict);
Py_INCREF(ldict);
self->dict = ldict;
1
0
The Buildbot has detected a new failure of ia64 Ubuntu 3.0.
Full details are available at:
http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.0/builds/216
Buildbot URL: http://www.python.org/dev/buildbot/all/
Buildslave for this Build: klose-debian-ia64
Build Reason:
Build Source Stamp: [branch branches/py3k] HEAD
Blamelist: benjamin.peterson
BUILD FAILED: failed test
Excerpt from the test logfile:
1 test failed:
test_urllib2
======================================================================
ERROR: test_badly_named_methods (test.test_urllib2.OpenerDirectorTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/pybot/buildarea/3.0.klose-debian-ia64/build/Lib/test/test_urllib2.py", line 408, in test_badly_named_methods
self.assertRaises(URLError, o.open, scheme+"://example.com/")
File "/home/pybot/buildarea/3.0.klose-debian-ia64/build/Lib/unittest.py", line 311, in failUnlessRaises
callableObj(*args, **kwargs)
File "/home/pybot/buildarea/3.0.klose-debian-ia64/build/Lib/urllib/request.py", line 352, in open
response = self._open(req, data)
File "/home/pybot/buildarea/3.0.klose-debian-ia64/build/Lib/urllib/request.py", line 375, in _open
'unknown_open', req)
File "/home/pybot/buildarea/3.0.klose-debian-ia64/build/Lib/urllib/request.py", line 330, in _call_chain
result = func(*args)
File "/home/pybot/buildarea/3.0.klose-debian-ia64/build/Lib/urllib/request.py", line 1100, in unknown_open
raise urllib.error.URLError('unknown url type: %s' % type)
urllib.error.URLError: <urlopen error unknown url type: do>
make: *** [buildbottest] Error 1
sincerely,
-The Buildbot
1
0
The Buildbot has detected a new failure of g4 osx.4 trunk.
Full details are available at:
http://www.python.org/dev/buildbot/all/g4%20osx.4%20trunk/builds/3638
Buildbot URL: http://www.python.org/dev/buildbot/all/
Buildslave for this Build: psf-g4
Build Reason:
Build Source Stamp: [branch trunk] HEAD
Blamelist: martin.v.loewis
BUILD FAILED: failed test
Excerpt from the test logfile:
Traceback (most recent call last):
File "/Users/buildslave/bb/trunk.psf-g4/build/Lib/threading.py", line 523, in __bootstrap_inner
self.run()
File "/Users/buildslave/bb/trunk.psf-g4/build/Lib/threading.py", line 478, in run
self.__target(*self.__args, **self.__kwargs)
File "/Users/buildslave/bb/trunk.psf-g4/build/Lib/test/test_smtplib.py", line 108, in debugging_server
poll_fun(0.01, asyncore.socket_map)
File "/Users/buildslave/bb/trunk.psf-g4/build/Lib/asyncore.py", line 183, in poll2
readwrite(obj, flags)
File "/Users/buildslave/bb/trunk.psf-g4/build/Lib/asyncore.py", line 107, in readwrite
obj.handle_error()
File "/Users/buildslave/bb/trunk.psf-g4/build/Lib/asyncore.py", line 103, in readwrite
obj.handle_expt_event()
File "/Users/buildslave/bb/trunk.psf-g4/build/Lib/asyncore.py", line 448, in handle_expt_event
raise socket.error(err, msg)
error: [Errno 54] Connection reset by peer
1 test failed:
test_smtplib
make: *** [buildbottest] Error 1
sincerely,
-The Buildbot
1
0
Author: martin.v.loewis
Date: Mon Jun 30 09:01:09 2008
New Revision: 64598
Log:
Add _multiprocessing module.
Modified:
python/trunk/Tools/msi/msi.py
Modified: python/trunk/Tools/msi/msi.py
==============================================================================
--- python/trunk/Tools/msi/msi.py (original)
+++ python/trunk/Tools/msi/msi.py Mon Jun 30 09:01:09 2008
@@ -92,7 +92,8 @@
'_ctypes.pyd',
'_ctypes_test.pyd',
'_sqlite3.pyd',
- '_hashlib.pyd'
+ '_hashlib.pyd',
+ '_multiprocessing.pyd'
]
# Well-known component UUIDs
1
0
Author: martin.v.loewis
Date: Mon Jun 30 08:57:39 2008
New Revision: 64597
Log:
Issue #3215: Build sqlite3 as sqlite3.dll, not sqlite3.pyd
Modified:
python/trunk/Misc/NEWS
python/trunk/PCbuild/sqlite3.vcproj
Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS (original)
+++ python/trunk/Misc/NEWS Mon Jun 30 08:57:39 2008
@@ -17,6 +17,11 @@
slice(None, 10, -1).indices(10) returns (9, 9, -1) instead of (9,
10, -1).
+Build
+-----
+
+- Issue #3215: Build sqlite3 as sqlite3.dll, not sqlite3.pyd.
+
What's New in Python 2.6 beta 1?
================================
Modified: python/trunk/PCbuild/sqlite3.vcproj
==============================================================================
--- python/trunk/PCbuild/sqlite3.vcproj (original)
+++ python/trunk/PCbuild/sqlite3.vcproj Mon Jun 30 08:57:39 2008
@@ -305,6 +305,7 @@
/>
<Tool
Name="VCLinkerTool"
+ OutputFile="$(OutDir)\$(ProjectName).dll"
/>
<Tool
Name="VCALinkTool"
@@ -428,6 +429,7 @@
/>
<Tool
Name="VCLinkerTool"
+ OutputFile="$(OutDir)\$(ProjectName).dll"
/>
<Tool
Name="VCALinkTool"
1
0
The Buildbot has detected a new failure of sparc Debian 3.0.
Full details are available at:
http://www.python.org/dev/buildbot/all/sparc%20Debian%203.0/builds/319
Buildbot URL: http://www.python.org/dev/buildbot/all/
Buildslave for this Build: klose-debian-sparc
Build Reason:
Build Source Stamp: [branch branches/py3k] HEAD
Blamelist: martin.v.loewis
BUILD FAILED: failed test
Excerpt from the test logfile:
1 test failed:
test_urllib2
======================================================================
ERROR: test_badly_named_methods (test.test_urllib2.OpenerDirectorTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/pybot/buildarea-sid/3.0.klose-debian-sparc/build/Lib/test/test_urllib2.py", line 408, in test_badly_named_methods
self.assertRaises(URLError, o.open, scheme+"://example.com/")
File "/home/pybot/buildarea-sid/3.0.klose-debian-sparc/build/Lib/unittest.py", line 311, in failUnlessRaises
callableObj(*args, **kwargs)
File "/home/pybot/buildarea-sid/3.0.klose-debian-sparc/build/Lib/urllib/request.py", line 352, in open
response = self._open(req, data)
File "/home/pybot/buildarea-sid/3.0.klose-debian-sparc/build/Lib/urllib/request.py", line 375, in _open
'unknown_open', req)
File "/home/pybot/buildarea-sid/3.0.klose-debian-sparc/build/Lib/urllib/request.py", line 330, in _call_chain
result = func(*args)
File "/home/pybot/buildarea-sid/3.0.klose-debian-sparc/build/Lib/urllib/request.py", line 1100, in unknown_open
raise urllib.error.URLError('unknown url type: %s' % type)
urllib.error.URLError: <urlopen error unknown url type: do>
make: *** [buildbottest] Error 1
sincerely,
-The Buildbot
1
0
The Buildbot has detected a new failure of ppc Debian unstable 3.0.
Full details are available at:
http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%203.0/builds…
Buildbot URL: http://www.python.org/dev/buildbot/all/
Buildslave for this Build: klose-debian-ppc
Build Reason:
Build Source Stamp: [branch branches/py3k] HEAD
Blamelist: martin.v.loewis
BUILD FAILED: failed test
Excerpt from the test logfile:
1 test failed:
test_ssl
make: *** [buildbottest] Error 1
sincerely,
-The Buildbot
1
0
The Buildbot has detected a new failure of i386 Ubuntu 3.0.
Full details are available at:
http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.0/builds/110
Buildbot URL: http://www.python.org/dev/buildbot/all/
Buildslave for this Build: klose-ubuntu-i386
Build Reason:
Build Source Stamp: [branch branches/py3k] HEAD
Blamelist: martin.v.loewis
BUILD FAILED: failed test
Excerpt from the test logfile:
1 test failed:
test_urllib2
======================================================================
ERROR: test_badly_named_methods (test.test_urllib2.OpenerDirectorTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/pybot/buildarea/3.0.klose-ubuntu-i386/build/Lib/test/test_urllib2.py", line 408, in test_badly_named_methods
self.assertRaises(URLError, o.open, scheme+"://example.com/")
File "/home/pybot/buildarea/3.0.klose-ubuntu-i386/build/Lib/unittest.py", line 311, in failUnlessRaises
callableObj(*args, **kwargs)
File "/home/pybot/buildarea/3.0.klose-ubuntu-i386/build/Lib/urllib/request.py", line 352, in open
response = self._open(req, data)
File "/home/pybot/buildarea/3.0.klose-ubuntu-i386/build/Lib/urllib/request.py", line 375, in _open
'unknown_open', req)
File "/home/pybot/buildarea/3.0.klose-ubuntu-i386/build/Lib/urllib/request.py", line 330, in _call_chain
result = func(*args)
File "/home/pybot/buildarea/3.0.klose-ubuntu-i386/build/Lib/urllib/request.py", line 1100, in unknown_open
raise urllib.error.URLError('unknown url type: %s' % type)
urllib.error.URLError: <urlopen error unknown url type: do>
make: *** [buildbottest] Error 1
sincerely,
-The Buildbot
1
0