]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
added expire() function + unit test fixes [ticket:95]
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 10 Mar 2006 05:03:17 +0000 (05:03 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 10 Mar 2006 05:03:17 +0000 (05:03 +0000)
lib/sqlalchemy/attributes.py
lib/sqlalchemy/mapping/objectstore.py
test/mapper.py

index a402a9e91498c3c020391e3ecebe8d1ad8106dd0..a41cdac9dfa5a62729e3cea4c815fb745fae07c8 100644 (file)
@@ -353,10 +353,20 @@ class AttributeManager(object):
         try:
             attr = obj.__dict__['_managed_attributes']
         except KeyError:
+            trigger = obj.__dict__.pop('_managed_trigger', None)
+            if trigger:
+                trigger()
             attr = {}
             obj.__dict__['_managed_attributes'] = attr
         return attr
 
+    def trigger_history(self, obj, callable):
+        try:
+            del obj.__dict__['_managed_attributes']
+        except KeyError:
+            pass
+        obj.__dict__['_managed_trigger'] = callable
+        
     def reset_history(self, obj, key):
         """removes the history object for the given attribute on the given object.
         When the attribute is next accessed, a new container will be created via the
index d2aca8b0697ae51734475de8683a2e9eaf362062..be3d96934c2b9749c27a7f71715138e3fbb17150 100644 (file)
@@ -145,9 +145,17 @@ class Session(object):
             self.uow.commit()
 
     def refresh(self, *obj):
+        """reloads the attributes for the given objects from the database, clears
+        any changes made."""
         for o in obj:
             self.uow.refresh(o)
 
+    def expire(self, *obj):
+        """invalidates the data in the given objects and sets them to refresh themselves
+        the next time they are requested."""
+        for o in obj:
+            global_attributes.trigger_history(o, lambda: refresh(o))
+
     def register_clean(self, obj):
         self._bind_to(obj)
         self.uow.register_clean(obj)
@@ -229,6 +237,11 @@ def refresh(*obj):
     """reloads the state of this object from the database, and cancels any in-memory
     changes."""
     get_session().refresh(*obj)
+
+def expire(*obj):
+    """invalidates the data in the given objects and sets them to refresh themselves
+    the next time they are requested."""
+    get_session().expire(*obj)
     
 def delete(*obj):
     """registers the given objects as to be deleted upon the next commit"""
index aa0b2289102f3bbdc96e785fdf9fe3b1888ee859..81592df8c9f5c2b9365142e887e6a20224b55703 100644 (file)
@@ -84,6 +84,31 @@ class MapperTest(MapperSuperTest):
         u2 = m.get(7)
         self.assert_(u is not u2)
 
+    def testrefresh(self):
+        m = mapper(User, users)
+        u = m.get(7)
+        u.user_name = 'foo'
+        objectstore.refresh(u)
+        
+        # its refreshed, so not dirty
+        self.assert_(u not in objectstore.get_session().uow.dirty)
+        
+        # username is back to the DB
+        self.assert_(u.user_name == 'jack')
+        
+        u.user_name = 'foo'
+        # now its dirty
+        self.assert_(u in objectstore.get_session().uow.dirty)
+        self.assert_(u.user_name == 'foo')
+        objectstore.expire(u)
+
+        # expired, but not refreshed yet.  still dirty
+        self.assert_(u in objectstore.get_session().uow.dirty)
+        # get the attribute, it refreshes
+        self.assert_(u.user_name == 'jack')
+        # not dirty anymore
+        self.assert_(u not in objectstore.get_session().uow.dirty)
+        
     def testmagic(self):
         m = mapper(User, users, properties = {
             'addresses' : relation(mapper(Address, addresses))