Beispiel #1
0
def apply_default_behavior(entity_attr: 'CdmEntityAttributeDefinition', fk_attr_name: Optional[str],
                           attr_group_name: Optional[str]):
    '''Applies the replaceAsForeignKey and addAttributeGroup operations to the entity attribute provided.'''
    ctx = entity_attr.ctx
    projection = CdmProjection(ctx)
    # Link for the Source property documentation.
    # https://docs.microsoft.com/en-us/common-data-model/sdk/convert-logical-entities-resolved-entities#source
    projection.source = entity_attr.entity
    # Link for the RunSequentially property documentation.
    # https://docs.microsoft.com/en-us/common-data-model/sdk/convert-logical-entities-resolved-entities#run-sequentially
    projection.run_sequentially = True

    entity_attr.entity = CdmEntityReference(ctx, projection, False)

    if fk_attr_name:
        foreign_key_attr = CdmTypeAttributeDefinition(ctx, fk_attr_name)
        foreign_key_attr.data_type = CdmDataTypeReference(ctx, 'entityId', True)

        # Link for the ReplaceAsForeignKey operation documentation.
        # https://docs.microsoft.com/en-us/common-data-model/sdk/projections/replaceasforeignkey
        replace_as_fk_operation = CdmOperationReplaceAsForeignKey(ctx)
        replace_as_fk_operation.condition = 'referenceOnly'
        replace_as_fk_operation.reference = 'addressLine'
        replace_as_fk_operation.replace_with = foreign_key_attr

        projection.operations.append(replace_as_fk_operation)

    if attr_group_name:
        # Link for the AddAttributeGroup operation documentation.
        # https://docs.microsoft.com/en-us/common-data-model/sdk/projections/addattributegroup
        add_attr_group_operation = CdmOperationAddAttributeGroup(ctx)
        add_attr_group_operation.condition = 'structured'
        add_attr_group_operation.attribute_group_name = attr_group_name

        projection.operations.append(add_attr_group_operation)
Beispiel #2
0
def apply_array_expansion(entity_attr: 'CdmEntityAttributeDefinition',
                          start_ordinal: int, end_ordinal: int,
                          rename_format: str, count_att_name: Optional[str]):
    '''Applies the arrayExpansion operation to the entity attribute provided.
    It also takes care of applying a renameattributes operation and optionally applying a addCountAttribute operation.'''
    ctx = entity_attr.ctx

    projection = CdmProjection(ctx)
    projection.source = entity_attr.entity
    projection.run_sequentially = True
    # Link for the Condition property documentation.
    # https://docs.microsoft.com/en-us/common-data-model/sdk/convert-logical-entities-resolved-entities#condition
    projection.condition = '!normalized'

    entity_attr.entity = CdmEntityReference(ctx, projection, False)

    # Link for the ArrayExpansion operation documentation.
    # https://docs.microsoft.com/en-us/common-data-model/sdk/projections/arrayexpansion
    arr_expansion_operation = CdmOperationArrayExpansion(ctx)
    arr_expansion_operation.start_ordinal = start_ordinal
    arr_expansion_operation.end_ordinal = end_ordinal
    projection.operations.append(arr_expansion_operation)

    # Link for the Renameattributes operation documentation.
    # https://docs.microsoft.com/en-us/common-data-model/sdk/projections/renameattributes
    # Doing an ArrayExpansion without a RenameAttributes afterwards will result in the expanded attributes being merged in the final resolved entity.
    # This is because ArrayExpansion does not rename the attributes it expands by default. The expanded attributes end up with the same name and gets merged.
    # Example: We expand A to A[1], A[2], A[3], but A[1], A[2], A[3] are still named "A".
    rename_attrs_operation = CdmOperationRenameAttributes(ctx)
    rename_attrs_operation.rename_format = rename_format
    projection.operations.append(rename_attrs_operation)

    if count_att_name:
        count_attribute = CdmTypeAttributeDefinition(ctx, count_att_name)
        count_attribute.data_type = CdmDataTypeReference(ctx, 'integer', True)

        # Link for the AddCountAttribute operation documentation.
        # https://docs.microsoft.com/en-us/common-data-model/sdk/projections/addcountattribute
        # It is recommended, but not mandated, to be used with the ArrayExpansion operation to provide an ArrayExpansion a count attribute that
        # represents the total number of expanded elements. AddCountAttribute can also be used by itself.
        add_count_attr_operation = CdmOperationAddCountAttribute(ctx)
        add_count_attr_operation.count_attribute = count_attribute
        projection.operations.append(add_count_attr_operation)
def apply_array_expansion(entity_attr: 'CdmEntityAttributeDefinition',
                          start_ordinal: int, end_ordinal: int,
                          rename_format: str, count_att_name: Optional[str]):
    '''Applies the arrayExpansion operation to the entity attribute provided.
    It also takes care of applying a renameattributes operation and optionally applying a addCountAttribute operation.'''
    ctx = entity_attr.ctx

    projection = CdmProjection(ctx)
    projection.source = entity_attr.entity
    projection.run_sequentially = True
    # Link for the Condition property documentation.
    # https://docs.microsoft.com/en-us/common-data-model/sdk/convert-logical-entities-resolved-entities#condition
    projection.condition = '!normalized'

    entity_attr.entity = CdmEntityReference(ctx, projection, False)

    # Link for the ArrayExpansion operation documentation.
    # https://docs.microsoft.com/en-us/common-data-model/sdk/projections/arrayexpansion
    arr_expansion_operation = CdmOperationArrayExpansion(ctx)
    arr_expansion_operation.start_ordinal = start_ordinal
    arr_expansion_operation.end_ordinal = end_ordinal
    projection.operations.append(arr_expansion_operation)

    # Link for the Renameattributes operation documentation.
    # https://docs.microsoft.com/en-us/common-data-model/sdk/projections/renameattributes
    rename_attrs_operation = CdmOperationRenameAttributes(ctx)
    rename_attrs_operation.rename_format = rename_format
    projection.operations.append(rename_attrs_operation)

    if count_att_name:
        count_attribute = CdmTypeAttributeDefinition(ctx, count_att_name)
        count_attribute.data_type = CdmDataTypeReference(ctx, 'integer', True)

        # Link for the AddCountAttribute operation documentation.
        # https://docs.microsoft.com/en-us/common-data-model/sdk/projections/addcountattribute
        add_count_attr_operation = CdmOperationAddCountAttribute(ctx)
        add_count_attr_operation.count_attribute = count_attribute
        projection.operations.append(add_count_attr_operation)
    def test_type_attribute_source(self):
        """Tests if setting the projection "source" on a type attribute triggers an error log"""

        corpus = CdmCorpusDefinition()
        error_count = 0

        def callback(level: 'CdmStatusLevel', message: str):
            nonlocal error_count
            error_count += 1

        corpus.set_event_callback(callback, CdmStatusLevel.ERROR)
        projection = CdmProjection(corpus.ctx)
        type_attribute = CdmTypeAttributeDefinition(corpus.ctx, 'attribute')
        type_attribute.projection = projection

        # First case, a projection without source.
        projection.validate()
        self.assertEqual(0, error_count)

        # Second case, a projection with a nested projection.
        inner_projection = CdmProjection(corpus.ctx)
        projection.source = CdmEntityReference(corpus.ctx, inner_projection,
                                               False)
        projection.validate()
        inner_projection.validate()
        self.assertEqual(0, error_count)

        # Third case, a projection with an explicit entity definition.
        inner_projection.source = CdmEntityReference(
            corpus.ctx, CdmEntityDefinition(corpus.ctx, 'Entity'), False)
        projection.validate()
        inner_projection.validate()
        self.assertEqual(1, error_count)
        error_count = 0

        # Third case, a projection with a named reference.
        inner_projection.source = CdmEntityReference(corpus.ctx, 'Entity',
                                                     False)
        projection.validate()
        inner_projection.validate()
        self.assertEqual(1, error_count)