Contact: fumanchu@aminus.org

Log in as guest/dejavu to create tickets

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

Changeset 324

Show
Ignore:
Timestamp:
11/17/06 18:03:00
Author:
dowski
Message:

Implementation of #80. A custom association path can now be passed to a UnitJoin.

Files:

Legend:

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

    r323 r324  
    365365        for wrapperA in classlist1: 
    366366            for wrapperB in classlist2: 
    367                 ua = wrapperA.cls._associations.get(wrapperB.cls.__name__, None) 
     367                path = unitjoin.path or wrapperB.cls.__name__ 
     368                ua = wrapperA.cls._associations.get(path, None) 
    368369                if ua: 
    369370                    nearTable, farTable = wrapperA, wrapperB 
    370371                    break 
    371                 ua = wrapperB.cls._associations.get(wrapperA.cls.__name__, None) 
     372                path = unitjoin.path or wrapperA.cls.__name__ 
     373                ua = wrapperB.cls._associations.get(path, None) 
    372374                if ua: 
    373375                    nearTable, farTable = wrapperB, wrapperA 
     
    415417                else: 
    416418                    seen[cls2] = None 
    417             return dejavu.UnitJoin(wclass1, wclass2, unitjoin.leftbiased) 
     419            uj = dejavu.UnitJoin(wclass1, wclass2, unitjoin.leftbiased) 
     420            # if the unitjoin had a custom association path, set it on 
     421            # the new UnitJoin instance 
     422            uj.path = unitjoin.path 
     423            return uj 
    418424        classes = wrap(classes) 
    419425         
  • trunk/storage/storeshelve.py

    r323 r324  
    191191            for indexA, clsA in enumerate(classlist1): 
    192192                for indexB, clsB in enumerate(classlist2): 
    193                     ua = clsA._associations.get(clsB.__name__, None) 
     193                    path = unitjoin.path or clsB.__name__ 
     194                    ua = clsA._associations.get(path, None) 
    194195                    if ua: 
    195196                        nearKey, farKey = ua.nearKey, ua.farKey 
    196197                        break 
    197                     ua = clsB._associations.get(clsA.__name__, None) 
     198                    path = unitjoin.path or clsA.__name__ 
     199                    ua = clsB._associations.get(path, None) 
    198200                    if ua: 
    199201                        nearKey, farKey = ua.farKey, ua.nearKey 
  • trunk/storage/storesqlite.py

    r323 r324  
    717717        for wrapperA in classlist1: 
    718718            for wrapperB in classlist2: 
    719                 ua = wrapperA.cls._associations.get(wrapperB.cls.__name__, None) 
     719                path = unitjoin.path or wrapperB.cls.__name__ 
     720                ua = wrapperA.cls._associations.get(path, None) 
    720721                if ua: 
    721722                    nearTable, farTable = wrapperA, wrapperB 
    722723                    break 
    723                 ua = wrapperB.cls._associations.get(wrapperA.cls.__name__, None) 
     724                path = unitjoin.path or wrapperA.cls.__name__ 
     725                ua = wrapperB.cls._associations.get(path, None) 
    724726                if ua: 
    725727                    nearTable, farTable = wrapperB, wrapperA 
  • trunk/test/zoo_fixture.py

    r323 r324  
    3939import dejavu 
    4040from dejavu import errors, logic 
    41 from dejavu import Unit, UnitProperty, ToOne, ToMany, UnitSequencerInteger 
     41from dejavu import Unit, UnitProperty, ToOne, ToMany, UnitSequencerInteger, UnitAssociation 
    4242from dejavu.test import tools 
    4343from dejavu import engines 
     
    6262    Age = UnitProperty(float, hints={'precision': 4}, default=1) 
    6363    MotherID = UnitProperty(int) 
     64    PreferredFoodID = UnitProperty(int) 
     65    AlternateFoodID = UnitProperty(int) 
    6466 
    6567Animal.many_to_one('ID', Animal, 'MotherID') 
     
    8284Zoo.one_to_many('ID', Animal, 'ZooID') 
    8385 
     86class AlternateFoodAssociation(UnitAssociation): 
     87    to_many = False 
     88    register = False 
     89     
     90    def related(self, unit, expr=None): 
     91        food = unit.sandbox.unit(Food, ID=unit.AlternateFoodID) 
     92        return food 
     93 
     94class Food(Unit): 
     95    """A food item.""" 
     96    Name = UnitProperty() 
     97    NutritionValue = UnitProperty(int) 
     98 
     99Food.one_to_many('ID', Animal, 'PreferredFoodID') 
     100 
     101descriptor = AlternateFoodAssociation('AlternateFoodID', Food, 'ID') 
     102descriptor.nearClass = Animal 
     103Animal._associations['Alternate Food'] = descriptor 
     104Animal.AlternateFood = descriptor 
     105del descriptor 
    84106 
    85107class Vet(Unit): 
     
    282304            for d in every17days: 
    283305                box.memorize(Visit(VetID=jm.ID, AnimalID=emp.ID, Date=d)) 
     306 
     307            # Foods 
     308            dead_fish = Food(Name="Dead Fish", Nutrition=5) 
     309            live_fish = Food(Name="Live Fish", Nutrition=10) 
     310            bunnies = Food(Name="Live Bunny Wabbit", Nutrition=10) 
     311            steak = Food(Name="T-Bone", Nutrition=7) 
     312            for food in [dead_fish, live_fish, bunnies, steak]: 
     313                box.memorize(food) 
     314             
     315            # Foods --> add preferred foods 
     316            lion.add(steak) 
     317            tiger.add(bunnies) 
     318            emp.add(live_fish) 
     319            adelie.add(live_fish) 
     320             
     321            # Foods --> add alternate foods 
     322            lion.AlternateFoodID = bunnies.ID 
     323            tiger.AlternateFoodID = steak.ID 
     324            emp.AlternateFoodID = dead_fish.ID 
     325            adelie.AlternateFoodID = dead_fish.ID 
    284326             
    285327        finally: 
     
    623665            animals = [mother.ID for anim, mother in box.recall(tree, f)] 
    624666            self.assertEqual(animals, [11]) 
     667        finally: 
     668            box.flush_all() 
     669             
     670    def test_8_CustomAssociations(self): 
     671        for store in arena.stores.itervalues(): 
     672            if hasattr(store, "sweep_all"): 
     673                store.sweep_all() 
     674         
     675        box = arena.new_sandbox() 
     676        try: 
     677            # Try different association paths 
     678            std_expected = ['Live Bunny Wabbit', 'Live Fish', 'Live Fish', 'T-Bone'] 
     679            cus_expected = ['Dead Fish', 'Dead Fish', 'Live Bunny Wabbit', 'T-Bone'] 
     680            uj = Animal & Food 
     681            for path, expected in [# standard path 
     682                                   (None, std_expected), 
     683                                   # custom path 
     684                                   ('Alternate Food', cus_expected)]: 
     685                 
     686                uj.path = path 
     687                results = box.recall(uj) 
     688                foods = [f for a,f in results] 
     689                foods.sort(dejavu.sort('Name')) 
     690                self.assertEqual([f.Name for f in foods], expected) 
     691 
     692            # Test the magic association methods 
     693            tiger = box.unit(Animal, Species='Tiger') 
     694            self.assertEqual(tiger.Food().Name, 'Live Bunny Wabbit') 
     695            self.assertEqual(tiger.AlternateFood().Name, 'T-Bone') 
     696             
    625697        finally: 
    626698            box.flush_all() 
  • trunk/units.py

    r323 r324  
    115115        self.class2 = class2 
    116116        self.leftbiased = leftbiased 
     117        self.path = None 
    117118         
    118119        # From http://msdn.microsoft.com/library/en-us/