Skip to content

Don't fetch warnings when there is next result #57

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 4, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
sudo: false
language: python
python: "3.5"

cache: pip
install:
- pip install tox
Expand All @@ -8,4 +10,8 @@ before_script:
- "mysql --help"
- "mysql --print-defaults"
- "mysql -e 'create database mysqldb_test charset utf8mb4;'"

script: TESTDB=travis.cnf tox


# vim: sw=4 ts=4 sts=4
18 changes: 12 additions & 6 deletions MySQLdb/cursors.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,14 @@ def _check_executed(self):
def _warning_check(self):
from warnings import warn
if self._warnings:
# When there is next result, fetching warnings cause "command
# out of sync" error.
if self._result and self._result.has_next:
msg = "There are %d MySQL warnings." % (self._warnings,)
self.messages.append(msg)
warn(msg, self.Warning, 3)
return

warnings = self._get_db().show_warnings()
if warnings:
# This is done in two loops in case
Expand Down Expand Up @@ -204,23 +212,21 @@ def execute(self, query, args=None):
if isinstance(query, unicode):
query = query.encode(db.unicode_literal.charset, 'surrogateescape')

res = None
try:
r = None
r = self._query(query)
res = self._query(query)
except TypeError as m:
if m.args[0] in ("not enough arguments for format string",
"not all arguments converted"):
self.errorhandler(self, ProgrammingError, m.args[0])
else:
self.errorhandler(self, TypeError, m)
except (SystemExit, KeyboardInterrupt):
raise
except:
except Exception:
exc, value = sys.exc_info()[:2]
self.errorhandler(self, exc, value)
self._executed = query
if not self._defer_warnings: self._warning_check()
return r
return res

def executemany(self, query, args):
"""Execute a multi-row query.
Expand Down
71 changes: 40 additions & 31 deletions _mysql.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static PyObject *_mysql_IntegrityError;
static PyObject *_mysql_InternalError;
static PyObject *_mysql_ProgrammingError;
static PyObject *_mysql_NotSupportedError;

typedef struct {
PyObject_HEAD
MYSQL connection;
Expand All @@ -88,6 +88,7 @@ typedef struct {
MYSQL_RES *result;
int nfields;
int use;
char has_next;
PyObject *converter;
} _mysql_ResultObject;

Expand Down Expand Up @@ -226,7 +227,7 @@ _mysql_Exception(_mysql_ConnectionObject *c)
Py_DECREF(t);
return NULL;
}

static char _mysql_server_init__doc__[] =
"Initialize embedded server. If this client is not linked against\n\
the embedded server library, this function does nothing.\n\
Expand All @@ -249,7 +250,7 @@ static PyObject *_mysql_server_init(
"already initialized");
return NULL;
}

if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", kwlist,
&cmd_args, &groups))
return NULL;
Expand Down Expand Up @@ -348,7 +349,7 @@ static PyObject *_mysql_server_end(
}
return _mysql_Exception(NULL);
}

#if MYSQL_VERSION_ID >= 32314
static char _mysql_thread_safe__doc__[] =
"Indicates whether the client is compiled as thread-safe.";
Expand Down Expand Up @@ -406,6 +407,7 @@ _mysql_ResultObject_Initialize(
else
result = mysql_store_result(&(conn->connection));
self->result = result;
self->has_next = (char)mysql_more_results(&(conn->connection));
Py_END_ALLOW_THREADS ;
if (!result) {
if (mysql_errno(&(conn->connection))) {
Expand Down Expand Up @@ -555,7 +557,7 @@ _mysql_ConnectionObject_Initialize(
char *init_command=NULL,
*read_default_file=NULL,
*read_default_group=NULL;

self->converter = NULL;
self->open = 0;
check_server_init(-1);
Expand Down Expand Up @@ -739,7 +741,7 @@ _mysql_connect(
PyObject *kwargs)
{
_mysql_ConnectionObject *c=NULL;

c = MyAlloc(_mysql_ConnectionObject, _mysql_ConnectionObject_Type);
if (c == NULL) return NULL;
if (_mysql_ConnectionObject_Initialize(c, args, kwargs)) {
Expand Down Expand Up @@ -1289,7 +1291,7 @@ _mysql_escape_dict(
Py_XDECREF(r);
return NULL;
}

static char _mysql_ResultObject_describe__doc__[] =
"Returns the sequence of 7-tuples required by the DB-API for\n\
the Cursor.description attribute.\n\
Expand Down Expand Up @@ -1326,7 +1328,7 @@ _mysql_ResultObject_describe(
Py_XDECREF(d);
return NULL;
}

static char _mysql_ResultObject_field_flags__doc__[] =
"Returns a tuple of field flags, one for each column in the result.\n\
" ;
Expand Down Expand Up @@ -1520,7 +1522,7 @@ _mysql__fetch_row(
int maxrows,
_PYFUNC *convert_row)
{
unsigned int i;
int i;
MYSQL_ROW row;

for (i = skiprows; i<(skiprows+maxrows); i++) {
Expand Down Expand Up @@ -1573,14 +1575,14 @@ _mysql_ResultObject_fetch_row(
_mysql_row_to_dict_old
};
_PYFUNC *convert_row;
unsigned int maxrows=1, how=0, skiprows=0, rowsadded;
int maxrows=1, how=0, skiprows=0, rowsadded;
PyObject *r=NULL;

if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii:fetch_row", kwlist,
&maxrows, &how))
return NULL;
check_result_connection(self);
if (how >= sizeof(row_converters)) {
if (how >= (int)sizeof(row_converters)) {
PyErr_SetString(PyExc_ValueError, "how out of range");
return NULL;
}
Expand Down Expand Up @@ -1734,7 +1736,7 @@ _mysql_ConnectionObject_get_character_set_info(
{
PyObject *result;
MY_CHARSET_INFO cs;

if (!PyArg_ParseTuple(args, "")) return NULL;
check_connection(self);
mysql_get_character_set_info(&(self->connection), &cs);
Expand Down Expand Up @@ -2653,6 +2655,13 @@ static struct PyMemberDef _mysql_ResultObject_memberlist[] = {
READONLY,
"Type conversion mapping"
},
{
"has_next",
T_BOOL,
offsetof(_mysql_ResultObject, has_next),
READONLY,
"Has next result"
},
{NULL} /* Sentinel */
};

Expand Down Expand Up @@ -2717,44 +2726,44 @@ PyTypeObject _mysql_ConnectionObject_Type = {
0, /* tp_setattr */
0, /*tp_compare*/
(reprfunc)_mysql_ConnectionObject_repr, /* tp_repr */

/* Method suites for standard classes */

0, /* (PyNumberMethods *) tp_as_number */
0, /* (PySequenceMethods *) tp_as_sequence */
0, /* (PyMappingMethods *) tp_as_mapping */

/* More standard operations (here for binary compatibility) */

0, /* (hashfunc) tp_hash */
0, /* (ternaryfunc) tp_call */
0, /* (reprfunc) tp_str */
(getattrofunc)_mysql_ConnectionObject_getattro, /* tp_getattro */
(setattrofunc)_mysql_ConnectionObject_setattro, /* tp_setattro */

/* Functions to access object as input/output buffer */
0, /* (PyBufferProcs *) tp_as_buffer */

/* (tp_flags) Flags to define presence of optional/expanded features */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
_mysql_connect__doc__, /* (char *) tp_doc Documentation string */

/* call function for all accessible objects */
(traverseproc) _mysql_ConnectionObject_traverse, /* tp_traverse */

/* delete references to contained objects */
(inquiry) _mysql_ConnectionObject_clear, /* tp_clear */

/* rich comparisons */
0, /* (richcmpfunc) tp_richcompare */

/* weak reference enabler */
0, /* (long) tp_weaklistoffset */

/* Iterators */
0, /* (getiterfunc) tp_iter */
0, /* (iternextfunc) tp_iternext */

/* Attribute descriptor and subclassing stuff */
(struct PyMethodDef *)_mysql_ConnectionObject_methods, /* tp_methods */
(struct PyMemberDef *)_mysql_ConnectionObject_memberlist, /* tp_members */
Expand Down Expand Up @@ -2789,45 +2798,45 @@ PyTypeObject _mysql_ResultObject_Type = {
0, /* tp_setattr */
0, /*tp_compare*/
(reprfunc)_mysql_ResultObject_repr, /* tp_repr */

/* Method suites for standard classes */

0, /* (PyNumberMethods *) tp_as_number */
0, /* (PySequenceMethods *) tp_as_sequence */
0, /* (PyMappingMethods *) tp_as_mapping */

/* More standard operations (here for binary compatibility) */

0, /* (hashfunc) tp_hash */
0, /* (ternaryfunc) tp_call */
0, /* (reprfunc) tp_str */
(getattrofunc)PyObject_GenericGetAttr, /* tp_getattro */
(setattrofunc)_mysql_ResultObject_setattro, /* tp_setattr */

/* Functions to access object as input/output buffer */
0, /* (PyBufferProcs *) tp_as_buffer */

/* Flags to define presence of optional/expanded features */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,

_mysql_ResultObject__doc__, /* (char *) tp_doc Documentation string */

/* call function for all accessible objects */
(traverseproc) _mysql_ResultObject_traverse, /* tp_traverse */

/* delete references to contained objects */
(inquiry) _mysql_ResultObject_clear, /* tp_clear */

/* rich comparisons */
0, /* (richcmpfunc) tp_richcompare */

/* weak reference enabler */
0, /* (long) tp_weaklistoffset */

/* Iterators */
0, /* (getiterfunc) tp_iter */
0, /* (iternextfunc) tp_iternext */

/* Attribute descriptor and subclassing stuff */
(struct PyMethodDef *) _mysql_ResultObject_methods, /* tp_methods */
(struct PyMemberDef *) _mysql_ResultObject_memberlist, /*tp_members */
Expand Down
5 changes: 2 additions & 3 deletions tests/configdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,15 @@
read_default_group = "MySQLdb-tests",
)


def connection_kwargs(kwargs):
db_kwargs = connect_kwargs.copy()
db_kwargs.update(kwargs)
return db_kwargs


def connection_factory(**kwargs):
import MySQLdb
db_kwargs = connection_kwargs(kwargs)
db = MySQLdb.connect(**db_kwargs)
return db



Loading