8000 Merge pull request #411 from methane/feature/binary-prefix · pkdevboxy/PyMySQL@0b25a72 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0b25a72

Browse files
committed
Merge pull request PyMySQL#411 from methane/feature/binary-prefix
Add _binary prefix for binaries.
2 parents b1238f4 + 0e0b166 commit 0b25a72

File tree

3 files changed

+51
-36
lines changed

3 files changed

+51
-36
lines changed
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
VERSION = (0, 6, 7, None)
2727

28-
from ._compat import text_type, JYTHON, IRONPYTHON
28+
from ._compat import text_type, JYTHON, IRONPYTHON, PY2
2929
from .constants import FIELD_TYPE
3030
from .converters import escape_dict, escape_sequence, escape_string
3131
from .err import Warning, Error, InterfaceError, DataError, \
@@ -76,8 +76,11 @@ def __hash__(self):
7676
def Binary(x):
7777
"""Return x as a binary type."""
7878
if isinstance(x, text_type) and not (JYTHON or IRONPYTHON):
79-
return x.encode()
80-
return bytes(x)
79+
x = x.encode()
80+
if PY2:
81+
return bytearray(x)
82+
else:
83+
return bytes(x)
8184

8285
def Connect(*args, **kwargs):
8386
"""

pymysql/converters.py

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,31 @@ def escape_int(value, mapping=None):
5757
def escape_float(value, mapping=None):
5858
return ('%.15g' % value)
5959

60+
_escape_table = [chr(x) for x in range(128)]
61+
_escape_table[0] = u'\\0'
62+
_escape_table[ord('\\')] = u'\\\\'
63+
_escape_table[ord('\n')] = u'\\n'
64+
_escape_table[ord('\r')] = u'\\r'
65+
_escape_table[ord('\032')] = u'\\Z'
66+
_escape_table[ord('"')] = u'\\"'
67+
_escape_table[ord("'")] = u"\\'"
68+
69+
def _escape_unicode(value, mapping=None):
70+
"""escapes *value* without adding quote.
71+
72+
Value should be unicode
73+
"""
74+
return value.translate(_escape_table)
75+
6076
if PY2:
6177
def escape_string(value, mapping=None):
6278
"""escape_string escapes *value* but not surround it with quotes.
6379
6480
Value should be bytes or unicode.
6581
"""
82+
if isinstance(value, unicode):
83+
return escape_unicode(value)
84+
assert isinstance(value, (bytes, bytearray))
6685
value = value.replace('\\', '\\\\')
6786
value = value.replace('\0', '\\0')
6887
value = value.replace('\n', '\\n')
@@ -71,22 +90,12 @@ def escape_string(value, mapping=None):
7190
value = value.replace("'", "\\'")
7291
value = value.replace('"', '\\"')
7392
return value
74-
else:
75-
_escape_table = [chr(x) for x in range(128)]
76-
_escape_table[0] = '\\0'
77-
_escape_table[ord('\\')] = '\\\\'
78-
_escape_table[ord('\n')] = '\\n'
79-
_escape_table[ord('\r')] = '\\r'
80-
_escape_table[ord('\032')] = '\\Z'
81-
_escape_table[ord('"')] = '\\"'
82-
_escape_table[ord("'")] = "\\'"
8393

84-
def escape_string(value, mapping=None):
85-
"""escape_string escapes *value* but not surround it with quotes.
86-
87-
Value should be str (unicode).
88-
"""
89-
return value.translate(_escape_table)
94+
def escape_bytes(value, mapping=None):
95+
assert isinstance(value, (bytes, bytearray))
96+
return b"_binary'%s'" % escape_string(value)
97+
else:
98+
escape_string = _escape_unicode
9099

91100
# On Python ~3.5, str.decode('ascii', 'surrogateescape') is slow.
92101
# (fixed in Python 3.6, http://bugs.python.org/issue24870)
@@ -95,15 +104,15 @@ def escape_string(value, mapping=None):
95104
_escape_bytes_table = _escape_table + [chr(i) for i in range(0xdc80, 0xdd00)]
96105

97106
def escape_bytes(value, mapping=None):
98-
return "'%s'" % value.decode('latin1').translate(_escape_bytes_table)
107+
return "_binary'%s'" % value.decode('latin1').translate(_escape_bytes_table)
108+
99109

110+
def escape_unicode(value, mapping=None):
111+
return u"'%s'" % _escape_unicode(value)
100112

101113
def escape_str(value, mapping=None):
102114
return "'%s'" % escape_string(value, mapping)
103115

104-
def escape_unicode(value, mapping=None):
105-
return escape_str(value, mapping)
106-
107116
def escape_None(value, mapping=None):
108117
return 'NULL'
109118

@@ -337,6 +346,7 @@ def convert_characters(connection, field, data):
337346
list: escape_sequence,
338347
set: escape_sequence,
339348
dict: escape_dict,
349+
bytearray: escape_bytes,
340350
type(None): escape_None,
341351
datetime.date: escape_date,
342352
datetime.datetime: escape_datetime,

pymysql/tests/test_issues.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def test_issue_16(self):
145145

146146
@unittest2.skip("test_issue_17() requires a custom, legacy MySQL configuration and will not be run.")
147147
def test_issue_17(self):
148-
""" could not connect mysql use passwod """
148+
"""could not connect mysql use passwod"""
149149
conn = self.connections[0]
150150
host = self.databases[0]["host"]
151151
db = self.databases[0]["db"]
@@ -413,9 +413,9 @@ def test_issue_364(self):
413413
"create table issue364 (value_1 binary(3), value_2 varchar(3)) "
414414
"engine=InnoDB default charset=utf8")
415415

416-
sql = "insert into issue364 (value_1, value_2) values (_binary%s, _binary%s)"
417-
usql = u"insert into issue364 (value_1, value_2) values (_binary%s, _binary%s)"
418-
values = [b"\x00\xff\x00", u"\xe4\xf6\xfc"]
416+
sql = "insert into issue364 (value_1, value_2) values (%s, %s)"
417+
usql = u"insert into issue364 (value_1, value_2) values (%s, %s)"
418+
values = [pymysql.Binary(b"\x00\xff\x00"), u"\xe4\xf6\xfc"]
419419

420420
# test single insert and select
421421
cur = conn.cursor()
@@ -446,30 +446,32 @@ def test_issue_363(self):
446446
"ENGINE=MyISAM default charset=utf8")
447447

448448
cur = conn.cursor()
449-
# FYI - not sure of 5.7.0 version
450-
if sys.version_info[0:2] >= (3,2) and self.mysql_server_is(conn, (5, 7, 0)):
449+
query = ("INSERT INTO issue363 (id, geom) VALUES"
450+
"(1998, GeomFromText('LINESTRING(1.1 1.1,2.2 2.2)'))")
451+
# From MySQL 5.7, ST_GeomFromText is added and GeomFromText is deprecated.
452+
if self.mysql_server_is(conn, (5, 7, 0)):
451453
with self.assertWarns(pymysql.err.Warning) as cm:
452-
cur.execute("INSERT INTO issue363 (id, geom) VALUES ("
453-
"1998, GeomFromText('LINESTRING(1.1 1.1,2.2 2.2)'))")
454+
cur.execute(query)
454455
else:
455-
cur.execute("INSERT INTO issue363 (id, geom) VALUES ("
456-
"1998, GeomFromText('LINESTRING(1.1 1.1,2.2 2.2)'))")
456+
cur.execute(query)
457457

458458
# select WKT
459+
query = "SELECT AsText(geom) FROM issue363"
459460
if sys.version_info[0:2] >= (3,2) and self.mysql_server_is(conn, (5, 7, 0)):
460461
with self.assertWarns(pymysql.err.Warning) as cm:
461-
cur.execute("SELECT AsText(geom) FROM issue363")
462+
cur.execute(query)
462463
else:
463-
cur.execute("SELECT AsText(geom) FROM issue363")
464+
cur.execute(query)
464465
row = cur.fetchone()
465466
self.assertEqual(row, ("LINESTRING(1.1 1.1,2.2 2.2)", ))
466467

467468
# select WKB
469+
query = "SELECT AsBinary(geom) FROM issue363"
468470
if sys.version_info[0:2] >= (3,2) and self.mysql_server_is(conn, (5, 7, 0)):
469471
with self.assertWarns(pymysql.err.Warning) as cm:
470-
cur.execute("SELECT AsBinary(geom) FROM issue363")
472+
cur.execute(query)
471473
else:
472-
cur.execute("SELECT AsBinary(geom) FROM issue363")
474+
cur.execute(query)
473475
row = cur.fetchone()
474476
self.assertEqual(row,
475477
(b"\x01\x02\x00\x00\x00\x02\x00\x00\x00"

0 commit comments

Comments
 (0)
0