Fix for CONPY-278:

In case of an (automatic) reconnect the connection property
connection_id was not updated, since there is no callback
functionality in Connector/C available to notify the application
that a reconnect occured. Instead of obtaining the connection_id
via MemberDef, connection_id is now implemented as getter function.
This commit is contained in:
Georg Richter
2024-01-31 17:21:48 +01:00
parent 28827984bd
commit 7c2134dddb
3 changed files with 52 additions and 11 deletions

View File

@ -218,7 +218,6 @@ typedef struct {
uint8_t status;
uint8_t asynchronous;
struct timespec last_used;
unsigned long thread_id;
char *server_info;
uint8_t closed;
#if MARIADB_PACKAGE_VERSION_ID > 30301

View File

@ -58,6 +58,9 @@ MrdbConnection_exception(PyObject *self, void *closure);
static PyObject *
MrdbConnection_getreconnect(MrdbConnection *self, void *closure);
static PyObject *
MrdbConnection_connection_id(MrdbConnection *self);
static int
MrdbConnection_setreconnect(MrdbConnection *self, PyObject *args,
void *closure);
@ -89,6 +92,8 @@ MrdbConnection_sets[]=
{"auto_reconnect", (getter)MrdbConnection_getreconnect,
(setter)MrdbConnection_setreconnect,
connection_auto_reconnect__doc__, NULL},
{"connection_id", (getter)MrdbConnection_connection_id,
NULL, "Id of current connection", NULL},
{"warnings", (getter)MrdbConnection_warnings, NULL,
connection_warnings__doc__, NULL},
GETTER_EXCEPTION("Error", Mariadb_Error, ""),
@ -166,11 +171,6 @@ MrdbConnection_Methods[] =
static struct
PyMemberDef MrdbConnection_Members[] =
{
{"connection_id",
T_LONG,
offsetof(MrdbConnection, thread_id),
READONLY,
"Id of current connection."},
{"dsn",
T_OBJECT,
offsetof(MrdbConnection, dsn),
@ -454,7 +454,6 @@ MrdbConnection_Initialize(MrdbConnection *self,
goto end;
}
self->thread_id= mysql_thread_id(self->mysql);
mariadb_get_infov(self->mysql, MARIADB_CONNECTION_HOST, (void *)&self->host);
has_error= 0;
@ -607,9 +606,6 @@ PyObject *MrdbConnection_ping(MrdbConnection *self)
return NULL;
}
/* in case a reconnect occurred, we need to obtain new thread_id */
self->thread_id= mysql_thread_id(self->mysql);
Py_RETURN_NONE;
}
/* }}} */
@ -777,7 +773,6 @@ PyObject *MrdbConnection_reconnect(MrdbConnection *self)
return NULL;
}
/* get capabilities */
self->thread_id= mysql_thread_id(self->mysql);
Py_RETURN_NONE;
}
/* }}} */
@ -801,6 +796,15 @@ PyObject *MrdbConnection_reset(MrdbConnection *self)
}
/* }}} */
/* {{{ MrdbConnection_connection_id */
static PyObject *MrdbConnection_connection_id(MrdbConnection *self)
{
MARIADB_CHECK_CONNECTION(self, NULL);
return PyLong_FromUnsignedLong(mysql_thread_id(self->mysql));
}
/* }}} */
/* {{{ MrdbConnection_warnings */
static PyObject *MrdbConnection_warnings(MrdbConnection *self)
{

View File

@ -268,6 +268,44 @@ class TestConnection(unittest.TestCase):
parse_version('3.3.0'))
pass
def test_conpy278(self):
test_conf= conf()
test_conf["reconnect"]= True
conn= mariadb.connect(**test_conf)
old_id= conn.connection_id
try:
conn.kill(conn.connection_id)
except mariadb.OperationalError:
conn.ping()
self.assertNotEqual(old_id, conn.connection_id)
conn.close()
conn= mariadb.connect(**test_conf)
old_id= conn.connection_id
try:
conn.kill(conn.connection_id)
except mariadb.OperationalError:
conn.ping()
self.assertNotEqual(old_id, conn.connection_id)
conn.close()
conn= mariadb.connect(**test_conf)
old_id= conn.connection_id
try:
conn.kill(conn.connection_id)
except mariadb.OperationalError:
pass
cursor= conn.cursor()
try:
cursor.execute("set @a:=1")
except mariadb.InterfaceError:
pass
cursor.execute("set @a:=1")
self.assertNotEqual(old_id, conn.connection_id)
old_id= conn.connection_id
conn.reconnect()
self.assertNotEqual(old_id, conn.connection_id)
conn.close()
if __name__ == '__main__':
unittest.main()