Menu

#680 Other ZMySQLDA instances are affected by unicode patch

v2.1
open
nobody
Database (56)
5
2014-08-23
2007-02-16
No

When combining unicode and non-unicode MySQL connections, each instance is affected by the other one. Depending on which instance used last.

This is due to the fact that some items of the conversions list are references instead of independent objects (e.g. conv[FIELD_TYPE.BLOB]).

Furthermore it is possible to patch just one file of the ZMySQLDA package to get unicode support instead of four files.

To get this working, you have to modify only two functions of db.py
Now you can turn on unicode support by adding the string "use_unicode" to the end(!) of the connection string.

def _parse_connection_string(self, connection):
kwargs = {'conv': self.conv.copy()}
items = split(connection)
if not items: return kwargs
if items[-1] == 'use_unicode':
self.use_unicode = True
del items[-1]
# Update the converters on the unicode object
def u(s):
return s.decode('UTF8')
kwargs['conv'][FIELD_TYPE.STRING] = u
kwargs['conv'][FIELD_TYPE.VAR_STRING] = u
kwargs['conv'][FIELD_TYPE.BLOB] = self.conv[FIELD_TYPE.BLOB][:]
kwargs['conv'][FIELD_TYPE.BLOB].insert(-1, (None, u))
else:
self.use_unicode = False
# Reset these elements - by default they should not be present
if self.conv.has_key(FIELD_TYPE.STRING):
kwargs['conv'][FIELD_TYPE.STRING] = self.conv[FIELD_TYPE.STRING]
elif kwargs['conv'].has_key(FIELD_TYPE.STRING):
del kwargs['conv'][FIELD_TYPE.STRING]
if self.conv.has_key(FIELD_TYPE.VAR_STRING):
kwargs['conv'][FIELD_TYPE.VAR_STRING] = self.conv[FIELD_TYPE.VAR_STRING]
elif kwargs['conv'].has_key(FIELD_TYPE.VAR_STRING):
del kwargs['conv'][FIELD_TYPE.VAR_STRING]
if self.conv.has_key(FIELD_TYPE.BLOB):
kwargs['conv'][FIELD_TYPE.BLOB] = self.conv[FIELD_TYPE.BLOB]
elif kwargs['conv'].has_key(FIELD_TYPE.BLOB):
del kwargs['conv'][FIELD_TYPE.BLOB]
db_host, items = items[0], items[1:]
if '@' in db_host:
db, host = split(db_host,'@',1)
kwargs['db'] = db
if ':' in host:
host, port = split(host,':',1)
kwargs['port'] = int(port)
kwargs['host'] = host
else:
kwargs['db'] = db_host
if kwargs['db'][0] in ('+', '-'):
self._try_transactions = kwargs['db'][0]
kwargs['db'] = kwargs['db'][1:]
else:
self._try_transactions = None
if not items: return kwargs
kwargs['user'], items = items[0], items[1:]
if not items: return kwargs
kwargs['passwd'], items = items[0], items[1:]
if not items: return kwargs
kwargs['unix_socket'], items = items[0], items[1:]
return kwargs

def string_literal(self, s):
if self.use_unicode and type(s) == unicode:
s = s.encode('UTF8')
return self.db.string_literal(s)

Discussion

  • Thimo Kraemer

    Thimo Kraemer - 2007-02-16

    db.py from the ZMySQLDA product

     
  • Thimo Kraemer

    Thimo Kraemer - 2007-02-16

    Logged In: YES
    user_id=1115795
    Originator: YES

    <pre>
    def _parse_connection_string(self, connection):
    kwargs = {'conv': self.conv.copy()}
    items = split(connection)
    if not items: return kwargs
    if items[-1] == 'use_unicode':
    self.use_unicode = True
    del items[-1]
    # Update the converters on the unicode object
    def u(s):
    return s.decode('UTF8')
    kwargs['conv'][FIELD_TYPE.STRING] = u
    kwargs['conv'][FIELD_TYPE.VAR_STRING] = u
    kwargs['conv'][FIELD_TYPE.BLOB] = self.conv[FIELD_TYPE.BLOB][:]
    kwargs['conv'][FIELD_TYPE.BLOB].insert(-1, (None, u))
    else:
    self.use_unicode = False
    # Reset these elements - by default they should not be present
    if self.conv.has_key(FIELD_TYPE.STRING):
    kwargs['conv'][FIELD_TYPE.STRING] = self.conv[FIELD_TYPE.STRING]
    elif kwargs['conv'].has_key(FIELD_TYPE.STRING):
    del kwargs['conv'][FIELD_TYPE.STRING]
    if self.conv.has_key(FIELD_TYPE.VAR_STRING):
    kwargs['conv'][FIELD_TYPE.VAR_STRING] = self.conv[FIELD_TYPE.VAR_STRING]
    elif kwargs['conv'].has_key(FIELD_TYPE.VAR_STRING):
    del kwargs['conv'][FIELD_TYPE.VAR_STRING]
    if self.conv.has_key(FIELD_TYPE.BLOB):
    kwargs['conv'][FIELD_TYPE.BLOB] = self.conv[FIELD_TYPE.BLOB]
    elif kwargs['conv'].has_key(FIELD_TYPE.BLOB):
    del kwargs['conv'][FIELD_TYPE.BLOB]
    db_host, items = items[0], items[1:]
    if '@' in db_host:
    db, host = split(db_host,'@',1)
    kwargs['db'] = db
    if ':' in host:
    host, port = split(host,':',1)
    kwargs['port'] = int(port)
    kwargs['host'] = host
    else:
    kwargs['db'] = db_host
    if kwargs['db'][0] in ('+', '-'):
    self._try_transactions = kwargs['db'][0]
    kwargs['db'] = kwargs['db'][1:]
    else:
    self._try_transactions = None
    if not items: return kwargs
    kwargs['user'], items = items[0], items[1:]
    if not items: return kwargs
    kwargs['passwd'], items = items[0], items[1:]
    if not items: return kwargs
    kwargs['unix_socket'], items = items[0], items[1:]
    return kwargs

    def string_literal(self, s):
    if self.use_unicode and type(s) == unicode:
    s = s.encode('UTF8')
    return self.db.string_literal(s)
    </pre>

     

Log in to post a comment.