From: Mike Bayer Date: Sat, 25 Mar 2006 00:17:51 +0000 (+0000) Subject: added expunge() method to objectstore X-Git-Tag: rel_0_1_5~28 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fcbd4f153980384089ce8d519607a1db8e7e8838;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git added expunge() method to objectstore correction in attributes reset_history to really reset in all cases added unit tests testing refresh()/expire() bug that was fixed by reset_history thing --- diff --git a/lib/sqlalchemy/attributes.py b/lib/sqlalchemy/attributes.py index bd730a1091..bd5868baf4 100644 --- a/lib/sqlalchemy/attributes.py +++ b/lib/sqlalchemy/attributes.py @@ -397,7 +397,10 @@ class AttributeManager(object): x.clear() del self.attribute_history(obj)[key] except KeyError: - pass + try: + del obj.__dict__[key] + except KeyError: + pass def class_managed(self, class_): """returns a dictionary of "history container definitions", which is attached to a diff --git a/lib/sqlalchemy/mapping/objectstore.py b/lib/sqlalchemy/mapping/objectstore.py index f978d16f72..6b3d7f034a 100644 --- a/lib/sqlalchemy/mapping/objectstore.py +++ b/lib/sqlalchemy/mapping/objectstore.py @@ -166,6 +166,10 @@ class Session(object): for o in obj: global_attributes.trigger_history(o, lambda: refresh(o)) + def expunge(self, *obj): + for o in obj: + self.uow.expunge(obj) + def register_clean(self, obj): self._bind_to(obj) self.uow.register_clean(obj) @@ -252,7 +256,10 @@ 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 expunge(*obj): + get_session().expunge(*obj) + def delete(*obj): """registers the given objects as to be deleted upon the next commit""" s = get_session().delete(*obj) diff --git a/lib/sqlalchemy/mapping/unitofwork.py b/lib/sqlalchemy/mapping/unitofwork.py index 2dc5248975..1e5388933d 100644 --- a/lib/sqlalchemy/mapping/unitofwork.py +++ b/lib/sqlalchemy/mapping/unitofwork.py @@ -104,6 +104,11 @@ class UnitOfWork(object): """returns True if the given key is present in this UnitOfWork's identity map.""" return self.identity_map.has_key(key) + def expunge(self, obj): + """removes this object completely from the UnitOfWork, including the identity map, + and the "new", "dirty" and "deleted" lists.""" + self._remove_deleted(obj) + def _remove_deleted(self, obj): if hasattr(obj, "_instance_key"): del self.identity_map[obj._instance_key] @@ -119,7 +124,7 @@ class UnitOfWork(object): del self.new[obj] except KeyError: pass - self.attributes.commit(obj) + #self.attributes.commit(obj) self.attributes.remove(obj) def _validate_obj(self, obj): diff --git a/test/mapper.py b/test/mapper.py index eff6566547..26668df1af 100644 --- a/test/mapper.py +++ b/test/mapper.py @@ -85,9 +85,14 @@ class MapperTest(MapperSuperTest): self.assert_(u is not u2) def testrefresh(self): - m = mapper(User, users) + m = mapper(User, users, properties={'addresses':relation(mapper(Address, addresses))}) u = m.get(7) u.user_name = 'foo' + a = Address() + u.addresses.append(a) + + self.assert_(a in u.addresses) + objectstore.refresh(u) # its refreshed, so not dirty @@ -96,16 +101,21 @@ class MapperTest(MapperSuperTest): # username is back to the DB self.assert_(u.user_name == 'jack') + self.assert_(a not in u.addresses) + u.user_name = 'foo' + u.addresses.append(a) # now its dirty self.assert_(u in objectstore.get_session().uow.dirty) self.assert_(u.user_name == 'foo') + self.assert_(a in u.addresses) 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') + self.assert_(a not in u.addresses) # not dirty anymore self.assert_(u not in objectstore.get_session().uow.dirty)