Finally chased down an ugly memory leak in _mysql. Tested with a script

I got from mxODBC author Marc-Andre Lemburg, which revealed the leak in
the first place.

Added a connection.rollback() method that always raises an
OperationalError, since MySQL doesn't have transactions.
connection.commit() still succeeds without doing anything.
This commit is contained in:
adustman
1999-03-18 06:20:14 +00:00
parent e1970cf20b
commit 31a706efde
2 changed files with 26 additions and 15 deletions

View File

@ -25,7 +25,10 @@ class Cursor:
self.result = None
self.arraysize = None
self.warnings = 1
## def __del__(self):
## self.result = None
##
def setinputsizes(self, size): pass
def setoutputsizes(self, size): pass
@ -115,6 +118,8 @@ class Connection:
self.db.close()
def commit(self): pass
def rollback(self): raise OperationalError, "transactions not supported"
def cursor(self, name=''):
return self.CursorClass(self, name)

View File

@ -68,6 +68,7 @@ _mysql_Exception(c)
PyTuple_SET_ITEM(t, 0, PyInt_FromLong((long)merr));
PyTuple_SET_ITEM(t, 1, PyString_FromString(mysql_error(&(c->connection))));
PyErr_SetObject(e, t);
Py_DECREF(t);
return NULL;
}
@ -358,7 +359,6 @@ _mysql_ResultObject_New(conn, result)
if (n) {
r->converter = PyMem_Malloc(n*sizeof(PyObject *));
fields = mysql_fetch_fields(result);
r->fields = fields;
for (i=0; i<n; i++) {
PyObject *tmp, *fun;
tmp = PyInt_FromLong((long) fields[i].type);
@ -501,13 +501,13 @@ _mysql_escape_row(self, args)
PyObject *self;
PyObject *args;
{
PyObject *o, *r, *item, *quoted, *str, *itemstr;
PyObject *o=NULL, *r=NULL, *item, *quoted, *str, *itemstr;
char *in, *out;
int i, n, len, size;
if (!PyArg_ParseTuple(args, "O:escape_row", &o)) return NULL;
if (!PySequence_Check(o)) return NULL;
if (!(n = PyObject_Length(o))) return NULL;
if (!(r = PyTuple_New(n))) return NULL;
if (!PyArg_ParseTuple(args, "O:escape_row", &o)) goto error2;
if (!PySequence_Check(o)) goto error2;
if (!(n = PyObject_Length(o))) goto error2;
if (!(r = PyTuple_New(n))) goto error;
for (i=0; i<n; i++) {
if (!(item = PySequence_GetItem(o, i))) goto error;
if (item == Py_None) {
@ -517,10 +517,13 @@ _mysql_escape_row(self, args)
else {
if (!(itemstr = PyObject_Str(item)))
goto error;
in = PyString_AsString(itemstr);
size = PyString_Size(itemstr);
if (!(in = PyString_AsString(itemstr))) {
Py_DECREF(itemstr);
goto error;
}
size = PyString_GET_SIZE(itemstr);
str = PyString_FromStringAndSize((char *)NULL, size*2+3);
if (!str) return PyErr_NoMemory();
if (!str) goto error;
out = PyString_AS_STRING(str);
len = mysql_escape_string(out+1, in, size);
*out = '\'' ;
@ -531,11 +534,13 @@ _mysql_escape_row(self, args)
Py_DECREF(itemstr);
quoted = str;
}
Py_DECREF(item);
PyTuple_SET_ITEM(r, i, quoted);
}
return r;
error:
Py_XDECREF(r);
error2:
return NULL;
}
@ -621,11 +626,12 @@ _mysql_ResultObject_fetch_row(self, args)
if (row[i]) {
if (self->converter[i])
v = PyObject_CallFunction(self->converter[i],
"s#",
row[i], length[i]);
"s#",
row[i],
(int)length[i]);
else
v = PyString_FromStringAndSize(row[i],
length[i]);
(int)length[i]);
if (!v) goto error;
}
else {
@ -991,7 +997,7 @@ _mysql_ResultObject_dealloc(self)
_mysql_ResultObject *self;
{
int i;
if (self->result) mysql_free_result(self->result);
mysql_free_result(self->result);
Py_DECREF(self->conn);
for (i=0; i<self->nfields; i++) Py_XDECREF(self->converter[i]);
PyMem_Free((char *) self->converter);
@ -1097,7 +1103,7 @@ _mysql_ConnectionObject_setattr(c, name, v)
{
if (v == NULL) {
PyErr_SetString(PyExc_AttributeError,
"can't delete file attributes");
"can't delete connection attributes");
return -1;
}
return PyMember_Set((char *)c, _mysql_ConnectionObject_memberlist, name, v);