Fix for CONPY-102:

Fixed default behavior of autocommit: If not autocommit mode was specified,
autocommit will be off by default (see https://www.python.org/dev/peps/pep-0249/#commit).
Added new keyword autocommit for connection class which might have the following values:
- None: use server default setting
- True: turns autocommit on
- False: turns autocommit off
This commit is contained in:
Georg Richter
2020-08-12 14:19:02 +02:00
parent 03f283a2ff
commit 0e91d76d52
6 changed files with 64 additions and 8 deletions

View File

@ -35,7 +35,7 @@ The mariadb module supports the standard defined by DB API 2.0 (PEP-249).
be used
- **init_command** (string): Specifies one or more commands to execute when connecting and reconnecting to the database server.
- **default_file** (string): Read options from the specified option file. If the file is an empty string, default configuration file(s) will be used
- **default_group** (string): -- Read options from the specified group
- **default_group** (string): Read options from the specified group
- **ssl_key** (string): Defines a path to a private key file to use for TLS. This option
requires that you use the absolute path, not a relative path. The specified key must be in PEM format
- **ssl_cert** (string): Defines a path to the X509 certificate file to use for TLS. This option requires that you use the absolute path, not a relative path. The X609 certificate must be in PEM format.
@ -45,6 +45,8 @@ The mariadb module supports the standard defined by DB API 2.0 (PEP-249).
- **ssl_crlpath** (string): Defines a path to a PEM file that should contain one or more revoked X509 certificates to use for TLS. This option requires that you use the absolute path, not a relative path.
- **ssl_verify_cert** (bool): Enables server certificate verification.
- **ssl** (bool): Always use a secure TLS connection
.. versionadded:: 1.0.1
- **autocommit** (bool or None): Specifies the autocommit settings: None will use the server default. True will enable autocommit, False will disable it (default).
:return: Returns a connection or raises an error if the connection between client and server couldn't be established.

View File

@ -74,7 +74,7 @@ be used</p>
</li>
<li><p><strong>init_command</strong> (string): Specifies one or more commands to execute when connecting and reconnecting to the database server.</p></li>
<li><p><strong>default_file</strong> (string): Read options from the specified option file. If the file is an empty string, default configuration file(s) will be used</p></li>
<li><p><strong>default_group</strong> (string): Read options from the specified group</p></li>
<li><p><strong>default_group</strong> (string): Read options from the specified group</p></li>
<li><dl class="simple">
<dt><strong>ssl_key</strong> (string): Defines a path to a private key file to use for TLS. This option</dt><dd><p>requires that you use the absolute path, not a relative path. The specified key must be in PEM format</p>
</dd>
@ -88,6 +88,12 @@ be used</p>
<li><p><strong>ssl_verify_cert</strong> (bool): Enables server certificate verification.</p></li>
<li><p><strong>ssl</strong> (bool): Always use a secure TLS connection</p></li>
</ul>
<div class="versionadded">
<p><span class="versionmodified added">New in version 1.0.1.</span></p>
</div>
<ul class="simple">
<li><p><strong>autocommit</strong> (bool or None): Specifies the autocommit settings: None will use the server default. True will enable autocommit, False will disable it (default).</p></li>
</ul>
<dl class="field-list simple">
<dt class="field-odd">Returns</dt>
<dd class="field-odd"><p>Returns a connection or raises an error if the connection between client and server couldnt be established.</p>

File diff suppressed because one or more lines are too long

View File

@ -71,3 +71,6 @@
" Enables server certificate verification.\n\n"\
"ssl: Boolean\n"\
" The connection must use TLS security or it will fail.\n\n"
"autocommit: Boolean or None\n"\
" Specifies the autocommit settings: None will use the server default,"\
" True will enable autocommit, False will disable it (default).\n\n"

View File

@ -30,7 +30,8 @@ char *dsn_keys[]= {
"ssl_verify_cert", "ssl",
"client_flag", "pool_name", "pool_size",
"pool_reset_connection", "plugin_dir",
"username", "db", "passwd",
"username", "db", "passwd",
"autocommit",
NULL
};
@ -312,9 +313,10 @@ MrdbConnection_Initialize(MrdbConnection *self,
unsigned int local_infile= 0xFF;
unsigned int connect_timeout=0, read_timeout=0, write_timeout=0,
compress= 0, ssl_verify_cert= 0;
PyObject *autocommit_obj= NULL;
if (!PyArg_ParseTupleAndKeywords(args, dsnargs,
"|sssssisiiibbssssssssssipisibssss:connect",
"|sssssisiiibbssssssssssipisibssssO:connect",
dsn_keys,
&dsn, &host, &user, &password, &schema, &port, &socket,
&connect_timeout, &read_timeout, &write_timeout,
@ -325,11 +327,22 @@ MrdbConnection_Initialize(MrdbConnection *self,
&ssl_verify_cert, &ssl_enforce,
&client_flags, &pool_name, &pool_size,
&reset_session, &plugin_dir,
&user, &schema, &password))
&user, &schema, &password,
&autocommit_obj))
{
return -1;
}
if (autocommit_obj)
{
if (autocommit_obj != Py_None &&
Py_TYPE(autocommit_obj) != &PyBool_Type)
{
PyErr_SetString(PyExc_TypeError, "Argument must be boolean or None");
return -1;
}
}
if (dsn)
{
mariadb_throw_exception(NULL, Mariadb_ProgrammingError, 1,
@ -421,6 +434,27 @@ MrdbConnection_Initialize(MrdbConnection *self,
goto end;
}
if (!autocommit_obj ||
(autocommit_obj && Py_TYPE(autocommit_obj) == &PyBool_Type))
{
uint8_t autocommit= (autocommit_obj) ?
(uint8_t) PyLong_AsUnsignedLong(autocommit_obj) : 0;
uint8_t server_autocommit;
uint32_t server_status;
mariadb_get_infov(self->mysql, MARIADB_CONNECTION_SERVER_STATUS, &server_status);
server_autocommit= server_status & SERVER_STATUS_AUTOCOMMIT;
if (server_autocommit != autocommit)
{
if (mysql_autocommit(self->mysql, autocommit))
{
mariadb_throw_exception(self->mysql, NULL, 0, NULL);
goto end;
}
}
}
end:
if (PyErr_Occurred())
return -1;

View File

@ -46,12 +46,11 @@ class TestConnection(unittest.TestCase):
def test_autocommit(self):
conn = self.connection
cursor = conn.cursor()
self.assertEqual(conn.autocommit, True)
conn.autocommit = False
self.assertEqual(conn.autocommit, False)
# revert
conn.autocommit = True
self.assertEqual(conn.autocommit, True)
def test_local_infile(self):
default_conf= conf()
@ -178,5 +177,17 @@ class TestConnection(unittest.TestCase):
except mariadb.ProgrammingError:
pass
def test_conpy101(self):
default_conf = conf()
c1 = mariadb.connect(user=default_conf["user"], database=default_conf["database"],
port=default_conf["port"], host=default_conf["host"])
self.assertEqual(c1.autocommit, False)
c1 = mariadb.connect(user=default_conf["user"], database=default_conf["database"],
port=default_conf["port"], host=default_conf["host"], autocommit=False)
self.assertEqual(c1.autocommit, False)
c1 = mariadb.connect(user=default_conf["user"], database=default_conf["database"],
port=default_conf["port"], host=default_conf["host"], autocommit=True)
self.assertEqual(c1.autocommit, True)
if __name__ == '__main__':
unittest.main()