Skip to content

Commit

Permalink
support local_infile_dir option (#755)
Browse files Browse the repository at this point in the history
Adds support for `MYSQL_OPT_LOAD_DATA_LOCAL_DIR` in `mysql_options()` as
the kwarg `local_infile_dir`. A bit safer alternative than `local_infile` for MySQL versions >= 8.0.21.
  • Loading branch information
RasmusKard authored Feb 23, 2025
1 parent 2076d16 commit 5b35866
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 5 deletions.
11 changes: 11 additions & 0 deletions doc/user_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
27 changes: 23 additions & 4 deletions src/MySQLdb/_mysql.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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;
Expand All @@ -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,
Expand All @@ -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;

Expand All @@ -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);\
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 7 additions & 1 deletion src/MySQLdb/connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 5b35866

Please sign in to comment.