Contact: fumanchu@aminus.org

Log in as guest/dejavu to create tickets

Changeset 349

Show
Ignore:
Timestamp:
12/13/06 12:55:49
Author:
fumanchu
Message:

Removed Unit.property. It was nicer to write than getattr, but ultimately too slow and too inviting of abuse. Oh, and db.view now calls the target property's coerce method (instead of e.g. quantizing decimals itself).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/codewalk.py

    r348 r349  
    5656                       (None,), ('cell',), (), '', '', 2, '', ('cell',)) 
    5757def deref_cell(cell): 
     58    """Return the value of 'cell' (an object from a func_closure).""" 
    5859    # FunctionType(code, globals[, name[, argdefs[, closure]]]) 
    5960    return FunctionType(_derefblock, {}, "", (), (cell,))() 
  • trunk/storage/db.py

    r348 r349  
    133133        """Set 'value' (of type 'dbtype') as a valid property on the unit.""" 
    134134        try: 
    135             # Skip the "property" classmethod to save a function call 
    136             # (which is ~4x slower). 
    137             # If someone overrides Unit.property, this will break 
    138             # their app, but it's called *so* often it seems worth it. 
    139 ##            prop = unit.__class__.property(key) 
    140135            prop = getattr(unit.__class__, key) 
    141136            cvalue = self.db.adapterfromdb.coerce(value, dbtype, prop.type) 
     
    169164            for key in idnames + [x for x in cls.properties if x not in idnames]: 
    170165                col = t.columns[key] 
    171                 prop = cls.property(key) 
     166                prop = getattr(cls, key) 
    172167                props.append((key, colnames.index(col.name), 
    173168                              col.dbtype, prop.type, prop.coerce)) 
     
    297292        data, _ = self.db.fetch(sql, self.db.get_transaction()) 
    298293        t = self.db[cls.__name__] 
    299         dbtypes = [t.columns[f].dbtype for f in fields] 
    300         props = [cls.property(x) for x in fields] 
     294         
     295        # Pre-calc inner loop data. 
     296        metadata = [] 
     297        for i, f in enumerate(fields): 
     298            prop = getattr(cls, f) 
     299            metadata.append((i, t.columns[f].dbtype, prop.type, prop.coerce)) 
    301300         
    302301        coerce = self.db.adapterfromdb.coerce 
     
    304303        for row in data: 
    305304            coerced_row = [] 
    306             for i, val in enumerate(row): 
    307                 prop = props[i] 
    308                 val = coerce(val, dbtypes[i], prop.type) 
    309                 if decimal and prop.type == decimal.Decimal and val is not None: 
    310                     scale = prop.hints.get('scale', None) 
    311                     if scale: 
    312                         val = val.quantize(decimal.Decimal("." + ("0" * scale))) 
     305            for i, dbtype, ptype, propcoerce in metadata: 
     306                val = coerce(row[i], dbtype, ptype) 
     307                if propcoerce: 
     308                    val = propcoerce(None, val) 
    313309                coerced_row.append(val) 
    314310            yield tuple(coerced_row) 
     
    590586            pytype1 = self.db.python_type(oldcol.dbtype) 
    591587            # Note we use newname, which assumes that property is in the class. 
    592             pytype2 = cls.property(newname).type 
     588            pytype2 = getattr(cls, newname).type 
    593589            oldcol.imperfect_type = not self.db.isrelatedtype(pytype1, pytype2) 
    594590            # Use the superclass call to avoid DROP COLUMN/ADD COLUMN. 
     
    634630                c = c[0] 
    635631                pytype1 = self.db.python_type(c.dbtype) 
    636                 pytype2 = cls.property(ckey).type 
     632                pytype2 = getattr(cls, ckey).type 
    637633                c.imperfect_type = not self.db.isrelatedtype(pytype1, pytype2) 
    638634                # Use the superclass call to avoid ALTER TABLE 
  • trunk/units.py

    r348 r349  
    354354     
    355355    def coerce(self, unit, value): 
     356        """Coerce the given value to the proper type for this property. 
     357         
     358        In the base class, the 'unit' arg is not used. When overriding 
     359        this class, you should allow for meaningful results even if 
     360        the supplied 'unit' arg is None. 
     361        """ 
    356362        if value is not None: 
    357363            selftype = self.type 
     
    546552            # instead of: 
    547553            #     unit = UnitSubClass() 
     554            #     unit._properties = {...} 
    548555            # If done this way, the caller must make CERTAIN that all of 
    549             # the values in _properties are set
     556            # the values in _properties are set, and must call cleanse()
    550557            self._properties = dict.fromkeys(cls.properties, None) 
    551              
    552             # We assume the caller will cleanse once they've set _properties. 
    553558        else: 
    554559            # Copy the class properties into self._properties, 
     
    645650        return tuple(product) 
    646651    indices = classmethod(indices) 
    647      
    648     def property(cls, key): 
    649         """Return the specified UnitProperty object (not its value).""" 
    650         # Retrieving from the class gives us 
    651         # the UnitProperty object, not its value. 
    652         return getattr(cls, key) 
    653     property = classmethod(property) 
    654652     
    655653    def adjust(self, **values):