Add _binary prefix for binaries.

On Python 2, bytearray represents binary data.
On Python 3, bytes and bytearray represents binary data.

reference:

https://github.com/go-sql-driver/mysql/pull/382
https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-46.html
https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-27.html
This commit is contained in:
INADA Naoki
2016-01-08 22:02:24 +09:00
parent d249c06827
commit c139119e65
3 changed files with 37 additions and 24 deletions

View File

@@ -25,7 +25,7 @@ THE SOFTWARE.
VERSION = (0, 6, 7, None)
from ._compat import text_type, JYTHON, IRONPYTHON
from ._compat import text_type, JYTHON, IRONPYTHON, PY2
from .constants import FIELD_TYPE
from .converters import escape_dict, escape_sequence, escape_string
from .err import Warning, Error, InterfaceError, DataError, \
@@ -76,8 +76,11 @@ ROWID = DBAPISet()
def Binary(x):
"""Return x as a binary type."""
if isinstance(x, text_type) and not (JYTHON or IRONPYTHON):
return x.encode()
return bytes(x)
x = x.encode()
if PY2:
return bytearray(x)
else:
return bytes(x)
def Connect(*args, **kwargs):
"""

View File

@@ -57,12 +57,31 @@ def escape_int(value, mapping=None):
def escape_float(value, mapping=None):
return ('%.15g' % value)
_escape_table = [chr(x) for x in range(128)]
_escape_table[0] = u'\\0'
_escape_table[ord('\\')] = u'\\\\'
_escape_table[ord('\n')] = u'\\n'
_escape_table[ord('\r')] = u'\\r'
_escape_table[ord('\032')] = u'\\Z'
_escape_table[ord('"')] = u'\\"'
_escape_table[ord("'")] = u"\\'"
def _escape_unicode(value, mapping=None):
"""escapes *value* without adding quote.
Value should be unicode
"""
return value.translate(_escape_table)
if PY2:
def escape_string(value, mapping=None):
"""escape_string escapes *value* but not surround it with quotes.
Value should be bytes or unicode.
"""
if isinstance(value, unicode):
return escape_unicode(value)
assert isinstance(value, bytes)
value = value.replace('\\', '\\\\')
value = value.replace('\0', '\\0')
value = value.replace('\n', '\\n')
@@ -71,22 +90,12 @@ if PY2:
value = value.replace("'", "\\'")
value = value.replace('"', '\\"')
return value
def escape_bytes(value, mapping=None):
assert isinstance(value, (bytes, bytearray))
return b"_binary'%s'" % value
else:
_escape_table = [chr(x) for x in range(128)]
_escape_table[0] = '\\0'
_escape_table[ord('\\')] = '\\\\'
_escape_table[ord('\n')] = '\\n'
_escape_table[ord('\r')] = '\\r'
_escape_table[ord('\032')] = '\\Z'
_escape_table[ord('"')] = '\\"'
_escape_table[ord("'")] = "\\'"
def escape_string(value, mapping=None):
"""escape_string escapes *value* but not surround it with quotes.
Value should be str (unicode).
"""
return value.translate(_escape_table)
escape_string = _escape_unicode
# On Python ~3.5, str.decode('ascii', 'surrogateescape') is slow.
# (fixed in Python 3.6, http://bugs.python.org/issue24870)
@@ -95,15 +104,15 @@ else:
_escape_bytes_table = _escape_table + [chr(i) for i in range(0xdc80, 0xdd00)]
def escape_bytes(value, mapping=None):
return "'%s'" % value.decode('latin1').translate(_escape_bytes_table)
return "_binary'%s'" % value.decode('latin1').translate(_escape_bytes_table)
def escape_unicode(value, mapping=None):
return u"'%s'" % _escape_unicode(value)
def escape_str(value, mapping=None):
return "'%s'" % escape_string(value, mapping)
def escape_unicode(value, mapping=None):
return escape_str(value, mapping)
def escape_None(value, mapping=None):
return 'NULL'
@@ -337,6 +346,7 @@ encoders = {
list: escape_sequence,
set: escape_sequence,
dict: escape_dict,
bytearray: escape_bytes,
type(None): escape_None,
datetime.date: escape_date,
datetime.datetime: escape_datetime,

View File

@@ -413,8 +413,8 @@ class TestGitHubIssues(base.PyMySQLTestCase):
"create table issue364 (value_1 binary(3), value_2 varchar(3)) "
"engine=InnoDB default charset=utf8")
sql = "insert into issue364 (value_1, value_2) values (_binary%s, _binary%s)"
usql = u"insert into issue364 (value_1, value_2) values (_binary%s, _binary%s)"
sql = "insert into issue364 (value_1, value_2) values (%s, %s)"
usql = u"insert into issue364 (value_1, value_2) values (%s, %s)"
values = [b"\x00\xff\x00", u"\xe4\xf6\xfc"]
# test single insert and select