dabo Commit
Revision 1521
Date: 2005-11-05 12:31:36 -0800 (Sat, 05 Nov 2005)
Author: ed

Changed:
U   trunk/dabo/biz/dBizobj.py
U   trunk/dabo/db/dCursorMixin.py

Log:
Fixed a potentially serious bug in the getDataSet() logic. I had assumed that 
making a copy of a list made a copy of its contents, too. That is wrong. 
getDataSet() takes a list of dicts, and uses the slice trick ([:]) to make a 
copy of the list; however, each element in the two lists refer to the same 
dict, and changing a value in one dict changed it in both. This is, oddly 
enough, almost exactly like the VFP problem when you ran a fully-optimized 
SQL-Select, the cursor it returned was not a copy of the data, but the source 
table USEd AGAIN.

I also added the replace() methods to the cursor and bizobj classes. I 
discovered the long-forgotten bizobj method 'replaceFor', which did more or 
less the same thing. I looked through all the source code, including the demos 
and IDE stuff, and can't find a single place where replaceFor() is used. If 
it's OK with you, Paul, I'd like to remove it to avoid confusion.

Speaking of duplication, I removed the getRowCount() and getRowNumber() methods 
of dCursorMixin. They have been marked as obsolete for some time now, and I 
don't see them used in any of our code.



Diff:
Modified: trunk/dabo/biz/dBizobj.py
===================================================================
--- trunk/dabo/biz/dBizobj.py   2005-11-05 18:34:14 UTC (rev 1520)
+++ trunk/dabo/biz/dBizobj.py   2005-11-05 20:31:36 UTC (rev 1521)
@@ -522,6 +522,18 @@
                return tuple([ff[0] for ff in flds])
                
                
+       def replace(self, field, valOrExpr, scope=None):
+               """Replaces the value of the specified field with the given 
value
+               or expression. All records matching the scope are affected; if
+               no scope is specified, all records are affected.
+               
+               'valOrExpr' will be treated as a literal value, unless it is 
prefixed
+               with an equals sign. All expressions will therefore be a string 
+               beginning with '='. Literals can be of any type. 
+               """
+               self._CurrentCursor.replace(field, valOrExpr, scope=scope)
+               
+
        def replaceFor(self, cond, fld, val):
                """Replaces all 'fld' values in the recordset with the specified
                value, as long as the record meets the specified condition. 

Modified: trunk/dabo/db/dCursorMixin.py
===================================================================
--- trunk/dabo/db/dCursorMixin.py       2005-11-05 18:34:14 UTC (rev 1520)
+++ trunk/dabo/db/dCursorMixin.py       2005-11-05 20:31:36 UTC (rev 1521)
@@ -660,9 +660,13 @@
                """
                try:
                        if rows is not None:
-                               ret = self._records[rowStart:rowStart+rows]
+                               tmp = self._records[rowStart:rowStart+rows]
                        else:
-                               ret = self._records[rowStart:]
+                               tmp = self._records[rowStart:]
+                       # The dicts in the returned dat set need to be copied; 
+                       # otherwise, modifying the data set will modify this 
+                       # cursor's records!
+                       ret = [tmprec.copy() for tmprec in tmp]
                except AttributeError:
                        # return empty dataset
                        return DataSet()
@@ -685,26 +689,22 @@
                ret = DataSet(ret)
                return ret
 
-
-       def getRowCount(self):
-               """ Get the row count of the current data set.
+       
+       def replace(self, field, valOrExpr, scope=None):
+               """Replaces the value of the specified field with the given 
value
+               or expression. All records matching the scope are affected; if
+               no scope is specified, all records are affected.
                
-               Obsolete: Just get this from the property RowCount.
+               'valOrExpr' will be treated as a literal value, unless it is 
prefixed
+               with an equals sign. All expressions will therefore be a string 
+               beginning with '='. Literals can be of any type. 
                """
-               return self.RowCount
+               if isinstance(self._records, DataSet):
+                       self._records.replace(field, valOrExpr, scope=scope)
+                       
 
-
-       def getRowNumber(self):
-               """ Get the active row number of the data set.
-               
-               Obsolete: Just get this from the property RowNumber.
-               """
-               return self.RowNumber
-
-
        def first(self):
-               """ Move the record pointer to the first record of the data 
set. 
-               """
+               """ Move the record pointer to the first record of the data 
set."""
                if self.RowCount > 0:
                        self.RowNumber = 0
                else:
@@ -712,8 +712,7 @@
 
 
        def prior(self):
-               """ Move the record pointer back one position in the recordset.
-               """
+               """ Move the record pointer back one position in the 
recordset."""
                if self.RowCount > 0:
                        if self.RowNumber > 0:
                                self.RowNumber -= 1
@@ -724,8 +723,7 @@
 
 
        def next(self):
-               """ Move the record pointer forward one position in the 
recordset.
-               """
+               """ Move the record pointer forward one position in the 
recordset."""
                if self.RowCount > 0:
                        if self.RowNumber < (self.RowCount-1):
                                self.RowNumber += 1
@@ -736,8 +734,7 @@
 
 
        def last(self):
-               """ Move the record pointer to the last record in the recordset.
-               """
+               """ Move the record pointer to the last record in the 
recordset."""
                if self.RowCount > 0:
                        self.RowNumber = self.RowCount-1
                else:
@@ -745,8 +742,7 @@
 
 
        def save(self, allrows=False):
-               """ Save any changes to the data back to the data store.
-               """
+               """ Save any changes to the data back to the data store."""
                # Make sure that there is data to save
                if self.RowCount <= 0:
                        raise dException.dException, _("No data to save")
@@ -2020,10 +2016,6 @@
                with an equals sign. All expressions will therefore be a string 
                beginning with '='. Literals can be of any type. 
                """
-               
-#              dabo.trace()
-               
-               
                if scope is None:
                        scope = "True"
                else:




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

Reply via email to