
from sa_gentestbase import *

class AB( Test_SA):
    def test_ABC_poly_1__inh_j__insts_ABC__Alazy_C__inhB___Blazy_A__BAlazy___inhC_A__Clazy_B__CAlazy___CBlazy_( me):
        meta=me.meta
        table_A = Table( 'A', meta,
            Column( 'linkA_id', Integer, ForeignKey( 'C.db_id',     name= 'linkA_id_fk',     use_alter= True, ), ),
            Column( 'name', String, ),
            Column( 'atype',   type_= String, ),
            Column( 'db_id',   primary_key= True,   type_= Integer, ),
        )
        table_B = Table( 'B', meta,
            Column( 'linkB_id', Integer, ForeignKey( 'A.db_id', ), ),
            Column( 'dataB', String, ),
            Column( 'db_id',   primary_key= True,   type_= Integer, ),
        )
        table_C = Table( 'C', meta,
            Column( 'linkC_id', Integer, ForeignKey( 'B.db_id', ), ),
            Column( 'dataC', String, ),
            Column( 'db_id', Integer, ForeignKey( 'A.db_id', ),   primary_key= True, ),
        )

        meta.create_all()

        class A( Base):
            props = ['db_id', 'linkA', 'name']
        class B( Base):
            props = ['db_id', 'linkB', 'dataB']
        class C( A):
            props = ['db_id', 'linkA', 'linkC', 'dataC', 'name']

        mapper_A = mapper( A, table_A,
                    polymorphic_identity= 'A',
                    polymorphic_on= table_A.c.atype,
                    select_table= outerjoin( table_A, table_C, table_C.c.db_id == table_A.c.db_id, ),
                    )
        mapper_A.add_property( 'linkA', relation( C,
                    foreign_keys= table_A.c.linkA_id,
                    lazy= True,
                    post_update= True,
                    primaryjoin= table_A.c.linkA_id == table_C.c.db_id,
                    remote_side= table_C.c.db_id,
                    uselist= False,
                    ) )

        mapper_B = mapper( B, table_B,
                    )
        mapper_B.add_property( 'linkB', relation( A,
                    foreign_keys= table_B.c.linkB_id,
                    lazy= True,
                    primaryjoin= table_B.c.linkB_id == table_A.c.db_id,
                    remote_side= table_A.c.db_id,
                    uselist= False,
                    ) )

        mapper_C = mapper( C, table_C,
                    inherit_condition= table_C.c.db_id == table_A.c.db_id,
                    inherits= mapper_A,
                    polymorphic_identity= 'C',
                    )
        mapper_C.add_property( 'linkC', relation( B,
                    foreign_keys= table_C.c.linkC_id,
                    lazy= True,
                    primaryjoin= table_C.c.linkC_id == table_B.c.db_id,
                    remote_side= table_B.c.db_id,
                    uselist= False,
                    ) )


        mapper_A1 = mapper( A, table_A.select( table_A.c.atype == 'A', ).alias( 'bz4A' ),
                    non_primary= True,
                    )



        #populate
        a = A()
        b = B()
        c = C()
        a.linkA = c
        a.name = 'anna'
        b.linkB = a
        b.dataB = 'gun'
        c.linkC = b
        c.dataC = 'mc'
        c.name = 'cc'

        session = create_session()
        session.save(a)
        session.save(b)
        session.save(c)
        session.flush()

        expects = [
            dict( klas= A, table= table_A, oid= a.db_id, exp_single= str(a),
                    exp_multi = [ str(a), str(c) ]),
            dict( klas= B, table= table_B, oid= b.db_id, exp_single= str(b),
                    exp_multi = [ str(b) ]),
            dict( klas= C, table= table_C, oid= c.db_id, exp_single= str(c),
                    exp_multi = [ str(c) ]),

        ]

        me.query( session, expects, idname='db_id' )

if __name__ == '__main__':
    setup()
    unittest.main()
