/// <summary> /// Create a 3-level nested projection object /// </summary> /// <param name="corpus"></param> /// <returns></returns> private CdmProjection CreateNestedProjection(CdmCorpusDefinition corpus) { CdmProjection projection3 = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef); { projection3.Source = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, "TestSource", simpleNameRef: true); } CdmEntityReference inlineProjectionEntityRef3 = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null); inlineProjectionEntityRef3.ExplicitReference = projection3; CdmProjection projection2 = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef); { projection2.Source = inlineProjectionEntityRef3; } CdmEntityReference inlineProjectionEntityRef2 = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null); inlineProjectionEntityRef2.ExplicitReference = projection2; CdmProjection projection1 = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef); { projection1.Source = inlineProjectionEntityRef2; } return(projection1); }
public async Task TestEntityProjUsingObjectModel() { CdmCorpusDefinition corpus = ProjectionTestUtils.GetLocalCorpus(testsSubpath, "TestEntityProjUsingObjectModel"); corpus.Storage.Mount("local", new LocalAdapter(TestHelper.GetActualOutputFolderPath(testsSubpath, "TestEntityProjUsingObjectModel"))); CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local"); // Create an entity CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot); // Create a projection CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot); // Create an ArrayExpansion operation CdmOperationArrayExpansion arrayExpansionOp = corpus.MakeObject <CdmOperationArrayExpansion>(CdmObjectType.OperationArrayExpansionDef); arrayExpansionOp.StartOrdinal = 1; arrayExpansionOp.EndOrdinal = 2; projection.Operations.Add(arrayExpansionOp); // Create an entity reference to hold this projection CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null); projectionEntityRef.ExplicitReference = projection; // Create another projection that does a rename so that we can see the expanded attributes in the final resolved entity CdmProjection projection2 = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef); projection2.Source = projectionEntityRef; // Create a RenameAttributes operation CdmOperationRenameAttributes renameAttrsOp = corpus.MakeObject <CdmOperationRenameAttributes>(CdmObjectType.OperationRenameAttributesDef); renameAttrsOp.RenameFormat = "{m}{o}"; projection2.Operations.Add(renameAttrsOp); // Create an entity reference to hold this projection CdmEntityReference projectionEntityRef2 = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null); projectionEntityRef2.ExplicitReference = projection2; // Set the entity's ExtendEntity to be the projection entity.ExtendsEntity = projectionEntityRef2; // Resolve the entity CdmEntityDefinition resolvedEntity = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", null, localRoot); // Verify correctness of the resolved attributes after running the projections // Original set of attributes: ["id", "name", "value", "date"] // Expand 1...2, renameFormat = {m}{o} Assert.AreEqual(8, resolvedEntity.Attributes.Count); Assert.AreEqual("id1", (resolvedEntity.Attributes[0] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("name1", (resolvedEntity.Attributes[1] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("value1", (resolvedEntity.Attributes[2] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("date1", (resolvedEntity.Attributes[3] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("id2", (resolvedEntity.Attributes[4] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("name2", (resolvedEntity.Attributes[5] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("value2", (resolvedEntity.Attributes[6] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("date2", (resolvedEntity.Attributes[7] as CdmTypeAttributeDefinition).Name); }
/// <summary> /// Create a simple projection object /// </summary> /// <param name="projectionSourceName"></param> /// <returns></returns> public CdmProjection CreateProjection(string projectionSourceName) { CdmProjection projection = Corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef); projection.Source = Corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, projectionSourceName, simpleNameRef: true); return(projection); }
/// <summary> /// Create an inline entity reference for a projection /// </summary> /// <param name="projectionSourceName"></param> /// <returns></returns> public CdmEntityReference CreateProjectionInlineEntityReference(CdmProjection projection) { CdmEntityReference projectionInlineEntityRef = Corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null); projectionInlineEntityRef.ExplicitReference = projection; return(projectionInlineEntityRef); }
public async Task TestNestedProjUsingObjectModel() { CdmCorpusDefinition corpus = TestHelper.GetLocalCorpus(testsSubpath, "TestNestedProjUsingObjectModel"); corpus.Storage.Mount("local", new LocalAdapter(TestHelper.GetActualOutputFolderPath(testsSubpath, "TestNestedProjUsingObjectModel"))); CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local"); // Create an entity CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot); // Create a projection CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot); // Create an ExcludeAttributes operation CdmOperationExcludeAttributes excludeAttrsOp = corpus.MakeObject <CdmOperationExcludeAttributes>(CdmObjectType.OperationExcludeAttributesDef); excludeAttrsOp.ExcludeAttributes.Add("id"); excludeAttrsOp.ExcludeAttributes.Add("date"); projection.Operations.Add(excludeAttrsOp); // Create an entity reference to hold this projection CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null); projectionEntityRef.ExplicitReference = projection; // Create another projection that uses the previous projection as its source CdmProjection projection2 = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef); projection2.Source = projectionEntityRef; // Create an ExcludeAttributes operation CdmOperationExcludeAttributes excludeAttrsOp2 = corpus.MakeObject <CdmOperationExcludeAttributes>(CdmObjectType.OperationExcludeAttributesDef); excludeAttrsOp2.ExcludeAttributes.Add("value"); projection2.Operations.Add(excludeAttrsOp2); // Create an entity reference to hold this projection CdmEntityReference projectionEntityRef2 = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null); projectionEntityRef2.ExplicitReference = projection2; // Create an entity attribute that contains this projection and add this to the entity CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute"); entityAttribute.Entity = projectionEntityRef2; entity.Attributes.Add(entityAttribute); // Resolve the entity CdmEntityDefinition resolvedEntity = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", null, localRoot); // Verify correctness of the resolved attributes after running the ExcludeAttributes operations // Original set of attributes: ["id", "name", "value", "date"] // Excluded attributes: ["id", "date"], ["value"] Assert.AreEqual(1, resolvedEntity.Attributes.Count); Assert.AreEqual("name", (resolvedEntity.Attributes[0] as CdmTypeAttributeDefinition).Name); }
/// <summary> /// Create a simple projection object /// </summary> /// <param name="corpus"></param> /// <returns></returns> private CdmProjection CreateProjection(CdmCorpusDefinition corpus) { CdmProjection projection = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef); { projection.Source = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, "TestSource", simpleNameRef: true); } return(projection); }
/// <summary> /// Applies the arrayExpansion operation to the entity attribute provided. /// It also takes care of applying a renameAttributes operation and optionally applying a addCountAttribute operation. /// </summary> /// <param name="entityAttr"></param> /// <param name="startOrdinal"></param> /// <param name="endOrdinal"></param> /// <param name="renameFormat"></param> /// <param name="countAttName"></param> static void ApplyArrayExpansion(CdmEntityAttributeDefinition entityAttr, int startOrdinal, int endOrdinal, string renameFormat, string countAttName) { var ctx = entityAttr.Ctx; CdmProjection projection = new CdmProjection(ctx) { Source = entityAttr.Entity, RunSequentially = true, // Link for the Condition property documentation. // https://docs.microsoft.com/en-us/common-data-model/sdk/convert-logical-entities-resolved-entities#condition Condition = "!normalized" }; entityAttr.Entity = new CdmEntityReference(ctx, projection, false); // Link for the ArrayExpansion operation documentation. // https://docs.microsoft.com/en-us/common-data-model/sdk/projections/arrayexpansion var arrExpansionOperation = new CdmOperationArrayExpansion(ctx) { StartOrdinal = startOrdinal, EndOrdinal = endOrdinal }; projection.Operations.Add(arrExpansionOperation); // 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". var renameAttrsOperation = new CdmOperationRenameAttributes(ctx) { RenameFormat = renameFormat }; projection.Operations.Add(renameAttrsOperation); if (countAttName != null) { var countAttribute = new CdmTypeAttributeDefinition(ctx, countAttName) { DataType = new 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. var addCountAttrOperation = new CdmOperationAddCountAttribute(ctx) { CountAttribute = countAttribute }; projection.Operations.Add(addCountAttrOperation); } }
/// <summary> /// Create a Combine Attribute Operation /// </summary> /// <returns></returns> public CdmOperationCombineAttributes CreateOperationCombineAttributes(CdmProjection projection, List <string> selectedAttributes, CdmTypeAttributeDefinition mergeIntoAttribute) { // CombineAttributes Operation CdmOperationCombineAttributes combineAttributesOp = new CdmOperationCombineAttributes(Corpus.Ctx) { Select = selectedAttributes, MergeInto = mergeIntoAttribute }; projection.Operations.Add(combineAttributesOp); return(combineAttributesOp); }
public async Task TestEAProjOM() { string className = "ProjectionIncludeTest"; string testName = "TestEAProjOM"; string entityName_RGB = "RGB"; List <TypeAttributeParam> attributeParams_RGB = new List <TypeAttributeParam>(); { attributeParams_RGB.Add(new TypeAttributeParam("Red", "string", "hasA")); attributeParams_RGB.Add(new TypeAttributeParam("Green", "string", "hasA")); attributeParams_RGB.Add(new TypeAttributeParam("Blue", "string", "hasA")); attributeParams_RGB.Add(new TypeAttributeParam("IsGrayscale", "boolean", "hasA")); } string entityName_Color = "Color"; List <TypeAttributeParam> attributeParams_Color = new List <TypeAttributeParam>(); { attributeParams_Color.Add(new TypeAttributeParam("ColorName", "string", "identifiedBy")); } List <string> includeAttributeNames = new List <string>() { "Red", "Green", "Blue" }; using (ProjectionOMTestUtil util = new ProjectionOMTestUtil(className, testName)) { CdmEntityDefinition entity_RGB = util.CreateBasicEntity(entityName_RGB, attributeParams_RGB); util.ValidateBasicEntity(entity_RGB, entityName_RGB, attributeParams_RGB); CdmEntityDefinition entity_Color = util.CreateBasicEntity(entityName_Color, attributeParams_Color); util.ValidateBasicEntity(entity_Color, entityName_Color, attributeParams_Color); CdmProjection projection_RGBColor = util.CreateProjection(entity_RGB.EntityName); CdmOperationIncludeAttributes operation_IncludeAttributes = util.CreateOperationInputAttributes(projection_RGBColor, includeAttributeNames); CdmEntityReference projectionEntityRef_RGBColor = util.CreateProjectionInlineEntityReference(projection_RGBColor); CdmEntityAttributeDefinition entityAttribute_RGBColor = util.CreateEntityAttribute("RGBColor", projectionEntityRef_RGBColor); entity_Color.Attributes.Add(entityAttribute_RGBColor); foreach (List <string> resOpts in resOptsCombinations) { await util.GetAndValidateResolvedEntity(entity_Color, resOpts); } await util.DefaultManifest.SaveAsAsync(util.ManifestDocName, saveReferenced : true); } }
/// <summary> /// Creates a projection /// </summary> public static CdmProjection CreateProjection(CdmCorpusDefinition corpus, CdmFolderDefinition localRoot) { // Create an entity reference to use as the source of the projection CdmEntityReference projectionSource = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null); projectionSource.ExplicitReference = CreateSourceEntity(corpus, localRoot); // Create the projection CdmProjection projection = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef); projection.Source = projectionSource; return(projection); }
/// <summary> /// Applies the arrayExpansion operation to the entity attribute provided. /// It also takes care of applying a renameAttributes operation and optionally applying a addCountAttribute operation. /// </summary> /// <param name="entityAttr"></param> /// <param name="startOrdinal"></param> /// <param name="endOrdinal"></param> /// <param name="renameFormat"></param> /// <param name="countAttName"></param> static void ApplyArrayExpansion(CdmEntityAttributeDefinition entityAttr, int startOrdinal, int endOrdinal, string renameFormat, string countAttName) { var ctx = entityAttr.Ctx; CdmProjection projection = new CdmProjection(ctx) { Source = entityAttr.Entity, RunSequentially = true, // Link for the Condition property documentation. // https://docs.microsoft.com/en-us/common-data-model/sdk/convert-logical-entities-resolved-entities#condition Condition = "!normalized" }; entityAttr.Entity = new CdmEntityReference(ctx, projection, false); // Link for the ArrayExpansion operation documentation. // https://docs.microsoft.com/en-us/common-data-model/sdk/projections/arrayexpansion var arrExpansionOperation = new CdmOperationArrayExpansion(ctx) { StartOrdinal = startOrdinal, EndOrdinal = endOrdinal }; projection.Operations.Add(arrExpansionOperation); // Link for the RenameAttributes operation documentation. // https://docs.microsoft.com/en-us/common-data-model/sdk/projections/renameattributes var renameAttrsOperation = new CdmOperationRenameAttributes(ctx) { RenameFormat = renameFormat }; projection.Operations.Add(renameAttrsOperation); if (countAttName != null) { var countAttribute = new CdmTypeAttributeDefinition(ctx, countAttName) { DataType = new CdmDataTypeReference(ctx, "integer", true) }; // Link for the AddCountAttribute operation documentation. // https://docs.microsoft.com/en-us/common-data-model/sdk/projections/addcountattribute var addCountAttrOperation = new CdmOperationAddCountAttribute(ctx) { CountAttribute = countAttribute }; projection.Operations.Add(addCountAttrOperation); } }
/// <summary> /// Create an Input Attribute Operation /// </summary> /// <returns></returns> public CdmOperationIncludeAttributes CreateOperationInputAttributes(CdmProjection projection, List <string> includeAttributes) { // IncludeAttributes Operation CdmOperationIncludeAttributes includeAttributesOp = new CdmOperationIncludeAttributes(Corpus.Ctx) { IncludeAttributes = new List <string>() }; foreach (string includeAttribute in includeAttributes) { includeAttributesOp.IncludeAttributes.Add(includeAttribute); } projection.Operations.Add(includeAttributesOp); return(includeAttributesOp); }
/// <summary> /// Applies the replaceAsForeignKey and addAttributeGroup operations to the entity attribute provided. /// </summary> /// <param name="entityAttr"></param> /// <param name="fkAttrName"></param> /// <param name="attrGroupName"></param> static void ApplyDefaultBehavior(CdmEntityAttributeDefinition entityAttr, string fkAttrName, string attrGroupName) { var ctx = entityAttr.Ctx; CdmProjection projection = new CdmProjection(ctx) { // Link for the Source property documentation. // https://docs.microsoft.com/en-us/common-data-model/sdk/convert-logical-entities-resolved-entities#source Source = entityAttr.Entity, // Link for the RunSequentially property documentation. // https://docs.microsoft.com/en-us/common-data-model/sdk/convert-logical-entities-resolved-entities#run-sequentially RunSequentially = true }; entityAttr.Entity = new CdmEntityReference(ctx, projection, false); if (fkAttrName != null) { var foreignKeyAttr = new CdmTypeAttributeDefinition(ctx, fkAttrName) { DataType = new CdmDataTypeReference(ctx, "entityId", true) }; // Link for the ReplaceAsForeignKey operation documentation. // https://docs.microsoft.com/en-us/common-data-model/sdk/projections/replaceasforeignkey var replaceAsFKOperation = new CdmOperationReplaceAsForeignKey(ctx) { Condition = "referenceOnly", Reference = "addressLine", ReplaceWith = foreignKeyAttr }; projection.Operations.Add(replaceAsFKOperation); } if (attrGroupName != null) { // Link for the AddAttributeGroup operation documentation. // https://docs.microsoft.com/en-us/common-data-model/sdk/projections/addattributegroup var addAttrGroupOperation = new CdmOperationAddAttributeGroup(ctx) { Condition = "structured", AttributeGroupName = attrGroupName }; projection.Operations.Add(addAttrGroupOperation); } }
public async Task TestEntityAttributeProjUsingObjectModel() { CdmCorpusDefinition corpus = ProjectionTestUtils.GetLocalCorpus(testsSubpath, "TestEntityAttributeProjUsingObjectModel"); corpus.Storage.Mount("local", new LocalAdapter(TestHelper.GetActualOutputFolderPath(testsSubpath, "TestEntityAttributeProjUsingObjectModel"))); CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local"); // Create an entity CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot); // Create a projection CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot); // Create an AddTypeAttribute operation CdmOperationAddTypeAttribute addTypeAttrOp = corpus.MakeObject <CdmOperationAddTypeAttribute>(CdmObjectType.OperationAddTypeAttributeDef); addTypeAttrOp.TypeAttribute = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, "testType"); addTypeAttrOp.TypeAttribute.DataType = corpus.MakeRef <CdmDataTypeReference>(CdmObjectType.DataTypeRef, "entityName", true); projection.Operations.Add(addTypeAttrOp); // Create an entity reference to hold this projection CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null); projectionEntityRef.ExplicitReference = projection; // Create an entity attribute that contains this projection and add this to the entity CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute"); entityAttribute.Entity = projectionEntityRef; entity.Attributes.Add(entityAttribute); // Resolve the entity CdmEntityDefinition resolvedEntity = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", null, localRoot); // Verify correctness of the resolved attributes after running the AddTypeAttribute operation // Original set of attributes: ["id", "name", "value", "date"] // Type attribute: "testType" Assert.AreEqual(5, resolvedEntity.Attributes.Count); Assert.AreEqual("id", (resolvedEntity.Attributes[0] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("name", (resolvedEntity.Attributes[1] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("value", (resolvedEntity.Attributes[2] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("date", (resolvedEntity.Attributes[3] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("testType", (resolvedEntity.Attributes[4] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("is.linkedEntity.name", resolvedEntity.Attributes[4].AppliedTraits[4].NamedReference); }
public void TestEntityAttributeSource() { CdmCorpusDefinition corpus = new CdmCorpusDefinition(); int errorCount = 0; corpus.SetEventCallback(new EventCallback() { Invoke = (level, message) => { errorCount++; } }, CdmStatusLevel.Error); CdmProjection projection = new CdmProjection(corpus.Ctx); CdmEntityAttributeDefinition _ = new CdmEntityAttributeDefinition(corpus.Ctx, "attribute") { Entity = new CdmEntityReference(corpus.Ctx, projection, false) }; // First case, a projection without source. projection.Validate(); Assert.AreEqual(1, errorCount); errorCount = 0; // Second case, a projection with a nested projection. CdmProjection innerProjection = new CdmProjection(corpus.Ctx); projection.Source = new CdmEntityReference(corpus.Ctx, innerProjection, false); projection.Validate(); innerProjection.Validate(); Assert.AreEqual(1, errorCount); errorCount = 0; // Third case, a projection with an explicit entity definition. innerProjection.Source = new CdmEntityReference(corpus.Ctx, new CdmEntityDefinition(corpus.Ctx, "Entity"), false); projection.Validate(); innerProjection.Validate(); Assert.AreEqual(0, errorCount); // Third case, a projection with a named reference. innerProjection.Source = new CdmEntityReference(corpus.Ctx, "Entity", false); projection.Validate(); innerProjection.Validate(); Assert.AreEqual(0, errorCount); }
public async Task TestEntityAttributeProjUsingObjectModel() { string testName = "TestEntityAttributeProjUsingObjectModel"; CdmCorpusDefinition corpus = ProjectionTestUtils.GetCorpus(testName, testsSubpath); CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local"); // Create an entity CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot); // Create a projection CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot); // Create an AddAttributeGroup operation CdmOperationAddAttributeGroup addAttGroupOp = corpus.MakeObject <CdmOperationAddAttributeGroup>(CdmObjectType.OperationAddAttributeGroupDef); addAttGroupOp.AttributeGroupName = "PersonAttributeGroup"; projection.Operations.Add(addAttGroupOp); // Create an entity reference to hold this projection CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null); projectionEntityRef.ExplicitReference = projection; // Create an entity attribute that contains this projection and add this to the entity CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute"); entityAttribute.Entity = projectionEntityRef; entity.Attributes.Add(entityAttribute); // Resolve the entity. CdmEntityDefinition resolvedEntity = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", null, localRoot); // Verify correctness of the resolved attributes after running the AddAttributeGroup operation // Original set of attributes: ["id", "name", "value", "date"] CdmAttributeGroupDefinition attGroupDefinition = this.ValidateAttributeGroup(resolvedEntity.Attributes, "PersonAttributeGroup"); Assert.AreEqual(4, attGroupDefinition.Members.Count); Assert.AreEqual("id", (attGroupDefinition.Members[0] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("name", (attGroupDefinition.Members[1] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("value", (attGroupDefinition.Members[2] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("date", (attGroupDefinition.Members[3] as CdmTypeAttributeDefinition).Name); }
public async Task TestEntityProjUsingObjectModel() { CdmCorpusDefinition corpus = TestHelper.GetLocalCorpus(testsSubpath, "TestEntityProjUsingObjectModel"); corpus.Storage.Mount("local", new LocalAdapter(TestHelper.GetActualOutputFolderPath(testsSubpath, "TestEntityProjUsingObjectModel"))); CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local"); // Create an entity CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot); // Create a projection CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot); // Create an ExcludeAttributes operation CdmOperationExcludeAttributes excludeAttrsOp = corpus.MakeObject <CdmOperationExcludeAttributes>(CdmObjectType.OperationExcludeAttributesDef); excludeAttrsOp.ExcludeAttributes = new List <string>() { "name", "value" }; projection.Operations.Add(excludeAttrsOp); // Create an entity reference to hold this projection CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null); projectionEntityRef.ExplicitReference = projection; // Set the entity's ExtendEntity to be the projection entity.ExtendsEntity = projectionEntityRef; // Resolve the entity CdmEntityDefinition resolvedEntity = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", null, localRoot); // Verify correctness of the resolved attributes after running the ExcludeAttributes operation // Original set of attributes: ["id", "name", "value", "date"] // Excluded attributes: ["name", "value"] Assert.AreEqual(2, resolvedEntity.Attributes.Count); Assert.AreEqual("id", (resolvedEntity.Attributes[0] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("date", (resolvedEntity.Attributes[1] as CdmTypeAttributeDefinition).Name); }
public static Projection ToData(CdmProjection instance, ResolveOptions resOpt, CopyOptions options) { if (instance == null) { return(null); } dynamic source = null; if (instance.Source != null && instance.Source.GetType() == typeof(string)) { source = instance.Source; } else if (instance.Source != null && !string.IsNullOrWhiteSpace(instance.Source.NamedReference) && instance.Source.ExplicitReference == null) { source = instance.Source.NamedReference; } else if (instance.Source != null && instance.Source.GetType() == typeof(CdmEntityReference)) { source = EntityReferencePersistence.ToData(instance.Source, resOpt, options); } List <OperationBase> operations = null; if (instance.Operations != null && instance.Operations.Count > 0) { operations = new List <OperationBase>(); foreach (CdmOperationBase operation in instance.Operations) { switch (operation.ObjectType) { case CdmObjectType.OperationAddCountAttributeDef: OperationAddCountAttribute addCountAttributeOp = OperationAddCountAttributePersistence.ToData(operation as CdmOperationAddCountAttribute, resOpt, options); operations.Add(addCountAttributeOp); break; case CdmObjectType.OperationAddSupportingAttributeDef: OperationAddSupportingAttribute addSupportingAttributeOp = OperationAddSupportingAttributePersistence.ToData(operation as CdmOperationAddSupportingAttribute, resOpt, options); operations.Add(addSupportingAttributeOp); break; case CdmObjectType.OperationAddTypeAttributeDef: OperationAddTypeAttribute addTypeAttributeOp = OperationAddTypeAttributePersistence.ToData(operation as CdmOperationAddTypeAttribute, resOpt, options); operations.Add(addTypeAttributeOp); break; case CdmObjectType.OperationExcludeAttributesDef: OperationExcludeAttributes excludeAttributesOp = OperationExcludeAttributesPersistence.ToData(operation as CdmOperationExcludeAttributes, resOpt, options); operations.Add(excludeAttributesOp); break; case CdmObjectType.OperationArrayExpansionDef: OperationArrayExpansion arrayExpansionOp = OperationArrayExpansionPersistence.ToData(operation as CdmOperationArrayExpansion, resOpt, options); operations.Add(arrayExpansionOp); break; case CdmObjectType.OperationCombineAttributesDef: OperationCombineAttributes combineAttributesOp = OperationCombineAttributesPersistence.ToData(operation as CdmOperationCombineAttributes, resOpt, options); operations.Add(combineAttributesOp); break; case CdmObjectType.OperationRenameAttributesDef: OperationRenameAttributes renameAttributesOp = OperationRenameAttributesPersistence.ToData(operation as CdmOperationRenameAttributes, resOpt, options); operations.Add(renameAttributesOp); break; case CdmObjectType.OperationReplaceAsForeignKeyDef: OperationReplaceAsForeignKey replaceAsForeignKeyOp = OperationReplaceAsForeignKeyPersistence.ToData(operation as CdmOperationReplaceAsForeignKey, resOpt, options); operations.Add(replaceAsForeignKeyOp); break; case CdmObjectType.OperationIncludeAttributesDef: OperationIncludeAttributes includeAttributesOp = OperationIncludeAttributesPersistence.ToData(operation as CdmOperationIncludeAttributes, resOpt, options); operations.Add(includeAttributesOp); break; case CdmObjectType.OperationAddAttributeGroupDef: OperationAddAttributeGroup addAttributeGroupOp = OperationAddAttributeGroupPersistence.ToData(operation as CdmOperationAddAttributeGroup, resOpt, options); operations.Add(addAttributeGroupOp); break; default: OperationBase baseOp = new OperationBase(); baseOp.Type = OperationTypeConvertor.OperationTypeToString(CdmOperationType.Error); operations.Add(baseOp); break; } } } return(new Projection { Explanation = instance.Explanation, Source = source, Operations = operations, Condition = instance.Condition, RunSequentially = instance.RunSequentially }); }
public async Task TestConditionalProjUsingObjectModel() { CdmCorpusDefinition corpus = ProjectionTestUtils.GetLocalCorpus(testsSubpath, "TestConditionalProjUsingObjectModel"); corpus.Storage.Mount("local", new LocalAdapter(TestHelper.GetActualOutputFolderPath(testsSubpath, "TestConditionalProjUsingObjectModel"))); CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local"); // Create an entity CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot); // Create a projection with a condition that states the operation should only execute when the resolution directive is 'referenceOnly' CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot); projection.Condition = "referenceOnly==true"; // Create an AddTypeAttribute operation CdmOperationAddTypeAttribute addTypeAttrOp = corpus.MakeObject <CdmOperationAddTypeAttribute>(CdmObjectType.OperationAddTypeAttributeDef); addTypeAttrOp.TypeAttribute = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, "testType"); addTypeAttrOp.TypeAttribute.DataType = corpus.MakeRef <CdmDataTypeReference>(CdmObjectType.DataTypeRef, "entityName", true); projection.Operations.Add(addTypeAttrOp); // Create an entity reference to hold this projection CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null); projectionEntityRef.ExplicitReference = projection; // Create an entity attribute that contains this projection and add this to the entity CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute"); entityAttribute.Entity = projectionEntityRef; entity.Attributes.Add(entityAttribute); // Create resolution options with the 'referenceOnly' directive ResolveOptions resOpt = new ResolveOptions(entity.InDocument); resOpt.Directives = new AttributeResolutionDirectiveSet(new HashSet <string> { "referenceOnly" }); // Resolve the entity with 'referenceOnly' CdmEntityDefinition resolvedEntityWithReferenceOnly = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot); // Verify correctness of the resolved attributes after running the AddTypeAttribute operation // Original set of attributes: ["id", "name", "value", "date"] // Type attribute: "testType" Assert.AreEqual(5, resolvedEntityWithReferenceOnly.Attributes.Count); Assert.AreEqual("id", (resolvedEntityWithReferenceOnly.Attributes[0] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("name", (resolvedEntityWithReferenceOnly.Attributes[1] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("value", (resolvedEntityWithReferenceOnly.Attributes[2] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("date", (resolvedEntityWithReferenceOnly.Attributes[3] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("testType", (resolvedEntityWithReferenceOnly.Attributes[4] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("is.linkedEntity.name", resolvedEntityWithReferenceOnly.Attributes[4].AppliedTraits[4].NamedReference); // Now resolve the entity with the 'structured' directive resOpt.Directives = new AttributeResolutionDirectiveSet(new HashSet <string> { "structured" }); CdmEntityDefinition resolvedEntityWithStructured = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot); // Verify correctness of the resolved attributes after running the AddTypeAttribute operation // Original set of attributes: ["id", "name", "value", "date"] // No Type attribute added, condition was false Assert.AreEqual(4, resolvedEntityWithStructured.Attributes.Count); Assert.AreEqual("id", (resolvedEntityWithStructured.Attributes[0] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("name", (resolvedEntityWithStructured.Attributes[1] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("value", (resolvedEntityWithStructured.Attributes[2] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("date", (resolvedEntityWithStructured.Attributes[3] as CdmTypeAttributeDefinition).Name); }
/// <summary> /// Create a projection object with operations /// </summary> /// <param name="corpus"></param> /// <returns></returns> private CdmProjection CreateProjectionWithOperationCollection(CdmCorpusDefinition corpus, CdmObject owner) { CdmProjection projection = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef); { projection.Source = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, "TestSource", simpleNameRef: true); } { // AddCountAttribute Operation CdmOperationAddCountAttribute addCountAttributeOp = new CdmOperationAddCountAttribute(corpus.Ctx) { CountAttribute = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef) }; projection.Operations.Add(addCountAttributeOp); // AddSupportingAttribute Operation CdmOperationAddSupportingAttribute addSupportingAttributesOp = new CdmOperationAddSupportingAttribute(corpus.Ctx) { SupportingAttribute = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef) }; projection.Operations.Add(addSupportingAttributesOp); // AddTypeAttribute Operation CdmOperationAddTypeAttribute addTypeAttributeOp = new CdmOperationAddTypeAttribute(corpus.Ctx) { TypeAttribute = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef) }; projection.Operations.Add(addTypeAttributeOp); // ExcludeAttributes Operation CdmOperationExcludeAttributes excludeAttributesOp = new CdmOperationExcludeAttributes(corpus.Ctx) { ExcludeAttributes = new List <string>() }; excludeAttributesOp.ExcludeAttributes.Add("testAttribute1"); projection.Operations.Add(excludeAttributesOp); // ArrayExpansion Operation CdmOperationArrayExpansion arrayExpansionOp = new CdmOperationArrayExpansion(corpus.Ctx) { StartOrdinal = 0, EndOrdinal = 1 }; projection.Operations.Add(arrayExpansionOp); // CombineAttributes Operation CdmOperationCombineAttributes combineAttributesOp = new CdmOperationCombineAttributes(corpus.Ctx) { Take = new List <string>(), MergeInto = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef) }; combineAttributesOp.Take.Add("testAttribute1"); projection.Operations.Add(combineAttributesOp); // RenameAttributes Operation CdmOperationRenameAttributes renameAttributesOp = new CdmOperationRenameAttributes(corpus.Ctx) { RenameFormat = "{m}" }; projection.Operations.Add(renameAttributesOp); // ReplaceAsForeignKey Operation CdmOperationReplaceAsForeignKey replaceAsForeignKeyOp = new CdmOperationReplaceAsForeignKey(corpus.Ctx) { Reference = "testAttribute1", ReplaceWith = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, "testForeignKey", simpleNameRef: false) }; projection.Operations.Add(replaceAsForeignKeyOp); // IncludeAttributes Operation CdmOperationIncludeAttributes includeAttributesOp = new CdmOperationIncludeAttributes(corpus.Ctx) { IncludeAttributes = new List <string>() }; includeAttributesOp.IncludeAttributes.Add("testAttribute1"); projection.Operations.Add(includeAttributesOp); } return(projection); }
public async Task TestConditionalProjUsingObjectModel() { string testName = nameof(TestConditionalProjUsingObjectModel); CdmCorpusDefinition corpus = TestHelper.GetLocalCorpus(testsSubpath, testName); CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local"); corpus.Storage.Mount("traitGroup", new LocalAdapter(traitGroupFilePath)); // Create an entity. CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot); entity.InDocument.Imports.Add("traitGroup:/TraitGroup.cdm.json"); // Create a projection with a condition that states the operation should only execute when the resolution directive is 'structured'. CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot); projection.Condition = "structured==true"; projection.RunSequentially = true; // Create an AlterTraits operation CdmOperationAlterTraits alterTraitsOp_1 = corpus.MakeObject <CdmOperationAlterTraits>(CdmObjectType.OperationAlterTraitsDef); alterTraitsOp_1.TraitsToAdd = new CdmCollection <CdmTraitReferenceBase>(corpus.Ctx, alterTraitsOp_1, CdmObjectType.TraitRef); alterTraitsOp_1.TraitsToAdd.Add(corpus.MakeRef <CdmTraitReference>(CdmObjectType.TraitRef, "means.TraitG100", true)); alterTraitsOp_1.TraitsToAdd.Add(corpus.MakeRef <CdmTraitGroupReference>(CdmObjectType.TraitGroupRef, "JobTitleBase", true)); alterTraitsOp_1.TraitsToRemove = new CdmCollection <CdmTraitReferenceBase>(corpus.Ctx, alterTraitsOp_1, CdmObjectType.TraitRef); alterTraitsOp_1.TraitsToRemove.Add(corpus.MakeRef <CdmTraitReference>(CdmObjectType.TraitRef, "means.TraitG300", true)); projection.Operations.Add(alterTraitsOp_1); CdmOperationAlterTraits alterTraitsOp_2 = corpus.MakeObject <CdmOperationAlterTraits>(CdmObjectType.OperationAlterTraitsDef); var traitG4 = corpus.MakeRef <CdmTraitReference>(CdmObjectType.TraitRef, "means.TraitG4", true); traitG4.Arguments.Add("precision", "5"); traitG4.Arguments.Add("scale", "15"); alterTraitsOp_2.TraitsToAdd = new CdmCollection <CdmTraitReferenceBase>(corpus.Ctx, alterTraitsOp_2, CdmObjectType.TraitRef); alterTraitsOp_2.TraitsToAdd.Add(traitG4); alterTraitsOp_2.ApplyTo = new List <string>() { "name" }; projection.Operations.Add(alterTraitsOp_2); // Create an entity reference to hold this projection. CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null); projectionEntityRef.ExplicitReference = projection; // Create an entity attribute that contains this projection and add this to the entity. CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute"); entityAttribute.Entity = projectionEntityRef; entity.Attributes.Add(entityAttribute); // Create resolution options with the 'referenceOnly' directive. ResolveOptions resOpt = new ResolveOptions(entity.InDocument) { Directives = new AttributeResolutionDirectiveSet(new HashSet <string> { "referenceOnly" }) }; CdmEntityDefinition resolvedEntityWithReferenceOnly = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot); // Original set of attributes: ["name", "age", "address", "phoneNumber", "email"] // Condition not met, no traits are added Assert.AreEqual(4, resolvedEntityWithReferenceOnly.Attributes.Count); ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithReferenceOnly.Attributes[0], "id", doesNotExist: true); ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithReferenceOnly.Attributes[1], "name", doesNotExist: true); ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithReferenceOnly.Attributes[2], "value", doesNotExist: true); ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithReferenceOnly.Attributes[3], "date", doesNotExist: true); CdmEntityDefinition resolvedEntityWithStructured = await ProjectionTestUtils.GetResolvedEntity(corpus, entity, new List <string> { "structured" }); // Original set of attributes: ["name", "age", "address", "phoneNumber", "email"] // Condition met, new traits are added Assert.AreEqual(4, resolvedEntityWithStructured.Attributes.Count); ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithStructured.Attributes[0], "id"); ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithStructured.Attributes[1], "name", true); ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithStructured.Attributes[2], "value"); ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithStructured.Attributes[3], "date"); }
public static CdmEntityAttributeDefinition FromData(CdmCorpusContext ctx, JToken obj) { var entityAttribute = ctx.Corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, (string)obj["name"]); entityAttribute.Description = Utils.PropertyFromDataToString(obj["description"]); entityAttribute.DisplayName = Utils.PropertyFromDataToString(obj["displayName"]); entityAttribute.Explanation = Utils.PropertyFromDataToString(obj["explanation"]); if (obj["cardinality"] != null) { string minCardinality = null; if (obj["cardinality"]["minimum"] != null) { minCardinality = (string)obj["cardinality"]["minimum"]; } string maxCardinality = null; if (obj["cardinality"]["maximum"] != null) { maxCardinality = (string)obj["cardinality"]["maximum"]; } if (string.IsNullOrWhiteSpace(minCardinality) || string.IsNullOrWhiteSpace(maxCardinality)) { Logger.Error(nameof(EntityAttributePersistence), ctx, $"Both minimum and maximum are required for the Cardinality property.", nameof(FromData)); } if (!CardinalitySettings.IsMinimumValid(minCardinality)) { Logger.Error(nameof(EntityAttributePersistence), ctx, $"Invalid minimum cardinality {minCardinality}.", nameof(FromData)); } if (!CardinalitySettings.IsMaximumValid(maxCardinality)) { Logger.Error(nameof(EntityAttributePersistence), ctx, $"Invalid maximum cardinality {maxCardinality}.", nameof(FromData)); } if (!string.IsNullOrWhiteSpace(minCardinality) && !string.IsNullOrWhiteSpace(maxCardinality) && CardinalitySettings.IsMinimumValid(minCardinality) && CardinalitySettings.IsMinimumValid(maxCardinality)) { entityAttribute.Cardinality = new CardinalitySettings(entityAttribute) { Minimum = minCardinality, Maximum = maxCardinality }; } } entityAttribute.IsPolymorphicSource = (bool?)obj["isPolymorphicSource"]; bool isProjection = obj["entity"] != null && !(obj["entity"] is JValue) && obj["entity"]["source"] != null; if (isProjection) { CdmProjection projection = ProjectionPersistence.FromData(ctx, obj["entity"]); projection.Owner = entityAttribute; CdmEntityReference inlineEntityRef = ctx.Corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null); inlineEntityRef.ExplicitReference = projection; entityAttribute.Entity = inlineEntityRef; } else { entityAttribute.Entity = EntityReferencePersistence.FromData(ctx, obj["entity"]); } entityAttribute.Purpose = PurposeReferencePersistence.FromData(ctx, obj["purpose"]); Utils.AddListToCdmCollection(entityAttribute.AppliedTraits, Utils.CreateTraitReferenceList(ctx, obj["appliedTraits"])); // ignore resolution guidance if the entity is a projection if (obj["resolutionGuidance"] != null && isProjection) { Logger.Error(nameof(EntityAttributePersistence), ctx, $"The EntityAttribute {entityAttribute.Name} is projection based. Resolution guidance is not supported with a projection."); } else { entityAttribute.ResolutionGuidance = AttributeResolutionGuidancePersistence.FromData(ctx, obj["resolutionGuidance"]); } return(entityAttribute); }
public async Task TestConditionalProjUsingObjectModel() { string testName = nameof(TestConditionalProjUsingObjectModel); CdmCorpusDefinition corpus = TestHelper.GetLocalCorpus(testsSubpath, testName); CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local"); // Create an entity. CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot); // Create a projection with a condition that states the operation should only execute when the resolution directive is 'structured'. CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot); projection.Condition = "structured==true"; // Create an AddArtifactAttribute operation CdmOperationAddArtifactAttribute addArtifactAttributeOp = corpus.MakeObject <CdmOperationAddArtifactAttribute>(CdmObjectType.OperationAddArtifactAttributeDef); addArtifactAttributeOp.NewAttribute = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, "newName"); ((CdmTypeAttributeDefinition)addArtifactAttributeOp.NewAttribute).DataType = corpus.MakeRef <CdmDataTypeReference>(CdmObjectType.DataTypeRef, "string", true); projection.Operations.Add(addArtifactAttributeOp); // Create an entity reference to hold this projection. CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null); projectionEntityRef.ExplicitReference = projection; // Create an entity attribute that contains this projection and add this to the entity. CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute"); entityAttribute.Entity = projectionEntityRef; entity.Attributes.Add(entityAttribute); // Create resolution options with the 'referenceOnly' directive. ResolveOptions resOpt = new ResolveOptions(entity.InDocument) { Directives = new AttributeResolutionDirectiveSet(new HashSet <string> { "referenceOnly" }) }; // Resolve the entity with 'referenceOnly' CdmEntityDefinition resolvedEntityWithReferenceOnly = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot); // Original set of attributes: ["id", "name", "value", "date"] // Condition not met, keep attributes in flat list Assert.AreEqual(4, resolvedEntityWithReferenceOnly.Attributes.Count); Assert.AreEqual("id", (resolvedEntityWithReferenceOnly.Attributes[0] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("name", (resolvedEntityWithReferenceOnly.Attributes[1] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("value", (resolvedEntityWithReferenceOnly.Attributes[2] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("date", (resolvedEntityWithReferenceOnly.Attributes[3] as CdmTypeAttributeDefinition).Name); // Now resolve the entity with the 'structured' directive resOpt.Directives = new AttributeResolutionDirectiveSet(new HashSet <string> { "structured" }); CdmEntityDefinition resolvedEntityWithStructured = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot); // Original set of attributes: ["id", "name", "value", "date"] // Condition met, keep attributes in flat list and add the new attribute "newName" all attributes at the end Assert.AreEqual(5, resolvedEntityWithStructured.Attributes.Count); Assert.AreEqual("id", (resolvedEntityWithStructured.Attributes[0] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("name", (resolvedEntityWithStructured.Attributes[1] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("value", (resolvedEntityWithStructured.Attributes[2] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("date", (resolvedEntityWithStructured.Attributes[3] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("newName", (resolvedEntityWithStructured.Attributes[4] as CdmTypeAttributeDefinition).Name); }
public async Task TestConditionalProjUsingObjectModel() { CdmCorpusDefinition corpus = ProjectionTestUtils.GetLocalCorpus(testsSubpath, "TestConditionalProjUsingObjectModel"); corpus.Storage.Mount("local", new LocalAdapter(TestHelper.GetActualOutputFolderPath(testsSubpath, "TestConditionalProjUsingObjectModel"))); CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local"); // Create an entity CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot); // Create a projection with a condition that states the operation should only execute when the resolution directive is 'referenceOnly' CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot); projection.Condition = "referenceOnly==true"; // Create an ArrayExpansion operation CdmOperationArrayExpansion arrayExpansionOp = corpus.MakeObject <CdmOperationArrayExpansion>(CdmObjectType.OperationArrayExpansionDef); arrayExpansionOp.StartOrdinal = 1; arrayExpansionOp.EndOrdinal = 2; projection.Operations.Add(arrayExpansionOp); // Create an entity reference to hold this projection CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null); projectionEntityRef.ExplicitReference = projection; // Create another projection that does a rename so that we can see the expanded attributes in the final resolved entity CdmProjection projection2 = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef); projection2.Source = projectionEntityRef; // Create a RenameAttributes operation CdmOperationRenameAttributes renameAttrsOp = corpus.MakeObject <CdmOperationRenameAttributes>(CdmObjectType.OperationRenameAttributesDef); renameAttrsOp.RenameFormat = "{m}{o}"; projection2.Operations.Add(renameAttrsOp); // Create an entity reference to hold this projection CdmEntityReference projectionEntityRef2 = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null); projectionEntityRef2.ExplicitReference = projection2; // Create an entity attribute that contains this projection and add this to the entity CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute"); entityAttribute.Entity = projectionEntityRef2; entity.Attributes.Add(entityAttribute); // Create resolution options with the 'referenceOnly' directive ResolveOptions resOpt = new ResolveOptions(entity.InDocument); resOpt.Directives = new AttributeResolutionDirectiveSet(new HashSet <string> { "referenceOnly" }); // Resolve the entity with 'referenceOnly' CdmEntityDefinition resolvedEntityWithReferenceOnly = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot); // Verify correctness of the resolved attributes after running the projections // Original set of attributes: ["id", "name", "value", "date"] // Expand 1...2, renameFormat = {m}{o} Assert.AreEqual(8, resolvedEntityWithReferenceOnly.Attributes.Count); Assert.AreEqual("id1", (resolvedEntityWithReferenceOnly.Attributes[0] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("name1", (resolvedEntityWithReferenceOnly.Attributes[1] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("value1", (resolvedEntityWithReferenceOnly.Attributes[2] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("date1", (resolvedEntityWithReferenceOnly.Attributes[3] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("id2", (resolvedEntityWithReferenceOnly.Attributes[4] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("name2", (resolvedEntityWithReferenceOnly.Attributes[5] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("value2", (resolvedEntityWithReferenceOnly.Attributes[6] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("date2", (resolvedEntityWithReferenceOnly.Attributes[7] as CdmTypeAttributeDefinition).Name); // Now resolve the entity with the default directives resOpt.Directives = new AttributeResolutionDirectiveSet(new HashSet <string> { }); CdmEntityDefinition resolvedEntityWithStructured = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot); // Verify correctness of the resolved attributes after running the projections // Original set of attributes: ["id", "name", "value", "date"] // Expand 1...2, renameFormat = {m}{o} Assert.AreEqual(4, resolvedEntityWithStructured.Attributes.Count); Assert.AreEqual("id", (resolvedEntityWithStructured.Attributes[0] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("name", (resolvedEntityWithStructured.Attributes[1] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("value", (resolvedEntityWithStructured.Attributes[2] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("date", (resolvedEntityWithStructured.Attributes[3] as CdmTypeAttributeDefinition).Name); }
public static CdmProjection FromData(CdmCorpusContext ctx, JToken obj) { if (obj == null) { return(null); } CdmProjection projection = ctx.Corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef); CdmEntityReference source = EntityReferencePersistence.FromData(ctx, obj["source"]); if (obj["explanation"] != null) { projection.Explanation = (string)obj["explanation"]; } projection.Condition = obj["condition"]?.ToString(); projection.RunSequentially = (bool?)obj["runSequentially"]; if (obj["operations"] != null) { List <JObject> operationJsons = obj["operations"]?.ToObject <List <JObject> >(); foreach (JObject operationJson in operationJsons) { string type = (string)operationJson["$type"]; switch (type) { case "addCountAttribute": CdmOperationAddCountAttribute addCountAttributeOp = OperationAddCountAttributePersistence.FromData(ctx, operationJson); projection.Operations.Add(addCountAttributeOp); break; case "addSupportingAttribute": CdmOperationAddSupportingAttribute addSupportingAttributeOp = OperationAddSupportingAttributePersistence.FromData(ctx, operationJson); projection.Operations.Add(addSupportingAttributeOp); break; case "addTypeAttribute": CdmOperationAddTypeAttribute addTypeAttributeOp = OperationAddTypeAttributePersistence.FromData(ctx, operationJson); projection.Operations.Add(addTypeAttributeOp); break; case "excludeAttributes": CdmOperationExcludeAttributes excludeAttributesOp = OperationExcludeAttributesPersistence.FromData(ctx, operationJson); projection.Operations.Add(excludeAttributesOp); break; case "arrayExpansion": CdmOperationArrayExpansion arrayExpansionOp = OperationArrayExpansionPersistence.FromData(ctx, operationJson); projection.Operations.Add(arrayExpansionOp); break; case "combineAttributes": CdmOperationCombineAttributes combineAttributesOp = OperationCombineAttributesPersistence.FromData(ctx, operationJson); projection.Operations.Add(combineAttributesOp); break; case "renameAttributes": CdmOperationRenameAttributes renameAttributesOp = OperationRenameAttributesPersistence.FromData(ctx, operationJson); projection.Operations.Add(renameAttributesOp); break; case "replaceAsForeignKey": CdmOperationReplaceAsForeignKey replaceAsForeignKeyOp = OperationReplaceAsForeignKeyPersistence.FromData(ctx, operationJson); projection.Operations.Add(replaceAsForeignKeyOp); break; case "includeAttributes": CdmOperationIncludeAttributes includeAttributesOp = OperationIncludeAttributesPersistence.FromData(ctx, operationJson); projection.Operations.Add(includeAttributesOp); break; case "addAttributeGroup": CdmOperationAddAttributeGroup addAttributeGroupOp = OperationAddAttributeGroupPersistence.FromData(ctx, operationJson); projection.Operations.Add(addAttributeGroupOp); break; default: Logger.Error(nameof(ProjectionPersistence), ctx, $"Invalid operation type '{type}'.", nameof(FromData)); break; } } } projection.Source = source; return(projection); }
public async Task TestEAProjOM() { string className = "ProjectionCombineTest"; string testName = "TestEAProjOM"; string entityName_Email = "Email"; List <TypeAttributeParam> attributeParams_Email = new List <TypeAttributeParam>(); { attributeParams_Email.Add(new TypeAttributeParam("EmailID", "string", "identifiedBy")); attributeParams_Email.Add(new TypeAttributeParam("Address", "string", "hasA")); attributeParams_Email.Add(new TypeAttributeParam("IsPrimary", "boolean", "hasA")); } string entityName_Phone = "Phone"; List <TypeAttributeParam> attributeParams_Phone = new List <TypeAttributeParam>(); { attributeParams_Phone.Add(new TypeAttributeParam("PhoneID", "string", "identifiedBy")); attributeParams_Phone.Add(new TypeAttributeParam("Number", "string", "hasA")); attributeParams_Phone.Add(new TypeAttributeParam("IsPrimary", "boolean", "hasA")); } string entityName_Social = "Social"; List <TypeAttributeParam> attributeParams_Social = new List <TypeAttributeParam>(); { attributeParams_Social.Add(new TypeAttributeParam("SocialID", "string", "identifiedBy")); attributeParams_Social.Add(new TypeAttributeParam("Account", "string", "hasA")); attributeParams_Social.Add(new TypeAttributeParam("IsPrimary", "boolean", "hasA")); } string entityName_Customer = "Customer"; List <TypeAttributeParam> attributeParams_Customer = new List <TypeAttributeParam>(); { attributeParams_Customer.Add(new TypeAttributeParam("CustomerName", "string", "hasA")); } List <string> selectedAttributes = new List <string>() { "EmailID", "PhoneID", "SocialID" }; using (ProjectionOMTestUtil util = new ProjectionOMTestUtil(className, testName)) { CdmEntityDefinition entity_Email = util.CreateBasicEntity(entityName_Email, attributeParams_Email); util.ValidateBasicEntity(entity_Email, entityName_Email, attributeParams_Email); CdmEntityDefinition entity_Phone = util.CreateBasicEntity(entityName_Phone, attributeParams_Phone); util.ValidateBasicEntity(entity_Phone, entityName_Phone, attributeParams_Phone); CdmEntityDefinition entity_Social = util.CreateBasicEntity(entityName_Social, attributeParams_Social); util.ValidateBasicEntity(entity_Social, entityName_Social, attributeParams_Social); CdmEntityDefinition entity_Customer = util.CreateBasicEntity(entityName_Customer, attributeParams_Customer); util.ValidateBasicEntity(entity_Customer, entityName_Customer, attributeParams_Customer); CdmProjection projection_Customer = util.CreateProjection(entity_Customer.EntityName); CdmTypeAttributeDefinition typeAttribute_MergeInto = util.CreateTypeAttribute("MergeInto", "string", "hasA"); CdmOperationCombineAttributes operation_CombineAttributes = util.CreateOperationCombineAttributes(projection_Customer, selectedAttributes, typeAttribute_MergeInto); CdmEntityReference projectionEntityRef_Customer = util.CreateProjectionInlineEntityReference(projection_Customer); CdmEntityAttributeDefinition entityAttribute_ContactAt = util.CreateEntityAttribute("ContactAt", projectionEntityRef_Customer); entity_Customer.Attributes.Add(entityAttribute_ContactAt); foreach (List <string> resOpts in resOptsCombinations) { await util.GetAndValidateResolvedEntity(entity_Customer, resOpts); } await util.DefaultManifest.SaveAsAsync(util.ManifestDocName, saveReferenced : true); } }
public async Task TestConditionalProjUsingObjectModel() { string testName = "TestConditionalProjUsingObjectModel"; CdmCorpusDefinition corpus = ProjectionTestUtils.GetCorpus(testName, testsSubpath); CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local"); // Create an entity. CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot); // Create a projection with a condition that states the operation should only execute when the resolution directive is 'structured'. CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot); projection.Condition = "structured==true"; // Create an AddAttributeGroup operation CdmOperationAddAttributeGroup addAttGroupOp = corpus.MakeObject <CdmOperationAddAttributeGroup>(CdmObjectType.OperationAddAttributeGroupDef); addAttGroupOp.AttributeGroupName = "PersonAttributeGroup"; projection.Operations.Add(addAttGroupOp); // Create an entity reference to hold this projection. CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null); projectionEntityRef.ExplicitReference = projection; // Create an entity attribute that contains this projection and add this to the entity. CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute"); entityAttribute.Entity = projectionEntityRef; entity.Attributes.Add(entityAttribute); // Create resolution options with the 'referenceOnly' directive. ResolveOptions resOpt = new ResolveOptions(entity.InDocument) { Directives = new AttributeResolutionDirectiveSet(new HashSet <string> { "referenceOnly" }) }; // Resolve the entity with 'referenceOnly' CdmEntityDefinition resolvedEntityWithReferenceOnly = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot); // Verify correctness of the resolved attributes after running the AddAttributeGroup operation // Original set of attributes: ["id", "name", "value", "date"] // Condition not met, keep attributes in flat list Assert.AreEqual(4, resolvedEntityWithReferenceOnly.Attributes.Count); Assert.AreEqual("id", (resolvedEntityWithReferenceOnly.Attributes[0] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("name", (resolvedEntityWithReferenceOnly.Attributes[1] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("value", (resolvedEntityWithReferenceOnly.Attributes[2] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("date", (resolvedEntityWithReferenceOnly.Attributes[3] as CdmTypeAttributeDefinition).Name); // Now resolve the entity with the 'structured' directive resOpt.Directives = new AttributeResolutionDirectiveSet(new HashSet <string> { "structured" }); CdmEntityDefinition resolvedEntityWithStructured = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot); // Verify correctness of the resolved attributes after running the AddAttributeGroup operation // Original set of attributes: ["id", "name", "value", "date"] // Condition met, put all attributes in an attribute group CdmAttributeGroupDefinition attGroupDefinition = this.ValidateAttributeGroup(resolvedEntityWithStructured.Attributes, "PersonAttributeGroup"); Assert.AreEqual(4, attGroupDefinition.Members.Count); Assert.AreEqual("id", (attGroupDefinition.Members[0] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("name", (attGroupDefinition.Members[1] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("value", (attGroupDefinition.Members[2] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("date", (attGroupDefinition.Members[3] as CdmTypeAttributeDefinition).Name); }