[Checkins] SVN: megrok.rdb/trunk/src/megrok/rdb/ automatic support for __parent__ and __name__ in Container. Many thanks go

Martijn Faassen faassen at infrae.com
Wed Aug 20 11:39:49 EDT 2008


Log message for revision 90026:
  automatic support for __parent__ and __name__ in Container. Many thanks go
  to Mike Bayer for his help on this.
  

Changed:
  U   megrok.rdb/trunk/src/megrok/rdb/components.py
  A   megrok.rdb/trunk/src/megrok/rdb/tests/location.py
  U   megrok.rdb/trunk/src/megrok/rdb/tests/test_rdb.py

-=-
Modified: megrok.rdb/trunk/src/megrok/rdb/components.py
===================================================================
--- megrok.rdb/trunk/src/megrok/rdb/components.py	2008-08-20 15:39:19 UTC (rev 90025)
+++ megrok.rdb/trunk/src/megrok/rdb/components.py	2008-08-20 15:39:48 UTC (rev 90026)
@@ -38,6 +38,26 @@
             keyfunc = default_keyfunc
         MappedCollection.__init__(self, keyfunc=keyfunc)
 
+    def _sa_on_link(self, adapter):
+        self.__parent__ = adapter.owner_state.obj()
+        self.__name__ = unicode(adapter.attr.key)
+        
+    def __setitem__(self, key, item):
+        self._receive(item)
+        MappedCollection.__setitem__(self, key, item)
+
+    def __delitem__(self, key):
+        self._release(self[key])
+        MappedCollection.__delitem__(self, key)
+
+    def _receive(self, item):
+        item.__name__ = unicode(self.keyfunc(item))
+        item.__parent__ = self
+
+    def _release(self, item):
+        del item.__name__
+        del item.__parent__
+    
     @collection.internally_instrumented
     @collection.appender
     def set(self, value, _sa_initiator=None):
@@ -47,4 +67,3 @@
             session.flush()
             key = self.keyfunc(value)
         self.__setitem__(key, value, _sa_initiator)
-

Added: megrok.rdb/trunk/src/megrok/rdb/tests/location.py
===================================================================
--- megrok.rdb/trunk/src/megrok/rdb/tests/location.py	                        (rev 0)
+++ megrok.rdb/trunk/src/megrok/rdb/tests/location.py	2008-08-20 15:39:48 UTC (rev 90026)
@@ -0,0 +1,114 @@
+"""
+ORM-managed objects such as collection attributes and the items in them should
+have an ILocation so it is easy to generate a URL for them.
+
+Let's first grok things::
+
+  >>> from grok.testing import grok
+  >>> grok('megrok.rdb.meta')
+  >>> grok(__name__)
+
+We need to set up an engine::
+
+  >>> from megrok.rdb.testing import configureEngine
+  >>> engine = configureEngine()
+  
+We now need to reflect the tables in our database to our classes::
+
+  >>> rdb.setupDatabase(metadata)
+
+Let's start using the database now::
+
+  >>> session = rdb.Session()
+  >>> philosophy = Department(name='Philosophy')
+  >>> session.add(philosophy)
+
+An unconnected object has ``__name__`` and ``__parent__`` of None::
+
+  >>> print philosophy.__name__
+  None
+  >>> print philosophy.__parent__
+  None
+
+The ``courses`` attribute of ``philosophy`` however does have a
+``__name__`` and ``__parent__``::
+
+  >>> philosophy.courses.__name__
+  u'courses'
+  >>> philosophy.courses.__parent__ is philosophy
+  True
+
+Let's create some objects to put in the ``courses`` attribute of
+``philosophy``:
+
+  >>> logic = Course(name='Logic')
+  >>> ethics = Course(name='Ethics')
+  >>> metaphysics = Course(name='Metaphysics')
+  >>> session.add_all([logic, ethics, metaphysics])
+
+At this stage these object are also unconnected, so have ``__name__``
+and ``__parent__`` of None::
+
+  >>> print logic.__name__
+  None
+  >>> print logic.__parent__
+  None
+
+Let's now add them to the courses container::
+
+  >>> philosophy.courses.set(logic)
+  >>> philosophy.courses.set(ethics)
+  >>> philosophy.courses.set(metaphysics)
+
+They now should have the proper parents::
+
+  >>> philosophy.courses[1].__name__
+  u'1'
+  >>> philosophy.courses[1].__parent__ is philosophy.courses
+  True
+  
+"""
+
+
+import grok
+from megrok import rdb
+
+from sqlalchemy import Column, ForeignKey
+from sqlalchemy.types import Integer, String
+from sqlalchemy.orm import relation, MapperExtension, EXT_CONTINUE
+
+metadata = rdb.MetaData()
+
+rdb.metadata(metadata)
+
+# class MyExtension(MapperExtension):
+#     def init_instance(self, mapper, class_, oldinit, instance, args, kwargs):
+#         if isinstance(instance, Department):
+#             instance.courses.__name__ = u'courses'
+#             instance.courses.__parent__ = instance
+#         return EXT_CONTINUE
+    
+class Courses(rdb.Container):
+    __parent__ = None
+    __name__ = None
+   
+class Department(rdb.Model):
+#     __mapper_args__ = {'extension': MyExtension()}
+
+    __parent__ = None
+    __name__ = None
+    
+    id = Column('id', Integer, primary_key=True)
+    name = Column('name', String(50))
+    courses = relation('Course', 
+                       backref='department',
+                       collection_class=Courses)
+
+class Course(rdb.Model):
+    __parent__ = None
+    __name__ = None
+   
+    id = Column('id', Integer, primary_key=True)
+    department_id = Column('department_id', Integer, 
+                           ForeignKey('department.id'))
+    name = Column('name', String(50))

Modified: megrok.rdb/trunk/src/megrok/rdb/tests/test_rdb.py
===================================================================
--- megrok.rdb/trunk/src/megrok/rdb/tests/test_rdb.py	2008-08-20 15:39:19 UTC (rev 90025)
+++ megrok.rdb/trunk/src/megrok/rdb/tests/test_rdb.py	2008-08-20 15:39:48 UTC (rev 90026)
@@ -49,6 +49,11 @@
         setUp=zopeSetUp,
         tearDown=zopeTearDown,
         optionflags=optionflags))
+    suite.addTest(doctest.DocTestSuite(
+        'megrok.rdb.tests.location',
+        setUp=zopeSetUp,
+        tearDown=zopeTearDown,
+        optionflags=optionflags))
     suite.addTest(doctest.DocFileSuite(
         '../schema.txt',
         optionflags=optionflags,



More information about the Checkins mailing list