Changeset 286

Show
Ignore:
Timestamp:
01/07/08 18:35:12 (5 years ago)
Author:
cleverdevil
Message:

Applied a patch, closing ticket 29, where the versioning extension was not appropriately handling versioned entities with onupdate events. Patch contributed by Remi Jolin <remi.jolin@…>.

Location:
elixir/trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • elixir/trunk/elixir/ext/versioned.py

    r267 r286  
    8888        instance.timestamp = datetime.now() 
    8989        return EXT_PASS 
    90          
    91     def after_insert(self, mapper, connection, instance): 
    92         colvalues = dict([(key, getattr(instance, key))  
    93                           for key in instance.c.keys()]) 
    94         instance.__class__.__history_table__.insert().execute(colvalues) 
    95         return EXT_PASS 
    96      
     90             
    9791    def before_update(self, mapper, connection, instance): 
    98         colvalues = dict([(key, getattr(instance, key))  
    99                           for key in instance.c.keys()]) 
    100         history = instance.__class__.__history_table__ 
    101          
    102         values = history.select(get_history_where(instance),  
    103                                 order_by=[desc(history.c.timestamp)], 
    104                                 limit=1).execute().fetchone() 
    105         # In case the data was dumped into the db, the initial version might  
    106         # be missing so we put this version in as the original. 
    107         if not values: 
    108             instance.version = colvalues['version'] = 1 
    109             instance.timestamp = colvalues['timestamp'] = datetime.now() 
    110             history.insert().execute(colvalues) 
    111             return EXT_PASS 
    112          
     92        values = instance.table.select(get_entity_where(instance)).execute().fetchone()  
     93 
    11394        # SA might've flagged this for an update even though it didn't change. 
    11495        # This occurs when a relation is updated, thus marking this instance 
     
    122103            if getattr(instance, key) != values[key]: 
    123104                # the instance was really updated, so we create a new version 
    124                 instance.version = colvalues['version'] = instance.version + 1 
    125                 instance.timestamp = colvalues['timestamp'] = datetime.now() 
    126                 history.insert().execute(colvalues) 
     105                colvalues = dict(values.items())  
     106                instance.__class__.__history_table__.insert().execute(colvalues)  
     107                instance.version = instance.version + 1 
     108                instance.timestamp = datetime.now() 
    127109                break 
    128110 
     
    190172        # attach utility methods and properties to the entity 
    191173        def get_versions(self): 
    192             return object_session(self).query(Version) \ 
    193                                        .filter(get_history_where(self)) \ 
    194                                        .all() 
     174            v = object_session(self).query(Version) \ 
     175                                    .filter(get_history_where(self)) \ 
     176                                    .order_by(Version.c.version) \ 
     177                                    .all() 
     178            # history contains all the previous records. 
     179            # Add the current one to the list to get all the versions 
     180            v.append(self) 
     181            return v 
    195182         
    196183        def get_as_of(self, dt): 
     
    209196         
    210197        def revert_to(self, to_version): 
     198            if isinstance(to_version, Version): 
     199                to_version = to_version.version 
     200                 
    211201            hist = entity.__history_table__ 
    212202            old_version = hist.select(and_( 
     
    221211            hist.delete(and_(get_history_where(self),  
    222212                             hist.c.version >= to_version)).execute() 
     213            self.expire() 
    223214            for event in after_revert_events:  
    224215                event(self) 
  • elixir/trunk/tests/test_versioning.py

    r271 r286  
    55import time 
    66 
     7nextOneValue = 0 
     8def nextOne(): 
     9    global nextOneValue 
     10    nextOneValue += 2 
     11    return nextOneValue 
    712 
    813def setup(): 
     
    2126        releasedate = Field(DateTime) 
    2227        ignoreme = Field(Integer, default=0) 
     28        autoupd = Field(Integer, default=nextOne, onupdate=nextOne) 
    2329        director = ManyToOne('Director', inverse='movies') 
    2430        actors = ManyToMany('Actor', inverse='movies', tablename='movie_casting') 
    2531        using_options(tablename='movies') 
    26         acts_as_versioned(ignore=['ignoreme']) 
     32        acts_as_versioned(ignore=['ignoreme', 'autoupd']) 
    2733 
    2834 
     
    6268        assert movie.title == '12 Monkeys' 
    6369        assert movie.director.name == 'Terry Gilliam' 
     70        assert movie.autoupd == 2, movie.autoupd 
    6471        movie.description = 'description two' 
    6572        session.flush(); session.clear() 
     
    7279        movie.description = 'description three' 
    7380        session.flush(); session.clear() 
    74      
     81 
    7582        # Edit the ignored field, this shouldn't change the version 
    7683        monkeys = Movie.get_by(title='12 Monkeys') 
     
    8390     
    8491        movie = Movie.get_by(title='12 Monkeys') 
     92        assert movie.autoupd == 8, movie.autoupd 
    8593        oldest_version = movie.get_as_of(after_create) 
    8694        middle_version = movie.get_as_of(after_update_one) 
     
    92100        assert oldest_version.description == 'draft description' 
    93101        assert oldest_version.ignoreme == 0 
     102        assert oldest_version.autoupd is not None 
     103        assert oldest_version.autoupd > 0 
    94104     
    95105        assert middle_version.version == 2 
    96106        assert middle_version.description == 'description two' 
     107        assert middle_version.autoupd > oldest_version.autoupd 
    97108     
    98         assert latest_version.version == 3 
     109        assert latest_version.version == 3, 'version=%i' % latest_version.version 
    99110        assert latest_version.description == 'description three' 
    100111        assert latest_version.ignoreme == 1 
     112        assert latest_version.autoupd > middle_version.autoupd 
    101113     
    102114        differences = latest_version.compare_with(oldest_version) 
     
    106118        assert movie.versions[0] == oldest_version 
    107119        assert movie.versions[1] == middle_version 
    108      
    109         movie.revert_to(1) 
     120        assert [v.version for v in movie.versions] == [1, 2, 3] 
     121 
     122        movie.description = 'description four' 
     123 
     124        movie.revert_to(2) 
    110125        session.flush(); session.clear() 
    111126     
    112127        movie = Movie.get_by(title='12 Monkeys') 
    113         assert movie.version == 1 
    114         assert movie.timestamp == initial_timestamp 
    115         assert movie.title == '12 Monkeys' 
    116         assert movie.director.name == 'Terry Gilliam' 
     128        assert movie.version == 2, "version=%i, should be 2" % movie.version 
     129        assert movie.description == 'description two', movie.description 
     130 
     131        movie.description = "description 3" 
     132        session.flush(); session.clear(); 
     133 
     134        movie = Movie.get_by(title='12 Monkeys') 
     135        movie.description = "description 4" 
     136        session.flush(); session.clear(); 
     137 
     138        movie = Movie.get_by(title='12 Monkeys') 
     139        assert movie.version == 4 
     140        movie.revert_to(movie.versions[-2]) 
     141        movie.description = "description 5" 
     142        session.flush(); session.clear(); 
     143 
     144        movie = Movie.get_by(title='12 Monkeys') 
     145        assert movie.version == 4 
     146        assert movie.versions[-2].description == "description 3"