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

Reply via email to