Author: phd
Date: 2006-10-27 09:28:27 -0600 (Fri, 27 Oct 2006)
New Revision: 2040
Modified:
SQLObject/branches/0.7-bugfix/docs/News.txt
SQLObject/branches/0.7-bugfix/sqlobject/inheritance/__init__.py
SQLObject/branches/0.7-bugfix/sqlobject/inheritance/tests/test_inherited_foreignKey.py
SQLObject/branches/0.7-bugfix/sqlobject/tests/test_foreignKey.py
Log:
InheritableSQLObject.selectBy() now correctly handles foreign keys, even foreign keys from the parent classes.
The patch is inspired and the test provided by Johan Dahlin <jd...@as...>.
Modified: SQLObject/branches/0.7-bugfix/docs/News.txt
===================================================================
--- SQLObject/branches/0.7-bugfix/docs/News.txt 2006-10-27 15:26:07 UTC (rev 2039)
+++ SQLObject/branches/0.7-bugfix/docs/News.txt 2006-10-27 15:28:27 UTC (rev 2040)
@@ -15,6 +15,9 @@
* Fixed a number of unicode-related problems with newer MySQLdb.
+* InheritableSQLObject.selectBy() now correctly handles foreign keys, even
+ foreign keys from the parent classes.
+
SQLObject 0.7.1
===============
Modified: SQLObject/branches/0.7-bugfix/sqlobject/inheritance/__init__.py
===================================================================
--- SQLObject/branches/0.7-bugfix/sqlobject/inheritance/__init__.py 2006-10-27 15:26:07 UTC (rev 2039)
+++ SQLObject/branches/0.7-bugfix/sqlobject/inheritance/__init__.py 2006-10-27 15:28:27 UTC (rev 2040)
@@ -245,9 +245,34 @@
def selectBy(cls, connection=None, **kw):
clause = []
+ foreignColumns = {}
+ currentClass = cls
+ while currentClass:
+ foreignColumns.update(dict([(column.foreignName, name)
+ for (name, column) in currentClass.sqlmeta.columns.items()
+ if column.foreignKey
+ ]))
+ currentClass = currentClass._parentClass
for name, value in kw.items():
- clause.append(getattr(cls.q, name) == value)
- clause = reduce(sqlbuilder.AND, clause)
+ if name in foreignColumns:
+ name = foreignColumns[name] # translate "key" to "keyID"
+ if isinstance(value, SQLObject):
+ value = value.id
+ currentClass = cls
+ while currentClass:
+ try:
+ clause.append(getattr(currentClass.q, name) == value)
+ break
+ except AttributeError, err:
+ pass
+ currentClass = currentClass._parentClass
+ else:
+ raise AttributeError("'%s' instance has no attribute '%s'"
+ % (cls.__name__, name))
+ if clause:
+ clause = reduce(sqlbuilder.AND, clause)
+ else:
+ clause = None # select all
conn = connection or cls._connection
return cls.SelectResultsClass(cls, clause, connection=conn)
Modified: SQLObject/branches/0.7-bugfix/sqlobject/inheritance/tests/test_inherited_foreignKey.py
===================================================================
--- SQLObject/branches/0.7-bugfix/sqlobject/inheritance/tests/test_inherited_foreignKey.py 2006-10-27 15:26:07 UTC (rev 2039)
+++ SQLObject/branches/0.7-bugfix/sqlobject/inheritance/tests/test_inherited_foreignKey.py 2006-10-27 15:28:27 UTC (rev 2040)
@@ -11,12 +11,17 @@
lastName = StringCol()
note = ForeignKey("Note", default=None)
+class Paper(SQLObject):
+ content = StringCol()
+
class EmployeeWithNotes(PersonWithNotes):
_inheritable = False
+ paper = ForeignKey("Paper", default=None)
def setup():
setupClass(Note)
setupClass(PersonWithNotes)
+ setupClass(Paper)
setupClass(EmployeeWithNotes)
note = Note(text="person")
@@ -24,6 +29,9 @@
note = Note(text="employee")
EmployeeWithNotes(firstName='Project', lastName='Leader', note=note)
+ paper = Paper(content="secret")
+ EmployeeWithNotes(firstName='Senior', lastName='Clerk', paper=paper)
+ PersonWithNotes(firstName='Some', lastName='Person')
def test_inheritance():
setup()
@@ -35,3 +43,35 @@
employee = EmployeeWithNotes.get(2)
assert isinstance(employee, EmployeeWithNotes)
assert employee.note.text == "employee"
+ save_employee = employee
+
+ persons = PersonWithNotes.select(PersonWithNotes.q.noteID <> None)
+ assert persons.count() == 2
+
+ persons = PersonWithNotes.selectBy(noteID=person.note.id)
+ assert persons.count() == 1
+
+ employee = EmployeeWithNotes.select(PersonWithNotes.q.noteID <> None)
+ assert employee.count() == 1
+
+ persons = PersonWithNotes.selectBy(noteID=person.note.id)
+ assert persons.count() == 1
+
+ persons = PersonWithNotes.selectBy(note=person.note)
+ assert persons.count() == 1
+
+ persons = PersonWithNotes.selectBy(note=None)
+ assert persons.count() == 2
+
+ employee = EmployeeWithNotes.selectBy(paperID=None)
+ assert employee.count() == 1
+
+ employee = EmployeeWithNotes.selectBy(paper=None)
+ assert employee.count() == 1
+
+ employee = EmployeeWithNotes.selectBy(note=save_employee.note,
+ paper=save_employee.paper)
+ assert employee.count() == 1
+
+ employee = EmployeeWithNotes.selectBy()
+ assert employee.count() == 2
Modified: SQLObject/branches/0.7-bugfix/sqlobject/tests/test_foreignKey.py
===================================================================
--- SQLObject/branches/0.7-bugfix/sqlobject/tests/test_foreignKey.py 2006-10-27 15:26:07 UTC (rev 2039)
+++ SQLObject/branches/0.7-bugfix/sqlobject/tests/test_foreignKey.py 2006-10-27 15:28:27 UTC (rev 2040)
@@ -38,6 +38,9 @@
s = TestWorkKey.selectBy(composer=None, title=None)
assert s[0]==w2
+ s = TestWorkKey.selectBy()
+ assert s.count() == 2
+
def test2():
setupClass([TestComposerKey, TestWorkKey2])
TestWorkKey2.sqlmeta.addColumn(ForeignKey('TestComposerKey'), changeSchema=True)
|