mirror of
https://github.com/PyMySQL/mysqlclient.git
synced 2025-08-15 19:31:54 +08:00
Merge https://github.com/farcepest/MySQLdb1 into merge-upstream
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,5 +7,6 @@
|
|||||||
*.zip
|
*.zip
|
||||||
*.egg
|
*.egg
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
|
.tox/
|
||||||
build/
|
build/
|
||||||
dist/
|
dist/
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
language: python
|
language: python
|
||||||
python:
|
python:
|
||||||
- "2.5"
|
|
||||||
- "2.6"
|
- "2.6"
|
||||||
- "2.7"
|
- "2.7"
|
||||||
- "pypy"
|
- "pypy"
|
||||||
|
@ -139,6 +139,11 @@ class Connection(_mysql.connection):
|
|||||||
local_infile
|
local_infile
|
||||||
integer, non-zero enables LOAD LOCAL INFILE; zero disables
|
integer, non-zero enables LOAD LOCAL INFILE; zero disables
|
||||||
|
|
||||||
|
autocommit
|
||||||
|
If False (default), autocommit is disabled.
|
||||||
|
If True, autocommit is enabled.
|
||||||
|
If None, autocommit isn't set and server default is used.
|
||||||
|
|
||||||
There are a number of undocumented, non-standard methods. See the
|
There are a number of undocumented, non-standard methods. See the
|
||||||
documentation for the MySQL C API for some hints on what they do.
|
documentation for the MySQL C API for some hints on what they do.
|
||||||
|
|
||||||
@ -182,6 +187,9 @@ class Connection(_mysql.connection):
|
|||||||
|
|
||||||
kwargs2['client_flag'] = client_flag
|
kwargs2['client_flag'] = client_flag
|
||||||
|
|
||||||
|
# PEP-249 requires autocommit to be initially off
|
||||||
|
autocommit = kwargs2.pop('autocommit', False)
|
||||||
|
|
||||||
super(Connection, self).__init__(*args, **kwargs2)
|
super(Connection, self).__init__(*args, **kwargs2)
|
||||||
self.cursorclass = cursorclass
|
self.cursorclass = cursorclass
|
||||||
self.encoders = dict([ (k, v) for k, v in conv.items()
|
self.encoders = dict([ (k, v) for k, v in conv.items()
|
||||||
@ -225,10 +233,15 @@ class Connection(_mysql.connection):
|
|||||||
self.encoders[types.UnicodeType] = unicode_literal
|
self.encoders[types.UnicodeType] = unicode_literal
|
||||||
self._transactional = self.server_capabilities & CLIENT.TRANSACTIONS
|
self._transactional = self.server_capabilities & CLIENT.TRANSACTIONS
|
||||||
if self._transactional:
|
if self._transactional:
|
||||||
# PEP-249 requires autocommit to be initially off
|
if autocommit is not None:
|
||||||
self.autocommit(False)
|
self.autocommit(autocommit)
|
||||||
self.messages = []
|
self.messages = []
|
||||||
|
|
||||||
|
def autocommit(self, on):
|
||||||
|
on = bool(on)
|
||||||
|
if self.get_autocommit() != on:
|
||||||
|
_mysql.connection.autocommit(self, on)
|
||||||
|
|
||||||
def cursor(self, cursorclass=None):
|
def cursor(self, cursorclass=None):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -241,6 +254,8 @@ class Connection(_mysql.connection):
|
|||||||
return (cursorclass or self.cursorclass)(self)
|
return (cursorclass or self.cursorclass)(self)
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
|
if self.get_autocommit():
|
||||||
|
self.query("BEGIN")
|
||||||
return self.cursor()
|
return self.cursor()
|
||||||
|
|
||||||
def __exit__(self, exc, value, tb):
|
def __exit__(self, exc, value, tb):
|
||||||
|
@ -129,13 +129,16 @@ def char_array(s):
|
|||||||
def array2Str(o, d):
|
def array2Str(o, d):
|
||||||
return Thing2Literal(o.tostring(), d)
|
return Thing2Literal(o.tostring(), d)
|
||||||
|
|
||||||
|
def quote_tuple(t, d):
|
||||||
|
return "(%s)" % (','.join(escape_sequence(t, d)))
|
||||||
|
|
||||||
conversions = {
|
conversions = {
|
||||||
IntType: Thing2Str,
|
IntType: Thing2Str,
|
||||||
LongType: Long2Int,
|
LongType: Long2Int,
|
||||||
FloatType: Float2Str,
|
FloatType: Float2Str,
|
||||||
NoneType: None2NULL,
|
NoneType: None2NULL,
|
||||||
TupleType: escape_sequence,
|
TupleType: quote_tuple,
|
||||||
ListType: escape_sequence,
|
ListType: quote_tuple,
|
||||||
DictType: escape_dict,
|
DictType: escape_dict,
|
||||||
InstanceType: Instance2Str,
|
InstanceType: Instance2Str,
|
||||||
ArrayType: array2Str,
|
ArrayType: array2Str,
|
||||||
|
@ -26,7 +26,7 @@ restr = r"""
|
|||||||
(?:
|
(?:
|
||||||
(?:\(
|
(?:\(
|
||||||
# ( - editor hightlighting helper
|
# ( - editor hightlighting helper
|
||||||
[^)]*
|
.*
|
||||||
\))
|
\))
|
||||||
|
|
|
|
||||||
'
|
'
|
||||||
@ -180,7 +180,11 @@ class BaseCursor(object):
|
|||||||
if isinstance(query, unicode):
|
if isinstance(query, unicode):
|
||||||
query = query.encode(db.unicode_literal.charset)
|
query = query.encode(db.unicode_literal.charset)
|
||||||
if args is not None:
|
if args is not None:
|
||||||
query = query % db.literal(args)
|
if isinstance(args, dict):
|
||||||
|
query = query % dict((key, db.literal(item))
|
||||||
|
for key, item in args.iteritems())
|
||||||
|
else:
|
||||||
|
query = query % tuple([db.literal(item) for item in args])
|
||||||
try:
|
try:
|
||||||
r = None
|
r = None
|
||||||
r = self._query(query)
|
r = self._query(query)
|
||||||
@ -236,7 +240,13 @@ class BaseCursor(object):
|
|||||||
e = m.end(1)
|
e = m.end(1)
|
||||||
qv = m.group(1)
|
qv = m.group(1)
|
||||||
try:
|
try:
|
||||||
q = [ qv % db.literal(a) for a in args ]
|
q = []
|
||||||
|
for a in args:
|
||||||
|
if isinstance(a, dict):
|
||||||
|
q.append(qv % dict((key, db.literal(item))
|
||||||
|
for key, item in a.iteritems()))
|
||||||
|
else:
|
||||||
|
q.append(qv % tuple([db.literal(item) for item in a]))
|
||||||
except TypeError, msg:
|
except TypeError, msg:
|
||||||
if msg.args[0] in ("not enough arguments for format string",
|
if msg.args[0] in ("not enough arguments for format string",
|
||||||
"not all arguments converted"):
|
"not all arguments converted"):
|
||||||
|
@ -51,7 +51,12 @@ def DateTime_or_None(s):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
d, t = s.split(sep, 1)
|
d, t = s.split(sep, 1)
|
||||||
return datetime(*[ int(x) for x in d.split('-')+t.split(':') ])
|
if '.' in t:
|
||||||
|
t, ms = t.split('.',1)
|
||||||
|
ms = ms.ljust(6, '0')
|
||||||
|
else:
|
||||||
|
ms = 0
|
||||||
|
return datetime(*[ int(x) for x in d.split('-')+t.split(':')+[ms] ])
|
||||||
except (SystemExit, KeyboardInterrupt):
|
except (SystemExit, KeyboardInterrupt):
|
||||||
raise
|
raise
|
||||||
except:
|
except:
|
||||||
@ -60,9 +65,14 @@ def DateTime_or_None(s):
|
|||||||
def TimeDelta_or_None(s):
|
def TimeDelta_or_None(s):
|
||||||
try:
|
try:
|
||||||
h, m, s = s.split(':')
|
h, m, s = s.split(':')
|
||||||
h, m, s = int(h), int(m), float(s)
|
if '.' in s:
|
||||||
td = timedelta(hours=abs(h), minutes=m, seconds=int(s),
|
s, ms = s.split('.')
|
||||||
microseconds=int(math.modf(s)[0] * 1000000))
|
ms = ms.ljust(6, '0')
|
||||||
|
else:
|
||||||
|
ms = 0
|
||||||
|
h, m, s, ms = int(h), int(m), int(s), int(ms)
|
||||||
|
td = timedelta(hours=abs(h), minutes=m, seconds=s,
|
||||||
|
microseconds=ms)
|
||||||
if h < 0:
|
if h < 0:
|
||||||
return -td
|
return -td
|
||||||
else:
|
else:
|
||||||
@ -74,9 +84,14 @@ def TimeDelta_or_None(s):
|
|||||||
def Time_or_None(s):
|
def Time_or_None(s):
|
||||||
try:
|
try:
|
||||||
h, m, s = s.split(':')
|
h, m, s = s.split(':')
|
||||||
h, m, s = int(h), int(m), float(s)
|
if '.' in s:
|
||||||
return time(hour=h, minute=m, second=int(s),
|
s, ms = s.split('.')
|
||||||
microsecond=int(math.modf(s)[0] * 1000000))
|
ms = ms.ljust(6, '0')
|
||||||
|
else:
|
||||||
|
ms = 0
|
||||||
|
h, m, s, ms = int(h), int(m), int(s), int(ms)
|
||||||
|
return time(hour=h, minute=m, second=s,
|
||||||
|
microsecond=ms)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
44
_mysql.c
44
_mysql.c
@ -121,7 +121,7 @@ static int _mysql_server_init_done = 0;
|
|||||||
/* According to https://dev.mysql.com/doc/refman/5.1/en/mysql-options.html
|
/* According to https://dev.mysql.com/doc/refman/5.1/en/mysql-options.html
|
||||||
The MYSQL_OPT_READ_TIMEOUT apear in the version 5.1.12 */
|
The MYSQL_OPT_READ_TIMEOUT apear in the version 5.1.12 */
|
||||||
#if MYSQL_VERSION_ID > 50112
|
#if MYSQL_VERSION_ID > 50112
|
||||||
#define HAVE_MYSQL_OPT_READ_TIMEOUT 1
|
#define HAVE_MYSQL_OPT_TIMEOUTS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
@ -566,13 +566,15 @@ _mysql_ConnectionObject_Initialize(
|
|||||||
"read_default_file", "read_default_group",
|
"read_default_file", "read_default_group",
|
||||||
"client_flag", "ssl",
|
"client_flag", "ssl",
|
||||||
"local_infile",
|
"local_infile",
|
||||||
#ifdef HAVE_MYSQL_OPT_READ_TIMEOUT
|
#ifdef HAVE_MYSQL_OPT_TIMEOUTS
|
||||||
"read_timeout",
|
"read_timeout",
|
||||||
|
"write_timeout",
|
||||||
#endif
|
#endif
|
||||||
NULL } ;
|
NULL } ;
|
||||||
int connect_timeout = 0;
|
int connect_timeout = 0;
|
||||||
#ifdef HAVE_MYSQL_OPT_READ_TIMEOUT
|
#ifdef HAVE_MYSQL_OPT_TIMEOUTS
|
||||||
int read_timeout = 0;
|
int read_timeout = 0;
|
||||||
|
int write_timeout = 0;
|
||||||
#endif
|
#endif
|
||||||
int compress = -1, named_pipe = -1, local_infile = -1;
|
int compress = -1, named_pipe = -1, local_infile = -1;
|
||||||
char *init_command=NULL,
|
char *init_command=NULL,
|
||||||
@ -584,8 +586,8 @@ _mysql_ConnectionObject_Initialize(
|
|||||||
check_server_init(-1);
|
check_server_init(-1);
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||||
#ifdef HAVE_MYSQL_OPT_READ_TIMEOUT
|
#ifdef HAVE_MYSQL_OPT_TIMEOUTS
|
||||||
"|ssssisOiiisssiOii:connect",
|
"|ssssisOiiisssiOiii:connect",
|
||||||
#else
|
#else
|
||||||
"|ssssisOiiisssiOi:connect",
|
"|ssssisOiiisssiOi:connect",
|
||||||
#endif
|
#endif
|
||||||
@ -598,8 +600,9 @@ _mysql_ConnectionObject_Initialize(
|
|||||||
&read_default_group,
|
&read_default_group,
|
||||||
&client_flag, &ssl,
|
&client_flag, &ssl,
|
||||||
&local_infile
|
&local_infile
|
||||||
#ifdef HAVE_MYSQL_OPT_READ_TIMEOUT
|
#ifdef HAVE_MYSQL_OPT_TIMEOUTS
|
||||||
, &read_timeout
|
, &read_timeout
|
||||||
|
, &write_timeout
|
||||||
#endif
|
#endif
|
||||||
))
|
))
|
||||||
return -1;
|
return -1;
|
||||||
@ -636,12 +639,17 @@ _mysql_ConnectionObject_Initialize(
|
|||||||
mysql_options(&(self->connection), MYSQL_OPT_CONNECT_TIMEOUT,
|
mysql_options(&(self->connection), MYSQL_OPT_CONNECT_TIMEOUT,
|
||||||
(char *)&timeout);
|
(char *)&timeout);
|
||||||
}
|
}
|
||||||
#ifdef HAVE_MYSQL_OPT_READ_TIMEOUT
|
#ifdef HAVE_MYSQL_OPT_TIMEOUTS
|
||||||
if (read_timeout) {
|
if (read_timeout) {
|
||||||
unsigned int timeout = read_timeout;
|
unsigned int timeout = read_timeout;
|
||||||
mysql_options(&(self->connection), MYSQL_OPT_READ_TIMEOUT,
|
mysql_options(&(self->connection), MYSQL_OPT_READ_TIMEOUT,
|
||||||
(char *)&timeout);
|
(char *)&timeout);
|
||||||
}
|
}
|
||||||
|
if (write_timeout) {
|
||||||
|
unsigned int timeout = write_timeout;
|
||||||
|
mysql_options(&(self->connection), MYSQL_OPT_WRITE_TIMEOUT,
|
||||||
|
(char *)&timeout);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (compress != -1) {
|
if (compress != -1) {
|
||||||
mysql_options(&(self->connection), MYSQL_OPT_COMPRESS, 0);
|
mysql_options(&(self->connection), MYSQL_OPT_COMPRESS, 0);
|
||||||
@ -891,7 +899,21 @@ _mysql_ConnectionObject_autocommit(
|
|||||||
if (err) return _mysql_Exception(self);
|
if (err) return _mysql_Exception(self);
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char _mysql_ConnectionObject_get_autocommit__doc__[] =
|
||||||
|
"Get the autocommit mode. True when enable; False when disable.\n";
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
_mysql_ConnectionObject_get_autocommit(
|
||||||
|
_mysql_ConnectionObject *self,
|
||||||
|
PyObject *args)
|
||||||
|
{
|
||||||
|
if (self->connection.server_status & SERVER_STATUS_AUTOCOMMIT) {
|
||||||
|
Py_RETURN_TRUE;
|
||||||
|
}
|
||||||
|
Py_RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static char _mysql_ConnectionObject_commit__doc__[] =
|
static char _mysql_ConnectionObject_commit__doc__[] =
|
||||||
"Commits the current transaction\n\
|
"Commits the current transaction\n\
|
||||||
@ -2317,6 +2339,12 @@ static PyMethodDef _mysql_ConnectionObject_methods[] = {
|
|||||||
METH_VARARGS,
|
METH_VARARGS,
|
||||||
_mysql_ConnectionObject_autocommit__doc__
|
_mysql_ConnectionObject_autocommit__doc__
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"get_autocommit",
|
||||||
|
(PyCFunction)_mysql_ConnectionObject_get_autocommit,
|
||||||
|
METH_NOARGS,
|
||||||
|
_mysql_ConnectionObject_get_autocommit__doc__
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"commit",
|
"commit",
|
||||||
(PyCFunction)_mysql_ConnectionObject_commit,
|
(PyCFunction)_mysql_ConnectionObject_commit,
|
||||||
|
@ -71,8 +71,9 @@ def get_config():
|
|||||||
if i.startswith(compiler_flag('I')) ]
|
if i.startswith(compiler_flag('I')) ]
|
||||||
|
|
||||||
if static:
|
if static:
|
||||||
extra_objects.append(os.path.join(
|
extra_objects.append(os.path.join(library_dirs[0],'lib%s.a' % client))
|
||||||
library_dirs[0],'lib%s.a' % client))
|
if client in libraries:
|
||||||
|
libraries.remove(client)
|
||||||
|
|
||||||
name = "MySQL-python"
|
name = "MySQL-python"
|
||||||
if enabled(options, 'embedded'):
|
if enabled(options, 'embedded'):
|
||||||
|
@ -77,7 +77,7 @@ class test_MySQLdb(capabilities.DatabaseTest):
|
|||||||
try:
|
try:
|
||||||
self.cursor.execute("describe some_non_existent_table");
|
self.cursor.execute("describe some_non_existent_table");
|
||||||
except self.connection.ProgrammingError, msg:
|
except self.connection.ProgrammingError, msg:
|
||||||
self.assertTrue(msg[0] == ER.NO_SUCH_TABLE)
|
self.assertEquals(msg[0], ER.NO_SUCH_TABLE)
|
||||||
|
|
||||||
def test_bug_3514287(self):
|
def test_bug_3514287(self):
|
||||||
c = self.cursor
|
c = self.cursor
|
||||||
|
Reference in New Issue
Block a user