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
|
||||
*.egg
|
||||
*.egg-info/
|
||||
.tox/
|
||||
build/
|
||||
dist/
|
||||
|
@ -1,6 +1,5 @@
|
||||
language: python
|
||||
python:
|
||||
- "2.5"
|
||||
- "2.6"
|
||||
- "2.7"
|
||||
- "pypy"
|
||||
|
@ -139,6 +139,11 @@ class Connection(_mysql.connection):
|
||||
local_infile
|
||||
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
|
||||
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
|
||||
|
||||
# PEP-249 requires autocommit to be initially off
|
||||
autocommit = kwargs2.pop('autocommit', False)
|
||||
|
||||
super(Connection, self).__init__(*args, **kwargs2)
|
||||
self.cursorclass = cursorclass
|
||||
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._transactional = self.server_capabilities & CLIENT.TRANSACTIONS
|
||||
if self._transactional:
|
||||
# PEP-249 requires autocommit to be initially off
|
||||
self.autocommit(False)
|
||||
if autocommit is not None:
|
||||
self.autocommit(autocommit)
|
||||
self.messages = []
|
||||
|
||||
def autocommit(self, on):
|
||||
on = bool(on)
|
||||
if self.get_autocommit() != on:
|
||||
_mysql.connection.autocommit(self, on)
|
||||
|
||||
def cursor(self, cursorclass=None):
|
||||
"""
|
||||
|
||||
@ -241,6 +254,8 @@ class Connection(_mysql.connection):
|
||||
return (cursorclass or self.cursorclass)(self)
|
||||
|
||||
def __enter__(self):
|
||||
if self.get_autocommit():
|
||||
self.query("BEGIN")
|
||||
return self.cursor()
|
||||
|
||||
def __exit__(self, exc, value, tb):
|
||||
|
@ -129,13 +129,16 @@ def char_array(s):
|
||||
def array2Str(o, d):
|
||||
return Thing2Literal(o.tostring(), d)
|
||||
|
||||
def quote_tuple(t, d):
|
||||
return "(%s)" % (','.join(escape_sequence(t, d)))
|
||||
|
||||
conversions = {
|
||||
IntType: Thing2Str,
|
||||
LongType: Long2Int,
|
||||
FloatType: Float2Str,
|
||||
NoneType: None2NULL,
|
||||
TupleType: escape_sequence,
|
||||
ListType: escape_sequence,
|
||||
TupleType: quote_tuple,
|
||||
ListType: quote_tuple,
|
||||
DictType: escape_dict,
|
||||
InstanceType: Instance2Str,
|
||||
ArrayType: array2Str,
|
||||
|
@ -26,7 +26,7 @@ restr = r"""
|
||||
(?:
|
||||
(?:\(
|
||||
# ( - editor hightlighting helper
|
||||
[^)]*
|
||||
.*
|
||||
\))
|
||||
|
|
||||
'
|
||||
@ -180,7 +180,11 @@ class BaseCursor(object):
|
||||
if isinstance(query, unicode):
|
||||
query = query.encode(db.unicode_literal.charset)
|
||||
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:
|
||||
r = None
|
||||
r = self._query(query)
|
||||
@ -236,7 +240,13 @@ class BaseCursor(object):
|
||||
e = m.end(1)
|
||||
qv = m.group(1)
|
||||
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:
|
||||
if msg.args[0] in ("not enough arguments for format string",
|
||||
"not all arguments converted"):
|
||||
|
@ -51,7 +51,12 @@ def DateTime_or_None(s):
|
||||
|
||||
try:
|
||||
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):
|
||||
raise
|
||||
except:
|
||||
@ -60,9 +65,14 @@ def DateTime_or_None(s):
|
||||
def TimeDelta_or_None(s):
|
||||
try:
|
||||
h, m, s = s.split(':')
|
||||
h, m, s = int(h), int(m), float(s)
|
||||
td = timedelta(hours=abs(h), minutes=m, seconds=int(s),
|
||||
microseconds=int(math.modf(s)[0] * 1000000))
|
||||
if '.' in s:
|
||||
s, ms = s.split('.')
|
||||
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:
|
||||
return -td
|
||||
else:
|
||||
@ -74,9 +84,14 @@ def TimeDelta_or_None(s):
|
||||
def Time_or_None(s):
|
||||
try:
|
||||
h, m, s = s.split(':')
|
||||
h, m, s = int(h), int(m), float(s)
|
||||
return time(hour=h, minute=m, second=int(s),
|
||||
microsecond=int(math.modf(s)[0] * 1000000))
|
||||
if '.' in s:
|
||||
s, ms = s.split('.')
|
||||
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:
|
||||
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
|
||||
The MYSQL_OPT_READ_TIMEOUT apear in the version 5.1.12 */
|
||||
#if MYSQL_VERSION_ID > 50112
|
||||
#define HAVE_MYSQL_OPT_READ_TIMEOUT 1
|
||||
#define HAVE_MYSQL_OPT_TIMEOUTS 1
|
||||
#endif
|
||||
|
||||
PyObject *
|
||||
@ -566,13 +566,15 @@ _mysql_ConnectionObject_Initialize(
|
||||
"read_default_file", "read_default_group",
|
||||
"client_flag", "ssl",
|
||||
"local_infile",
|
||||
#ifdef HAVE_MYSQL_OPT_READ_TIMEOUT
|
||||
#ifdef HAVE_MYSQL_OPT_TIMEOUTS
|
||||
"read_timeout",
|
||||
"write_timeout",
|
||||
#endif
|
||||
NULL } ;
|
||||
int connect_timeout = 0;
|
||||
#ifdef HAVE_MYSQL_OPT_READ_TIMEOUT
|
||||
#ifdef HAVE_MYSQL_OPT_TIMEOUTS
|
||||
int read_timeout = 0;
|
||||
int write_timeout = 0;
|
||||
#endif
|
||||
int compress = -1, named_pipe = -1, local_infile = -1;
|
||||
char *init_command=NULL,
|
||||
@ -584,8 +586,8 @@ _mysql_ConnectionObject_Initialize(
|
||||
check_server_init(-1);
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||
#ifdef HAVE_MYSQL_OPT_READ_TIMEOUT
|
||||
"|ssssisOiiisssiOii:connect",
|
||||
#ifdef HAVE_MYSQL_OPT_TIMEOUTS
|
||||
"|ssssisOiiisssiOiii:connect",
|
||||
#else
|
||||
"|ssssisOiiisssiOi:connect",
|
||||
#endif
|
||||
@ -598,8 +600,9 @@ _mysql_ConnectionObject_Initialize(
|
||||
&read_default_group,
|
||||
&client_flag, &ssl,
|
||||
&local_infile
|
||||
#ifdef HAVE_MYSQL_OPT_READ_TIMEOUT
|
||||
#ifdef HAVE_MYSQL_OPT_TIMEOUTS
|
||||
, &read_timeout
|
||||
, &write_timeout
|
||||
#endif
|
||||
))
|
||||
return -1;
|
||||
@ -636,12 +639,17 @@ _mysql_ConnectionObject_Initialize(
|
||||
mysql_options(&(self->connection), MYSQL_OPT_CONNECT_TIMEOUT,
|
||||
(char *)&timeout);
|
||||
}
|
||||
#ifdef HAVE_MYSQL_OPT_READ_TIMEOUT
|
||||
#ifdef HAVE_MYSQL_OPT_TIMEOUTS
|
||||
if (read_timeout) {
|
||||
unsigned int timeout = read_timeout;
|
||||
mysql_options(&(self->connection), MYSQL_OPT_READ_TIMEOUT,
|
||||
(char *)&timeout);
|
||||
}
|
||||
if (write_timeout) {
|
||||
unsigned int timeout = write_timeout;
|
||||
mysql_options(&(self->connection), MYSQL_OPT_WRITE_TIMEOUT,
|
||||
(char *)&timeout);
|
||||
}
|
||||
#endif
|
||||
if (compress != -1) {
|
||||
mysql_options(&(self->connection), MYSQL_OPT_COMPRESS, 0);
|
||||
@ -891,7 +899,21 @@ _mysql_ConnectionObject_autocommit(
|
||||
if (err) return _mysql_Exception(self);
|
||||
Py_INCREF(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__[] =
|
||||
"Commits the current transaction\n\
|
||||
@ -2317,6 +2339,12 @@ static PyMethodDef _mysql_ConnectionObject_methods[] = {
|
||||
METH_VARARGS,
|
||||
_mysql_ConnectionObject_autocommit__doc__
|
||||
},
|
||||
{
|
||||
"get_autocommit",
|
||||
(PyCFunction)_mysql_ConnectionObject_get_autocommit,
|
||||
METH_NOARGS,
|
||||
_mysql_ConnectionObject_get_autocommit__doc__
|
||||
},
|
||||
{
|
||||
"commit",
|
||||
(PyCFunction)_mysql_ConnectionObject_commit,
|
||||
|
@ -71,8 +71,9 @@ def get_config():
|
||||
if i.startswith(compiler_flag('I')) ]
|
||||
|
||||
if static:
|
||||
extra_objects.append(os.path.join(
|
||||
library_dirs[0],'lib%s.a' % client))
|
||||
extra_objects.append(os.path.join(library_dirs[0],'lib%s.a' % client))
|
||||
if client in libraries:
|
||||
libraries.remove(client)
|
||||
|
||||
name = "MySQL-python"
|
||||
if enabled(options, 'embedded'):
|
||||
|
@ -77,7 +77,7 @@ class test_MySQLdb(capabilities.DatabaseTest):
|
||||
try:
|
||||
self.cursor.execute("describe some_non_existent_table");
|
||||
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):
|
||||
c = self.cursor
|
||||
|
Reference in New Issue
Block a user