Hello. I think I fixed a longstanding problem with UnicodeCol - at last you
can use unicode strings in .select() and .selectBy() queries. There are
some limitations, though:
- only simple q-magic fields are supported; no expressions;
- only == and <> operators are supported;
The following will work::
MyTable.select(u'value' == MyTable.q.name)
MyTable.select(MyTable.q.name <> u'value')
MyTable.selectBy(name = u'value')
The following will not work::
MyTable.select((MyTable.q.name + MyTable.q.surname) == u'value')
The patch with tests is attached. I am eagerly waiting for feedback.
Technically, I've found a way to pass dbEncoding to __sqlrepr__ so that
the column can convert the value to a string - for this I have created a
special field that only overrides __eq__ and __ne__ - I believe these are
the most frequent cases.
Oleg.
--
Oleg Broytmann http://phd.pp.ru/ [EMAIL PROTECTED]
Programmers don't die, they just GOSUB without RETURN.
Index: sqlobject/sqlbuilder.py
===================================================================
--- sqlobject/sqlbuilder.py (revision 1884)
+++ sqlobject/sqlbuilder.py (working copy)
@@ -326,6 +326,25 @@
registerConverter(SQLObjectField, SQLExprConverter)
+
+class UnicodeOp(SQLOp):
+ def __init__(self, op, expr1, expr2):
+ if isinstance(expr2, unicode):
+ expr2 = expr2.encode(expr1.column.dbEncoding)
+ SQLOp.__init__(self, op, expr1, expr2)
+
+class UnicodeField(SQLObjectField):
+ def __init__(self, tableName, fieldName, original, column):
+ SQLObjectField.__init__(self, tableName, fieldName, original)
+ self.column = column
+ def __eq__(self, other):
+ return UnicodeOp('=', self, other)
+ def __ne__(self, other):
+ return UnicodeOp('<>', self, other)
+
+registerConverter(UnicodeField, SQLExprConverter)
+
+
class Table(SQLExpression):
FieldClass = Field
@@ -342,6 +361,7 @@
class SQLObjectTable(Table):
FieldClass = SQLObjectField
+ UnicodeFieldClass = UnicodeField
def __init__(self, soClass):
self.soClass = soClass
@@ -358,9 +378,12 @@
elif attr not in self.soClass.sqlmeta.columns:
raise AttributeError("%s instance has no attribute '%s'" %
(self.soClass.__name__, attr))
else:
- return self.FieldClass(self.tableName,
- self.soClass.sqlmeta.columns[attr].dbName,
- attr)
+ column = self.soClass.sqlmeta.columns[attr]
+ if hasattr(column, "dbEncoding"):
+ return self.UnicodeFieldClass(self.tableName, column.dbName,
+ attr, column)
+ else:
+ return self.FieldClass(self.tableName, column.dbName, attr)
class TableSpace:
TableClass = Table
Index: sqlobject/tests/test_unicode.py
===================================================================
--- sqlobject/tests/test_unicode.py (revision 1884)
+++ sqlobject/tests/test_unicode.py (working copy)
@@ -5,7 +5,7 @@
## Unicode columns
########################################
-class Unicode1(SQLObject):
+class TestUnicode(SQLObject):
count = IntCol(alternateID=True)
col1 = UnicodeCol()
col2 = UnicodeCol(dbEncoding='latin-1')
@@ -16,24 +16,47 @@
def enumerate(lst):
return [(i, lst[i]) for i in range(len(lst))]
-def test_create():
- setupClass(Unicode1)
- data = [u'\u00f0', u'test', 'ascii test']
+data = [u'\u00f0', u'test', 'ascii test']
+items = []
+def setup():
+ global items
items = []
+ setupClass(TestUnicode)
for i, n in enumerate(data):
- items.append(Unicode1(count=i, col1=n, col2=n))
+ items.append(TestUnicode(count=i, col1=n, col2=n))
+
+def test_create():
+ setup()
for n, item in zip(data, items):
- item.col1 = item.col2 = n
- for n, item in zip(data, items):
assert item.col1 == item.col2
assert item.col1 == n
- conn = Unicode1._connection
+
+ conn = TestUnicode._connection
rows = conn.queryAll("""
SELECT count, col1, col2
- FROM unicode1
+ FROM test_unicode
ORDER BY count
""")
for count, col1, col2 in rows:
assert data[count].encode('utf-8') == col1
assert data[count].encode('latin1') == col2
+
+def test_select():
+ setup()
+ for value in data:
+ rows = list(TestUnicode.select(TestUnicode.q.col1 == value))
+ assert len(rows) == 1
+ rows = list(TestUnicode.select(TestUnicode.q.col2 == value))
+ assert len(rows) == 1
+ rows = list(TestUnicode.select(AND(
+ TestUnicode.q.col1 == value,
+ TestUnicode.q.col2 == value
+ )))
+ assert len(rows) == 1
+ rows = list(TestUnicode.selectBy(col1=value))
+ assert len(rows) == 1
+ rows = list(TestUnicode.selectBy(col2=value))
+ assert len(rows) == 1
+ rows = list(TestUnicode.selectBy(col1=value, col2=value))
+ assert len(rows) == 1
Index: sqlobject/main.py
===================================================================
--- sqlobject/main.py (revision 1884)
+++ sqlobject/main.py (working copy)
@@ -1328,9 +1328,15 @@
select = classmethod(select)
def selectBy(cls, connection=None, **kw):
+ new_kw = kw.copy()
+ for key, column in cls.sqlmeta.columns.items():
+ if (key in kw) and isinstance(column, col.SOUnicodeCol):
+ value = kw[key]
+ if isinstance(value, unicode):
+ new_kw[key] = value.encode(column.dbEncoding)
conn = connection or cls._connection
return cls.SelectResultsClass(cls,
- conn._SO_columnClause(cls, kw),
+ conn._SO_columnClause(cls, new_kw),
connection=conn)
selectBy = classmethod(selectBy)
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
sqlobject-discuss mailing list
sqlobject-discuss@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss