def generate_table_schema_interface(ti): '''!+DO_NOT_REORDER_USER_APPLIED_INTERFACES def get_domain_interfaces(domain_model): """Return the domain bases for an interface as well as a filtered implements only list (base interfaces removed). Note that for 2nd level (mapped) domain classes i.e. those that inherit from another domain class e.g. Event(Doc), Office(Group), OfficeMember(GroupMember), an IIModelInterface-providing I*TableSchema interface had already been created (for base class) and assigned to the super class--and that interface will match as one of the domain_base interfaces here. """ domain_bases = [] domain_implements = [] for iface in interface.implementedBy(domain_model): if IIModelInterface.providedBy(iface): domain_bases.append(iface) else: domain_implements.append(iface) domain_bases = tuple(domain_bases) or (IAlchemistContent,) return domain_bases, domain_implements bases, implements = get_domain_interfaces(ti.domain_model) ''' # derived_table_schema: # - ALWAYS dynamically generated # - directlyProvides IIModelInterface (by virtue of IAlchemistContent) type_key = naming.polymorphic_identity(ti.domain_model) # use the class's mapper select table as input for the transformation table_schema_interface_name = naming.table_schema_interface_name(type_key) domain_table = utils.get_local_table(ti.domain_model) derived_table_schema = transmute( domain_table, annotation=ti.descriptor_model, interface_name=table_schema_interface_name, __module__=INTERFACE_MODULE.__name__, #_generated_by="bungeni.alchemist.catalyst.generate_table_schema_interface" #bases=bases) bases=(IAlchemistContent, )) # apply, register on type_info, set on module interface.classImplements(ti.domain_model, derived_table_schema) utils.inisetattr(ti, "derived_table_schema", derived_table_schema) setattr(INTERFACE_MODULE, table_schema_interface_name, derived_table_schema) log.info("generate_table_schema_interface: %s", derived_table_schema) # defensive sanity check - that derived_table_schema is precisely the FIRST # resolving IIModelInterface-providing interface implemented by domain_model # !+ this failing does not necessarily mean an incorrectness for iface in interface.implementedBy(ti.domain_model): if IIModelInterface.providedBy(iface): assert iface is derived_table_schema, (ti.domain_model, iface, id(iface), derived_table_schema, id(derived_table_schema)) break '''!+DO_NOT_REORDER_USER_APPLIED_INTERFACES
def generate_table_schema_interface(ti): '''!+DO_NOT_REORDER_USER_APPLIED_INTERFACES def get_domain_interfaces(domain_model): """Return the domain bases for an interface as well as a filtered implements only list (base interfaces removed). Note that for 2nd level (mapped) domain classes i.e. those that inherit from another domain class e.g. Event(Doc), Office(Group), OfficeMember(GroupMember), an IIModelInterface-providing I*TableSchema interface had already been created (for base class) and assigned to the super class--and that interface will match as one of the domain_base interfaces here. """ domain_bases = [] domain_implements = [] for iface in interface.implementedBy(domain_model): if IIModelInterface.providedBy(iface): domain_bases.append(iface) else: domain_implements.append(iface) domain_bases = tuple(domain_bases) or (IAlchemistContent,) return domain_bases, domain_implements bases, implements = get_domain_interfaces(ti.domain_model) ''' # derived_table_schema: # - ALWAYS dynamically generated # - directlyProvides IIModelInterface (by virtue of IAlchemistContent) type_key = naming.polymorphic_identity(ti.domain_model) # use the class's mapper select table as input for the transformation table_schema_interface_name = naming.table_schema_interface_name(type_key) domain_table = utils.get_local_table(ti.domain_model) derived_table_schema = transmute( domain_table, annotation=ti.descriptor_model, interface_name=table_schema_interface_name, __module__=INTERFACE_MODULE.__name__, #_generated_by="bungeni.alchemist.catalyst.generate_table_schema_interface" #bases=bases) bases=(IAlchemistContent,)) # apply, register on type_info, set on module interface.classImplements(ti.domain_model, derived_table_schema) utils.inisetattr(ti, "derived_table_schema", derived_table_schema) setattr(INTERFACE_MODULE, table_schema_interface_name, derived_table_schema) log.info("generate_table_schema_interface: %s", derived_table_schema) # defensive sanity check - that derived_table_schema is precisely the FIRST # resolving IIModelInterface-providing interface implemented by domain_model # !+ this failing does not necessarily mean an incorrectness for iface in interface.implementedBy(ti.domain_model): if IIModelInterface.providedBy(iface): assert iface is derived_table_schema, (ti.domain_model, iface, id(iface), derived_table_schema, id(derived_table_schema)) break '''!+DO_NOT_REORDER_USER_APPLIED_INTERFACES
def GenerateDomainInterface(ctx, interface_name=None): # when called from zcml, most likely we'll get a class not an instance # if it is a class go ahead and call instantiate it if isinstance(ctx.descriptor, type): ctx.descriptor = ctx.descriptor() # if the interface module is none, then use the nearest one to the domain class if ctx.interface_module is None: ctx.interface_module = _get_interface_module_for(ctx) # interface for domain model if not interface_name: interface_name = "I%s"%(ctx.domain_model.__name__) if ctx.echo: ctx.logger.debug("%s: generated interface %s.%s " % ( ctx.domain_model.__name__, ctx.interface_module.__name__, interface_name)) from alchemist.catalyst.domain import getDomainInterfaces #!+ALCHEMIST_INTERNAL bases, implements = getDomainInterfaces(ctx.domain_model) # use the class"s mapper select table as input for the transformation domain_mapper = orm.class_mapper(ctx.domain_model) ## 0.4 and 0.5 compatibility, 0.5 has the table as local_table (select_table) is none lazy gen? #domain_table = getattr(domain_mapper, "local_table", domain_mapper.select_table) # The 0.6 has no attribute select_table attribute. We still have 0.4 # compitability thought domain_table = (domain_mapper.local_table if sa_version[1] >= 5 else domain_mapper.select_table) # if the domain model already implements a model interface, use it # instead of generating a new one for iface in interface.implementedBy(ctx.domain_model): if (IIModelInterface.providedBy(iface) and iface.__name__ == interface_name ): domain_interface = iface break else: domain_interface = sa2zs.transmute( domain_table, annotation=ctx.descriptor, interface_name = interface_name, __module__ = ctx.interface_module.__name__, bases=bases) # if we're replacing an existing interface, make sure the new # interface implements it old = getattr(ctx.interface_module, interface_name, None) if old is not None: implements.append(old) implements.insert(0, domain_interface) # ensure interfaces are unique, preserving the order #implements = [ ifc for i,ifc in enumerate(implements) # if implements.index(ifc)==i ] # # XXX: Oooh, strangely the above does not work... it turns out that # implements contains seemingly repeated interfaces e.g. the first and last # interfaces are both "<InterfaceClass bungeni.models.interfaces.IReport>" # but, they are not the same! So, to compare unique we use the string # representation of each interface: # str_implements = map(str, implements) # implements = [ ifc for i,ifc in enumerate(implements) # if str_implements.index(str(ifc))==i ] # Ooops making the interfaces unique breaks other things downstream :( interface.classImplementsOnly(ctx.domain_model, *implements) setattr(ctx.interface_module, interface_name, domain_interface) ctx.domain_interface = domain_interface
def GenerateDomainInterface(ctx, interface_name=None): # when called from zcml, most likely we'll get a class not an instance # if it is a class go ahead and call instantiate it if isinstance(ctx.descriptor, type): ctx.descriptor = ctx.descriptor() # if the interface module is none, then use the nearest one to the domain class if ctx.interface_module is None: ctx.interface_module = _get_interface_module_for(ctx) # interface for domain model if not interface_name: interface_name = "I%s" % (ctx.domain_model.__name__) if ctx.echo: ctx.logger.debug("%s: generated interface %s.%s " % (ctx.domain_model.__name__, ctx.interface_module.__name__, interface_name)) from alchemist.catalyst.domain import getDomainInterfaces #!+ALCHEMIST_INTERNAL bases, implements = getDomainInterfaces(ctx.domain_model) # use the class"s mapper select table as input for the transformation domain_mapper = orm.class_mapper(ctx.domain_model) ## 0.4 and 0.5 compatibility, 0.5 has the table as local_table (select_table) is none lazy gen? #domain_table = getattr(domain_mapper, "local_table", domain_mapper.select_table) # The 0.6 has no attribute select_table attribute. We still have 0.4 # compitability thought domain_table = (domain_mapper.local_table if sa_version[1] >= 5 else domain_mapper.select_table) # if the domain model already implements a model interface, use it # instead of generating a new one for iface in interface.implementedBy(ctx.domain_model): if (IIModelInterface.providedBy(iface) and iface.__name__ == interface_name): domain_interface = iface break else: domain_interface = sa2zs.transmute( domain_table, annotation=ctx.descriptor, interface_name=interface_name, __module__=ctx.interface_module.__name__, bases=bases) # if we're replacing an existing interface, make sure the new # interface implements it old = getattr(ctx.interface_module, interface_name, None) if old is not None: implements.append(old) implements.insert(0, domain_interface) # ensure interfaces are unique, preserving the order #implements = [ ifc for i,ifc in enumerate(implements) # if implements.index(ifc)==i ] # # XXX: Oooh, strangely the above does not work... it turns out that # implements contains seemingly repeated interfaces e.g. the first and last # interfaces are both "<InterfaceClass bungeni.models.interfaces.IReport>" # but, they are not the same! So, to compare unique we use the string # representation of each interface: # str_implements = map(str, implements) # implements = [ ifc for i,ifc in enumerate(implements) # if str_implements.index(str(ifc))==i ] # Ooops making the interfaces unique breaks other things downstream :( interface.classImplementsOnly(ctx.domain_model, *implements) setattr(ctx.interface_module, interface_name, domain_interface) ctx.domain_interface = domain_interface