self.dependencies = {}
self.tasks = {}
self.saved_histories = util.HashSet()
-
- def register_object(self, obj, isdelete = False, listonly = False, **kwargs):
+ self.__modified = False
+
+ def register_object(self, obj, isdelete = False, listonly = False, postupdate=False, **kwargs):
"""adds an object to this UOWTransaction to be updated in the database.
'isdelete' indicates whether the object is to be deleted or saved (update/inserted).
self.mappers.append(mapper)
task = self.get_task_by_mapper(mapper)
+ if postupdate:
+ mod = task.append_postupdate(obj)
+ self.__modified = self.__modified or mod
+ return
+
# for a cyclical task, things need to be sorted out already,
# so this object should have already been added to the appropriate sub-task
# can put an assertion here to make sure....
if task.circular:
return
- if obj not in task.objects:
- self.__modified = True
- task.append(obj, listonly, isdelete=isdelete, **kwargs)
+ mod = task.append(obj, listonly, isdelete=isdelete, **kwargs)
+ self.__modified = self.__modified or mod
def unregister_object(self, obj):
mapper = object_mapper(obj)
dependent operations at the per-object instead of per-task level. """
try:
rec = self.objects[obj]
+ retval = False
except KeyError:
rec = UOWTaskElement(obj)
self.objects[obj] = rec
+ retval = True
if not listonly:
rec.listonly = False
if childtask:
rec.childtasks.append(childtask)
if isdelete:
rec.isdelete = True
-
+ return retval
+
+ def append_postupdate(self, obj):
+ # postupdates are UPDATED immeditely (for now)
+ self.mapper.save_obj([obj], self.uowtransaction, postupdate=True)
+ return True
+
def delete(self, obj):
try:
del self.objects[obj]
for child in self.childtasks:
header(buf, _indent() + " |- Child tasks\n")
child._dump(buf, indent + 1)
+# for obj in self.postupdate:
+# header(buf, _indent() + " |- Post Update objects\n")
+# buf.write(_repr(obj) + "\n")
for element in self.todelete_elements():
for task in element.childtasks:
header(buf, _indent() + " |- Delete subelements of UOWTaskElement(%s)\n" % id(element))
uowcommit.register_processor(stub, self, self.parent, True)
elif self.direction == PropertyLoader.ONETOMANY:
if self.post_update:
- raise InvalidRequestError("post_update not yet supported with one-to-many relation")
- uowcommit.register_dependency(self.parent, self.mapper)
- uowcommit.register_processor(self.parent, self, self.parent, False)
- uowcommit.register_processor(self.parent, self, self.parent, True)
+ stub = PropertyLoader.MapperStub(self.mapper)
+ uowcommit.register_dependency(self.mapper, stub)
+ uowcommit.register_dependency(self.parent, stub)
+ uowcommit.register_processor(stub, self, self.parent, False)
+ uowcommit.register_processor(stub, self, self.parent, True)
+ else:
+ uowcommit.register_dependency(self.parent, self.mapper)
+ uowcommit.register_processor(self.parent, self, self.parent, False)
+ uowcommit.register_processor(self.parent, self, self.parent, True)
elif self.direction == PropertyLoader.MANYTOONE:
if self.post_update:
stub = PropertyLoader.MapperStub(self.mapper)
uowcommit.register_dependency(self.mapper, stub)
+ uowcommit.register_dependency(self.parent, stub)
uowcommit.register_processor(stub, self, self.parent, False)
uowcommit.register_processor(stub, self, self.parent, True)
else:
statement = self.secondary.insert()
statement.execute(*secondary_insert)
elif self.direction == PropertyLoader.MANYTOONE and delete:
- # head object is being deleted, and we manage a foreign key object.
- # dont have to do anything to it.
if self.post_update:
+ # post_update means we have to update our row to not reference the child object
+ # before we can DELETE the row
for obj in deplist:
self._synchronize(obj, None, None, True)
- task.mapper.save_obj([obj], uowcommit, postupdate=True)
+ uowcommit.register_object(obj, postupdate=True)
elif self.direction == PropertyLoader.ONETOMANY and delete:
# head object is being deleted, and we manage its list of child objects
# the child objects have to have their foreign key to the parent set to NULL
childlist = getlist(obj, False)
for child in childlist.deleted_items() + childlist.unchanged_items():
self._synchronize(obj, child, None, True)
- uowcommit.register_object(child)
+ uowcommit.register_object(child, postupdate=self.post_update)
elif self.association is not None:
# manage association objects.
for obj in deplist:
#print "DELETE ASSOC OBJ", repr(child)
uowcommit.register_object(child, isdelete=True)
else:
- for obj in deplist:
- if self.direction == PropertyLoader.MANYTOONE:
- uowcommit.register_object(obj)
+ for obj in deplist:
childlist = getlist(obj, passive=True)
- if childlist is None: continue
- for child in childlist.added_items():
- self._synchronize(obj, child, None, False)
- if self.direction == PropertyLoader.ONETOMANY and child is not None:
- if self.post_update:
- task.mapper.save_obj([child],uowcommit, postupdate=True)
- else:
- uowcommit.register_object(child)
- if self.post_update:
- task.mapper.save_obj([obj], uowcommit, postupdate=True)
- if self.direction != PropertyLoader.MANYTOONE or len(childlist.added_items()) == 0:
+ if childlist is not None:
+ for child in childlist.added_items():
+ self._synchronize(obj, child, None, False)
+ if self.direction == PropertyLoader.ONETOMANY and child is not None:
+ uowcommit.register_object(child, postupdate=self.post_update)
+ if self.direction == PropertyLoader.MANYTOONE:
+ uowcommit.register_object(obj, postupdate=self.post_update)
+ if self.direction != PropertyLoader.MANYTOONE:
for child in childlist.deleted_items():
if not self.private:
self._synchronize(obj, child, None, True)