Contact: fumanchu@aminus.org

Log in as guest/dejavu to create tickets

I think I've seen this ORM somewhere before...

Changeset 221

Show
Ignore:
Timestamp:
07/11/06 18:01:29
Author:
dowski
Message:

Some decimal.Decimal related enhancements (see MC #305).

1. New storeado.float_from_com and decimal_from_com functions. These functions properly convert the CURRENCY tuples that can be returned by pythoncom.

2. storage/storeado.py can now handle decimal.Decimal objects returned by pythoncom for CURRENCY datatypes. This will be the default behavior of pythoncom in the future.

3. Tests for the new decimal handling functionality in storage/storeado.py. Tests storing and retrieving FixedPoint? and Decimal values 3 ways; with the values stored in the database as DOUBLES (standard), with values in the database stored as CURRENCY and recalled as tuples, and finally stored as CURRENCY and recalled as Decimals.

4. arenas.Arena.add_store can now accept a storage manager class as well as a class string or instance.

Files:

Legend:

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

    r220 r221  
    11 
    22import ConfigParser 
     3from types import ClassType 
    34 
    45from containers import Graph 
     
    7071        if isinstance(store, basestring): 
    7172            store = xray.classes(store)(name, self, options or {}) 
     73 
     74        elif isinstance(store, (type, ClassType)): 
     75            store = store(name, self, options or {}) 
    7276         
    7377        self.stores[name] = store 
  • trunk/storage/storeado.py

    r220 r221  
    121121    return datetime.time(hour, minute, second) 
    122122 
     123def float_from_com(com_currency): 
     124    """Convert a value from a Currency field to a float value. 
     125 
     126    Courtesy of Alex Martelli from: 
     127    http://groups.google.com/group/comp.lang.python/browse_frm/thread/fed03c64735c9e9c 
     128    """ 
     129    return float((long(com_currency[1])&0xFFFFFFFFL) | 
     130                 (long(com_currency[0]) << 32)) / 1e4 
     131 
     132def decimal_from_com(com_currency): 
     133    """Convert a value from a Currency field to a Decimal value.""" 
     134     
     135    return decimal.Decimal(str(float_from_com(com_currency))) 
     136 
    123137 
    124138class AdapterFromADO(db.AdapterFromDB): 
     
    163177        # See coerce_datetime 
    164178        return time_from_com(value) 
     179 
     180    def coerce_decimal_Decimal(self, value, coltype): 
     181        if coltype == 0x06: 
     182            # Currency 
     183            if isinstance(value, tuple): 
     184                value = decimal_from_com(value) 
     185        else: 
     186            value = decimal.Decimal(str(value)) 
     187        return value.quantize(decimal.Decimal('.01')) 
    165188     
    166189    def coerce_fixedpoint_FixedPoint(self, value, coltype): 
    167190        if coltype == 0x06: 
    168191            # Currency 
    169             value = value[1] / 10000.0 
     192            if isinstance(value, tuple): 
     193                value = float_from_com(value) 
    170194        return fixedpoint.FixedPoint(value) 
    171195     
     
    173197        if coltype == 0x06: 
    174198            # Currency 
    175             value = value[1] / 10000.0 
     199            if isinstance(value, tuple): 
     200                value = float_from_com(value) 
    176201        return float(value) 
    177202     
  • trunk/test/test_storemsaccess.py

    r220 r221  
    1818                          "The MSAccess test will not be run.") 
    1919    else: 
     20         
     21        class CurrencyAdapter(storeado.FieldTypeAdapter_MSAccess): 
     22            """Stores Decimal and FixedPoint objects as CURRENCY.""" 
     23             
     24            def coerce_decimal_Decimal(self, cls, key): 
     25                return "CURRENCY" 
     26 
     27            def coerce_fixedpoint_FixedPoint(self, cls, key): 
     28                return "CURRENCY" 
     29             
    2030        SM_class = "dejavu.storage.storeado.StorageManagerADO_MSAccess" 
    2131        opts = {u'Connect': "PROVIDER=MICROSOFT.JET.OLEDB.4.0;" 
     
    2535        def run(): 
    2636            import zoo_fixture 
     37 
     38            # lists to keep track of the test_currency runs             
     39            standard_runs = [] 
     40            altered_runs = [] 
     41             
     42            def test_currency(obj): 
     43                sm = zoo_fixture.arena.stores['testSM'] 
     44                fta = sm.typeAdapter.__class__.__name__ 
     45                 
     46                clsnames = ('Exhibit', 'Zoo') 
     47                tblnames = [sm.table_name(cn).strip('[]') for cn in clsnames] 
     48                colnames = ('Acreage', 'Admission') 
     49                targets = dict(zip(tblnames, colnames)) 
     50                data, _ = sm.fetch(storeado.adSchemaColumns, conn=None, 
     51                                   schema=True) 
     52                for row in data: 
     53                    match = targets.get(row[2]) 
     54                    if not match: 
     55                        continue 
     56                    if match == row[3]: 
     57##                        print row[2], row[3], row[11] 
     58                        dt = row[11] 
     59 
     60                        if fta in ("CurrencyAdapter",):                     
     61                            obj.assertEqual(dt, storeado.adCurrency) 
     62                        else: 
     63                            obj.assertEqual(dt, storeado.adDouble) 
     64                            obj.assertEqual(len(standard_runs), 0) 
     65                     
     66                     
    2767            # Isolate schema changes from one test to the next. 
    2868            reload(zoo_fixture) 
     69 
     70            # test the standard MS Access setup where Decimal and FixedPoint 
     71            # objects are stored in the database as INTEGERS, LONGS or DOUBLES 
     72            print 
     73            print "Standard MSAccess test." 
     74            zoo_fixture.ZooTests.test_currency = test_currency 
    2975            zoo_fixture.init() 
    3076            zoo_fixture.run(SM_class, opts) 
     77            standard_runs.append(True) 
     78 
     79            # plugin the adapter for testing CURRENCY columns 
     80            storeado.StorageManagerADO_MSAccess.typeAdapter = CurrencyAdapter() 
     81 
     82            reload(zoo_fixture) 
     83 
     84            # test storing and recalling Decimal values to the database using 
     85            # CURRENCY columns - the (current) default behavior of pythoncom 
     86            # is to return CURRENCY values as a tuple 
     87            print 
     88            print "MSAccess test - CURRENCY returned as tuple." 
     89            zoo_fixture.ZooTests.test_currency = test_currency 
     90            zoo_fixture.init() 
     91            zoo_fixture.run(SM_class, opts) 
     92            altered_runs.append(True) 
     93 
     94            # set pythoncom to return CURRENCY values as Decimal objects 
     95            pythoncom.__future_currency__ = True 
     96             
     97            reload(zoo_fixture) 
     98 
     99            # test storing and recalling Decimal values to the database using 
     100            # CURRENCY columns - CURRENCY values are now returned as Decimal 
     101            # objects 
     102            print 
     103            print "MSAccess test - CURRENCY returned as Decimal." 
     104            zoo_fixture.ZooTests.test_currency = test_currency 
     105            zoo_fixture.init() 
     106            zoo_fixture.run(SM_class, opts) 
     107            altered_runs.append(True) 
    31108 
    32109if __name__ == "__main__":