Hi,
In r3109, I implemented a workaround for cursor.description
returning UTF-8 encoded column names, at least with pysqlite2.
Now I just noticed that query.py also uses the cursor.description
and I'm looking for a better fix.
So far, I didn't find a way to override the 'description' property
of the pysqlite2.dbapi2.Cursor object. More specifically, in the
overriding property, I wasn't able to find a way to call the
original property.
So, unless there's a way to make the above work, I'd like to propose
the following change.
-- Christian
Index: trac/ticket/report.py
===================================================================
--- trac/ticket/report.py (revision 3118)
+++ trac/ticket/report.py (working copy)
@@ -22,6 +22,7 @@
from trac import util
from trac.core import *
+from trac.db import get_column_names
from trac.perm import IPermissionRequestor
from trac.util import sorted
from trac.util.markup import html
@@ -249,7 +250,7 @@
# Convert the header info to HDF-format
idx = 0
for col in cols:
- title=col[0].capitalize()
+ title=col.capitalize()
prefix = 'report.headers.%d' % idx
req.hdf['%s.real' % prefix] = col[0]
if title.startswith('__') and title.endswith('__'):
@@ -270,7 +271,7 @@
colIndex = None
hiddenCols = 0
for x in range(len(cols)):
- colName = cols[x][0]
+ colName = cols[x]
if colName == sortCol:
colIndex = x
if colName.startswith('__') and colName.endswith('__'):
@@ -297,7 +298,7 @@
numrows = len(row)
for cell in row:
cell = unicode(cell)
- column = cols[col_idx][0]
+ column = cols[col_idx]
value = {}
# Special columns begin and end with '__'
if column.startswith('__') and column.endswith('__'):
@@ -315,7 +316,7 @@
column = column[1:]
if column in ('ticket', 'id', '_id', '#', 'summary'):
id_cols = [idx for idx, col in enumerate(cols)
- if col[0] in ('ticket', 'id', '_id')]
+ if col in ('ticket', 'id', '_id')]
if id_cols:
id_val = row[id_cols[0]]
value['ticket_href'] = req.href.ticket(id_val)
@@ -385,10 +386,7 @@
# FIXME: fetchall should probably not be used.
info = cursor.fetchall() or []
- cols = cursor.description or []
- # NOTE: At least pysqlite will return an UTF-8 string here...
- if cols and isinstance(cols[0][0], str):
- cols = [(unicode(d[0], 'utf-8'),) + (None,)*6 for d in cols]
+ cols = get_column_names(cursor)
db.rollback()
@@ -465,7 +463,7 @@
req.send_header('Content-Type', 'text/plain;charset=utf-8')
req.end_headers()
- req.write(sep.join([c[0] for c in cols]) + '\r\n')
+ req.write(sep.join(cols) + '\r\n')
for row in rows:
req.write(sep.join(
[unicode(c).replace(sep,"_")
Index: trac/ticket/query.py
===================================================================
--- trac/ticket/query.py (revision 3118)
+++ trac/ticket/query.py (working copy)
@@ -20,6 +20,7 @@
import time
from trac.core import *
+from trac.db import get_column_names
from trac.perm import IPermissionRequestor
from trac.ticket import Ticket, TicketSystem
from trac.util import format_datetime, http_date, shorten_line, CRLF
@@ -145,13 +146,13 @@
db = self.env.get_db_cnx()
cursor = db.cursor()
cursor.execute(sql, args)
- columns = cursor.description
+ columns = get_column_names(cursor)
results = []
for row in cursor:
id = int(row[0])
result = {'id': id, 'href': self.env.href.ticket(id)}
for i in range(1, len(columns)):
- name, val = columns[i][0], row[i]
+ name, val = columns[i], row[i]
if name == self.group:
val = val or 'None'
elif name == 'reporter':
Index: trac/db/api.py
===================================================================
--- trac/db/api.py (revision 3118)
+++ trac/db/api.py (working copy)
@@ -21,6 +21,12 @@
from trac.db.pool import ConnectionPool
+def get_column_names(cursor):
+ return cursor.description and \
+ [(isinstance(d[0], str) and [unicode(d[0], 'utf-8')] or [d[0]])[0]
+ for d in cursor.description] or []
+
+
class IDatabaseConnector(Interface):
"""Extension point interface for components that support the connection to
relational databases."""
_______________________________________________
Trac-dev mailing list
[email protected]
http://lists.edgewall.com/mailman/listinfo/trac-dev