def to_data(instance: CdmTypeAttributeDefinition, ctx: CdmCorpusContext, res_opt: ResolveOptions, options: CopyOptions) -> TypeAttribute:
        properties = TypeAttributePersistence.create_properties(instance, res_opt, options)
        origin_data_type_name = TypeInfo(
        type_name = '',
        properties = properties,
        is_complex_type = False,
        is_nullable = instance._get_property('isNullable'),
        type_family = 'cdm')

        t2pm = TraitToPropertyMap(instance)
        numeric_traits = t2pm._fetch_trait_reference('is.data_format.numeric.shaped')
        if numeric_traits is not None:
            for numeric_traits_arg in numeric_traits.argument:
                if numeric_traits_arg.name == 'precision':
                    origin_data_type_name.precision = numeric_traits_arg.value
                if numeric_traits_arg.Name == 'scale':
                    origin_data_type_name.scale = numeric_traits_arg.value

        data_format = instance._get_property('dataFormat')
        origin_data_type_name = utils.cdm_data_format_to_syms_data_type(data_format, origin_data_type_name)
        if origin_data_type_name == None:
            return None
        if origin_data_type_name.type_name == None:
            logger.error(ctx, _TAG, 'toData', instance.at_corpus_path, CdmLogCode.ERR_PERSIST_SYMS_UNKNOWN_DATA_FORMAT,
                             instance.display_name)
            return None

        data_col = DataColumn(
        origin_data_type_name = origin_data_type_name,
        name = instance.name)
        return data_col
Example #2
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)
    def create_properties(instance: CdmTypeAttributeDefinition, res_opt: ResolveOptions, options: CopyOptions):
        properties = {}
    
        display_name = instance._get_property('display_name')
        source_name = instance._get_property('source_name')
        description = instance._get_property('description')
        is_read_only = instance._get_property('isReadOnly')
        maximum_length = instance._get_property('maximum_length')
        maximum_value = instance._get_property('maximum_value')
        minimum_value = instance._get_property('minimum_value')
        source_ordering = instance._get_property('source_ordering')
        value_constrained_to_list = instance._get_property('value_constrained_to_list')
        is_primary_key = instance._get_property('is_primary_key')
        def_value = instance._get_property('defaultValue')

        if display_name is not None:
            properties['cdm:display_name'] = display_name

        if instance.explanation is not None:
            properties['cdm:explanation'] = instance.explanation

        if source_name is not None:
            properties['cdm:source_name'] = source_name

        if description is not None:
            properties['cdm:description'] = description

        if instance.applied_traits is not None and len(instance.applied_traits) > 0:
            applied_traits = \
                [trait for trait in instance.applied_traits
                 if isinstance(trait, CdmTraitGroupReference) or not trait.is_from_property] \
                    if instance.applied_traits else None
            properties['cdm:traits'] = copy_data_utils._array_copy_data(res_opt, applied_traits, options)
                       
        if is_read_only is not None:
            properties['cdm:isReadOnly'] = is_read_only
        
        if maximum_length is not None:
            properties['cdm:maximumLength'] = maximum_length
        
        if maximum_value is not None:
            properties['cdm:maximumValue'] = maximum_value
        
        if minimum_value is not None:
            properties['cdm:minimumValue'] = minimum_value

        if source_ordering is not None and source_ordering != 0:
            properties['cdm:sourceOrdering'] = source_ordering

        if value_constrained_to_list is not None:
            properties['cdm:valueConstrainedToList'] = value_constrained_to_list

        if is_primary_key is not None:
            properties['cdm:isPrimaryKey'] = is_primary_key

        if def_value is not None:
            properties['cdm:defaultValue'] = def_value

        return properties
Example #4
0
    def test_trait_to_unknown_data_format(self):
        """Test trait to data format when unknown data format trait is in an attribute."""
        cdm_attribute = CdmTypeAttributeDefinition(CdmCorpusContext(CdmCorpusDefinition(), None), 'SomeAttribute')
        cdm_attribute.applied_traits.append('is.data_format.someRandomDataFormat')
        trait_to_property_map = TraitToPropertyMap(cdm_attribute)

        data_format = trait_to_property_map._traits_to_data_format(False)

        self.assertEqual(CdmDataFormat.UNKNOWN, data_format)
Example #5
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)
Example #6
0
    def test_trait_to_json_data_format(self):
        """Test trait to data format when calculated data format should be JSON."""
        cdm_attribute = CdmTypeAttributeDefinition(CdmCorpusContext(CdmCorpusDefinition(), None), 'SomeAttribute')
        cdm_attribute.applied_traits.append('is.dataFormat.array')
        cdm_attribute.applied_traits.append('means.content.text.JSON')
        trait_to_property_map = TraitToPropertyMap(cdm_attribute)

        data_format = trait_to_property_map._traits_to_data_format(False)

        self.assertEqual(CdmDataFormat.JSON, data_format)
    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)
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)
Example #9
0
    async def test_projection_performance_on_load(self):
        """A test class for testing the performance of projection operations"""
        corpus = TestHelper.get_local_corpus(self.tests_subpath, 'TestProjectionPerformanceOnLoad')
        entity = await corpus.fetch_object_async('largeProjectionEntity.cdm.json/largeProjectionEntity')
        operation = entity.attributes[0].entity.explicit_reference.operations[0]
        attGroup = operation.new_attribute.explicit_reference

        # add a large number of attributes to the projection
        for i in range(10000):
            attGroup.members.append(CdmTypeAttributeDefinition(corpus.ctx, 'a' + str(i)))
        start = time.time()
        # reindex the entity to run through the visit function
        await entity.in_document._index_if_needed(ResolveOptions(entity.in_document), True)
        stop = time.time()
        self.assertLess(stop - start, 500)
    def test_update_and_fetch_list_lookup(self):
        """Test update and fetch list lookup default value without attributeValue and displayOrder."""
        corpus = CdmCorpusDefinition()
        cdm_attribute = CdmTypeAttributeDefinition(corpus.ctx, 'SomeAttribute')
        trait_to_property_map = TraitToPropertyMap(cdm_attribute)

        constant_values = [{'languageTag': 'en', 'displayText': 'Fax'}]

        trait_to_property_map.update_property_value('defaultValue',
                                                    constant_values)
        result = trait_to_property_map.fetch_property_value('defaultValue')

        self.assertEqual(1, len(result))
        self.assertEqual('en', result[0].get('languageTag'))
        self.assertEqual('Fax', result[0].get('displayText'))
        self.assertIsNone(result[0].get('attributeValue'))
        self.assertIsNone(result[0].get('displayOrder'))
Example #11
0
    def to_data(instance: CdmTypeAttributeDefinition, res_opt: ResolveOptions,
                options: CopyOptions) -> TypeAttribute:
        if instance is None:
            return None

        applied_traits = \
            [trait for trait in instance.applied_traits if not trait.is_from_property] \
            if instance.applied_traits else None

        data = TypeAttribute()
        data.explanation = instance.explanation
        data.purpose = PurposeReferencePersistence.to_data(
            instance.purpose, res_opt, options) if instance.purpose else None
        data.dataType = DataTypeReferencePersistence.to_data(
            instance.data_type, res_opt,
            options) if instance.data_type else None
        data.name = instance.name
        data.appliedTraits = copy_data_utils._array_copy_data(
            res_opt, applied_traits, options)
        data.resolutionGuidance = AttributeResolutionGuidancePersistence.to_data(
            instance.resolution_guidance, res_opt,
            options) if instance.resolution_guidance else None
        data.projection = ProjectionPersistence.to_data(
            instance.projection, res_opt, options)
        data.attributeContext = AttributeContextReferencePersistence.to_data(
            instance.attribute_context, res_opt,
            options) if instance.attribute_context else None

        is_read_only = instance._get_property('isReadOnly')
        if is_read_only:
            data.isReadOnly = is_read_only

        is_nullable = instance._get_property('isNullable')
        if is_nullable:
            data.isNullable = is_nullable

        data.sourceName = instance._get_property('sourceName')

        source_ordering = instance._get_property('sourceOrdering')
        if source_ordering:
            data.sourceOrdering = source_ordering

        data.displayName = instance._get_property('displayName')
        data.description = instance._get_property('description')

        value_constrained_to_list = instance._get_property(
            'valueConstrainedToList')
        if value_constrained_to_list:
            data.valueConstrainedToList = value_constrained_to_list

        is_primary_key = instance._get_property('isPrimaryKey')
        if is_primary_key:
            data.isPrimaryKey = is_primary_key

        data.maximumLength = instance._get_property('maximumLength')
        data.maximumValue = instance._get_property('maximumValue')
        data.minimumValue = instance._get_property('minimumValue')

        data_format = instance._get_property('dataFormat')
        if data_format != CdmDataFormat.UNKNOWN:
            data.dataFormat = data_format.value

        default_value = instance._get_property('defaultValue')
        if default_value:
            data.defaultValue = default_value

        return data
Example #12
0
    def _build_fake_tree(self,
                         corpus: 'CdmCorpusDefinition') -> 'ProjectionContext':
        proj_dir = ProjectionDirective(ResolveOptions(), None)
        pc = ProjectionContext(proj_dir, None)

        p1 = ProjectionAttributeState(corpus.ctx)
        p1._current_resolved_attribute = ResolvedAttribute(
            proj_dir._res_opt, CdmTypeAttributeDefinition(corpus.ctx, '1'),
            '1', None)
        p2 = ProjectionAttributeState(corpus.ctx)
        p2._current_resolved_attribute = ResolvedAttribute(
            proj_dir._res_opt, CdmTypeAttributeDefinition(corpus.ctx, '2'),
            '2', None)
        p4 = ProjectionAttributeState(corpus.ctx)
        p4._current_resolved_attribute = ResolvedAttribute(
            proj_dir._res_opt, CdmTypeAttributeDefinition(corpus.ctx, '4'),
            '4', None)
        p5 = ProjectionAttributeState(corpus.ctx)
        p5._current_resolved_attribute = ResolvedAttribute(
            proj_dir._res_opt, CdmTypeAttributeDefinition(corpus.ctx, '5'),
            '5', None)
        p6 = ProjectionAttributeState(corpus.ctx)
        p6._current_resolved_attribute = ResolvedAttribute(
            proj_dir._res_opt, CdmTypeAttributeDefinition(corpus.ctx, '6'),
            '6', None)
        p7 = ProjectionAttributeState(corpus.ctx)
        p7._current_resolved_attribute = ResolvedAttribute(
            proj_dir._res_opt, CdmTypeAttributeDefinition(corpus.ctx, '7'),
            '7', None)
        p8 = ProjectionAttributeState(corpus.ctx)
        p8._current_resolved_attribute = ResolvedAttribute(
            proj_dir._res_opt, CdmTypeAttributeDefinition(corpus.ctx, '8'),
            '8', None)
        p9 = ProjectionAttributeState(corpus.ctx)
        p9._current_resolved_attribute = ResolvedAttribute(
            proj_dir._res_opt, CdmTypeAttributeDefinition(corpus.ctx, '9'),
            '9', None)
        p10 = ProjectionAttributeState(corpus.ctx)
        p10._current_resolved_attribute = ResolvedAttribute(
            proj_dir._res_opt, CdmTypeAttributeDefinition(corpus.ctx, '10'),
            '10', None)
        p11 = ProjectionAttributeState(corpus.ctx)
        p11._current_resolved_attribute = ResolvedAttribute(
            proj_dir._res_opt, CdmTypeAttributeDefinition(corpus.ctx, '11'),
            '11', None)
        p12 = ProjectionAttributeState(corpus.ctx)
        p12._current_resolved_attribute = ResolvedAttribute(
            proj_dir._res_opt, CdmTypeAttributeDefinition(corpus.ctx, '12'),
            '12', None)
        p13 = ProjectionAttributeState(corpus.ctx)
        p13._current_resolved_attribute = ResolvedAttribute(
            proj_dir._res_opt, CdmTypeAttributeDefinition(corpus.ctx, '13'),
            '13', None)
        p14 = ProjectionAttributeState(corpus.ctx)
        p14._current_resolved_attribute = ResolvedAttribute(
            proj_dir._res_opt, CdmTypeAttributeDefinition(corpus.ctx, '14'),
            '14', None)
        p15 = ProjectionAttributeState(corpus.ctx)
        p15._current_resolved_attribute = ResolvedAttribute(
            proj_dir._res_opt, CdmTypeAttributeDefinition(corpus.ctx, '15'),
            '15', None)
        p16 = ProjectionAttributeState(corpus.ctx)
        p16._current_resolved_attribute = ResolvedAttribute(
            proj_dir._res_opt, CdmTypeAttributeDefinition(corpus.ctx, '16'),
            '16', None)
        p17 = ProjectionAttributeState(corpus.ctx)
        p17._current_resolved_attribute = ResolvedAttribute(
            proj_dir._res_opt, CdmTypeAttributeDefinition(corpus.ctx, '17'),
            '17', None)

        p1._previous_state_list = []
        p2._previous_state_list = []
        p4._previous_state_list = []
        p5._previous_state_list = []
        p6._previous_state_list = []
        p7._previous_state_list = []
        p8._previous_state_list = []
        p9._previous_state_list = []
        p10._previous_state_list = []
        p11._previous_state_list = []
        p12._previous_state_list = []
        p13._previous_state_list = []
        p14._previous_state_list = []
        p15._previous_state_list = []
        p16._previous_state_list = []
        p17._previous_state_list = []

        p11._previous_state_list.append(p7)
        p7._previous_state_list.append(p2)
        p2._previous_state_list.append(p1)
        p12._previous_state_list.append(p8)
        p8._previous_state_list.append(p1)
        p13._previous_state_list.append(p9)
        p9._previous_state_list.append(p4)
        p9._previous_state_list.append(p5)
        p13._previous_state_list.append(p10)
        p10._previous_state_list.append(p6)
        p14._previous_state_list.append(p16)
        p16._previous_state_list.append(p1)
        p15._previous_state_list.append(p7)
        p17._previous_state_list.append(p8)

        pc._current_attribute_state_set._add(p11)
        pc._current_attribute_state_set._add(p12)
        pc._current_attribute_state_set._add(p13)
        pc._current_attribute_state_set._add(p14)
        pc._current_attribute_state_set._add(p15)
        pc._current_attribute_state_set._add(p17)

        return pc