Author: luke
Date: 2008-03-17 15:04:50 -0600 (Mon, 17 Mar 2008)
New Revision: 3342
Modified:
SQLObject/trunk/sqlobject/main.py
SQLObject/trunk/sqlobject/sqlbuilder.py
SQLObject/trunk/sqlobject/tests/test_sqlbuilder_joins_instances.py
Log:
.j attribute on SO classes, and sqlbuilder.SQLObjectTableWithJoins class for auto-constructing join expressions as 'cls.j.joinName' or 'cls.j.foreignKeyName'
Modified: SQLObject/trunk/sqlobject/main.py
===================================================================
--- SQLObject/trunk/sqlobject/main.py 2008-03-17 17:36:06 UTC (rev 3341)
+++ SQLObject/trunk/sqlobject/main.py 2008-03-17 21:04:50 UTC (rev 3342)
@@ -798,6 +798,7 @@
# more.
if not is_base:
cls.q = sqlbuilder.SQLObjectTable(cls)
+ cls.j = sqlbuilder.SQLObjectTableWithJoins(cls)
classregistry.registry(cls.sqlmeta.registry).addClass(cls)
Modified: SQLObject/trunk/sqlobject/sqlbuilder.py
===================================================================
--- SQLObject/trunk/sqlobject/sqlbuilder.py 2008-03-17 17:36:06 UTC (rev 3341)
+++ SQLObject/trunk/sqlobject/sqlbuilder.py 2008-03-17 21:04:50 UTC (rev 3342)
@@ -414,6 +414,30 @@
def _getattrFromUnicodeColumn(self, column, attr):
return self.UnicodeFieldClass(self.tableName, column.dbName, attr, column)
+class SQLObjectTableWithJoins(SQLObjectTable):
+
+ def __getattr__(self, attr):
+ if attr+'ID' in [k for (k,v) in self.soClass.sqlmeta.columns.items() if v.foreignKey]:
+ column = self.soClass.sqlmeta.columns[attr+'ID']
+ return self._getattrFromForeignKey(column, attr)
+ elif attr in [x.joinMethodName for x in self.soClass.sqlmeta.joins]:
+ join = [x for x in self.soClass.sqlmeta.joins if x.joinMethodName == attr][0]
+ return self._getattrFromJoin(join, attr)
+ else:
+ return SQLObjectTable.__getattr__(self, attr)
+
+ def _getattrFromForeignKey(self, column, attr):
+ ret = getattr(self, column.name) == \
+ getattr(self.soClass, '_SO_class_'+column.foreignKey).q.id
+ return ret
+
+ def _getattrFromJoin(self, join, attr):
+ if hasattr(join, 'otherColumn'):
+ return AND(join.otherClass.q.id == Field(join.intermediateTable, join.otherColumn),
+ Field(join.intermediateTable, join.joinColumn) == self.soClass.q.id)
+ else:
+ return getattr(join.otherClass.q, join.joinColumn)==self.soClass.q.id
+
class TableSpace:
TableClass = Table
Modified: SQLObject/trunk/sqlobject/tests/test_sqlbuilder_joins_instances.py
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_sqlbuilder_joins_instances.py 2008-03-17 17:36:06 UTC (rev 3341)
+++ SQLObject/trunk/sqlobject/tests/test_sqlbuilder_joins_instances.py 2008-03-17 21:04:50 UTC (rev 3342)
@@ -43,3 +43,20 @@
def testInstance():
assert list(SBAddress.select(AND(SBPerson.q.id==SBAddress.q.personID, SBPerson.q.id==ppl[0].id))) == \
list(ppl[0].addresses)
+
+def testFK():
+ assert list(SBPerson.select(AND(SBAddress.j.person, SBAddress.q.city=='London'))) == \
+ list(SBPerson.select(AND(SBPerson.q.id==SBAddress.q.personID, SBAddress.q.city=='London')))
+
+def testRelatedJoin2():
+ assert list(SBAddress.select(AND(SBAddress.j.sharedPeople, SBPerson.q.name=='Julia'))) == \
+ list(SBPerson.select(SBPerson.q.name=='Julia').throughTo.sharedAddresses)
+
+def testJoin2():
+ assert list(SBAddress.select(AND(SBPerson.j.addresses, SBPerson.q.name=='Julia'))) == \
+ list(SBAddress.select(AND(SBPerson.q.id==SBAddress.q.personID, SBPerson.q.name=='Julia'))) == \
+ list(SBPerson.selectBy(name='Julia').throughTo.addresses)
+
+def testFK2():
+ assert list(SBAddress.select(AND(SBAddress.j.person, SBPerson.q.name=='Julia'))) == \
+ list(SBAddress.select(AND(SBPerson.q.id==SBAddress.q.personID, SBPerson.q.name=='Julia')))
|