Author: luke
Date: 2007-03-28 08:22:33 -0600 (Wed, 28 Mar 2007)
New Revision: 2464
Modified:
SQLObject/branches/sqlbuilder-views/sqlobject/converters.py
SQLObject/branches/sqlbuilder-views/sqlobject/sqlbuilder.py
SQLObject/branches/sqlbuilder-views/sqlobject/sresults.py
SQLObject/branches/sqlbuilder-views/sqlobject/tests/test_select_through.py
Log:
Merge cleaned up sqlbuilder-sresults branch changes (r2459:2462)
Modified: SQLObject/branches/sqlbuilder-views/sqlobject/converters.py
===================================================================
--- SQLObject/branches/sqlbuilder-views/sqlobject/converters.py 2007-03-28 14:08:17 UTC (rev 2463)
+++ SQLObject/branches/sqlbuilder-views/sqlobject/converters.py 2007-03-28 14:22:33 UTC (rev 2464)
@@ -227,7 +227,6 @@
registerConverter(Decimal, DecimalConverter)
def sqlrepr(obj, db=None):
- import sqlbuilder
try:
reprFunc = obj.__sqlrepr__
except AttributeError:
@@ -237,20 +236,4 @@
(type(obj), repr(obj))
return converter(obj, db)
else:
- doCache = hasattr(db, 'doSQLReprCache')
- ret = None
- if doCache:
- cache = getattr(obj, '_sqlreprCache', {})
- if not isinstance(cache, dict):
- #Alias etc
- cache = {}
- ret = cache.get(db, None)
- if ret is None:
- ret = reprFunc(db)
- if doCache:
- try:
- cache[db] = ret
- obj._sqlreprCache = cache
- except TypeError:
- pass
- return ret
+ return reprFunc(db)
Modified: SQLObject/branches/sqlbuilder-views/sqlobject/sqlbuilder.py
===================================================================
--- SQLObject/branches/sqlbuilder-views/sqlobject/sqlbuilder.py 2007-03-28 14:08:17 UTC (rev 2463)
+++ SQLObject/branches/sqlbuilder-views/sqlobject/sqlbuilder.py 2007-03-28 14:22:33 UTC (rev 2464)
@@ -77,8 +77,6 @@
from converters import sqlrepr, registerConverter, TRUE, FALSE
-default_sqlrepr_db = None
-
safeSQLRE = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_\.]*$')
def sqlIdentifier(obj):
# some db drivers return unicode column names
@@ -188,28 +186,13 @@
def tablesUsed(self, db):
return self.tablesUsedDict(db).keys()
def tablesUsedDict(self, db):
- doCache = hasattr(db, 'doTablesUsedCache')
- tables = None
- if doCache:
- cache = getattr(self, '_tablesUsedCache', {})
- if not isinstance(cache, dict):
- #Alias etc
- cache = {}
- tables = cache.get(db, None)
- if tables is None:
- tables = {}
- for table in self.tablesUsedImmediate():
- if hasattr(table, '__sqlrepr__'):
- table = sqlrepr(table, db)
- tables[table] = 1
- for component in self.components():
- tables.update(tablesUsedDict(component, db))
- if doCache:
- try:
- cache[db] = tables
- self._tablesUsedCache = cache
- except TypeError:
- pass
+ tables = {}
+ for table in self.tablesUsedImmediate():
+ if hasattr(table, '__sqlrepr__'):
+ table = sqlrepr(table, db)
+ tables[table] = 1
+ for component in self.components():
+ tables.update(tablesUsedDict(component, db))
return tables
def tablesUsedImmediate(self):
return []
Modified: SQLObject/branches/sqlbuilder-views/sqlobject/sresults.py
===================================================================
--- SQLObject/branches/sqlbuilder-views/sqlobject/sresults.py 2007-03-28 14:08:17 UTC (rev 2463)
+++ SQLObject/branches/sqlbuilder-views/sqlobject/sresults.py 2007-03-28 14:22:33 UTC (rev 2464)
@@ -281,61 +281,59 @@
return results[0]
def throughTo(self):
+ class _throughTo_getter(object):
+ def __init__(self, inst):
+ self.sresult = inst
+ def __getattr__(self, attr):
+ return self.sresult._throughTo(attr)
return _throughTo_getter(self)
throughTo = property(throughTo)
def _throughTo(self, attr):
+ otherClass = None
+ orderBy = sqlbuilder.NoDefault
+
ref = self.sourceClass.sqlmeta.columns.get(attr.endswith('ID') and attr or attr+'ID', None)
if ref and ref.foreignKey:
- return self._throughToFK(ref)
+ otherClass, clause = self._throughToFK(ref)
else:
join = [x for x in self.sourceClass.sqlmeta.joins if x.joinMethodName==attr]
if join:
join = join[0]
+ orderBy = join.orderBy
if hasattr(join, 'otherColumn'):
- return self._throughToRelatedJoin(join)
- return self._throughToMultipleJoin(join)
+ otherClass, clause = self._throughToRelatedJoin(join)
+ else:
+ otherClass, clause = self._throughToMultipleJoin(join)
- raise AttributeError("throughTo argument (got %s) should be name of foreignKey or SQL*Join in %s" % (attr, self.sourceClass))
+ if not otherClass:
+ raise AttributeError("throughTo argument (got %s) should be name of foreignKey or SQL*Join in %s" % (attr, self.sourceClass))
+ return otherClass.select(clause,
+ distinct=True,
+ orderBy=orderBy,
+ connection=self._getConnection())
+
def _throughToFK(self, col):
otherClass = getattr(self.sourceClass, "_SO_class_"+col.foreignKey)
query = sqlbuilder.Alias(self.queryForSelect(), "%s_%s" % (self.sourceClass.__name__, col.name))
- return otherClass.select(otherClass.q.id==getattr(query.q, getattr(self.sourceClass.q, col.name).fieldName),
- distinct=True,
- connection=self._getConnection())
+ return otherClass, otherClass.q.id==getattr(query.q, getattr(self.sourceClass.q, col.name).fieldName)
def _throughToMultipleJoin(self, join):
otherClass = join.otherClass
query = self.queryForSelect()
query = sqlbuilder.Alias(query, "%s_%s" % (self.sourceClass.__name__, join.joinMethodName))
joinColumn = getattr(otherClass.q, join.soClass.sqlmeta.style.dbColumnToPythonAttr(join.joinColumn))
- return otherClass.select(joinColumn == getattr(query.q, self.sourceClass.q.id.fieldName),
- distinct=True,
- orderBy=join.orderBy,
- connection=self._getConnection())
+ return otherClass, joinColumn==getattr(query.q, self.sourceClass.q.id.fieldName)
def _throughToRelatedJoin(self, join):
otherClass = join.otherClass
intTable = sqlbuilder.Table(join.intermediateTable)
- print join.joinColumn, join.otherColumn
query = self.queryForSelect().newItems([getattr(intTable, join.joinColumn)])
query = sqlbuilder.Alias(query, "%s_%s" % (self.sourceClass.__name__, join.joinMethodName))
- print query
clause = sqlbuilder.AND(otherClass.q.id == getattr(intTable, join.otherColumn),
getattr(intTable, join.joinColumn) == getattr(query.q, join.joinColumn))
- ret = otherClass.select(clause,
- distinct=True,
- orderBy=join.orderBy,
- connection=self._getConnection())
- print ret
- return ret
+ return otherClass, clause
-class _throughTo_getter(object):
- def __init__(self, inst):
- self.sresult = inst
- def __getattr__(self, attr):
- return self.sresult._throughTo(attr)
-
__all__ = ['SelectResults']
Modified: SQLObject/branches/sqlbuilder-views/sqlobject/tests/test_select_through.py
===================================================================
--- SQLObject/branches/sqlbuilder-views/sqlobject/tests/test_select_through.py 2007-03-28 14:08:17 UTC (rev 2463)
+++ SQLObject/branches/sqlbuilder-views/sqlobject/tests/test_select_through.py 2007-03-28 14:22:33 UTC (rev 2464)
@@ -1,6 +1,7 @@
from sqlobject import *
from sqlobject.sqlbuilder import *
from sqlobject.tests.dbtest import *
+import py
''' Tests retrieving objects through a join/fk on a selectResults
'''
@@ -36,6 +37,9 @@
mod.twos = twos
mod.ones = ones
+def testBadRef():
+ py.test.raises(AttributeError, 'threes[0].throughTo.four')
+
def testThroughFK():
assert list(threes[0].ones.throughTo.three) == [threes[0]]
@@ -43,7 +47,6 @@
assert list(threes[0].ones.throughTo.twos) == [twos[0], twos[1]]
def testThroughRelatedJoin():
- print [list(x.threes) for x in threes[0].twos]
assert list(threes[0].twos.throughTo.threes) == [threes[0], threes[1]]
\ No newline at end of file
|