]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
moved dirty flags, dirty attributes to unitofwork
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 7 Sep 2005 05:34:57 +0000 (05:34 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 7 Sep 2005 05:34:57 +0000 (05:34 +0000)
lib/sqlalchemy/objectstore.py

index 7bcf00fd8fd07578fa7be77a1b54dd18336895f0..b1e454e024922148746ec7a11ecce62cb182a4af 100644 (file)
 # along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
+
+"""maintains all currently loaded objects in memory,
+using the "identity map" pattern.  Also provides a "unit of work" object which tracks changes
+to objects so that they may be properly persisted within a transactional scope."""
+
 import thread
+import sqlalchemy.util as util
+import weakref
 
 def get_id_key(ident, class_, table, selectable):
+    """returns an identity-map key for use in storing/retrieving an item from the identity map, given
+    a tuple of the object's primary key values.
+    
+    ident - a tuple of primary key values corresponding to the object to be stored.  these values
+    should be in the same order as the primary keys of the table
+    class_ - a reference to the object's class
+    table - a Table object where the object's primary fields are stored.
+    selectable - a Selectable object which represents all the object's column-based fields.  this Selectable
+    may be synonymous with the table argument or can be a larger construct containing that table.
+    return value: a tuple object which is used as an identity key.
+    """
     return (class_, table, tuple(ident))
 def get_instance_key(object, class_, table, selectable):
+    """returns an identity-map key for use in storing/retrieving an item from the identity map, given
+    the object instance itself.
+    
+    object - the object to be stored.  it is assumed that the object's primary key attributes are
+    populated.
+    class_ - a reference to the object's class
+    table - a Table object where the object's primary fields are stored.
+    selectable - a Selectable object which represents all the object's column-based fields.  this Selectable
+    may be synonymous with the table argument or can be a larger construct containing that table.
+    return value: a tuple object which is used as an identity key.
+    """
     return (class_, table, tuple([getattr(object, column.key, None) for column in selectable.primary_keys]))
 def get_row_key(row, class_, table, selectable):
+    """returns an identity-map key for use in storing/retrieving an item from the identity map, given
+    a result set row.
+    
+    row - a sqlalchemy.dbengine.RowProxy instance or other map corresponding result-set column
+    names to their values within a row.
+    class_ - a reference to the object's class
+    table - a Table object where the object's primary fields are stored.
+    selectable - a Selectable object which represents all the object's column-based fields.  this Selectable
+    may be synonymous with the table argument or can be a larger construct containing that table.
+    return value: a tuple object which is used as an identity key.
+    """
     return (class_, table, tuple([row[column.label] for column in selectable.primary_keys]))
 
 identity_map = {}
@@ -34,6 +74,7 @@ def get(key):
         return val
     
 def put(key, obj, scope='thread'):
+
     if isinstance(obj, dict):
         raise "cant put a dict in the object store"
         
@@ -68,19 +109,52 @@ def has_key(key):
     
 class UnitOfWork:
     def __init__(self):
-        pass
+        self.dirty = util.HashSet()
+        self.clean = util.HashSet()
+        self.deleted = util.HashSet()
+        self.attribute_history = weakref.WeakKeyDictionary()
+        
+    def attribute_set(self, obj, key, value):
+        self.register_attribute(obj, key).setattr(value)    
+    def attribute_deleted(self, obj, key, value):
+        self.register_attribute(obj, key).delattr(value)    
+    
+    def register_attribute(self, obj, key):
+        try:
+            attributes = self.attribute_history[obj]
+        except KeyError:
+            attributes = self.attribute_history.setdefault(obj, {})
+        try:
+            return attributes[key]
+        except KeyError:
+            return attributes.setdefault(key, util.PropHistory(obj.__dict__.get(key, None)))
         
     def register_clean(self, obj):
-        pass
+        self.clean.append(obj)
+        try:
+            del self.dirty[obj]
+        except KeyError:
+            pass
 
     def register_new(self, obj):
         pass
         
     def register_dirty(self, obj):
-        pass
+        self.dirty.append(obj)
+        try:
+            del self.clean[obj]
+        except KeyError:
+            pass
+
+    def is_dirty(self, obj):
+        return self.dirty.contains(obj)
         
     def register_deleted(self, obj):
         pass   
         
+    def commit(self):
+        for item in self.dirty:
+            self.clean.append(item)
+        self.dirty.clear()
         
-        
\ No newline at end of file
+uow = util.ScopedRegistry(lambda: UnitOfWork(), "thread")        
\ No newline at end of file