Author: phd
Date: 2010-10-15 06:32:04 -0600 (Fri, 15 Oct 2010)
New Revision: 4261
Added:
SQLObject/trunk/sqlobject/tests/test_perConnection.py
Modified:
SQLObject/trunk/docs/News.txt
SQLObject/trunk/sqlobject/col.py
SQLObject/trunk/sqlobject/dbconnection.py
SQLObject/trunk/sqlobject/main.py
SQLObject/trunk/sqlobject/sqlbuilder.py
Log:
Merged revision 4260 from branch 0.14: a bug was fixed in a subtle case
when a per-instance connection is not passed to validators.
Modified: SQLObject/trunk/docs/News.txt
===================================================================
--- SQLObject/trunk/docs/News.txt 2010-10-15 12:20:07 UTC (rev 4260)
+++ SQLObject/trunk/docs/News.txt 2010-10-15 12:32:04 UTC (rev 4261)
@@ -34,6 +34,12 @@
* Major API change: attribute 'dirty' was moved to sqlmeta.
+SQLObject 0.13.1
+================
+
+* A bug was fixed in a subtle case when a per-instance connection is not
+ passed to validators.
+
SQLObject 0.13.0
================
Modified: SQLObject/trunk/sqlobject/col.py
===================================================================
--- SQLObject/trunk/sqlobject/col.py 2010-10-15 12:20:07 UTC (rev 4260)
+++ SQLObject/trunk/sqlobject/col.py 2010-10-15 12:32:04 UTC (rev 4261)
@@ -503,13 +503,19 @@
def to_python(self, value, state):
if value is None:
return None
- connection = state.soObject._connection
- dbEncoding = getattr(connection, "dbEncoding", None) or "ascii"
+ try:
+ connection = state.connection or state.soObject._connection
+ except AttributeError:
+ dbEncoding = "ascii"
+ binaryType = type(None) # Just a simple workaround
+ else:
+ dbEncoding = getattr(connection, "dbEncoding", None) or "ascii"
+ binaryType = connection._binaryType
if isinstance(value, unicode):
return value.encode(dbEncoding)
if self.dataType and isinstance(value, self.dataType):
return value
- if isinstance(value, (str, buffer, connection._binaryType, sqlbuilder.SQLExpression)):
+ if isinstance(value, (str, buffer, binaryType, sqlbuilder.SQLExpression)):
return value
if hasattr(value, '__unicode__'):
return unicode(value).encode(dbEncoding)
@@ -1305,10 +1311,14 @@
return value
if isinstance(value, float):
value = str(value)
- connection = state.soObject._connection
- if hasattr(connection, "decimalSeparator"):
- value = value.replace(connection.decimalSeparator, ".")
try:
+ connection = state.connection or state.soObject._connection
+ except AttributeError:
+ pass
+ else:
+ if hasattr(connection, "decimalSeparator"):
+ value = value.replace(connection.decimalSeparator, ".")
+ try:
return Decimal(value)
except:
raise validators.Invalid("expected a Decimal in the DecimalCol '%s', got %s %r instead" % \
@@ -1320,10 +1330,14 @@
if isinstance(value, float):
value = str(value)
if isinstance(value, basestring):
- connection = state.soObject._connection
- if hasattr(connection, "decimalSeparator"):
- value = value.replace(connection.decimalSeparator, ".")
try:
+ connection = state.connection or state.soObject._connection
+ except AttributeError:
+ pass
+ else:
+ if hasattr(connection, "decimalSeparator"):
+ value = value.replace(connection.decimalSeparator, ".")
+ try:
return Decimal(value)
except:
raise validators.Invalid("can not parse Decimal value '%s' in the DecimalCol from '%s'" %
@@ -1427,12 +1441,19 @@
def to_python(self, value, state):
if value is None:
return None
+ try:
+ connection = state.connection or state.soObject._connection
+ except AttributeError:
+ dbName = None
+ binaryType = type(None) # Just a simple workaround
+ else:
+ dbName = connection.dbName
+ binaryType = connection._binaryType
if isinstance(value, str):
- connection = state.soObject._connection
- if connection.dbName == "sqlite":
+ if dbName == "sqlite":
value = connection.module.decode(value)
return value
- if isinstance(value, (buffer, state.soObject._connection._binaryType)):
+ if isinstance(value, (buffer, binaryType)):
cachedValue = self._cachedValue
if cachedValue and cachedValue[1] == value:
return cachedValue[0]
@@ -1445,7 +1466,8 @@
def from_python(self, value, state):
if value is None:
return None
- binary = state.soObject._connection.createBinary(value)
+ connection = state.connection or state.soObject._connection
+ binary = connection.createBinary(value)
self._cachedValue = (value, binary)
return binary
@@ -1497,8 +1519,12 @@
if value is None:
return None
if isinstance(value, unicode):
- connection = state.soObject._connection
- dbEncoding = getattr(connection, "dbEncoding", None) or "ascii"
+ try:
+ connection = state.connection or state.soObject._connection
+ except AttributeError:
+ dbEncoding = "ascii"
+ else:
+ dbEncoding = getattr(connection, "dbEncoding", None) or "ascii"
value = value.encode(dbEncoding)
if isinstance(value, str):
return pickle.loads(value)
Modified: SQLObject/trunk/sqlobject/dbconnection.py
===================================================================
--- SQLObject/trunk/sqlobject/dbconnection.py 2010-10-15 12:20:07 UTC (rev 4260)
+++ SQLObject/trunk/sqlobject/dbconnection.py 2010-10-15 12:32:04 UTC (rev 4261)
@@ -582,7 +582,7 @@
if key in kw:
value = kw.pop(key)
if col.from_python:
- value = col.from_python(value, sqlbuilder.SQLObjectState(soClass))
+ value = col.from_python(value, sqlbuilder.SQLObjectState(soClass, connection=self))
data[col.dbName] = value
elif col.foreignName in kw:
obj = kw.pop(col.foreignName)
Modified: SQLObject/trunk/sqlobject/main.py
===================================================================
--- SQLObject/trunk/sqlobject/main.py 2010-10-15 12:20:07 UTC (rev 4260)
+++ SQLObject/trunk/sqlobject/main.py 2010-10-15 12:32:04 UTC (rev 4261)
@@ -1321,7 +1321,7 @@
for n, v in zip(name, value):
from_python = getattr(cls, '_SO_from_python_' + n)
if from_python:
- v = from_python(v, sqlbuilder.SQLObjectState(cls))
+ v = from_python(v, sqlbuilder.SQLObjectState(cls, connection=connection))
new_value.append(v)
condition = sqlbuilder.AND(*[getattr(cls.q, n)==v for n,v in zip(name, new_value)])
return (connection or cls._connection)._SO_selectOneAlt(
Modified: SQLObject/trunk/sqlobject/sqlbuilder.py
===================================================================
--- SQLObject/trunk/sqlobject/sqlbuilder.py 2010-10-15 12:20:07 UTC (rev 4260)
+++ SQLObject/trunk/sqlobject/sqlbuilder.py 2010-10-15 12:32:04 UTC (rev 4261)
@@ -80,8 +80,9 @@
class SQLObjectState(object):
- def __init__(self, soObject):
+ def __init__(self, soObject, connection=None):
self.soObject = weakref.proxy(soObject)
+ self.connection = connection
safeSQLRE = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_\.]*$')
Copied: SQLObject/trunk/sqlobject/tests/test_perConnection.py (from rev 4260, SQLObject/branches/0.14/sqlobject/tests/test_perConnection.py)
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_perConnection.py (rev 0)
+++ SQLObject/trunk/sqlobject/tests/test_perConnection.py 2010-10-15 12:32:04 UTC (rev 4261)
@@ -0,0 +1,15 @@
+from sqlobject import *
+from sqlobject.tests.dbtest import *
+
+########################################
+## Per-instance connection
+########################################
+
+class TestPerConnection(SQLObject):
+ test = StringCol()
+
+def test_perConnection():
+ connection = getConnection()
+ TestPerConnection.createTable(connection=connection)
+ TestPerConnection(test='test', connection=connection)
+ assert len(list(TestPerConnection.select(TestPerConnection.q.test=='test', connection=connection))) == 1
|