Ejemplo n.º 1
0
        /// <summary>
        /// Create a constant entity that contains the source mapping to a foreign key.
        /// e.g.
        /// an fk created to entity "Customer" based on the "customerName", would add a parameter to the "is.linkedEntity.identifier" trait as follows:
        ///   [
        ///     "/Customer.cdm.json/Customer",
        ///     "customerName"
        ///   ]
        /// In the case of polymorphic source, there will be a collection of such entries.
        /// </summary>
        /// <param name="corpus"></param>
        /// <param name="foundResAttrList"></param>
        /// <returns></returns>
        internal static CdmEntityReference CreateForeignKeyLinkedEntityIdentifierTraitParameter(ProjectionDirective projDir, CdmCorpusDefinition corpus, List <ProjectionAttributeState> refFoundList)
        {
            CdmEntityReference traitParamEntRef = null;

            List <Tuple <string, string> > entRefAndAttrNameList = new List <Tuple <string, string> >();

            foreach (ProjectionAttributeState refFound in refFoundList)
            {
                ResolvedAttribute resAttr = refFound.CurrentResolvedAttribute;

                if (resAttr?.Target?.Owner != null &&
                    (resAttr.Target.ObjectType == CdmObjectType.TypeAttributeDef || resAttr.Target.ObjectType == CdmObjectType.EntityAttributeDef))
                {
                    // find the linked entity
                    var owner = resAttr.Target.Owner;

                    while (owner != null && owner.ObjectType != CdmObjectType.EntityDef)
                    {
                        owner = owner.Owner;
                    }

                    // find where the projection is defined
                    var projectionDoc = projDir.Owner?.InDocument;

                    if (owner?.ObjectType == CdmObjectType.EntityDef && projectionDoc != null)
                    {
                        CdmEntityDefinition entDef = owner.FetchObjectDefinition <CdmEntityDefinition>(projDir.ResOpt);
                        if (entDef != null)
                        {
                            // should contain relative path without the namespace
                            string relativeEntPath = entDef.Ctx.Corpus.Storage.CreateRelativeCorpusPath(entDef.AtCorpusPath, projectionDoc);
                            entRefAndAttrNameList.Add(new Tuple <string, string>(relativeEntPath, resAttr.ResolvedName));
                        }
                    }
                }
            }

            if (entRefAndAttrNameList.Count > 0)
            {
                CdmConstantEntityDefinition constantEntity = corpus.MakeObject <CdmConstantEntityDefinition>(CdmObjectType.ConstantEntityDef);
                constantEntity.EntityShape = corpus.MakeRef <CdmEntityReference>(CdmObjectType.EntityRef, "entityGroupSet", true);
                string originalSourceEntityAttributeName = projDir.OriginalSourceEntityAttributeName;
                if (originalSourceEntityAttributeName == null)
                {
                    originalSourceEntityAttributeName = "";
                }

                constantEntity.ConstantValues = entRefAndAttrNameList.Select((entAndAttrName) => new List <string> {
                    entAndAttrName.Item1, entAndAttrName.Item2, $"{originalSourceEntityAttributeName}_{entAndAttrName.Item1.Substring(entAndAttrName.Item1.LastIndexOf("/") + 1)}"
                }).ToList();

                traitParamEntRef = corpus.MakeRef <CdmEntityReference>(CdmObjectType.EntityRef, constantEntity, false);
            }

            return(traitParamEntRef);
        }
Ejemplo n.º 2
0
 public static ConstantEntity ToData(CdmConstantEntityDefinition instance, ResolveOptions resOpt, CopyOptions options)
 {
     return(new ConstantEntity
     {
         Explanation = instance.Explanation,
         ConstantEntityName = instance.ConstantEntityName,
         EntityShape = Utils.JsonForm(instance.EntityShape, resOpt, options),
         ConstantValues = instance.ConstantValues
     });
 }
Ejemplo n.º 3
0
        internal void UpdateDefaultValue(dynamic newDefault)
        {
            if (newDefault is JArray)
            {
                JArray array = (JArray)newDefault;
                int    l     = array.Count;
                if (l > 0 && array[0]["languageTag"] != null && array[0]["displayText"] != null)
                {
                    // looks like something we understand
                    List <List <string> > tab = new List <List <string> >();
                    var corr = (array[0]["correlatedValue"] != null);
                    for (var i = 0; i < l; i++)
                    {
                        var row = new List <string>
                        {
                            (string)array[i]["languageTag"],
                            (string)array[i]["displayText"],
                            (string)array[i]["attributeValue"],
                            (string)array[i]["displayOrder"]
                        };
                        if (corr)
                        {
                            row.Add((string)array[i]["correlatedValue"]);
                        }
                        tab.Add(row);
                    }
                    CdmConstantEntityDefinition cEnt = this.Ctx.Corpus.MakeObject <CdmConstantEntityDefinition>(CdmObjectType.ConstantEntityDef, null, false);
                    cEnt.EntityShape    = this.Ctx.Corpus.MakeRef <CdmEntityReference>(CdmObjectType.EntityRef, corr ? "listLookupCorrelatedValues" : "listLookupValues", true);
                    cEnt.ConstantValues = tab;

                    newDefault = this.Ctx.Corpus.MakeRef <CdmEntityReference>(CdmObjectType.EntityRef, cEnt, false);
                    this.UpdateTraitArgument("does.haveDefault", "default", newDefault);
                }
                else
                {
                    Logger.Error(nameof(TraitToPropertyMap), this.Host.Ctx, "Default value missing languageTag or displayText.");
                }
            }
            else
            {
                Logger.Error(nameof(TraitToPropertyMap), this.Host.Ctx, "Default value type not supported. Please use JArray.");
            }
        }
Ejemplo n.º 4
0
        public static dynamic FetchReplacementValue(ResolveOptions resOpt, dynamic oldValue, dynamic newValue, bool wasSet)
        {
            if (oldValue == null)
            {
                return(newValue);
            }

            if (!wasSet)
            {
                // must explicitly set a value to override
                // if a new value is not set, then newValue holds nothing or the default.
                // in this case, if there was already a value in this argument then just keep using it.
                return(oldValue);
            }

            if (oldValue is string)
            {
                return(newValue);
            }
            CdmObject ov = oldValue as CdmObject;
            CdmObject nv = newValue as CdmObject;

            // replace an old table with a new table? actually just mash them together
            if (ov != null && ov.ObjectType == CdmObjectType.EntityRef &&
                nv != null && nv.GetType() != typeof(string) && nv.ObjectType == CdmObjectType.EntityRef)
            {
                var oldEnt = ov.FetchObjectDefinition <CdmConstantEntityDefinition>(resOpt);
                var newEnt = nv.FetchObjectDefinition <CdmConstantEntityDefinition>(resOpt);

                // check that the entities are the same shape
                if (newEnt == null)
                {
                    return(ov);
                }

                // BUG
                CdmEntityDefinition entDefShape = null;
                if (oldEnt == null || ((entDefShape = oldEnt.EntityShape.FetchObjectDefinition <CdmEntityDefinition>(resOpt)) != newEnt.EntityShape.FetchObjectDefinition <CdmEntityDefinition>(resOpt)))
                {
                    return(nv);
                }

                var oldCv = oldEnt.ConstantValues;
                var newCv = newEnt.ConstantValues;
                // rows in old?
                if (oldCv == null || oldCv.Count == 0)
                {
                    return(nv);
                }
                // rows in new?
                if (newCv == null || newCv.Count == 0)
                {
                    return(ov);
                }

                // make a set of rows in the old one and add the new ones. this will union the two
                // find rows in the new one that are not in the old one. slow, but these are small usually
                IDictionary <string, List <string> > unionedRows = new Dictionary <string, List <string> >();

                // see if any of the entity atts are the primary key, meaning, the only thing that causes us to merge dups unique.
                // i know this makes you think about a snake eating its own tail, but fetch the resolved attributes of the constant shape
                int pkAtt = -1;
                if (entDefShape != null)
                {
                    var resOptShape  = new ResolveOptions(entDefShape.InDocument);
                    var resAttsShape = entDefShape.FetchResolvedAttributes(resOptShape);
                    if (resAttsShape != null)
                    {
                        pkAtt = resAttsShape.Set.FindIndex((ra) => ra.ResolvedTraits.Find(resOptShape, "is.identifiedBy") != null);
                    }
                }

                for (int i = 0; i < oldCv.Count; i++)
                {
                    List <string> row = oldCv[i];
                    string        key;
                    // the entity might have a PK, if so, only look at that values as the key
                    if (pkAtt != -1)
                    {
                        key = row[pkAtt];
                    }
                    else
                    {
                        key = row.Aggregate((prev, curr) =>
                        {
                            return($"{(!string.IsNullOrEmpty(prev) ? prev : "")}::{curr}");
                        });
                    }
                    unionedRows[key] = row;
                }

                for (int i = 0; i < newCv.Count; i++)
                {
                    List <string> row = newCv[i];
                    string        key;
                    // the entity might have a PK, if so, only look at that values as the key
                    if (pkAtt != -1)
                    {
                        key = row[pkAtt];
                    }
                    else
                    {
                        key = row.Aggregate((prev, curr) =>
                        {
                            return($"{(!string.IsNullOrEmpty(prev) ? prev : "")}::{curr}");
                        });
                    }
                    unionedRows[key] = row;
                }

                if (unionedRows.Count == oldCv.Count)
                {
                    return(ov);
                }
                List <List <string> > allRows = unionedRows.Values.ToList();

                CdmConstantEntityDefinition replacementEnt = (CdmConstantEntityDefinition)oldEnt.Copy(resOpt);
                replacementEnt.ConstantValues = allRows;
                return(resOpt.WrtDoc.Ctx.Corpus.MakeRef <CdmEntityReference>(CdmObjectType.EntityRef, replacementEnt, false));
            }

            return(newValue);
        }
Ejemplo n.º 5
0
        public static dynamic FetchReplacementValue(ResolveOptions resOpt, dynamic oldValue, dynamic newValue, bool wasSet)
        {
            if (oldValue == null)
            {
                return(newValue);
            }

            if (!wasSet)
            {
                // must explicitly set a value to override
                // if a new value is not set, then newValue holds nothing or the default.
                // in this case, if there was already a value in this argument then just keep using it.
                return(oldValue);
            }

            if (oldValue is string)
            {
                return(newValue);
            }
            CdmObject ov = oldValue as CdmObject;
            CdmObject nv = newValue as CdmObject;

            // replace an old table with a new table? actually just mash them together
            if (ov != null && ov.ObjectType == CdmObjectType.EntityRef &&
                nv != null && nv.GetType() != typeof(string) && nv.ObjectType == CdmObjectType.EntityRef)
            {
                var oldEnt = ov.FetchObjectDefinition <CdmConstantEntityDefinition>(resOpt);
                var newEnt = nv.FetchObjectDefinition <CdmConstantEntityDefinition>(resOpt);

                // check that the entities are the same shape
                if (newEnt == null)
                {
                    return(ov);
                }

                // BUG
                if (oldEnt == null || (oldEnt.EntityShape.FetchObjectDefinition <CdmEntityDefinition>(resOpt) != newEnt.EntityShape.FetchObjectDefinition <CdmEntityDefinition>(resOpt)))
                {
                    return(nv);
                }

                var oldCv = oldEnt.ConstantValues;
                var newCv = newEnt.ConstantValues;
                // rows in old?
                if (oldCv == null || oldCv.Count == 0)
                {
                    return(nv);
                }
                // rows in new?
                if (newCv == null || newCv.Count == 0)
                {
                    return(ov);
                }

                // make a set of rows in the old one and add the new ones. this will union the two
                // find rows in the new one that are not in the old one. slow, but these are small usually
                IDictionary <string, List <string> > unionedRows = new Dictionary <string, List <string> >();
                for (int i = 0; i < oldCv.Count; i++)
                {
                    List <string> row = oldCv[i];
                    string        key = row.Aggregate((prev, curr) =>
                    {
                        StringBuilder result = new StringBuilder(!string.IsNullOrEmpty(prev) ? prev : "");
                        result.Append("::");
                        result.Append(curr);
                        return(result.ToString());
                    });
                    unionedRows[key] = row;
                }

                for (int i = 0; i < newCv.Count; i++)
                {
                    List <string> row = newCv[i];
                    string        key = row.Aggregate((prev, curr) =>
                    {
                        StringBuilder result = new StringBuilder(!string.IsNullOrEmpty(prev) ? prev : "");
                        result.Append("::");
                        result.Append(curr);
                        return(result.ToString());
                    });
                    unionedRows[key] = row;
                }

                if (unionedRows.Count == oldCv.Count)
                {
                    return(ov);
                }
                List <List <string> > allRows = unionedRows.Values.ToList();

                CdmConstantEntityDefinition replacementEnt = (CdmConstantEntityDefinition)oldEnt.Copy(resOpt);
                replacementEnt.ConstantValues = allRows;
                return(resOpt.WrtDoc.Ctx.Corpus.MakeRef <CdmEntityReference>(CdmObjectType.EntityRef, replacementEnt, false));
            }

            return(newValue);
        }