public static CdmOperationAddCountAttribute FromData(CdmCorpusContext ctx, JToken obj) { if (obj == null) { return(null); } CdmOperationAddCountAttribute addCountAttributeOp = ctx.Corpus.MakeObject <CdmOperationAddCountAttribute>(CdmObjectType.OperationAddCountAttributeDef); if (obj["$type"] != null && !StringUtils.EqualsWithIgnoreCase(obj["$type"].ToString(), OperationTypeConvertor.OperationTypeToString(CdmOperationType.AddCountAttribute))) { Logger.Error(nameof(OperationAddCountAttributePersistence), ctx, $"$type {(string)obj["$type"]} is invalid for this operation."); } else { addCountAttributeOp.Type = CdmOperationType.AddCountAttribute; } if (obj["explanation"] != null) { addCountAttributeOp.Explanation = (string)obj["explanation"]; } if (obj["countAttribute"] != null) { addCountAttributeOp.CountAttribute = Utils.CreateAttribute(ctx, obj["countAttribute"]) as CdmTypeAttributeDefinition; } return(addCountAttributeOp); }
/// <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); } }
public static OperationAddCountAttribute ToData(CdmOperationAddCountAttribute instance, ResolveOptions resOpt, CopyOptions options) { if (instance == null) { return(null); } OperationAddCountAttribute obj = OperationBasePersistence.ToData <OperationAddCountAttribute>(instance, resOpt, options); obj.CountAttribute = Utils.JsonForm(instance.CountAttribute, resOpt, options); return(obj); }
public static CdmOperationAddCountAttribute FromData(CdmCorpusContext ctx, JToken obj) { if (obj == null) { return(null); } CdmOperationAddCountAttribute addCountAttributeOp = OperationBasePersistence.FromData <CdmOperationAddCountAttribute>(ctx, CdmObjectType.OperationAddCountAttributeDef, obj); addCountAttributeOp.CountAttribute = Utils.CreateAttribute(ctx, obj["countAttribute"]) as CdmTypeAttributeDefinition; return(addCountAttributeOp); }
public static OperationAddCountAttribute ToData(CdmOperationAddCountAttribute instance, ResolveOptions resOpt, CopyOptions options) { if (instance == null) { return(null); } return(new OperationAddCountAttribute { Type = OperationTypeConvertor.OperationTypeToString(CdmOperationType.AddCountAttribute), Explanation = instance.Explanation, CountAttribute = Utils.JsonForm(instance.CountAttribute, resOpt, options) }); }
/// <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); } }
public async Task TestEntityAttributeProjUsingObjectModel() { CdmCorpusDefinition corpus = TestHelper.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 AddCountAttribute operation CdmOperationAddCountAttribute addCountAttrOp = corpus.MakeObject <CdmOperationAddCountAttribute>(CdmObjectType.OperationAddCountAttributeDef); addCountAttrOp.CountAttribute = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, "testCount"); addCountAttrOp.CountAttribute.DataType = corpus.MakeRef <CdmDataTypeReference>(CdmObjectType.DataTypeRef, "integer", true); projection.Operations.Add(addCountAttrOp); // 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 AddCountAttribute operation // Original set of attributes: ["id", "name", "value", "date"] // Count attribute: "testCount" 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("testCount", (resolvedEntity.Attributes[4] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("is.linkedEntity.array.count", resolvedEntity.Attributes[4].AppliedTraits[1].NamedReference); }
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 TestConditionalProjUsingObjectModel() { CdmCorpusDefinition corpus = TestHelper.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 AddCountAttribute operation CdmOperationAddCountAttribute addCountAttrOp = corpus.MakeObject <CdmOperationAddCountAttribute>(CdmObjectType.OperationAddCountAttributeDef); addCountAttrOp.CountAttribute = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, "testCount"); addCountAttrOp.CountAttribute.DataType = corpus.MakeRef <CdmDataTypeReference>(CdmObjectType.DataTypeRef, "integer", true); projection.Operations.Add(addCountAttrOp); // 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 AddCountAttribute operation // Original set of attributes: ["id", "name", "value", "date"] // Count attribute: "testCount" 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("testCount", (resolvedEntityWithReferenceOnly.Attributes[4] as CdmTypeAttributeDefinition).Name); Assert.AreEqual("is.linkedEntity.array.count", resolvedEntityWithReferenceOnly.Attributes[4].AppliedTraits[1].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 AddCountAttribute operation // Original set of attributes: ["id", "name", "value", "date"] // No Count 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); }