Skip to content

Commit afcf052

Browse files
committed
Merge branch 'release/2.2.1' into develop
2 parents 1d41cb6 + d40a8b0 commit afcf052

File tree

7 files changed

+79
-17
lines changed

7 files changed

+79
-17
lines changed

CHANGES.txt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,22 @@ Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
88
Full release notes:
99
http://dev.mysql.com/doc/relnotes/connector-python/en/
1010

11+
v2.2.1
12+
======
13+
14+
- Add support for Protocol Buffers 3
15+
- Add View support (without DDL)
16+
- Implement get_default_schema() method in BaseSchema
17+
- DevAPI: Per ReplicaSet SQL execution
18+
- DevAPI: XSession accepts a list of routers
19+
- DevAPI: Define action on adding empty list of documents
20+
- BUG23729357: Fix fetching BIT datatype
21+
- BUG23583381: Add who_am_i and am_i_real methods to DatabaseObject
22+
- BUG23568257: Add fetch_one method to mysqlx.result
23+
- BUG23550743: Add close method to XSession and NodeSession
24+
- BUG23550057: Add support for URI as connection data
25+
1126
v2.2.0
1227
======
1328

1429
- Provide initial implementation of new DevAPI
15-

README.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ License information can be found in the LICENSE.txt file.
1111
Requirements
1212
============
1313

14-
Python Protobuf (version >= 2.6.1)
14+
Python Protobuf (version >= 3.0.0)
1515
https://developers.google.com/protocol-buffers/docs/downloads
1616

1717

cpyint

lib/cpy_distutils.py

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# MySQL Connector/Python - MySQL driver written in Python.
2-
# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
2+
# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
33

44
# MySQL Connector/Python is licensed under the terms of the GPLv2
55
# <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -125,7 +125,11 @@ def unix_lib_is64bit(lib_file):
125125
lib_file = mysqlclient_libs[-1]
126126

127127
log.debug("# Using file command to test lib_file {0}".format(lib_file))
128-
prc = Popen(['file', '-L', lib_file], stdin=PIPE, stderr=STDOUT,
128+
if platform.uname() == 'SunOS':
129+
cmd_list = ['file', '-L', lib_file]
130+
else:
131+
cmd_list = ['file', '-L', lib_file]
132+
prc = Popen(cmd_list, stdin=PIPE, stderr=STDOUT,
129133
stdout=PIPE)
130134
stdout = prc.communicate()[0]
131135
stdout = stdout.split(':')[1]
@@ -166,6 +170,9 @@ def get_mysql_config_info(mysql_config):
166170
libs = shlex.split(info['libs'])
167171
info['lib_dir'] = libs[0].replace('-L', '')
168172
info['libs'] = [ lib.replace('-l', '') for lib in libs[1:] ]
173+
if platform.uname()[0] == 'SunOS':
174+
info['lib_dir'] = info['lib_dir'].replace('-R', '')
175+
info['libs'] = [lib.replace('-R', '') for lib in info['libs']]
169176
log.debug("# info['libs']: ")
170177
for lib in info['libs']:
171178
log.debug("# {0}".format(lib))
@@ -178,7 +185,17 @@ def get_mysql_config_info(mysql_config):
178185
# Try to figure out the architecture
179186
info['arch'] = None
180187
if os.name == 'posix':
181-
pathname = os.path.join(info['lib_dir'], 'lib' + info['libs'][0]) + '*'
188+
if platform.uname()[0] == 'SunOS':
189+
print("info['lib_dir']: {0}".format(info['lib_dir']))
190+
print("info['libs'][0]: {0}".format(info['libs'][0]))
191+
pathname = os.path.abspath(os.path.join(info['lib_dir'],
192+
'lib',
193+
info['libs'][0])) + '/*'
194+
else:
195+
pathname = os.path.join(info['lib_dir'],
196+
'lib' + info['libs'][0]) + '*'
197+
print("# Looking mysqlclient_lib at path: {0}".format(pathname))
198+
log.debug("# searching mysqlclient_lib at: %s", pathname)
182199
libs = glob(pathname)
183200
mysqlclient_libs = []
184201
for filepath in libs:
@@ -198,7 +215,12 @@ def get_mysql_config_info(mysql_config):
198215
log.debug("#+ {0}".format(mysqlclient_lib))
199216
log.debug("# tested mysqlclient_lib[-1]: "
200217
"{0}".format(mysqlclient_libs[-1]))
201-
proc = Popen(['file', '-L', mysqlclient_libs[-1]], stdout=PIPE,
218+
if platform.uname()[0] == 'SunOS':
219+
print("mysqlclient_lib: {0}".format(mysqlclient_libs[-1]))
220+
cmd_list = ['file', mysqlclient_libs[-1]]
221+
else:
222+
cmd_list = ['file', '-L', mysqlclient_libs[-1]]
223+
proc = Popen(cmd_list, stdout=PIPE,
202224
universal_newlines=True)
203225
stdout, _ = proc.communicate()
204226
stdout = stdout.split(':')[1]
@@ -360,9 +382,9 @@ def _finalize_connector_c(self, connc_loc):
360382
# We try to offer a nice message when the architecture of Python
361383
# is not the same as MySQL Connector/C binaries.
362384
py_arch = '64-bit' if ARCH_64BIT else '32-bit'
363-
log.debug("# Python architecture: {0}".format(py_arch))
364-
log.debug("# Python ARCH_64BIT: {0}".format(ARCH_64BIT))
365-
log.debug("# self.arch: {0}".format(self.arch))
385+
print("# Python architecture: {0}".format(py_arch))
386+
print("# Python ARCH_64BIT: {0}".format(ARCH_64BIT))
387+
print("# self.arch: {0}".format(self.arch))
366388
if ARCH_64BIT != connc_64bit:
367389
log.error("Python is {0}, but does not "
368390
"match MySQL C API {1} architecture, "

lib/mysqlx/authentication.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,32 @@
2424
"""Implementation of MySQL Authentication Plugin."""
2525

2626
import hashlib
27+
import struct
28+
29+
from .compat import PY3, UNICODE_TYPES, hexlify
2730

2831

2932
class MySQL41AuthPlugin(object):
3033
def __init__(self, username, password):
3134
self._username = username
32-
self._password = password
35+
self._password = password.encode("utf-8") \
36+
if isinstance(password, UNICODE_TYPES) else password
3337

3438
def name(self):
3539
return "MySQL 4.1 Authentication Plugin"
3640

3741
def auth_name(self):
3842
return "MYSQL41"
3943

40-
def xor_string(self, a, b):
44+
def xor_string(self, hash1, hash2):
4145
"""Encrypt/Decrypt function used for password encryption in
4246
authentication, using a simple XOR.
4347
"""
44-
return "".join([chr(ord(x) ^ ord(y)) for x, y in zip(a, b)])
48+
if PY3:
49+
xored = [h1 ^ h2 for (h1, h2) in zip(hash1, hash2)]
50+
else:
51+
xored = [ord(h1) ^ ord(h2) for (h1, h2) in zip(hash1, hash2)]
52+
return struct.pack("20B", *xored)
4553

4654
def build_authentication_response(self, data):
4755
"""Hashing for MySQL 4.1 authentication
@@ -50,7 +58,8 @@ def build_authentication_response(self, data):
5058
h1 = hashlib.sha1(self._password).digest()
5159
h2 = hashlib.sha1(h1).digest()
5260
auth_response = self.xor_string(
53-
h1, hashlib.sha1(data + h2).digest()).encode("hex")
54-
return "{0}\0{1}\0*{2}\0".format("", self._username, auth_response)
61+
h1, hashlib.sha1(data + h2).digest())
62+
return "{0}\0{1}\0*{2}\0".format("", self._username,
63+
hexlify(auth_response))
5564
else:
5665
return "{0}\0{1}\0".format("", self._username)

lib/mysqlx/compat.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,31 @@
2525

2626
import sys
2727
import decimal
28+
import binascii
29+
2830

2931
PY3 = sys.version_info.major == 3
3032

3133

3234
if PY3:
3335
from urllib.parse import urlparse
36+
37+
def hexlify(data):
38+
return binascii.hexlify(data).decode("utf-8")
39+
3440
NUMERIC_TYPES = (int, float, decimal.Decimal,)
3541
INT_TYPES = (int,)
3642
UNICODE_TYPES = (str,)
3743
STRING_TYPES = (str,)
3844
BYTE_TYPES = (bytearray, bytes,)
45+
46+
3947
else:
4048
from urlparse import urlparse
49+
50+
def hexlify(data):
51+
return data.encode("hex")
52+
4153
NUMERIC_TYPES = (int, float, decimal.Decimal, long,)
4254
INT_TYPES = (int, long,)
4355
UNICODE_TYPES = (unicode,)

tests/test_mysqlx_connection.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,17 @@
6565
("áé'í'óú:unicode@127.0.0.1",
6666
{"schema": "", "host": "127.0.0.1", "password": "unicode",
6767
"port": 33060, "user": "áé'í'óú"}),
68+
("unicode:áé'í'óú@127.0.0.1",
69+
{"schema": "", "host": "127.0.0.1", "password": "áé'í'óú",
70+
"port": 33060, "user": "unicode"}),
6871
)
6972

7073

7174
_ROUTER_LIST_RESULTS = ( # (uri, result)
72-
("áé'í'óú:unicode@127.0.0.1", {"schema": "", "host": "127.0.0.1", "port": 33060,
73-
"password": "unicode", "user": "áé'í'óú"}),
75+
("áé'í'óú:unicode@127.0.0.1", {"schema": "", "host": "127.0.0.1",
76+
"port": 33060, "password": "unicode", "user": "áé'í'óú"}),
77+
("unicode:áé'í'óú@127.0.0.1", {"schema": "", "host": "127.0.0.1",
78+
"port": 33060, "password": "áé'í'óú", "user": "unicode"}),
7479
("user:password@[127.0.0.1, localhost]", {"schema": "", "routers":
7580
[{"host": "127.0.0.1", "port": 33060}, {"host": "localhost", "port":
7681
33060}], "password": "password", "user": "user"}),

0 commit comments

Comments
 (0)