Commits

Mike Bayer committed 93f4522

added objectstore.refresh(), including supporting changes in mapper, attributes, util

Comments (0)

Files changed (4)

lib/sqlalchemy/attributes.py

         self.extension = extension
     def gethistory(self, *args, **kwargs):
         return self
+    def clear(self):
+        del self.obj.__dict__[self.key]
     def history_contains(self, obj):
         return self.orig is obj or self.obj.__dict__[self.key] is obj
     def setattr_clean(self, value):
                 pass
                 
     def remove(self, obj):
-        """not sure what this is."""
+        """called when an object is totally being removed from memory"""
+        # currently a no-op since the state of the object is attached to the object itself
         pass
 
     def create_history(self, obj, key, uselist, callable_=None, **kwargs):
         When the attribute is next accessed, a new container will be created via the
         class-level history container definition."""
         try:
+            x = self.attribute_history(obj)[key]
+            x.clear()
             del self.attribute_history(obj)[key]
         except KeyError:
             pass

lib/sqlalchemy/mapping/mapper.py

     def instances(self, cursor, *mappers, **kwargs):
         limit = kwargs.get('limit', None)
         offset = kwargs.get('offset', None)
+        populate_existing = kwargs.get('populate_existing', False)
         
         result = util.HistoryArraySet()
         if len(mappers):
             row = cursor.fetchone()
             if row is None:
                 break
-            self._instance(row, imap, result)
+            self._instance(row, imap, result, populate_existing=populate_existing)
             i = 0
             for m in mappers:
                 m._instance(row, imap, otherresults[i])
         #print "key: " + repr(key) + " ident: " + repr(ident)
         return self._get(key, ident)
         
-    def _get(self, key, ident=None):
+    def _get(self, key, ident=None, reload=False):
+        if not reload:
+            try:
+                return objectstore.get_session()._get(key)
+            except KeyError:
+                pass
+            
+        if ident is None:
+            ident = key[1]
+        i = 0
+        params = {}
+        for primary_key in self.pks_by_table[self.table]:
+            params["pk_"+primary_key.key] = ident[i]
+            i += 1
         try:
-            return objectstore.get_session()._get(key)
-        except KeyError:
-            if ident is None:
-                ident = key[2]
-            i = 0
-            params = {}
-            for primary_key in self.pks_by_table[self.table]:
-                params["pk_"+primary_key.key] = ident[i]
-                i += 1
-            try:
-                return self.select(self._get_clause, params=params)[0]
-            except IndexError:
-                return None
+            statement = self._compile(self._get_clause)
+            return self._select_statement(statement, params=params, populate_existing=reload)[0]
+        except IndexError:
+            return None
 
         
     def identity_key(self, *primary_key):
 
     def select_whereclause(self, whereclause=None, params=None, **kwargs):
         statement = self._compile(whereclause, **kwargs)
-        if params is not None:
-            return self.select_statement(statement, **params)
-        else:
-            return self.select_statement(statement)
+        return self._select_statement(statement, params=params)
 
     def count(self, whereclause=None, params=None, **kwargs):
         s = self.table.count(whereclause)
             return s.scalar()
 
     def select_statement(self, statement, **params):
-        statement.use_labels = True
-        return self.instances(statement.execute(**params))
+        return self._select_statement(statement, params=params)
 
     def select_text(self, text, **params):
         t = sql.text(text, engine=self.primarytable.engine)
         return self.instances(t.execute(**params))
 
+    def _select_statement(self, statement, params=None, **kwargs):
+        statement.use_labels = True
+        if params is None:
+            params = {}
+        return self.instances(statement.execute(**params), **kwargs)
+
     def _getpropbycolumn(self, column):
         try:
             prop = self.columntoproperty[column.original]
 
             isnew = False
             if populate_existing:
-                isnew = not imap.has_key(identitykey)
-                if isnew:
+                if not imap.has_key(identitykey):
                     imap[identitykey] = instance
                 for prop in self.props.values():
-                    prop.execute(instance, row, identitykey, imap, isnew)
+                    prop.execute(instance, row, identitykey, imap, True)
 
             if self.extension.append_result(self, row, imap, result, instance, isnew, populate_existing=populate_existing):
                 if result is not None:

lib/sqlalchemy/mapping/objectstore.py

         if self.parent_uow is None:
             self.uow.commit()
 
+    def refresh(self, *obj):
+        for o in obj:
+            self.uow.refresh(o)
+
     def register_clean(self, obj):
         self._bind_to(obj)
         self.uow.register_clean(obj)
     current mapped object instances, as they are no longer in the Identity Map."""
     get_session().clear()
 
+def refresh(*obj):
+    """reloads the state of this object from the database, and cancels any in-memory
+    changes."""
+    get_session().refresh(*obj)
+    
 def delete(*obj):
     """registers the given objects as to be deleted upon the next commit"""
     s = get_session().delete(*obj)
     def _put(self, key, obj):
         self.identity_map[key] = obj
 
+    def refresh(self, obj):
+        self.rollback_object(obj)
+        object_mapper(obj)._get(obj._instance_key, reload=True)
+
     def has_key(self, key):
         """returns True if the given key is present in this UnitOfWork's identity map."""
         return self.identity_map.has_key(key)

lib/sqlalchemy/util.py

         self.records = {}
         for l in list:
             self.append_nohistory(l)
+    def clear(self):
+        """clears the list and removes all history."""
+        self.data[:] = []
+        self.records = {}
     def added_items(self):
         """returns a list of items that have been added since the last "committed" state."""
         return [key for key in self.data if self.records[key] is True]