Changeset 3372

Show
Ignore:
Timestamp:
09/15/07 12:07:44 (1 year ago)
Author:
ed
Message:

Added more rigorous checking to determine if calls to getFIelds() need to be made. Now the code tracks the field list requested by each select statement, and if the list has not changed, the call to _storeFieldTypes() can be safely skipped.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/dabo/db/dBackend.py

    r3323 r3372  
    400400 
    401401 
    402     def setNonUpdateFields(self, cursor, callback, autoQuote=True): 
     402    def setNonUpdateFields(self, cursor, autoQuote=True): 
    403403        """Normally, this routine should work for all backends. But 
    404404        in the case of SQLite, the routine that grabs an empty cursor 
     
    408408        if not cursor.Table: 
    409409            # No table specified, so no update checking is possible 
    410             return 
     410            return None 
    411411        # This is the current description of the cursor. 
    412412        if not cursor.FieldDescription: 
     
    437437                if (b[1] != s[1]) or (b[3] != s[3]) or (b[4] != s[4]) 
    438438                or (b[5] != s[5]) or (b[6] != s[6]) ] 
    439         callback(ret0) 
     439        return ret0 
    440440 
    441441 
  • trunk/dabo/db/dCursorMixin.py

    r3339 r3372  
    6767        # Is the sort case-sensitive? 
    6868        self.sortCase = True 
     69        # Holds the last SQL run in a requery() call. 
     70        self._lastSQL = "" 
     71        # These are used to determine if the field list of successive select statements 
     72        # are identical. 
     73        self.__lastExecute = "" 
     74        self.__lastFieldList = "" 
     75        self._whitespacePat = re.compile(r"(\s+)") 
     76        self._selectStatementPat = re.compile(r"\bselect\b(.+)\bfrom\b", re.I | re.M | re.S) 
    6977        # Holds the keys in the original, unsorted order for unsorting the dataset 
    7078        self.__unsortedRows = [] 
     
    168176 
    169177 
    170     def _correctFieldType(self, field_val, field_name, _fromRequery=False): 
     178    def _correctFieldType(self, field_val, field_name, _newQuery=False): 
    171179        """Correct the type of the passed field_val, based on self.DataStructure. 
    172180 
     
    178186        ret = field_val 
    179187        showError = False 
    180         if _fromRequery: 
     188        if _newQuery: 
    181189            pythonType = self._types.get(field_name, type(field_val)) 
    182190            daboType = dabo.db.getDaboType(pythonType) 
     
    259267 
    260268 
    261     def execute(self, sql, params=(), _fromRequery=False, errorClass=None): 
     269    def execute(self, sql, params=(), _newQuery=False, errorClass=None): 
    262270        """ Execute the sql, and populate the DataSet if it is a select statement.""" 
    263271        # The idea here is to let the super class do the actual work in 
     
    300308        self.BackendObject.massageDescription(self) 
    301309 
    302         if _fromRequery
     310        if self._newStructure(sql)
    303311            self._storeFieldTypes() 
    304312 
     
    323331                    for idx, fldName in enumerate(fldNames): 
    324332                        dic[fldName] = self._correctFieldType(field_val=row[idx], 
    325                                 field_name=fldName, _fromRequery=_fromRequery) 
     333                                field_name=fldName, _newQuery=_newQuery) 
    326334                    tmpRows.append(dic) 
    327335                _records = tmpRows 
     
    331339                    for fld, val in row.items(): 
    332340                        row[fld] = self._correctFieldType(field_val=val, field_name=fld, 
    333                                 _fromRequery=_fromRequery) 
     341                                _newQuery=_newQuery) 
    334342 
    335343        self._records = dDataSet(_records) 
     
    351359        self._syncAuxProperties() 
    352360        return ac.execute(sql) 
     361     
     362     
     363    def _newStructure(self, sql): 
     364        """Attempts to parse the SQL to determine if the fields being selected will require 
     365        a new call to set the structure. Non-select statements likewise will return False. 
     366        """ 
     367        if sql == self.__lastExecute: 
     368            return False 
     369        # See if it's a select statement 
     370        mtch = self._selectStatementPat.search(sql) 
     371        if not mtch: 
     372            return False 
     373        # Normalize white space 
     374        fldlist = self._whitespacePat.sub(" ", mtch.groups()[0]).strip() 
     375        if self.__lastFieldList == fldlist: 
     376            return False 
     377        else: 
     378            self.__lastFieldList = fldlist 
     379            return True 
    353380 
    354381 
     
    370397 
    371398    def requery(self, params=None): 
    372         self._lastSQL = self.CurrentSQL 
     399        currSQL = self.CurrentSQL 
     400        newQuery = (self._lastSQL != currSQL) 
     401        self._lastSQL = currSQL 
    373402        self.lastParams = params 
    374403        self._savedStructureDescription = [] 
    375404 
    376         self.execute(self.CurrentSQL, params, _fromRequery=True
     405        self.execute(currSQL, params, _newQuery=newQuery
    377406 
    378407        # clear mementos and new record flags: 
     
    380409        self._newRecords = {} 
    381410 
    382         # Check for any derived fields that should not be included in 
    383         # any updates. 
    384         self.__setNonUpdateFields() 
     411        if newQuery: 
     412            # Check for any derived fields that should not be included in 
     413            # any updates. 
     414            self.__setNonUpdateFields() 
    385415 
    386416        # Clear the unsorted list, and then apply the current sort 
     
    642672            self.__nonUpdateFields = nonUpdateFieldAliases 
    643673        else: 
     674            # Create the _dataStructure attribute 
     675            self._getDataStructure() 
    644676            # Delegate to the backend object to figure it out. 
    645             self.BackendObject.setNonUpdateFields(self, self.__setNonUpdateFields
     677            self.__nonUpdateFields = self.BackendObject.setNonUpdateFields(self
    646678 
    647679 
  • trunk/dabo/db/dbSQLite.py

    r3326 r3372  
    3535            for idx, field_name in enumerate(fieldNames): 
    3636                if _types: 
    37                     ret[field_name] = cursor._correctFieldType(row[idx], field_name, _fromRequery=True) 
     37                    ret[field_name] = cursor._correctFieldType(row[idx], field_name, _newQuery=True) 
    3838                else: 
    3939                    ret[field_name] = row[idx] 
     
    162162 
    163163 
    164     def setNonUpdateFields(self, cursor, callback): 
     164    def setNonUpdateFields(self, cursor): 
    165165        # Use an alternative, since grabbing an empty cursor, as is done in the  
    166166        # default method, doesn't provide a  description. Assume that any field with  
     
    168168        if not cursor.Table: 
    169169            # No table specified, so no update checking is possible 
    170             return 
     170            return None 
    171171        # This is the current description of the cursor. 
    172172        descFlds = cursor.FieldDescription 
     
    178178        stdFlds = [ff["name"] for ff in rs] 
    179179        # Get all the fields that are not in the table. 
    180         callback([d[0] for d in descFlds  
    181                 if d[0] not in [s[0] for s in stdFlds] ]) 
     180        return [d[0] for d in descFlds  
     181                if d[0] not in [s[0] for s in stdFlds] ] 
    182182         
    183183