Py_DECREF(self->myenvobj);
self->myenvobj = NULL;
}
+ PyObject_Del(self);
self = NULL;
}
return self;
err = db_env_create(&self->db_env, flags);
MYDB_END_ALLOW_THREADS;
if (makeDBError(err)) {
+ PyObject_Del(self);
self = NULL;
}
else {
#endif
MYDB_END_ALLOW_THREADS;
if (makeDBError(err)) {
+ PyObject_Del(self);
self = NULL;
}
DBObject* secondaryDB = (DBObject*)db->app_private;
PyObject* callback = secondaryDB->associateCallback;
int type = secondaryDB->primaryDBType;
- PyObject* key;
- PyObject* data;
PyObject* args;
PyObject* result = NULL;
if (callback != NULL) {
MYDB_BEGIN_BLOCK_THREADS;
- if (type == DB_RECNO || type == DB_QUEUE) {
- key = PyInt_FromLong( *((db_recno_t*)priKey->data));
- }
- else {
- key = PyString_FromStringAndSize(priKey->data, priKey->size);
- }
- data = PyString_FromStringAndSize(priData->data, priData->size);
- args = PyTuple_New(2);
+ if (type == DB_RECNO || type == DB_QUEUE)
+ args = Py_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);
if (args != NULL) {
- PyTuple_SET_ITEM(args, 0, key); /* steals reference */
- PyTuple_SET_ITEM(args, 1, data); /* steals reference */
result = PyEval_CallObject(callback, args);
}
if (args == NULL || result == NULL) {
PyErr_Print();
}
- Py_DECREF(args);
- if (result) {
- Py_DECREF(result);
- }
+ Py_XDECREF(args);
+ Py_XDECREF(result);
MYDB_END_BLOCK_THREADS;
}
/* Save a reference to the callback in the secondary DB. */
Py_XDECREF(secondaryDB->associateCallback);
- Py_INCREF(callback);
+ Py_XINCREF(callback);
secondaryDB->associateCallback = callback;
secondaryDB->primaryDBType = _DB_get_type(self);
#else
retval = Py_BuildValue("OOO", keyObj, pkeyObj, dataObj);
#endif
+ Py_DECREF(keyObj);
}
else /* return just the pkey and data */
{
retval = Py_BuildValue("OO", pkeyObj, dataObj);
#endif
}
+ Py_DECREF(dataObj);
+ Py_DECREF(pkeyObj);
FREE_DBT(pkey);
FREE_DBT(data);
}
cursors[length] = NULL;
for (x=0; x<length; x++) {
PyObject* item = PySequence_GetItem(cursorsObj, x);
+ if (item == NULL) {
+ free(cursors);
+ return NULL;
+ }
if (!DBCursorObject_Check(item)) {
PyErr_SetString(PyExc_TypeError,
"Sequence of DBCursor objects expected");
#endif
if (NULL == self->db) {
- PyErr_SetObject(DBError, Py_BuildValue("(is)", 0,
- "Cannot call open() twice for DB object"));
+ PyObject *t = Py_BuildValue("(is)", 0,
+ "Cannot call open() twice for DB object");
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
return NULL;
}
int res = 0;
PyObject *args;
PyObject *result;
- PyObject *leftObject;
- PyObject *rightObject;
DBObject *self = (DBObject *)db->app_private;
if (self == NULL || self->btCompareCallback == NULL) {
} else {
MYDB_BEGIN_BLOCK_THREADS;
- leftObject = PyString_FromStringAndSize(leftKey->data, leftKey->size);
- rightObject = PyString_FromStringAndSize(rightKey->data, rightKey->size);
-
- args = PyTuple_New(2);
+ args = Py_BuildValue("s#s#", leftKey->data, leftKey->size,
+ rightKey->data, rightKey->size);
if (args != NULL) {
+ /* XXX(twouters) I highly doubt this INCREF is correct */
Py_INCREF(self);
- PyTuple_SET_ITEM(args, 0, leftObject); /* steals reference */
- PyTuple_SET_ITEM(args, 1, rightObject); /* steals reference */
result = PyEval_CallObject(self->btCompareCallback, args);
}
if (args == NULL || result == NULL) {
res = _default_cmp(leftKey, rightKey);
}
- Py_DECREF(args);
+ Py_XDECREF(args);
Py_XDECREF(result);
MYDB_END_BLOCK_THREADS;
{
int err;
PyObject *comparator;
- PyObject *tuple, *emptyStr, *result;
+ PyObject *tuple, *result;
if (!PyArg_ParseTuple(args, "O:set_bt_compare", &comparator))
return NULL;
* string objects here. verify that it returns an int (0).
* err if not.
*/
- tuple = PyTuple_New(2);
- emptyStr = PyString_FromStringAndSize(NULL, 0);
- if (tuple == NULL || emptyStr == NULL)
- return NULL;
-
- Py_INCREF(emptyStr); /* now we have two references */
- PyTuple_SET_ITEM(tuple, 0, emptyStr); /* steals reference */
- PyTuple_SET_ITEM(tuple, 1, emptyStr); /* steals reference */
+ tuple = Py_BuildValue("(ss)", "", "");
result = PyEval_CallObject(comparator, tuple);
Py_DECREF(tuple);
- if (result == NULL || !PyInt_Check(result)) {
+ if (result == NULL)
+ return NULL;
+ if (!PyInt_Check(result)) {
PyErr_SetString(PyExc_TypeError,
"callback MUST return an int");
return NULL;
"callback failed to return 0 on two empty strings");
return NULL;
}
+ Py_DECREF(result);
/* We don't accept multiple set_bt_compare operations, in order to
* simplify the code. This would have no real use, as one cannot
PyEval_InitThreads();
#endif
- err = self->db->set_bt_compare(self->db,
- (comparator != NULL ?
- _db_compareCallback : NULL));
+ err = self->db->set_bt_compare(self->db, _db_compareCallback);
if (err) {
/* restore the old state in case of error */
void* sp;
if (self->db == NULL) {
- PyErr_SetObject(DBError,
- Py_BuildValue("(is)", 0, "DB object has been closed"));
+ PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
return -1;
}
int flags = 0;
if (self->db == NULL) {
- PyErr_SetObject(DBError,
- Py_BuildValue("(is)", 0, "DB object has been closed"));
+ PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
return -1;
}
return NULL;
list = PyList_New(0);
- if (list == NULL) {
- PyErr_SetString(PyExc_MemoryError, "PyList_New failed");
+ if (list == NULL)
return NULL;
- }
/* get a cursor */
MYDB_BEGIN_ALLOW_THREADS;
err = self->db->cursor(self->db, txn, &cursor, 0);
MYDB_END_ALLOW_THREADS;
- RETURN_IF_ERR();
+ if (makeDBError(err)) {
+ Py_DECREF(list);
+ return NULL;
+ }
if (CHECK_DBFLAG(self, DB_THREAD)) {
key.flags = DB_DBT_REALLOC;
break;
}
break;
+ default:
+ PyErr_Format(PyExc_ValueError, "Unknown key type 0x%x", type);
+ item = NULL;
+ break;
}
if (item == NULL) {
Py_DECREF(list);
- PyErr_SetString(PyExc_MemoryError, "List item creation failed");
list = NULL;
goto done;
}
#else
retval = Py_BuildValue("OOO", keyObj, pkeyObj, dataObj);
#endif
+ Py_DECREF(keyObj);
FREE_DBT(key);
}
else /* return just the pkey and data */
retval = Py_BuildValue("OO", pkeyObj, dataObj);
#endif
}
+ Py_DECREF(dataObj);
+ Py_DECREF(pkeyObj);
FREE_DBT(pkey);
FREE_DBT(data);
}
RETURN_IF_ERR();
list = PyList_New(0);
- if (list == NULL) {
- PyErr_SetString(PyExc_MemoryError, "PyList_New failed");
+ if (list == NULL)
return NULL;
- }
if (log_list) {
for (log_list_start = log_list; *log_list != NULL; ++log_list) {
item = PyString_FromString (*log_list);
if (item == NULL) {
Py_DECREF(list);
- PyErr_SetString(PyExc_MemoryError,
- "List item creation failed");
list = NULL;
break;
}
return NULL;
if (!self->txn) {
- PyErr_SetObject(DBError, Py_BuildValue("(is)", 0,
- "DBTxn must not be used after txn_commit or txn_abort"));
+ PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
+ "after txn_commit or txn_abort");
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
return NULL;
}
txn = self->txn;
}
if (!self->txn) {
- PyErr_SetObject(DBError, Py_BuildValue("(is)", 0,
- "DBTxn must not be used after txn_commit or txn_abort"));
+ PyObject *t = Py_BuildValue("(is)", 0,"DBTxn must not be used "
+ "after txn_commit or txn_abort");
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
return NULL;
}
MYDB_BEGIN_ALLOW_THREADS;
return NULL;
if (!self->txn) {
- PyErr_SetObject(DBError, Py_BuildValue("(is)", 0,
- "DBTxn must not be used after txn_commit or txn_abort"));
+ PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
+ "after txn_commit or txn_abort");
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
return NULL;
}
MYDB_BEGIN_ALLOW_THREADS;
return NULL;
if (!self->txn) {
- PyErr_SetObject(DBError, Py_BuildValue("(is)", 0,
- "DBTxn must not be used after txn_commit or txn_abort"));
+ PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
+ "after txn_commit or txn_abort");
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
return NULL;
}
txn = self->txn;
return NULL;
if (!self->txn) {
- PyErr_SetObject(DBError, Py_BuildValue("(is)", 0,
- "DBTxn must not be used after txn_commit or txn_abort"));
+ PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
+ "after txn_commit or txn_abort");
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
return NULL;
}
MYDB_BEGIN_ALLOW_THREADS;