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
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))