Author: phd
Date: Wed Jun 15 06:29:23 2011
New Revision: 4403
Log:
One encoding for all UnicodeCol's per table or per connection.
Modified:
SQLObject/trunk/docs/News.txt
SQLObject/trunk/docs/TODO.txt
SQLObject/trunk/sqlobject/col.py
SQLObject/trunk/sqlobject/main.py
SQLObject/trunk/sqlobject/tests/test_unicode.py
Modified: SQLObject/trunk/docs/News.txt
==============================================================================
--- SQLObject/trunk/docs/News.txt Mon May 30 05:07:33 2011 (r4402)
+++ SQLObject/trunk/docs/News.txt Wed Jun 15 06:29:23 2011 (r4403)
@@ -21,6 +21,11 @@
now SQLObject uses text_factory instead and properly returns empty
strings.
+* It is now possible to declare one encoding for all UnicodeCol's per
+ table (as sqlmeta.dbEncoding) or per connection (as connection.dbEncoding).
+ Default (if dbEncoding is found neither in column nor in table nor in
+ connection) is 'utf-8'.
+
Source code and internals
-------------------------
Modified: SQLObject/trunk/docs/TODO.txt
==============================================================================
--- SQLObject/trunk/docs/TODO.txt Mon May 30 05:07:33 2011 (r4402)
+++ SQLObject/trunk/docs/TODO.txt Wed Jun 15 06:29:23 2011 (r4403)
@@ -1,9 +1,6 @@
TODO
----
-* Declare one encoding for all UnicodeCol's per table or even per connection.
- Don't forget about fromDatabase.
-
* Allow to override ConsoleWriter/LogWriter classes and makeDebugWriter
function.
Modified: SQLObject/trunk/sqlobject/col.py
==============================================================================
--- SQLObject/trunk/sqlobject/col.py Mon May 30 05:07:33 2011 (r4402)
+++ SQLObject/trunk/sqlobject/col.py Wed Jun 15 06:29:23 2011 (r4403)
@@ -535,15 +535,21 @@
class UnicodeStringValidator(validators.Validator):
+ def getDbEncoding(self, state):
+ try:
+ return self.dbEncoding
+ except AttributeError:
+ return self.soCol.getDbEncoding(state)
+
def to_python(self, value, state):
if value is None:
return None
if isinstance(value, (unicode, sqlbuilder.SQLExpression)):
return value
if isinstance(value, str):
- return unicode(value, self.dbEncoding)
+ return unicode(value, self.getDbEncoding(state))
if isinstance(value, array): # MySQL
- return unicode(value.tostring(), self.dbEncoding)
+ return unicode(value.tostring(), self.getDbEncoding(state))
if hasattr(value, '__unicode__'):
return unicode(value)
raise validators.Invalid("expected a str or a unicode in the UnicodeCol '%s', got %s %r instead" % \
@@ -555,22 +561,37 @@
if isinstance(value, (str, sqlbuilder.SQLExpression)):
return value
if isinstance(value, unicode):
- return value.encode(self.dbEncoding)
+ return value.encode(self.getDbEncoding(state))
if hasattr(value, '__unicode__'):
- return unicode(value).encode(self.dbEncoding)
+ return unicode(value).encode(self.getDbEncoding(state))
raise validators.Invalid("expected a str or a unicode in the UnicodeCol '%s', got %s %r instead" % \
(self.name, type(value), value), value, state)
class SOUnicodeCol(SOStringLikeCol):
def __init__(self, **kw):
- self.dbEncoding = kw.pop('dbEncoding', 'UTF-8')
+ self.dbEncoding = kw.pop('dbEncoding', None)
super(SOUnicodeCol, self).__init__(**kw)
def createValidators(self):
- return [UnicodeStringValidator(name=self.name,
- dbEncoding=self.dbEncoding)] + \
+ return [UnicodeStringValidator(name=self.name, soCol=self)] + \
super(SOUnicodeCol, self).createValidators()
+ def getDbEncoding(self, state):
+ if self.dbEncoding:
+ return self.dbEncoding
+ dbEncoding = state.soObject.sqlmeta.dbEncoding
+ if dbEncoding:
+ return dbEncoding
+ try:
+ connection = state.connection or state.soObject._connection
+ except AttributeError:
+ dbEncoding = None
+ else:
+ dbEncoding = getattr(connection, "dbEncoding", None)
+ if not dbEncoding:
+ dbEncoding = "utf-8"
+ return dbEncoding
+
class UnicodeCol(Col):
baseClass = SOUnicodeCol
Modified: SQLObject/trunk/sqlobject/main.py
==============================================================================
--- SQLObject/trunk/sqlobject/main.py Mon May 30 05:07:33 2011 (r4402)
+++ SQLObject/trunk/sqlobject/main.py Wed Jun 15 06:29:23 2011 (r4403)
@@ -234,6 +234,9 @@
# Does the row require syncing?
dirty = False
+ # Default encoding for UnicodeCol's
+ dbEncoding = None
+
__metaclass__ = declarative.DeclarativeMeta
def __classinit__(cls, new_attrs):
Modified: SQLObject/trunk/sqlobject/tests/test_unicode.py
==============================================================================
--- SQLObject/trunk/sqlobject/tests/test_unicode.py Mon May 30 05:07:33 2011 (r4402)
+++ SQLObject/trunk/sqlobject/tests/test_unicode.py Wed Jun 15 06:29:23 2011 (r4403)
@@ -38,8 +38,7 @@
assert data[count].encode('utf-8') == col1
assert data[count].encode('latin1') == col2
-def test_select():
- setup()
+def _test_select():
for i, value in enumerate(data):
rows = list(TestUnicode.select(TestUnicode.q.col1 == value))
assert len(rows) == 1
@@ -79,3 +78,29 @@
assert len(rows) == 1
rows = list(TestUnicode.select(TestUnicode.q.col1.contains(u"\u00f0")))
assert len(rows) == 1
+
+def test_select():
+ setup()
+ _test_select()
+
+def test_dbEncoding():
+ setup()
+ assert TestUnicode.sqlmeta.dbEncoding is None
+ assert not hasattr(TestUnicode._connection, 'dbEncoding') or \
+ TestUnicode._connection.dbEncoding is None
+
+ TestUnicode.sqlmeta.dbEncoding = 'utf-8'
+ _test_select()
+ TestUnicode.sqlmeta.dbEncoding = 'latin-1'
+ raises(AssertionError, _test_select)
+ TestUnicode.sqlmeta.dbEncoding = 'ascii'
+ raises(UnicodeEncodeError, _test_select)
+ TestUnicode.sqlmeta.dbEncoding = None
+
+ TestUnicode._connection.dbEncoding = 'utf-8'
+ _test_select()
+ TestUnicode._connection.dbEncoding = 'latin-1'
+ raises(AssertionError, _test_select)
+ TestUnicode._connection.dbEncoding = 'ascii'
+ raises(UnicodeEncodeError, _test_select)
+ del TestUnicode.sqlmeta.dbEncoding
|