Hack for character encoding in communication with database.
Added encoding from unicode to str in execute_query, and wrote wrapper functions with decoding for the cursor methods fetchone and fetchall. This means that from now on, one should never call these methods directly on cursor objects, but instead call execute_query, fetchone, fetchall, fetchone_dict or fetchall_dict in util.py. I plan to separate out this code to a new module (db.py?), and rewrite it in a way that makes it harder to write things like c.execute by mistake.
This commit is contained in:
parent
b50fe04b1f
commit
bf188c99ae
30
cli/util.py
30
cli/util.py
|
@ -1,12 +1,32 @@
|
||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
db_encoding = 'utf8'
|
||||||
|
|
||||||
|
def value_to_db(value):
|
||||||
|
if type(value) == unicode:
|
||||||
|
return value.encode(db_encoding)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def value_from_db(value):
|
||||||
|
if type(value) == str:
|
||||||
|
return unicode(value, db_encoding)
|
||||||
|
return value
|
||||||
|
|
||||||
def execute_query(cursor, query, bindings):
|
def execute_query(cursor, query, bindings):
|
||||||
for (key, val) in bindings.items():
|
for (key, val) in bindings.items():
|
||||||
if val == None:
|
if val == None:
|
||||||
query = query.replace('%(' + key + ')d', 'NULL')
|
query = query.replace('%(' + key + ')d', 'NULL')
|
||||||
|
bindings = map_dict(value_to_db, bindings)
|
||||||
cursor.execute(query, bindings)
|
cursor.execute(query, bindings)
|
||||||
|
|
||||||
|
def fetchone(cursor):
|
||||||
|
return map(value_from_db, cursor.fetchone())
|
||||||
|
|
||||||
|
def fetchall(cursor):
|
||||||
|
return map(lambda row: map(value_from_db, row),
|
||||||
|
cursor.fetchall())
|
||||||
|
|
||||||
def make_result_dict(cursor, row):
|
def make_result_dict(cursor, row):
|
||||||
d = {}
|
d = {}
|
||||||
for i in xrange(len(row)):
|
for i in xrange(len(row)):
|
||||||
|
@ -14,14 +34,14 @@ def make_result_dict(cursor, row):
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def fetchone_dict(cursor):
|
def fetchone_dict(cursor):
|
||||||
row = cursor.fetchone()
|
row = fetchone(cursor)
|
||||||
if row != None:
|
if row != None:
|
||||||
return make_result_dict(cursor, row)
|
return make_result_dict(cursor, row)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def fetchall_dict(cursor):
|
def fetchall_dict(cursor):
|
||||||
return map(lambda r: make_result_dict(cursor, r),
|
return map(lambda r: make_result_dict(cursor, r),
|
||||||
cursor.fetchall())
|
fetchall(cursor))
|
||||||
|
|
||||||
def first(lst):
|
def first(lst):
|
||||||
return lst[0]
|
return lst[0]
|
||||||
|
@ -56,6 +76,12 @@ def mapcond(fun, predicate, lst):
|
||||||
return x
|
return x
|
||||||
return map(mapfun, lst)
|
return map(mapfun, lst)
|
||||||
|
|
||||||
|
def map_dict(fun, d):
|
||||||
|
res = {}
|
||||||
|
for key in d:
|
||||||
|
res[key] = fun(d[key])
|
||||||
|
return res
|
||||||
|
|
||||||
def maptup(fun, lst):
|
def maptup(fun, lst):
|
||||||
return tuple(map(fun, lst))
|
return tuple(map(fun, lst))
|
||||||
|
|
||||||
|
|
Reference in New Issue