def _create_projection_with_operation_collection(self, corpus: 'CdmCorpusDefinition', owner: 'CdmObject') -> 'CdmProjection':
        """Create a projection object with operations"""
        projection = corpus.make_object(CdmObjectType.PROJECTION_DEF)
        projection.source = corpus.make_object(CdmObjectType.ENTITY_REF, 'TestSource', True)

        # AddCountAttribute Operation
        add_count_attribute_op = CdmOperationAddCountAttribute(corpus.ctx)
        add_count_attribute_op.count_attribute = corpus.make_object(CdmObjectType.TYPE_ATTRIBUTE_DEF)
        projection.operations.append(add_count_attribute_op)

        # AddSupportingAttribute Operation
        add_supporting_attribute_op = CdmOperationAddSupportingAttribute(corpus.ctx)
        add_supporting_attribute_op.supporting_attribute = corpus.make_object(CdmObjectType.TYPE_ATTRIBUTE_DEF)
        projection.operations.append(add_supporting_attribute_op)

        # AddTypeAttribute Operation
        add_type_attribute_op = CdmOperationAddTypeAttribute(corpus.ctx)
        add_type_attribute_op.type_attribute = corpus.make_object(CdmObjectType.TYPE_ATTRIBUTE_DEF)
        projection.operations.append(add_type_attribute_op)

        # ExcludeAttributes Operation
        exclude_attributes_op = CdmOperationExcludeAttributes(corpus.ctx)
        exclude_attributes_op.exclude_attributes = []
        exclude_attributes_op.exclude_attributes.append('testAttribute1')
        projection.operations.append(exclude_attributes_op)

        # ArrayExpansion Operation
        array_expansion_op = CdmOperationArrayExpansion(corpus.ctx)
        array_expansion_op.start_ordinal = 0
        array_expansion_op.end_ordinal = 1
        projection.operations.append(array_expansion_op)

        # CombineAttributes Operation
        combine_attributes_op = CdmOperationCombineAttributes(corpus.ctx)
        combine_attributes_op.select = []
        combine_attributes_op.merge_into = corpus.make_object(CdmObjectType.TYPE_ATTRIBUTE_DEF)
        combine_attributes_op.select.append('testAttribute1')
        projection.operations.append(combine_attributes_op)

        # RenameAttributes Operation
        rename_attributes_op = CdmOperationRenameAttributes(corpus.ctx)
        rename_attributes_op.rename_format = '{m}'
        projection.operations.append(rename_attributes_op)

        # ReplaceAsForeignKey Operation
        replace_as_foreign_key_op = CdmOperationReplaceAsForeignKey(corpus.ctx)
        replace_as_foreign_key_op.reference = 'testAttribute1'
        replace_as_foreign_key_op.replace_with = corpus.make_object(CdmObjectType.TYPE_ATTRIBUTE_DEF, 'testForeignKey', False)
        projection.operations.append(replace_as_foreign_key_op)

        # IncludeAttributes Operation
        include_attributes_op = CdmOperationIncludeAttributes(corpus.ctx)
        include_attributes_op.include_attributes = []
        include_attributes_op.include_attributes.append('testAttribute1')
        projection.operations.append(include_attributes_op)

        return projection
Esempio n. 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_get_default_condition_expression(self):
        """Unit test for ConditionExpression._get_default_condition_expression"""
        corpus = TestHelper.get_local_corpus(
            self.tests_subpath, 'test_get_default_condition_expression')
        corpus.storage.mount(
            'local',
            LocalAdapter(
                TestHelper.get_actual_output_folder_path(
                    self.tests_subpath,
                    'test_get_default_condition_expression')))
        local_root = corpus.storage.fetch_root_folder('local')
        manifest_default = self._create_default_manifest(corpus, local_root)

        entity_test_source = self._create_entity_test_source(
            corpus, manifest_default, local_root)

        # projection for a non entity attribute
        op_coll = CdmOperationCollection(corpus.ctx, entity_test_source)

        # add 1st FK
        op_coll.append(CdmOperationReplaceAsForeignKey(corpus.ctx))
        self.assertEqual(
            ' (referenceOnly || noMaxDepth || (depth > maxDepth)) ',
            ConditionExpression._get_default_condition_expression(
                op_coll, entity_test_source))

        # add 2nd FK
        op_coll.append(CdmOperationReplaceAsForeignKey(corpus.ctx))
        self.assertEqual(
            ' (referenceOnly || noMaxDepth || (depth > maxDepth)) ',
            ConditionExpression._get_default_condition_expression(
                op_coll, entity_test_source))

        op_coll.clear()

        # add AddCount
        op_coll.append(CdmOperationAddCountAttribute(corpus.ctx))
        self.assertEqual(
            ' (!structured) ',
            ConditionExpression._get_default_condition_expression(
                op_coll, entity_test_source))

        # add ArrayExpansion
        op_coll.append(CdmOperationArrayExpansion(corpus.ctx))
        self.assertEqual(
            ' (!structured) ',
            ConditionExpression._get_default_condition_expression(
                op_coll, entity_test_source))

        op_coll.clear()

        # add AddSupporting
        op_coll.append(CdmOperationAddSupportingAttribute(corpus.ctx))
        self.assertEqual(
            ' (true) ',
            ConditionExpression._get_default_condition_expression(
                op_coll, entity_test_source))

        entity_test_entity_attribute = corpus.make_object(
            CdmObjectType.ENTITY_ATTRIBUTE_DEF, 'TestEntityAttribute', False)

        # projection for a non entity attribute
        op_coll_EA = CdmOperationCollection(corpus.ctx,
                                            entity_test_entity_attribute)

        # add 1st FK
        op_coll_EA.append(CdmOperationReplaceAsForeignKey(corpus.ctx))
        self.assertEqual(
            ' ( (!normalized) || (cardinality.maximum <= 1) )  &&  (referenceOnly || noMaxDepth || (depth > maxDepth)) ',
            ConditionExpression._get_default_condition_expression(
                op_coll_EA, entity_test_entity_attribute))

        # add 2nd FK
        op_coll_EA.append(CdmOperationReplaceAsForeignKey(corpus.ctx))
        self.assertEqual(
            ' ( (!normalized) || (cardinality.maximum <= 1) )  &&  (referenceOnly || noMaxDepth || (depth > maxDepth)) ',
            ConditionExpression._get_default_condition_expression(
                op_coll_EA, entity_test_entity_attribute))

        op_coll_EA.clear()

        # add AddCount
        op_coll_EA.append(CdmOperationAddCountAttribute(corpus.ctx))
        self.assertEqual(
            ' ( (!normalized) || (cardinality.maximum <= 1) )  &&  (!structured) ',
            ConditionExpression._get_default_condition_expression(
                op_coll_EA, entity_test_entity_attribute))

        # add ArrayExpansion
        op_coll_EA.append(CdmOperationArrayExpansion(corpus.ctx))
        self.assertEqual(
            ' ( (!normalized) || (cardinality.maximum <= 1) )  &&  (!structured) ',
            ConditionExpression._get_default_condition_expression(
                op_coll_EA, entity_test_entity_attribute))

        op_coll_EA.clear()

        # add AddSupporting
        op_coll_EA.append(CdmOperationAddSupportingAttribute(corpus.ctx))
        self.assertEqual(
            ' ( (!normalized) || (cardinality.maximum <= 1) )  &&  (true) ',
            ConditionExpression._get_default_condition_expression(
                op_coll_EA, entity_test_entity_attribute))