diff --git a/doc/user_guide.rst b/doc/user_guide.rst index 8c76417..391b162 100644 --- a/doc/user_guide.rst +++ b/doc/user_guide.rst @@ -396,6 +396,17 @@ connect(parameters...) server_public_key_path specifies path to a RSA public key used by caching sha2 password authentication. See https://dev.mysql.com/doc/refman/9.0/en/caching-sha2-pluggable-authentication.html + + local_infile + sets ``MYSQL_OPT_LOCAL_INFILE`` in ``mysql_options()`` enabling LOAD LOCAL INFILE from any path; zero disables; + + *This must be a keyword parameter.* + + local_infile_dir + sets ``MYSQL_OPT_LOAD_DATA_LOCAL_DIR`` in ``mysql_options()`` enabling LOAD LOCAL INFILE from any path; + if ``local_infile`` is set to ``True`` then this is ignored; + + *This must be a keyword parameter.* .. _mysql_ssl_set: http://dev.mysql.com/doc/refman/en/mysql-ssl-set.html diff --git a/src/MySQLdb/_mysql.c b/src/MySQLdb/_mysql.c index d6df4df..cd95b64 100644 --- a/src/MySQLdb/_mysql.c +++ b/src/MySQLdb/_mysql.c @@ -48,6 +48,10 @@ PERFORMANCE OF THIS SOFTWARE. #define HAVE_MYSQL_SERVER_PUBLIC_KEY #endif +#if !defined(MARIADB_VERSION_ID) && MYSQL_VERSION_ID >= 80021 +#define HAVE_MYSQL_OPT_LOCAL_INFILE_DIR +#endif + #define PY_SSIZE_T_CLEAN 1 #include "Python.h" @@ -436,7 +440,7 @@ _mysql_ConnectionObject_Initialize( "client_flag", "ssl", "ssl_mode", "local_infile", "read_timeout", "write_timeout", "charset", - "auth_plugin", "server_public_key_path", + "auth_plugin", "server_public_key_path", "local_infile_dir", NULL } ; int connect_timeout = 0; int read_timeout = 0; @@ -448,14 +452,15 @@ _mysql_ConnectionObject_Initialize( *read_default_group=NULL, *charset=NULL, *auth_plugin=NULL, - *server_public_key_path=NULL; + *server_public_key_path=NULL, + *local_infile_dir=NULL; self->converter = NULL; self->open = false; self->reconnect = false; if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "|ssssisOiiisssiOsiiisss:connect", + "|ssssisOiiisssiOsiiissss:connect", kwlist, &host, &user, &passwd, &db, &port, &unix_socket, &conv, @@ -469,7 +474,8 @@ _mysql_ConnectionObject_Initialize( &write_timeout, &charset, &auth_plugin, - &server_public_key_path + &server_public_key_path, + &local_infile_dir )) return -1; @@ -479,6 +485,13 @@ _mysql_ConnectionObject_Initialize( return -1; } #endif + +#ifndef HAVE_MYSQL_OPT_LOCAL_INFILE_DIR + if (local_infile_dir) { + PyErr_SetString(_mysql_NotSupportedError, "local_infile_dir is not supported"); + return -1; + } +#endif // For compatibility with PyPy, we need to keep strong reference // to unicode objects until we use UTF8. #define _stringsuck(d,t,s) {t=PyMapping_GetItemString(s,#d);\ @@ -599,6 +612,12 @@ _mysql_ConnectionObject_Initialize( } #endif +#ifdef HAVE_MYSQL_OPT_LOCAL_INFILE_DIR + if (local_infile_dir) { + mysql_options(&(self->connection), MYSQL_OPT_LOAD_DATA_LOCAL_DIR, local_infile_dir); + } +#endif + Py_BEGIN_ALLOW_THREADS conn = mysql_real_connect(&(self->connection), host, user, passwd, db, port, unix_socket, client_flag); diff --git a/src/MySQLdb/connections.py b/src/MySQLdb/connections.py index 5bcfc93..a61aaae 100644 --- a/src/MySQLdb/connections.py +++ b/src/MySQLdb/connections.py @@ -142,7 +142,13 @@ class object, used to create cursors (keyword only) See https://dev.mysql.com/doc/refman/9.0/en/caching-sha2-pluggable-authentication.html :param bool local_infile: - enables LOAD LOCAL INFILE; zero disables + sets ``MYSQL_OPT_LOCAL_INFILE`` in ``mysql_options()`` enabling LOAD LOCAL INFILE from any path; zero disables; + + :param str local_infile_dir: + sets ``MYSQL_OPT_LOAD_DATA_LOCAL_DIR`` in ``mysql_options()`` enabling LOAD LOCAL INFILE from any path; + if ``local_infile`` is set to ``True`` then this is ignored; + + supported for mysql version >= 8.0.21 :param bool autocommit: If False (default), autocommit is disabled.