Skip to content

Commit 8b05e4a

Browse files
author
Geert Vanderkelen
committed
Merge branch 'release-2.0.3' into master-2.0
2 parents 0f68012 + af58f23 commit 8b05e4a

File tree

18 files changed

+221
-53
lines changed

18 files changed

+221
-53
lines changed

CHANGES.txt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,21 @@ MySQL Connector/Python 2.0 - Release Notes & Changes
33
====================================================
44

55
MySQL Connector/Python
6-
Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
6+
Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
77

88
Full release notes:
99
http://dev.mysql.com/doc/relnotes/connector-python/en/
1010

11+
v2.0.3
12+
======
13+
14+
- BUG19703022: Fix using passwords with integers only in option files
15+
- BUG19777815: Add support for warnings with MySQLCursor.callproc()
16+
- BUG19972427: Fix creating of redundant connections in Django
17+
- BUG19331658: Fix connection pooling with MySQL Fabric
18+
- BUG19930054: Lost connection to server error during query
19+
- BUG19803702: Fix reporting errors with non-ascii characters
20+
1121
v2.0.2
1222
======
1323

README.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ MySQL Connector/Python 2.0
33
==========================
44

55
MySQL Connector/Python
6-
Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
6+
Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
77

88
License information can be found in the LICENSE.txt file.
99

@@ -28,7 +28,7 @@ doubt, this particular copy of the software is released
2828
under the version 2 of the GNU General Public License.
2929
MySQL Connector/Python is brought to you by Oracle.
3030

31-
Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
31+
Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
3232

3333
License information can be found in the LICENSE.txt file.
3434

cpyint

lib/mysql/connector/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ def connect(*args, **kwargs):
139139
raise InterfaceError("fabric and failover arguments can not be used")
140140

141141
if 'fabric' in kwargs:
142+
if 'pool_name' in kwargs:
143+
raise AttributeError("'pool_name' argument is not supported with "
144+
" MySQL Fabric. Use 'pool_size' instead.")
142145
from .fabric import connect as fabric_connect
143146
return fabric_connect(*args, **kwargs)
144147

lib/mysql/connector/conversion.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,11 @@ def set_unicode(self, value=True):
6666

6767
def to_mysql(self, value):
6868
"""Convert Python data type to MySQL"""
69-
return value
69+
type_name = value.__class__.__name__.lower()
70+
try:
71+
return getattr(self, "_{0}_to_mysql".format(type_name))(value)
72+
except AttributeError:
73+
return value
7074

7175
def to_python(self, vtype, value):
7276
"""Convert MySQL data type to Python"""

lib/mysql/connector/cursor.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -697,12 +697,14 @@ def callproc(self, procname, args=()):
697697
call = "CALL {0}({1})".format(procname, ','.join(argnames))
698698

699699
for result in self._connection.cmd_query_iter(call):
700+
# pylint: disable=W0212
701+
tmp = MySQLCursorBuffered(self._connection._get_self())
702+
tmp._handle_result(result)
703+
if tmp._warnings is not None:
704+
self._warnings = tmp._warnings
705+
# pylint: enable=W0212
700706
if 'columns' in result:
701-
# pylint: disable=W0212
702-
tmp = MySQLCursorBuffered(self._connection._get_self())
703-
tmp._handle_result(result)
704707
results.append(tmp)
705-
# pylint: enable=W0212
706708

707709
if argnames:
708710
select = "SELECT {0}".format(','.join(argtypes))

lib/mysql/connector/django/base.py

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ def __init__(self, connection):
192192
self.supports_microsecond_precision = self._microseconds_precision()
193193

194194
def _microseconds_precision(self):
195-
if self.connection.server_version >= (5, 6, 3):
195+
if self.connection.mysql_version >= (5, 6, 3):
196196
return True
197197
return False
198198

@@ -212,7 +212,7 @@ def _mysql_storage_engine(self):
212212
cursor.execute(droptable)
213213
cursor.execute('CREATE TABLE {table} (X INT)'.format(table=tblname))
214214

215-
if self.connection.server_version >= (5, 0, 0):
215+
if self.connection.mysql_version >= (5, 0, 0):
216216
cursor.execute(
217217
"SELECT ENGINE FROM INFORMATION_SCHEMA.TABLES "
218218
"WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s",
@@ -399,7 +399,7 @@ def sequence_reset_by_name_sql(self, style, sequences):
399399
# Truncate already resets the AUTO_INCREMENT field from
400400
# MySQL version 5.0.13 onwards. Refs #16961.
401401
res = []
402-
if self.connection.server_version < (5, 0, 13):
402+
if self.connection.mysql_version < (5, 0, 13):
403403
fmt = "{alter} {table} {{tablename}} {auto_inc} {field};".format(
404404
alter=style.SQL_KEYWORD('ALTER'),
405405
table=style.SQL_KEYWORD('TABLE'),
@@ -431,13 +431,7 @@ def value_to_db_datetime(self, value):
431431
"MySQL backend does not support timezone-aware times."
432432
)
433433

434-
try:
435-
# Django 1.6
436-
self.connection.ensure_connection()
437-
except AttributeError:
438-
if not self.connection.connection:
439-
self.connection._connect()
440-
return self.connection.connection.converter._datetime_to_mysql(value)
434+
return self.connection.converter.to_mysql(value)
441435

442436
def value_to_db_time(self, value):
443437
if value is None:
@@ -448,13 +442,7 @@ def value_to_db_time(self, value):
448442
raise ValueError("MySQL backend does not support timezone-aware "
449443
"times.")
450444

451-
try:
452-
# Django 1.6
453-
self.connection.ensure_connection()
454-
except AttributeError:
455-
if not self.connection.connection:
456-
self.connection._connect()
457-
return self.connection.connection.converter._time_to_mysql(value)
445+
return self.connection.converter.to_mysql(value)
458446

459447
def year_lookup_bounds(self, value):
460448
# Again, no microseconds
@@ -467,7 +455,7 @@ def year_lookup_bounds_for_datetime_field(self, value):
467455
# Again, no microseconds
468456
first, second = super(DatabaseOperations,
469457
self).year_lookup_bounds_for_datetime_field(value)
470-
if self.connection.server_version >= (5, 6, 4):
458+
if self.connection.mysql_version >= (5, 6, 4):
471459
return [first.replace(microsecond=0), second]
472460
else:
473461
return [first.replace(microsecond=0),
@@ -522,15 +510,8 @@ class DatabaseWrapper(BaseDatabaseWrapper):
522510

523511
def __init__(self, *args, **kwargs):
524512
super(DatabaseWrapper, self).__init__(*args, **kwargs)
525-
self.server_version = None
526-
527-
# Since some features depend on the MySQL version, we need to connect
528-
try:
529-
# Django 1.6
530-
self.ensure_connection()
531-
except AttributeError:
532-
self._connect()
533513

514+
self.converter = DjangoMySQLConverter()
534515
self.ops = DatabaseOperations(self)
535516
self.features = DatabaseFeatures(self)
536517
self.client = DatabaseClient(self)
@@ -584,14 +565,13 @@ def get_connection_params(self):
584565
def get_new_connection(self, conn_params):
585566
# Django 1.6
586567
cnx = mysql.connector.connect(**conn_params)
587-
self.server_version = cnx.get_server_version()
588568
cnx.set_converter_class(DjangoMySQLConverter)
589569

590570
return cnx
591571

592572
def init_connection_state(self):
593573
# Django 1.6
594-
if self.server_version < (5, 5, 3):
574+
if self.mysql_version < (5, 5, 3):
595575
# See sysvar_sql_auto_is_null in MySQL Reference manual
596576
self.connection.cmd_query("SET SQL_AUTO_IS_NULL = 0")
597577

@@ -737,6 +717,11 @@ def is_usable(self):
737717
# Django 1.6
738718
return self.connection.is_connected()
739719

740-
@property
720+
@cached_property
741721
def mysql_version(self):
742-
return self.server_version
722+
config = self.get_connection_params()
723+
temp_conn = mysql.connector.connect(**config)
724+
server_version = temp_conn.get_server_version()
725+
temp_conn.close()
726+
727+
return server_version

lib/mysql/connector/django/creation.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def __init__(self, connection):
3030
'IntegerField': 'integer',
3131
'BigIntegerField': 'bigint',
3232
'IPAddressField': 'char(15)',
33+
3334
'GenericIPAddressField': 'char(39)',
3435
'NullBooleanField': 'bool',
3536
'OneToOneField': 'integer',
@@ -42,7 +43,7 @@ def __init__(self, connection):
4243
}
4344

4445
# Support for microseconds
45-
if self.connection.get_server_version() >= (5, 6, 4):
46+
if self.connection.mysql_version >= (5, 6, 4):
4647
self.data_types.update({
4748
'DateTimeField': 'datetime(6)',
4849
'TimeField': 'time(6)',

lib/mysql/connector/errors.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
from . import utils
2828
from .locales import get_client_error
29+
from .catch23 import PY2
2930

3031
# _CUSTOM_ERROR_EXCEPTIONS holds custom exceptions and is ued by the
3132
# function custom_error_exception. _ERROR_EXCEPTIONS (at bottom of module)
@@ -187,7 +188,7 @@ def __init__(self, msg=None, errno=None, values=None, sqlstate=None):
187188
if self.msg and self.errno != -1:
188189
fields = {
189190
'errno': self.errno,
190-
'msg': self.msg
191+
'msg': self.msg.encode('utf8') if PY2 else self.msg
191192
}
192193
if self.sqlstate:
193194
fmt = '{errno} ({state}): {msg}'

lib/mysql/connector/fabric/connection.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
HAVE_SSL = True
6262
# pylint: enable=F0401,E0611
6363

64-
from ..connection import MySQLConnection
64+
import mysql.connector
6565
from ..pooling import MySQLConnectionPool
6666
from ..errors import (
6767
Error, InterfaceError, NotSupportedError, MySQLFabricError, InternalError,
@@ -1123,6 +1123,8 @@ def store_config(self, **kwargs):
11231123
del test_config['pool_name']
11241124
if 'pool_size' in test_config:
11251125
del test_config['pool_size']
1126+
if 'pool_reset_session' in test_config:
1127+
del test_config['pool_reset_session']
11261128
try:
11271129
pool = MySQLConnectionPool(pool_name=str(uuid.uuid4()))
11281130
pool.set_config(**test_config)
@@ -1186,7 +1188,7 @@ def _connect(self):
11861188
dbconfig['host'] = mysqlserver.host
11871189
dbconfig['port'] = mysqlserver.port
11881190
try:
1189-
self._mysql_cnx = MySQLConnection(**dbconfig)
1191+
self._mysql_cnx = mysql.connector.connect(**dbconfig)
11901192
except Error as exc:
11911193
if counter == attempts:
11921194
self.reset_cache(mysqlserver.group)

lib/mysql/connector/network.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,12 @@ def recv_plain(self):
220220
"""Receive packets from the MySQL server"""
221221
try:
222222
# Read the header of the MySQL packet, 4 bytes
223-
packet = bytearray(4)
224-
read = self.sock.recv_into(packet, 4)
225-
if read != 4:
226-
raise errors.InterfaceError(errno=2013)
223+
packet = bytearray(b'')
224+
while len(packet) < 4:
225+
chunk = self.sock.recv(4)
226+
if not chunk:
227+
raise errors.InterfaceError(errno=2013)
228+
packet += chunk
227229

228230
# Save the packet number and payload length
229231
self._packet_number = packet[3]

lib/mysql/connector/optionfiles.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,14 @@ def read_option_files(**config):
103103
except KeyError:
104104
continue
105105

106+
not_evaluate = ('password', 'passwd')
106107
for option, value in config_options.items():
107108
if option not in config:
108109
try:
109-
config[option] = eval(value[0]) # pylint: disable=W0123
110+
if option in not_evaluate:
111+
config[option] = value[0]
112+
else:
113+
config[option] = eval(value[0]) # pylint: disable=W0123
110114
except (NameError, SyntaxError):
111115
config[option] = value[0]
112116

lib/mysql/connector/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
as mysql.connector.version.
2727
"""
2828

29-
VERSION = (2, 0, 2, '', 0)
29+
VERSION = (2, 0, 3, '', 0)
3030

3131
if VERSION[3] and VERSION[4]:
3232
VERSION_TEXT = '{0}.{1}.{2}{3}{4}'.format(*VERSION)

tests/data/option_files/my.cnf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
[client]
3+
password=12345
34
port=1000
45
socket=/var/run/mysqld/mysqld.sock
56
ssl-ca=dummyCA

0 commit comments

Comments
 (0)