dabo Commit
Revision 2588
Date: 2006-12-30 14:53:24 -0800 (Sat, 30 Dec 2006)
Author: Paul

Changed:
U   branches/paul_sandbox/dabo/biz/dBizobj.py
U   branches/paul_sandbox/dabo/db/dCursorMixin.py

Log:
I've worked a bit on the new memento design while on vacation here in 
Miami Beach, and things seem to be coming together nicely. Of course,
with all big changes I keep finding other places to clean up, and I
can't remember everything but when/if this gets merged back into 
trunk I'll be more specific about the changes.




Diff:
Modified: branches/paul_sandbox/dabo/biz/dBizobj.py
===================================================================
--- branches/paul_sandbox/dabo/biz/dBizobj.py   2006-12-30 18:02:17 UTC (rev 
2587)
+++ branches/paul_sandbox/dabo/biz/dBizobj.py   2006-12-30 22:53:24 UTC (rev 
2588)
@@ -6,8 +6,8 @@
 from dabo.dLocalize import _
 import dabo.dException as dException
 from dabo.dObject import dObject
+from dabo.lib.profilehooks import profile as profile
 
-
 class dBizobj(dObject):
        """ The middle tier, where the business logic resides."""
        # Class to instantiate for the cursor object
@@ -253,48 +253,55 @@
 
 
        def saveAll(self, startTransaction=False, topLevel=True):
-               """ Iterates through all the records of the bizobj, and calls 
save()
-               for any record that has pending changes.
-               """
-               changedRows = self.getChangedRows()
-               cursor = self._CurrentCursor
+               """Saves all changes to the bizobj and children."""
 
                useTransact = startTransaction or topLevel
-               if useTransact:
-                       # Tell the cursor to begin a transaction, if needed.
-                       cursor.beginTransaction()
-               try:
-                       self.scanRows(self.save, changedRows, 
startTransaction=False, topLevel=False)
-               except dException.ConnectionLostException, e:
-                       raise dException.ConnectionLostException, e
-               except dException.DBQueryException, e:
-                       # Something failed; reset things.
+               old_currentCursorKey = self.__currentCursorKey
+               old_pk = getattr(self.Record, self.KeyField)
+
+               for key, cursor in self.__cursors.iteritems():
                        if useTransact:
-                               cursor.rollbackTransaction()
-                       # Pass the exception to the UI
-                       raise dException.DBQueryException, e
-               except dException.dException, e:
+                               # Tell the cursor to begin a transaction, if 
needed.
+                               cursor.beginTransaction()
+#                      self.scanRows(self.save, changedRows, 
startTransaction=False, topLevel=False)
+                       print "saveAll: key, cursor:", key, cursor
+                       self._CurrentCursor = key
+                       changed_keys = list(set(cursor._mementos.keys() + 
cursor._newRecords.keys()))
+                       for pk in changed_keys:
+                               print "changed_key:", pk
+                               self._moveToPK(pk)
+                               try:
+                                       self.save(startTransaction=False, 
topLevel=False)
+                               except dException.ConnectionLostException, e:
+                                       self._CurrentCursor = 
old_currentCursorKey
+                                       self._moveToPK(old_pk)
+                                       raise 
dException.ConnectionLostException, e
+                               except dException.DBQueryException, e:
+                                       # Something failed; reset things.
+                                       if useTransact:
+                                               cursor.rollbackTransaction()
+                                       # Pass the exception to the UI
+                                       self._CurrentCursor = 
old_currentCursorKey
+                                       self._moveToPK(old_pk)
+                                       raise dException.DBQueryException, e
+                               except dException.dException, e:
+                                       if useTransact:
+                                               cursor.rollbackTransaction()
+                                       self._CurrentCursor = 
old_currentCursorKey
+                                       self._moveToPK(old_pk)
+                                       raise
+
                        if useTransact:
-                               cursor.rollbackTransaction()
-                       raise dException.dException, e
+                               cursor.commitTransaction()
 
-               if useTransact:
-                       cursor.commitTransaction()
+               self._CurrentCursor = old_currentCursorKey
+               self._moveToPK(old_pk)
 
 
-       def _saveRowIfChanged(self, startTransaction, topLevel):
-               """ Meant to be called as part of a scan loop. That means that 
we can
-               assume that the current record is the one we want to act on. 
Also, we
-               can pass False for the two parameters, since they will have 
already been
-               accounted for in the calling method.
-               """
-               if self.isChanged():
-                       self.save(startTransaction, topLevel)
+       def save(self, startTransaction=False, topLevel=True):
+               """Save any changes that have been made in the current row.
 
-
-       def save(self, startTransaction=False, topLevel=True):
-               """ Save any changes that have been made in the data set. If the
-               save is successful, the save() of all child bizobjs will be
+               If the save is successful, the saveAll() of all child bizobjs 
will be
                called as well.
                """
                cursor = self._CurrentCursor
@@ -356,7 +363,7 @@
                        if useTransact:
                                cursor.rollbackTransaction()
                        # Pass the exception to the UI
-                       raise dException.dException, e
+                       raise
 
                # Some backends (Firebird particularly) need to be told to write
                # their changes even if no explicit transaction was started.
@@ -369,38 +376,31 @@
 
 
        def cancelAll(self):
-               """ Iterates through all the records, canceling each in turn. 
"""
-               errMsg = self.beforeCancel()
-               if errMsg:
-                       raise dException.dException, errMsg
-               for cursor in self.__cursors.values():
-                       cursor.cancel(allRows=True)
-               for child in self.__children:
-                       child.cancelAll()
-               self.afterCancel()
+               """Cancel all changes made to the current dataset, including 
all children."""
+               self.scanChangedRows(self.cancel, allCursors=True)
 
 
        def cancel(self):
-               """ Cancel any changes to the current record, reverting the 
fields
-               back to their original values.
+               """Cancel all changes to the current record and all children.
+
+               Two hook methods will be called: beforeCancel() and 
afterCancel(). The
+               former, if it returns an error message, will raise an exception 
and not
+               continue cancelling the record.
                """
                errMsg = self.beforeCancel()
                if errMsg:
                        raise dException.dException, errMsg
 
-               # Tell the cursor to cancel any changes
+               # Tell the cursor and all children to cancel themselves:
                self._CurrentCursor.cancel()
-               # Tell each child to cancel themselves
                for child in self.__children:
                        child.cancelAll()
-                       #child.requery()
 
-#              self.setMemento()
                self.afterCancel()
 
 
        def delete(self, startTransaction=False):
-               """ Delete the current row of the data set."""
+               """Delete the current row of the data set."""
                cursor = self._CurrentCursor
                errMsg = self.beforeDelete()
                if not errMsg:
@@ -557,6 +557,43 @@
                                        self.RowNumber = row
 
 
+       def scanChangedRows(self, func, allCursors=False, *args, **kwargs):
+               """Move the record pointer to each changed row, and call func.
+
+               If allCursors is True, all other cursors for different parent 
records will 
+               be iterated as well. 
+
+               If you want to end the scan on the next iteration, set 
self.exitScan=True.
+
+               Records are scanned in arbitrary order. Any exception raised by 
calling
+               func() will be passed   up to the caller.
+               """
+               self.exitScan = False
+               old_currentCursorKey = self.__currentCursorKey
+               old_pk = getattr(self.Record, self.KeyField)
+
+               if allCursors:
+                       cursors = self.__cursors
+               else:
+                       cursors = [{None: self._CurrentCursor}]
+
+               for key, cursor in cursors.iteritems():
+                       self._CurrentCursor = key
+                       changed_keys = list(set(cursor._mementos.keys() + 
cursor._newRecords.keys()))
+                       for pk in changed_keys:
+                               self._moveToPK(pk)
+                               try:
+                                       func(*args, **kwargs)
+                               except:
+                                       # Reset things and bail:
+                                       self._CurrentCursor = 
old_currentCursorKey
+                                       self._moveToPK(old_pk)
+                                       raise
+               
+               self._CurrentCursor = old_currentCursorKey
+               self._moveToPK(old_pk)
+
+
        def getFieldNames(self):
                """Returns a tuple of all the field names in the cursor."""
                flds = self._CurrentCursor.getFields()
@@ -845,6 +882,7 @@
                return ret
 
 
+       @profile
        def isAnyChanged(self):
                """ Returns True if any record in the current record set has 
been
                changed.
@@ -939,6 +977,13 @@
                # Fill in the link to the parent record
                if self.Parent and self.FillLinkFromParent and self.LinkField:
                        self.setParentFK()
+
+               # Add the new record flag if there's a KeyField defined:
+               if self.KeyField:
+                       rec = self._CurrentCursor._records[self.RowNumber]
+                       print "dbizobj.new(): pk: ", rec[self.KeyField]
+                       self._CurrentCursor._newRecords[rec[self.KeyField]] = 
None
+
                # Call the custom hook method
                self.onNew()
 

Modified: branches/paul_sandbox/dabo/db/dCursorMixin.py
===================================================================
--- branches/paul_sandbox/dabo/db/dCursorMixin.py       2006-12-30 18:02:17 UTC 
(rev 2587)
+++ branches/paul_sandbox/dabo/db/dCursorMixin.py       2006-12-30 22:53:24 UTC 
(rev 2588)
@@ -831,11 +831,8 @@
                        row = self.RowNumber
 
                rec = self._records[row]
-               mem = self._mementos[rec[self.KeyField]]
+               mem = self._mementos.get(rec[self.KeyField], {})
                
-               print "mementos:", self._mementos
-               print "mem", mem
-
                for k, v in mem.items():
                        ret[k] = (v, rec[k])
                return ret
@@ -972,7 +969,7 @@
                                        # this object started the transaction.
                                        if useTransaction:
                                                self.rollbackTransaction()
-                                       raise dException.QueryException, e
+                                       raise
        
                if useTransaction:
                        self.beginTransaction()
@@ -1169,9 +1166,7 @@
                        
        
        def delete(self, delRowNum=None):
-               """ Delete the specified row. If no row specified, 
-               delete the currently active row.
-               """
+               """Delete the specified row, or the currently active row."""
                if self.RowNumber < 0 or self.RowCount == 0:
                        # No query has been run yet
                        raise dException.NoRecordsException, _("No record to 
delete")
@@ -1180,10 +1175,12 @@
                        delRowNum = self.RowNumber
 
                rec = self._records[delRowNum]
-               newrec =  rec.has_key(kons.CURSOR_NEWFLAG)
-               if newrec:
+#              newrec =  rec.has_key(kons.CURSOR_NEWFLAG)
+               if self._newRecords.has_key(rec[self.KeyField]):
+                       print "delete(): new record"
                        res = True
                else:
+                       print "delete(): not new record", self._newRecords
                        pkWhere = self.makePkWhere()
                        # some backends(PostgreSQL) don't return information 
about number of deleted rows
                        # try to fetch it before
@@ -1925,9 +1922,10 @@
        
        def _getIsAdding(self):
                """ Return True if the current record is a new record."""
-               return 
self._records[self.RowNumber].has_key(kons.CURSOR_NEWFLAG)
-               
+#              return 
self._records[self.RowNumber].has_key(kons.CURSOR_NEWFLAG)
+               return 
self._newRecords.has_key(self._records[self.RowNumber][self.KeyField])
        
+
        def _getKeyField(self):
                try:
                        return self._keyField




_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-dev

Reply via email to