Author: reinhard Date: 2009-10-15 16:43:16 -0500 (Thu, 15 Oct 2009) New Revision: 9974
Modified: trunk/gnue-forms/src/GFForm.py Log: Avoid recursive commit in some weird cases. Modified: trunk/gnue-forms/src/GFForm.py =================================================================== --- trunk/gnue-forms/src/GFForm.py 2009-10-15 21:35:36 UTC (rev 9973) +++ trunk/gnue-forms/src/GFForm.py 2009-10-15 21:43:16 UTC (rev 9974) @@ -113,6 +113,10 @@ # focusin/focusout triggers doesn't run endEditing and beginEditing self.__editing_blocked = False + # Set to true while commit is running to avoid recursively called + # commits. + self.__committing = False + self._instance = None # Hackery until proper layout support is added @@ -1434,80 +1438,91 @@ def execute_commit(self): - # Save all current records, since they get lost in the Pre-Commit - # trigger code - for block in self._logic._blockList: - block._precommitRecord = block._currentRecord + # Avoid recursive commits that could happen when committing moves + # around resultset cursors and some of the blocks have autocommit + # feature enabled. + if self.__committing: + return - # Form level pre-commit triggers - self.processTrigger('Pre-Commit', ignoreAbort=False) + self.__committing = True + try: + # Save all current records, since they get lost in the Pre-Commit + # trigger code + for block in self._logic._blockList: + block._precommitRecord = block._currentRecord - # Block level pre-commit triggers - for block in self._logic._blockList: - block.processTrigger('Pre-Commit') + # Form level pre-commit triggers + self.processTrigger('Pre-Commit', ignoreAbort=False) - # FIXME: Is this a GoodThing(tm)? Maybe we would really *want* to move - # the record pointer at commit time in the trigger? - for block in self._logic._blockList: - block.goto_record(block._precommitRecord) + # Block level pre-commit triggers + for block in self._logic._blockList: + block.processTrigger('Pre-Commit') - # Set the mode to commit on all blocks - for block in self._logic._blockList: - block.mode = 'commit' + # FIXME: Is this a GoodThing(tm)? Maybe we would really *want* to move + # the record pointer at commit time in the trigger? + for block in self._logic._blockList: + block.goto_record(block._precommitRecord) - try: - # Process the commit on all blocks + # Set the mode to commit on all blocks for block in self._logic._blockList: - assert gDebug(5, "Saving %s" % block.name) - try: - block.post() - except Exception: - # jump to offending block - # FIXME: does not work with master/detail, always moves the - # focus to master record. - if block != self._currentBlock: - self.__find_and_change_focus([block], False) - raise - finally: - for block in self._logic._blockList: - block.mode = 'normal' + block.mode = 'commit' - try: - # Now do the real commit() on the backend connections (only - # once per connection, if multiple blocks are sharing the same - # connection) - for connection in self.__get_connections().itervalues(): - connection.commit() - except: - # Make sure the block is in consistent state again; this has to - # be done in any case if the processCommit was successful, even - # if the connection commit failed! try: - for block in self._logic._blockList: - block.requery(False) + # Process the commit on all blocks + for block in self._logic._blockList: + assert gDebug(5, "Saving %s" % block.name) + try: + block.post() + except Exception: + # jump to offending block + # FIXME: does not work with master/detail, always moves the + # focus to master record. + if block != self._currentBlock: + self.__find_and_change_focus([block], False) + raise + finally: + for block in self._logic._blockList: + block.mode = 'normal' + + try: + # Now do the real commit() on the backend connections (only + # once per connection, if multiple blocks are sharing the same + # connection) + for connection in self.__get_connections().itervalues(): + connection.commit() except: - # Ignore exceptions happening in requery so they don't - # obfuscate the original exception that happened in commit. - pass - # FIXME: We have to think more about the question what's the right - # way to act when an exception happenend in the COMMIT. - raise + # Make sure the block is in consistent state again; this has to + # be done in any case if the processCommit was successful, even + # if the connection commit failed! + try: + for block in self._logic._blockList: + block.requery(False) + except: + # Ignore exceptions happening in requery so they don't + # obfuscate the original exception that happened in commit. + pass + # FIXME: We have to think more about the question what's the right + # way to act when an exception happenend in the COMMIT. + raise - for block in self._logic._blockList: - block.requery(True) + for block in self._logic._blockList: + block.requery(True) - # Execute Post-Commit-Trigger for each block - for block in self._logic._blockList: - block.processTrigger('Post-Commit') + # Execute Post-Commit-Trigger for each block + for block in self._logic._blockList: + block.processTrigger('Post-Commit') - for block in self._logic._blockList: - if block.autoClear: - block.clear() + for block in self._logic._blockList: + if block.autoClear: + block.clear() - # Execute Post-Commit-Trigger for the form - self.processTrigger('Post-Commit') + # Execute Post-Commit-Trigger for the form + self.processTrigger('Post-Commit') + finally: + self.__committing = False + # ------------------------------------------------------------------------- # Roll back any uncommitted transaction # ------------------------------------------------------------------------- _______________________________________________ commit-gnue mailing list commit-gnue@gnu.org http://lists.gnu.org/mailman/listinfo/commit-gnue