def map_computed_properties(cls):
     from p2.datashackle.management.model.model import Model
     t = setobject_table_registry.lookup_by_class(Model.__name__)
     select = t.select().where(t.c.klass == cls.__name__)
     rec = dict(select.execute().first())
     
     cls.sa_map_dispose()
     if rec['table'] == SpanType.get_table_name():
         orm.mapper(cls,
                    inherits=SpanType._sa_class_manager.mapper,
                    polymorphic_identity=cls.__name__,
                    properties=cls.mapper_properties)
     else:
         table = setobject_table_registry.lookup_by_class(cls.__name__)
         orm.mapper(cls,
                    table,
                    inherits=SpanType._sa_class_manager.mapper,
                    polymorphic_identity=cls.__name__,
                    properties=cls.mapper_properties)
 def map_computed_properties(cls):
     cls.sa_map_dispose()
     p2_widget = setobject_table_registry.lookup_by_class(WidgetType.__name__)    
     # Map base class
     orm.mapper(
         WidgetType,
         p2_widget,
         polymorphic_on=p2_widget.c.widget_type,
         polymorphic_identity='widgettype',
         properties=WidgetType.mapper_properties
         )
    def map_computed_properties(cls):
        cls.sa_map_dispose()
        table_type = setobject_table_registry.lookup_by_class(SpanType.__name__)

        # Map base class
        #    
        # with_polymorphic="*":  This loads attributes from tables that use
        # joined table inheritance (p2_span_embeddedform) as well.
        # when doing something like query(SpanType).filter(RelationSpan.span_identifier = relation_span_id)
        span_mapper = orm.mapper(
            cls,
            table_type,
            polymorphic_on=table_type.c.span_type,
            polymorphic_identity='spantype',
            properties=cls.mapper_properties,
            with_polymorphic='*'
       )
    def compute_orm_properties(self, THIS_IS_A_DIRTY_HACK_PROPERTIES_DICT):
        mappedsotype = setobject_type_registry.lookup(self.target_model.klass)
        xref_table_class = None
        sourcetable = setobject_table_registry.lookup_by_class(self.source_model.klass)
        targettable = setobject_table_registry.lookup_by_class(self.target_model.klass)
        if self.cardinality.id == 'MANY_TO_ONE' or \
                self.cardinality.id == 'ONE(FK)_TO_ONE':
            # take primary key on our side
            primaryfk = getattr(sourcetable.c, self.relation.foreignkeycol)
            primaryidentifier = getattr(targettable.c, mappedsotype.get_primary_key_attr_name())
            primaryjoin = (primaryfk == primaryidentifier)
            secondaryjoin = None
        elif self.cardinality.id == 'ONE_TO_MANY' or \
                self.cardinality.id == 'ONE_TO_ONE(FK)':
            # take primary key on other side
            primaryfk = getattr(targettable.c, self.relation.foreignkeycol)
            primaryidentifier = getattr(
                sourcetable.c,
                setobject_type_registry.lookup(self.source_model.klass).get_primary_key_attr_name()
            )
            primaryjoin = (primaryfk == primaryidentifier)
            secondaryjoin = None
        elif self.cardinality.id == 'MANY_TO_MANY':
            # xref! we actually need two clauses here.
            
            # Obtain table class:
            xref_table_class = setobject_table_registry.get_by_table(self.relation.xref_table)
            if xref_table_class is None:
                # Class is not mapped (probably not having a primary key or something like that) -> autoload
                xref_table_class = Table(self.relation.xref_table, metadata, autoload=True, useexisting=True, autoload_with=getUtility(IDbUtility).engine)
            
            # Compose two join clauses
            primaryjoin = (cls.get_primary_key_column() == getattr(xref_table_class.c, self.relation.foreignkeycol))
            secondaryjoin = (mappedsotype.get_primary_key_column() == getattr(xref_table_class.c, self.relation.foreignkeycol2))
        
        # add the obtained setobject to our mapped properties
        if self.cardinality.id == 'MANY_TO_ONE':
            # This mapping should really not happen here and now.
            # Instead, the linkage MUST be persisted into
            # table p2_linkage at save time!

            THIS_IS_A_DIRTY_HACK_PROPERTIES_DICT[self.attr_name] = orm.relation(
                mappedsotype,
                uselist=False,
                cascade=self.cascade,
                back_populates=self.back_populates,
                primaryjoin=primaryjoin,
                post_update=self.post_update
            )
            relationarguments = {
                'uselist' : False,
                'cascade' : self.cascade,
                'back_populates' : self.back_populates,
                'primaryjoin' : primaryjoin,
                'post_update' : self.post_update
            }
        else:
            # the other side has the foreign key, store things as a collection
            
            order_by = None
            collection_class = None
            
            # This is a special case for the spans as they should not be mapped as ordinary
            # dictionary, but rather as an orderable dictionary. This is necessary to retain the insert order
            # as a ordinary dict isn't ordered. Consider this to be implemented in a more generic way if this
            # use case is occuring for user relations as well.
            if self.attr_name == 'spans' and self.source_model.klass == 'WidgetType':
                collection_class=SpanCollectionClass
                span_table = setobject_table_registry.lookup_by_table('p2_span')
                order_by=span_table.c.order
            
            # This is another special case to ensure the widgets being tab ordered
            if self.attr_name == 'widgets' and self.source_model.klass == 'FormType':
                collection_class = WidgetCollectionClass
                widget_table = setobject_table_registry.lookup_by_table('p2_widget')
                order_by=widget_table.c.tab_order
            
            # Get collection class
            if collection_class == None:
                if self.ref_key is None:
                    collection_class = column_mapped_collection(mappedsotype.get_primary_key_column())
                else:
                    mapped_column = mappedsotype.get_column(self.ref_key)
                    collection_class = column_mapped_collection(mapped_column)
            
            # Compute arguments:
            relationarguments = {
                'back_populates' : self.back_populates,
                'collection_class' : collection_class,
                'uselist' : True,
                'primaryjoin': primaryjoin,
                'cascade' : self.cascade,
                'post_update' : self.post_update
                }
            if order_by is not None:
                relationarguments['order_by'] = order_by
        
        # Set xref table if we got one
        if xref_table_class is not None:
            relationarguments['secondary'] = xref_table_class
            if secondaryjoin is not None:
                relationarguments['secondaryjoin'] = secondaryjoin
        
        return relationarguments
 def get_column(cls, name):
     """Returns a column by name"""
     table_type = setobject_table_registry.lookup_by_class(cls.__name__)
     return getattr(table_type.c, name)