]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
basic many to many...
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 10 Sep 2005 18:50:33 +0000 (18:50 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 10 Sep 2005 18:50:33 +0000 (18:50 +0000)
lib/sqlalchemy/mapper.py
lib/sqlalchemy/objectstore.py
test/mapper.py

index a12c01304e2b9015c87941006d8b4bc6e99457b6..9a7cf0044e19d350dbe74b32e75ae2d97eb8edff 100644 (file)
@@ -501,7 +501,8 @@ class PropertyLoader(MapperProperty):
 
     def register_dependencies(self, objlist, uow):
         if self.secondaryjoin is not None:
-            pass
+            uow.register_dependency(self.parent, self.mapper, None, None)
+            uow.register_dependency(self.mapper, None, self, objlist)
         elif self.foreignkey.table == self.target:
             uow.register_dependency(self.parent, self.mapper, self, objlist)
         elif self.foreignkey.table == self.parent.table:
@@ -509,33 +510,63 @@ class PropertyLoader(MapperProperty):
         else:
             raise " no foreign key ?"
 
-    def process_dependencies(self, deplist):
+    def process_dependencies(self, deplist, uow):
 
-        for obj in deplist:
+        def getlist(obj):
             if self.uselist:
-                childlist = objectstore.uow().register_list_attribute(obj, self.key)
+                return uow.register_list_attribute(obj, self.key)
             else:
-                childlist = objectstore.uow().register_attribute(obj, self.key)
+                return uow.register_attribute(obj, self.key)
 
-            if self.secondaryjoin is not None:
-                pass
-            elif self.foreignkey.table == self.target:
-                setter = ForeignKeySetter(self.parent, self.mapper, self.parent.table, self.target, self.secondary, obj)
+        setter = ForeignKeySetter(self.parent, self.mapper, self.parent.table, self.target, self.secondary)
+
+        if self.secondaryjoin is not None:
+            print "secondaries !"
+            secondary_delete = []
+            secondary_insert = []
+            for obj in deplist:
+                childlist = getlist(obj)
                 for child in childlist.added_items():
                     setter.obj = obj
                     setter.child = child
                     setter.associationrow = {}
                     self.primaryjoin.accept_visitor(setter)
-                
-            elif self.foreignkey.table == self.parent.table:
-                setter = ForeignKeySetter(self.parent, self.mapper, self.parent.table, self.target, self.secondary, None)
+                    self.secondaryjoin.accept_visitor(setter)
+                    secondary_insert.append(setter.associationrow)
+                for child in childlist.deleted_items():
+                    setter.obj = obj
+                    setter.child = child
+                    setter.associationrow = {}
+                    setter.clearkeys = True
+                    self.primaryjoin.accept_visitor(setter)
+                    self.secondaryjoin.accept_visitor(setter)
+                    secondary_delete.append(setter.associationrow)
+            if len(secondary_delete):
+                statement = self.secondary.delete(sql.and_(*[c == sql.bindparam(c.key) for c in self.secondary.c]))
+                statement.echo = self.mapper.echo
+                statement.execute(*secondary_delete)
+            if len(secondary_insert):
+                statement = self.secondary.insert()
+                statement.echo = self.mapper.echo
+                statement.execute(*secondary_insert)
+        elif self.foreignkey.table == self.target:
+            for obj in deplist:
+                childlist = getlist(obj)
+                for child in childlist.added_items():
+                    setter.obj = obj
+                    setter.child = child
+                    setter.associationrow = {}
+                    self.primaryjoin.accept_visitor(setter)
+        elif self.foreignkey.table == self.parent.table:
+            for obj in deplist:
+                childlist = getlist(obj)
                 for child in childlist.added_items():
                     setter.obj = child
                     setter.child = obj
                     setter.associationrow = {}
                     self.primaryjoin.accept_visitor(setter)
-            else:
-                raise " no foreign key ?"
+        else:
+            raise " no foreign key ?"
         
     def save(self, obj, traverse):
         # saves child objects
@@ -748,13 +779,13 @@ class ForeignKeySetter(sql.ClauseVisitor):
     """traverses a join condition of a parent/child object or two objects attached by
     an association table and sets properties on either the child object or an 
     association table row according to the join properties."""
-    def __init__(self, parentmapper, childmapper, primarytable, secondarytable, associationtable, obj):
+    def __init__(self, parentmapper, childmapper, primarytable, secondarytable, associationtable):
         self.parentmapper = parentmapper
         self.childmapper = childmapper
         self.primarytable = primarytable
         self.secondarytable = secondarytable
         self.associationtable = associationtable
-        self.obj = obj
+        self.obj = None
         self.associationrow = {}
         self.clearkeys = False
         self.child = None
index 31b3f9a22139d4ebe4ad53208a380a5d01e05433..2a9617e74367a3ed8a3f0663dcf3cda6196675ce 100644 (file)
@@ -181,10 +181,6 @@ class UnitOfWork(object):
 
     def is_dirty(self, obj):
         if not self.dirty.contains(obj):
-            # if we know nothing about this object, register it as dirty (or new ?)
-            if not self.clean.contains(obj):
-                self.register_new(obj)
-                return True
             return False
         else:
             return True
@@ -229,16 +225,17 @@ class UnitOfWork(object):
             for obj in obj_list:
                 mapper.save_obj(obj)
             for dep in deplist:
-                (processor, list) = dep
-                processor.process_dependencies(list)
+                (processor, stuff_to_process) = dep
+                processor.process_dependencies(stuff_to_process, self)
 
         self.new.clear()
         self.dirty.clear()
 
-    def register_dependency(self, obj, dependency, processor, list):
+    def register_dependency(self, obj, dependency, processor, stuff_to_process):
         self.dependencies[(obj, dependency)] = True
         deplist = self.dependencies.setdefault(obj, [])
-        deplist.append((processor, list))
+        if processor is not None:
+            deplist.append((processor, stuff_to_process))
         
     
 uow = util.ScopedRegistry(lambda: UnitOfWork(), "thread")        
\ No newline at end of file
index fa6814f75b99b9d73a53ce1bbb6329e0374a7ab6..f6819135a0ac7502e8aaf70ec19e006874d53d84 100644 (file)
@@ -382,14 +382,29 @@ class SaveTest(AssertMixin):
         m = mapper(Address, addresses, properties = dict(
             user = relation(User, users, foreignkey = addresses.c.user_id, primaryjoin = users.c.user_id == addresses.c.user_id, lazy = True, uselist = False)
         ))
-        a = Address()
-        a.email_address = 'themaster@foo.com'
-        a.user = User()
-        a.user.user_name = 'thesub'
+        data = [
+            {'user_name' : 'thesub' , 'email_address' : 'bar@foo.com'},
+            {'user_name' : 'assdkfj' , 'email_address' : 'thesdf@asdf.com'},
+            {'user_name' : 'n4knd' , 'email_address' : 'asf3@bar.org'},
+            {'user_name' : 'v88f4' , 'email_address' : 'adsd5@llala.net'},
+            {'user_name' : 'asdf8d' , 'email_address' : 'theater@foo.com'}
+        ]
+        objects = []
+        for elem in data:
+            a = Address()
+            a.email_address = elem['email_address']
+            a.user = User()
+            a.user.user_name = elem['user_name']
+            objects.append(a)
+            
+        objectstore.uow().commit()
 
+        objects[2].email_address = 'imnew@foo.bar'
+        objects[3].user = User()
+        objects[3].user.user_name = 'imnewlyadded'
+        
         objectstore.uow().commit()
         return
-
         m.save(a)
         l = sql.select([users, addresses], sql.and_(users.c.user_id==addresses.c.address_id, addresses.c.address_id==a.address_id)).execute()
         r = engine.ResultProxy(l)
@@ -485,7 +500,10 @@ class SaveTest(AssertMixin):
         klist = keywordmapper.select(keywords.c.name.in_('blue', 'big', 'round'))
         for k in klist:
             item.keywords.append(k)
-        m.save(item)
+
+        objectstore.uow().commit()
+        return
+
         l = m.select(items.c.item_id == item.item_id)
 
         self.assert_result(l, Item,