Beispiel #1
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);
        }
Beispiel #2
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);
        }