Author: phd
Date: 2005-06-01 13:48:41 +0000 (Wed, 01 Jun 2005)
New Revision: 809
Added:
trunk/SQLObject/sqlobject/tests/test_SingleJoin.py
Modified:
trunk/SQLObject/docs/SQLObjectRelationships.txt
trunk/SQLObject/sqlobject/joins.py
Log:
Added SingleJoin. Thanks to michelts <mic...@gm...>.
Modified: trunk/SQLObject/docs/SQLObjectRelationships.txt
===================================================================
--- trunk/SQLObject/docs/SQLObjectRelationships.txt 2005-05-30 17:08:10 UTC (rev 808)
+++ trunk/SQLObject/docs/SQLObjectRelationships.txt 2005-06-01 13:48:41 UTC (rev 809)
@@ -9,7 +9,7 @@
~~~~~~~~~~~~~~~~~~~~~~~~~
See `One-to-Many Relationships`_ for an example of one-to-many
-relationships.
+relationships.
Several keyword arguments are allowed to the `MultipleJoin` constructor:
@@ -77,3 +77,8 @@
name = StringCol(length=50, alternateID=True)
roles = RelatedJoin('Person', joinColumn='role', otherColumn='person',
intermediateTable='assigned_roles')
+
+SingleJoin: One-to-One
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Similar to `MultipleJoin`, but returns just one object, not a list.
Modified: trunk/SQLObject/sqlobject/joins.py
===================================================================
--- trunk/SQLObject/sqlobject/joins.py 2005-05-30 17:08:10 UTC (rev 808)
+++ trunk/SQLObject/sqlobject/joins.py 2005-06-01 13:48:41 UTC (rev 809)
@@ -4,7 +4,7 @@
import classregistry
from col import popKey
-__all__ = ['MultipleJoin', 'SQLMultipleJoin', 'RelatedJoin', 'SQLRelatedJoin']
+__all__ = ['MultipleJoin', 'SQLMultipleJoin', 'RelatedJoin', 'SQLRelatedJoin', 'SingleJoin']
def getID(obj):
try:
@@ -133,17 +133,17 @@
conn = None
return self._applyOrderBy([self.otherClass.get(id, conn) for (id,) in ids if id is not None], self.otherClass)
+class MultipleJoin(Join):
+ baseClass = SOMultipleJoin
+
class SOSQLMultipleJoin(SOMultipleJoin):
def performJoin(self, inst):
- results=self.otherClass.select(getattr(self.otherClass.q, self.soClass.sqlmeta.style.dbColumnToPythonAttr(self.joinColumn))==inst.id)
+ results = self.otherClass.select(getattr(self.otherClass.q, self.soClass.sqlmeta.style.dbColumnToPythonAttr(self.joinColumn)) == inst.id)
if self.orderBy is NoDefault:
self.orderBy = self.otherClass.sqlmeta.defaultOrder
return results.orderBy(self.orderBy)
-class MultipleJoin(Join):
- baseClass = SOMultipleJoin
-
class SQLMultipleJoin(Join):
baseClass = SOSQLMultipleJoin
@@ -202,6 +202,9 @@
self.otherColumn,
getID(other))
+class RelatedJoin(MultipleJoin):
+ baseClass = SORelatedJoin
+
class SOSQLRelatedJoin(SORelatedJoin):
def performJoin(self, inst):
options={
@@ -225,11 +228,33 @@
# TODO (michelts), apply order by on the selection
return results
-class RelatedJoin(MultipleJoin):
- baseClass = SORelatedJoin
-
class SQLRelatedJoin(RelatedJoin):
baseClass = SOSQLRelatedJoin
def capitalize(name):
return name[0].capitalize() + name[1:]
+
+class SOSingleJoin(SOMultipleJoin):
+
+ def __init__(self, makeDefault=False, **kw):
+ SOMultipleJoin.__init__(self, **kw)
+ self.makeDefault = makeDefault
+
+ def performJoin(self, inst):
+ pythonColumn = self.soClass.sqlmeta.style.dbColumnToPythonAttr(self.joinColumn)
+ results = self.otherClass.select(getattr(self.otherClass.q, pythonColumn) == inst.id)
+ if results.count() == 0:
+ if not self.makeDefault:
+ return None
+ else:
+ kw = {pythonColumn[:-2]: inst} # skipping the ID (from foreignkeyID)
+ return self.otherClass(**kw) # instanciating the otherClass with all
+ # values to their defaults, except the foreign key
+ # TODO I don't think this is the best way to know the column as foreignKey
+ # reather than foreignKeyID, but I don't found a sqlmeta.style function
+ # to do the work, if there isn't such function, I must create it.
+ else:
+ return results[0]
+
+class SingleJoin(Join):
+ baseClass = SOSingleJoin
Added: trunk/SQLObject/sqlobject/tests/test_SingleJoin.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_SingleJoin.py 2005-05-30 17:08:10 UTC (rev 808)
+++ trunk/SQLObject/sqlobject/tests/test_SingleJoin.py 2005-06-01 13:48:41 UTC (rev 809)
@@ -0,0 +1,25 @@
+from sqlobject import *
+from sqlobject.tests.dbtest import *
+
+class PersonWithAlbum(SQLObject):
+ name = StringCol()
+ # albumNone returns the album or none
+ albumNone = SingleJoin('PhotoAlbum', joinColumn='person_id')
+ # albumInstance returns the album or an default album instance
+ albumInstance = SingleJoin('PhotoAlbum', makeDefault=True, joinColumn='person_id')
+
+class PhotoAlbum(SQLObject):
+ color = StringCol(default='red')
+ person = ForeignKey('PersonWithAlbum')
+
+def test_1():
+ setupClass([PersonWithAlbum, PhotoAlbum])
+
+ person = PersonWithAlbum(name='Gokou (Kakarouto)')
+ assert not person.albumNone # I don't created an album, this way it returns None
+ assert isinstance(person.albumInstance, PhotoAlbum)
+
+ album = PhotoAlbum(person=person)
+ assert person.albumNone
+ assert isinstance(person.albumNone, PhotoAlbum)
+ assert isinstance(person.albumInstance, PhotoAlbum)
|