Skip to content

Master 2.0 #27

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 54 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
f286c0f
BUG19584116: Fix extra signal causing runtime error in Django
peeyushgupta Sep 10, 2014
a297798
BUG19522948: Fix data corruption with TEXT and prepared statements
peeyushgupta Sep 30, 2014
594ba11
BUG19584051: Fix comparision of type_code of columns for PEP-249
peeyushgupta Sep 25, 2014
5ad222d
BUG19660283: Fix failing unit tests with MySQL server 5.7.5
peeyushgupta Oct 1, 2014
e7b9eef
Update CPYINT revision
Oct 1, 2014
3ca12b0
BUG19667984: Fix converting invalid datetime values in Django backend
peeyushgupta Oct 8, 2014
f7c5ee8
Update CPYINT revision
Oct 8, 2014
a1328a7
BUG19711759: Fix Pylint issue in network module
peeyushgupta Oct 8, 2014
fae86c0
BUG19642249: Improve errors reporting invalid sharding keys
Oct 10, 2014
740912f
BUG19549363: Raise error when compression used with reset_session
peeyushgupta Oct 10, 2014
57504c8
BUG19677659: Move testings of errors to internal repository
peeyushgupta Sep 30, 2014
89a731e
BUG19500097: Fix string decoding with binary character set
peeyushgupta Oct 1, 2014
282e371
BUG19642249: Improve errors reporting invalid sharding keys
Oct 10, 2014
cb3ccf5
Prepare release 2.0.2
Oct 10, 2014
29a45f0
Update CPYINT revision
Oct 11, 2014
bd21ac9
Update CPYINT revision
Oct 14, 2014
0f68012
Merge branch 'release-2.0.2' into master-2.0
Nov 14, 2014
3476c09
BUG19803702: Fix reporting errors with non-ascii characters
peeyushgupta Nov 14, 2014
6bce471
BUG74483: Lost connection to server error during query
peeyushgupta Oct 30, 2014
08847cc
Merge branch 'BUG19930054' into maintenance-2.0.3
peeyushgupta Nov 26, 2014
142dba9
BUG19331658: Fix connection pooling with MySQL Fabric
peeyushgupta Nov 12, 2014
f27093e
BUG19972427: Fix creating of redundant connections in Django
peeyushgupta Dec 4, 2014
f452732
BUG19331658: Fix connection pooling with MySQL Fabric
peeyushgupta Dec 5, 2014
3889e86
BUG19777815: Add support for warnings with MySQLCursor.callproc()
peeyushgupta Dec 12, 2014
cdacb3f
BUG19703022: Fix using passwords with integers only in option files
peeyushgupta Nov 4, 2014
c522648
Update CPYINT revision
Dec 15, 2014
d942d37
Prepare release 2.0.3
Dec 15, 2014
cf3cd96
Update CPYINT revision
Dec 16, 2014
02d6729
Update CPYINT revision
Dec 17, 2014
36dfa81
Update CPYINT revision
Dec 18, 2014
732df13
Update CPYINT revision
Dec 18, 2014
5802db9
Update CPYINT revision
Jan 12, 2015
9de5f81
Update CPYINT revision
Jan 13, 2015
6a8f266
Change copyright year to 2015
Jan 14, 2015
07cabd3
Change copyright year to 2015 in README.txt
Jan 19, 2015
af58f23
Update CPYINT revision
Jan 23, 2015
8b05e4a
Merge branch 'release-2.0.3' into master-2.0
Jan 29, 2015
990d601
BUG20106629: Support Django Safetext and SafeBytes type
peeyushgupta Dec 2, 2014
6c06989
BUG20407036: Fix incorrect arguments to mysld_stmt_execute error
peeyushgupta Jan 27, 2015
004edd0
BUG20301989: Fix conversion of empty set
peeyushgupta Mar 12, 2015
2a37147
BUG20462427: Fix receiving large field data from server
peeyushgupta Mar 20, 2015
06aa860
BUG20324089: Fix HASH based sharding with MySQL Fabric
peeyushgupta Feb 18, 2015
8e0cd7e
Prepare release 2.0.4
peeyushgupta Mar 30, 2015
78bec22
Update CPYINT revision
peeyushgupta Mar 31, 2015
f45b5d9
Update CPYINT revision
peeyushgupta Mar 31, 2015
5186cf1
Update CPYINT revision
peeyushgupta Apr 1, 2015
44e81a6
Merge branch 'release-2.0.4' into master-2.0
peeyushgupta Apr 22, 2015
c70adb3
Remove old python-internal submodule
nmariz Oct 4, 2016
7be8e73
Add connector-python-internal submodule
nmariz Oct 4, 2016
c026c37
BUG22529828: Fix potential SQL injection
nmariz Oct 4, 2016
5b680be
Fix version and update CPYINT revision
nmariz Oct 4, 2016
641a56f
Update CPYINT revision
nmariz Oct 6, 2016
9373f5c
Update copyright year in README.txt
nmariz Oct 12, 2016
36d868e
Fix copyright year in README.txt
nmariz Oct 17, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[submodule "cpyint"]
path = cpyint
url = ../python-internal.git
branch = master
url = ../connector-python-internal
branch = master-2.0
41 changes: 40 additions & 1 deletion CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,50 @@ MySQL Connector/Python 2.0 - Release Notes & Changes
====================================================

MySQL Connector/Python
Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.

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


v2.0.5
======
- BUG22529828: Fix potencial SQL injection

v2.0.4
======

- BUG20324089: Fix HASH based sharding with MySQL Fabric
- BUG20462427: Fix receiving large field data from server
- BUG20301989: Fix conversion of empty set
- BUG20407036: Fix incorrect arguments to mysld_stmt_execute error
- BUG20106629: Support Django Safetext and SafeBytes type

v2.0.3
======

- BUG19703022: Fix using passwords with integers only in option files
- BUG19777815: Add support for warnings with MySQLCursor.callproc()
- BUG19972427: Fix creating of redundant connections in Django
- BUG19331658: Fix connection pooling with MySQL Fabric
- BUG19930054: Lost connection to server error during query
- BUG19803702: Fix reporting errors with non-ascii characters

v2.0.2
======

- BUG19500097: Fix string decoding with binary character set
- BUG19677659: Move testings of errors to internal repository
- BUG19549363: Raise error when compression used with reset_session
- BUG19642249: Improve errors reporting invalid sharding keys
- BUG19711759: Fix Pylint issue in network module
- BUG19667984: Fix converting invalid datetime values in Django backend
- BUG19660283: Fix failing unit tests with MySQL server 5.7.5
- BUG19584051: Fix comparison of type_code of columns for PEP-249
- BUG19522948: Fix data corruption with TEXT and prepared statements
- BUG19584116: Fix extra signal causing runtime error in Django


v2.0.1
======

Expand Down
4 changes: 2 additions & 2 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ MySQL Connector/Python 2.0
==========================

MySQL Connector/Python
Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.

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

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

Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.

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

Expand Down
2 changes: 1 addition & 1 deletion cpyint
3 changes: 3 additions & 0 deletions lib/mysql/connector/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ def connect(*args, **kwargs):
raise InterfaceError("fabric and failover arguments can not be used")

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

Expand Down
17 changes: 14 additions & 3 deletions lib/mysql/connector/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def __init__(self, *args, **kwargs):
self._ssl_active = False
self._auth_plugin = None
self._pool_config_version = None
self._compress = False

if len(kwargs) > 0:
self.connect(**kwargs)
Expand Down Expand Up @@ -271,6 +272,7 @@ def config(self, **kwargs):

try:
if config['compress']:
self._compress = True
self.set_client_flags([ClientFlag.COMPRESS])
except KeyError:
pass # Missing compress argument is OK
Expand Down Expand Up @@ -884,6 +886,10 @@ def cmd_change_user(self, username='', password='', database='',
if self.unread_result:
raise errors.InternalError("Unread result found.")

if self._compress:
raise errors.NotSupportedError("Change user is not supported with "
"compression.")

packet = self._protocol.make_change_user(
handshake=self._handshake,
username=username, password=password, database=database,
Expand Down Expand Up @@ -943,8 +949,13 @@ def reset_session(self, user_variables=None, session_variables=None):
try:
self.cmd_reset_connection()
except errors.NotSupportedError:
self.cmd_change_user(self._user, self._password,
self._database, self._charset_id)
if self._compress:
raise errors.NotSupportedError(
"Reset session is not supported with compression for "
"MySQL server version 5.7.2 or earlier.")
else:
self.cmd_change_user(self._user, self._password,
self._database, self._charset_id)

cur = self.cursor()
if user_variables:
Expand Down Expand Up @@ -1135,7 +1146,7 @@ def python_charset(self):
Returns a string.
"""
encoding = CharacterSet.get_info(self._charset_id)[0]
if encoding == 'utf8mb4':
if encoding in ('utf8mb4', 'binary'):
return 'utf8'
else:
return encoding
Expand Down
23 changes: 18 additions & 5 deletions lib/mysql/connector/conversion.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# MySQL Connector/Python - MySQL driver written in Python.
# Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.

# MySQL Connector/Python is licensed under the terms of the GPLv2
# <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
Expand Down Expand Up @@ -66,7 +66,11 @@ def set_unicode(self, value=True):

def to_mysql(self, value):
"""Convert Python data type to MySQL"""
return value
type_name = value.__class__.__name__.lower()
try:
return getattr(self, "_{0}_to_mysql".format(type_name))(value)
except AttributeError:
return value

def to_python(self, vtype, value):
"""Convert MySQL data type to Python"""
Expand Down Expand Up @@ -178,10 +182,15 @@ def _str_to_mysql(self, value):

def _unicode_to_mysql(self, value):
"""Convert unicode"""
encoded = value.encode(self.charset)
if self.charset_id in CharacterSet.slash_charsets:
charset = self.charset
charset_id = self.charset_id
if charset == 'binary':
charset = 'utf8'
charset_id = CharacterSet.get_charset_info(charset)[0]
encoded = value.encode(charset)
if charset_id in CharacterSet.slash_charsets:
if b'\x5c' in encoded:
return HexLiteral(value, self.charset)
return HexLiteral(value, charset)
return encoded

def _bytes_to_mysql(self, value):
Expand Down Expand Up @@ -517,6 +526,8 @@ def _SET_to_python(self, value, dsc=None): # pylint: disable=C0103
"""
set_type = None
val = value.decode(self.charset)
if not val:
return set()
try:
set_type = set(val.split(','))
except ValueError:
Expand All @@ -537,6 +548,8 @@ def _STRING_to_python(self, value, dsc=None): # pylint: disable=C0103
if dsc[7] & FieldFlag.BINARY:
return value

if self.charset == 'binary':
return value
if isinstance(value, (bytes, bytearray)) and self.use_unicode:
return value.decode(self.charset)

Expand Down
63 changes: 53 additions & 10 deletions lib/mysql/connector/cursor.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# MySQL Connector/Python - MySQL driver written in Python.
# Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.

# MySQL Connector/Python is licensed under the terms of the GPLv2
# <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
Expand Down Expand Up @@ -29,6 +29,7 @@
import weakref

from . import errors
from .catch23 import PY2

SQL_COMMENT = r"\/\*.*?\*\/"
RE_SQL_COMMENT = re.compile(
Expand All @@ -42,6 +43,14 @@
re.I | re.M | re.S)
RE_SQL_INSERT_VALUES = re.compile(r'.*VALUES\s*(\(.*\)).*', re.I | re.M | re.S)
RE_PY_PARAM = re.compile(b'(%s)')
RE_PY_MAPPING_PARAM = re.compile(
br'''
%
\((?P<mapping_key>[^)]+)\)
(?P<conversion_type>[diouxXeEfFgGcrs%])
''',
re.X
)
RE_SQL_SPLIT_STMTS = re.compile(
b''';(?=(?:[^"'`]*["'`][^"'`]*["'`])*[^"'`]*$)''')
RE_SQL_FIND_PARAM = re.compile(
Expand Down Expand Up @@ -73,6 +82,35 @@ def remaining(self):
return len(self.params) - self.index


def _bytestr_format_dict(bytestr, value_dict):
"""
>>> _bytestr_format_dict(b'%(a)s', {b'a': b'foobar'})
b'foobar
>>> _bytestr_format_dict(b'%%(a)s', {b'a': b'foobar'})
b'%%(a)s'
>>> _bytestr_format_dict(b'%%%(a)s', {b'a': b'foobar'})
b'%%foobar'
>>> _bytestr_format_dict(b'%(x)s %(y)s',
... {b'x': b'x=%(y)s', b'y': b'y=%(x)s'})
b'x=%(y)s y=%(x)s'
"""
def replace(matchobj):
value = None
groups = matchobj.groupdict()
if groups["conversion_type"] == b"%":
value = b"%"
if groups["conversion_type"] == b"s":
key = groups["mapping_key"].encode("utf-8") \
if PY2 else groups["mapping_key"]
value = value_dict[key]
if value is None:
raise ValueError("Unsupported conversion_type: {0}"
"".format(groups["conversion_type"]))
return value.decode("utf-8") if PY2 else value
return RE_PY_MAPPING_PARAM.sub(replace, bytestr.decode("utf-8")
if PY2 else bytestr)


class CursorBase(object):
"""
Base for defining MySQLCursor. This class is a skeleton and defines
Expand Down Expand Up @@ -355,7 +393,10 @@ def _process_params_dict(self, params):
conv = to_mysql(conv)
conv = escape(conv)
conv = quote(conv)
res["%({0})s".format(key).encode()] = conv
if PY2:
res[key] = conv
else:
res[key.encode()] = conv
except Exception as err:
raise errors.ProgrammingError(
"Failed processing pyformat-parameters; %s" % err)
Expand Down Expand Up @@ -488,8 +529,8 @@ def execute(self, operation, params=None, multi=False):

if params is not None:
if isinstance(params, dict):
for key, value in self._process_params_dict(params).items():
stmt = stmt.replace(key, value)
stmt = _bytestr_format_dict(
stmt, self._process_params_dict(params))
elif isinstance(params, (list, tuple)):
psub = _ParamSubstitutor(self._process_params(params))
stmt = RE_PY_PARAM.sub(psub, stmt)
Expand Down Expand Up @@ -543,8 +584,8 @@ def remove_comments(match):
for params in seq_params:
tmp = fmt
if isinstance(params, dict):
for key, value in self._process_params_dict(params).items():
tmp = tmp.replace(key, value)
tmp = _bytestr_format_dict(
tmp, self._process_params_dict(params))
else:
psub = _ParamSubstitutor(self._process_params(params))
tmp = RE_PY_PARAM.sub(psub, tmp)
Expand Down Expand Up @@ -697,12 +738,14 @@ def callproc(self, procname, args=()):
call = "CALL {0}({1})".format(procname, ','.join(argnames))

for result in self._connection.cmd_query_iter(call):
# pylint: disable=W0212
tmp = MySQLCursorBuffered(self._connection._get_self())
tmp._handle_result(result)
if tmp._warnings is not None:
self._warnings = tmp._warnings
# pylint: enable=W0212
if 'columns' in result:
# pylint: disable=W0212
tmp = MySQLCursorBuffered(self._connection._get_self())
tmp._handle_result(result)
results.append(tmp)
# pylint: enable=W0212

if argnames:
select = "SELECT {0}".format(','.join(argtypes))
Expand Down
24 changes: 14 additions & 10 deletions lib/mysql/connector/dbapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,22 @@

from . import constants

class _DBAPITypeObject:
class _DBAPITypeObject(object):

def __init__(self, *values):
self.values = values

def __cmp__(self, other):
def __eq__(self, other):
if other in self.values:
return 0
if other < self.values:
return 1
return True
else:
return -1
return False

def __ne__(self, other):
if other in self.values:
return False
else:
return True

Date = datetime.date
Time = datetime.time
Expand All @@ -64,8 +68,8 @@ def TimestampFromTicks(ticks):

Binary = bytes

STRING = _DBAPITypeObject(constants.FieldType.get_string_types())
BINARY = _DBAPITypeObject(constants.FieldType.get_binary_types())
NUMBER = _DBAPITypeObject(constants.FieldType.get_number_types())
DATETIME = _DBAPITypeObject(constants.FieldType.get_timestamp_types())
STRING = _DBAPITypeObject(*constants.FieldType.get_string_types())
BINARY = _DBAPITypeObject(*constants.FieldType.get_binary_types())
NUMBER = _DBAPITypeObject(*constants.FieldType.get_number_types())
DATETIME = _DBAPITypeObject(*constants.FieldType.get_timestamp_types())
ROWID = _DBAPITypeObject()
Loading