Changeset 354

Show
Ignore:
Timestamp:
07/07/08 13:07:42 (5 years ago)
Author:
ged
Message:

- Fixed acts_as_list extension with autoloaded entities (patch from maqr,

closes ticket #52).

Location:
elixir/trunk
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • elixir/trunk/CHANGES

    r353 r354  
    1717        pass 
    1818    A.name = Field(String(32)) 
    19 - Added add_mapper_property and add_table_column helper method in 
     19- Added add_mapper_property and add_table_column helper methods in 
    2020  EntityBuilders. 
    2121- Added full_tablename property on EntityDescriptor (includes schema name if 
     
    3232      SA 0.4) 
    3333    * autoexpire=True (with SA 0.5). 
    34 - removed objectstore 
     34- removed objectstore and other SA 0.3 or older support code. 
    3535 
    3636Bug fixes: 
     
    4040- Fixed inheritance with autoloaded entities: when using autoload, we 
    4141  shouldn't try to add columns to the table (closes tickets #41 and #43). 
     42- Fixed acts_as_list extension with autoloaded entities (patch from maqr, 
     43  closes ticket #52). 
    4244- Fixed ColumnProperty to work with latest version of SQLAlchemy (O.4.5 and 
    4345  later) 
  • elixir/trunk/elixir/ext/list.py

    r349 r354  
    5353 
    5454 
    55 The above example can then be used to manage ordered todo lists for people.  
     55The above example can then be used to manage ordered todo lists for people. 
    5656Note that you must set the `order_by` property on the `Person.todo` relation in 
    57 order for the relation to respect the ordering. Here is an example of using  
     57order for the relation to respect the ordering. Here is an example of using 
    5858this model in practice: 
    5959 
     
    104104 
    105105    def create_non_pk_cols(self): 
    106         self.position_column = Column(self.column_name, Integer) 
    107         self.entity._descriptor.add_column(self.position_column) 
     106        if self.entity._descriptor.autoload: 
     107            for c in self.entity.table.c: 
     108                if c.name == self.column_name: 
     109                    self.position_column = c 
     110            if not hasattr(self, 'position_column'): 
     111                raise Exception( 
     112                    "Could not find column '%s' in autoloaded table '%s', " 
     113                    "needed by entity '%s'." % (self.column_name, 
     114                        self.entity.table.name, self.entity.__name__)) 
     115        else: 
     116            self.position_column = Column(self.column_name, Integer) 
     117            self.entity._descriptor.add_column(self.position_column) 
    108118 
    109119    def after_table(self): 
     
    163173 
    164174        def move_to_top(self): 
    165             # move the items that were above this item down one 
    166             self.table.update( 
    167                 and_( 
    168                     position_column <= getattr(self, position_column_name), 
    169                     qualifier_method(self) 
    170                 ), 
    171                 values = { 
    172                     position_column: position_column + 1 
    173                 } 
    174             ).execute() 
    175  
    176             # move this item to the first position 
    177             self.table.update(get_entity_where(self)) \ 
    178                       .execute(**{position_column_name: 1}) 
     175            self.move_to(1) 
    179176 
    180177        def move_to(self, position): 
     
    207204 
    208205        def move_lower(self): 
     206            # replace for ex.: p.todos.insert(x + 1, p.todos.pop(x)) 
    209207            self.move_to(getattr(self, position_column_name) + 1) 
    210208 
  • elixir/trunk/tests/test_acts_as_list.py

    r349 r354  
     1from sqlalchemy import Table, Column, MetaData 
     2 
    13from elixir import * 
    24from elixir.ext.list import acts_as_list 
    35 
    4 def setup(): 
    5     global ToDo, Person 
    6  
    7     class ToDo(Entity): 
    8         subject = Field(String(128)) 
    9         owner = ManyToOne('Person') 
    10  
    11         def qualify(self): 
    12             return ToDo.owner_id == self.owner_id 
    13  
    14         acts_as_list(qualifier=qualify, column_name='position') 
    15  
    16         def __repr__(self): 
    17             return '<%d:%s>' % (self.position, self.subject) 
    18  
    19     class Person(Entity): 
    20         name = Field(String(64)) 
    21         todos = OneToMany('ToDo', order_by='position') 
    22  
    23  
    24     setup_all() 
    25     metadata.bind = 'sqlite:///' 
    26  
    27  
    28 def teardown(): 
    29     cleanup_all() 
    30  
    316 
    327class TestActsAsList(object): 
    33     def setup(self): 
    34         create_all() 
    358 
    369    def teardown(self): 
    37         drop_all() 
    38         session.clear() 
     10        cleanup_all(True) 
    3911 
    4012    def test_acts_as_list(self): 
     13        class ToDo(Entity): 
     14            subject = Field(String(128)) 
     15            owner = ManyToOne('Person') 
     16 
     17            def qualify(self): 
     18                return ToDo.owner_id == self.owner_id 
     19 
     20            acts_as_list(qualifier=qualify, column_name='position') 
     21 
     22            def __repr__(self): 
     23                return '<%d:%s>' % (self.position, self.subject) 
     24 
     25        class Person(Entity): 
     26            name = Field(String(64)) 
     27            todos = OneToMany('ToDo', order_by='position') 
     28 
     29        metadata.bind = 'sqlite:///' 
     30 
     31        setup_all(True) 
     32 
    4133        # create a person 
    4234        # you must create and commit this _before_ you attach todo's to it 
     
    7466 
    7567        # lets shuffle them again for the sake of testing move_to_bottom 
    76         # and move_to_top 
    7768        p.todos[2].move_to_top() 
    7869        session.commit(); session.clear() 
     
    117108        assert p.todos[1].subject == 'Three' 
    118109        assert p.todos[1].position == 2 
     110 
     111    def test_acts_as_list_autoload(self): 
     112        # Make autoload test fixture 
     113        meta = MetaData('sqlite:///') 
     114 
     115        preloaded_table = Table('preloaded', meta, 
     116            Column('name', String(32), primary_key=True), 
     117            Column('position', Integer)) 
     118 
     119        meta.create_all() 
     120 
     121        class Preloaded(Entity): 
     122            using_options(tablename='preloaded', autoload=True) 
     123            acts_as_list() 
     124 
     125        metadata.bind = meta.bind 
     126        setup_all() 
     127 
     128        i = Preloaded(name='Foo') 
     129        session.commit() 
     130        assert i.name == 'Foo' 
     131        assert i.position == 1 
     132 
     133        j = Preloaded(name='Bar') 
     134        session.commit() 
     135        assert j.name == 'Bar' 
     136        assert j.position == 2