コード例 #1
0
        public void AddPaths(DcColumn sd, DcColumn td, Mapping gMapping) // Add this pair by expanding it using the mapping
        {
            Debug.Assert(sd != null && sd.Input == SourceTab, "Wrong use: source path must start from the source table.");
            Debug.Assert(td != null && td.Input == TargetTab, "Wrong use: target path must start from the target table.");

            Debug.Assert(sd != null && sd.Output == gMapping.SourceTab, "Wrong use: source path must end where the mapping starts.");
            Debug.Assert(td != null && td.Output == gMapping.TargetTab, "Wrong use: target path must end where the mapping starts.");

            if (gMapping.Matches.Count == 0)      // If there are no continuations then add only the starting segments (for example, for mappings between primitive tables)
            {
                ColumnPath sp = new ColumnPath(); // A path consists of one segment
                sp.InsertLast(sd);

                ColumnPath tp = new ColumnPath(); // A path consists of one segment
                tp.InsertLast(td);

                PathMatch match = new PathMatch(sp, tp);
                Matches.Add(match);
            }

            foreach (PathMatch gMatch in gMapping.Matches)
            {
                ColumnPath sp = new ColumnPath(); // Create source path by concatenating one segment and continuation path from the mapping
                sp.InsertLast(sd);
                sp.InsertLast(gMatch.SourcePath);

                ColumnPath tp = new ColumnPath(); // Create target path by concatenating one segment and continuation path from the mapping
                tp.InsertLast(td);
                tp.InsertLast(gMatch.TargetPath);

                PathMatch match = new PathMatch(sp, tp);
                Matches.Add(match);
            }
        }
コード例 #2
0
        public bool Compatible(PathMatch match) // The specified match is compatible with (does not contradicts to) this match
        {
            // Main rule: if a coverage condition holds for one path (in one or another direction) then it must hold for the other path (in the same direction)

            // SourcePath -> TargetPath
            if (match.SourcePath.StartsWith(SourcePath))         // The specified match continues this path
            {
                return(match.TargetPath.StartsWith(TargetPath)); // The same must be true for the other paths
            }
            else if (SourcePath.StartsWith(match.SourcePath))    // Opposite
            {
                return(TargetPath.StartsWith(match.TargetPath)); // The same must be true for the other paths
            }

            // TargetPath -> SourcePath
            if (match.TargetPath.StartsWith(TargetPath))
            {
                return(match.SourcePath.StartsWith(SourcePath));
            }
            else if (TargetPath.StartsWith(match.TargetPath))
            {
                return(SourcePath.StartsWith(match.SourcePath));
            }

            // Neither source path nor target paths cover.
            // This means they have some intersection (meet table they both continue).
            // This meet point defines an implicit match which we do not check but it might contradict to other matches.

            return(true);
        }
コード例 #3
0
 public void AddMatches(List <PathMatch> matches) // Import all path matches (as new objects) that fit into this mapping
 {
     foreach (PathMatch m in matches)
     {
         PathMatch match = new PathMatch(m);
         AddMatch(match);
     }
 }
コード例 #4
0
 public bool AreMatched(PathMatch match) // Determine if both paths are matched (true if there exist the same or more specific match)
 {
     foreach (PathMatch m in Matches)
     {
         if (m.Matches(match))
         {
             return(true);
         }
     }
     return(false); // Not found
 }
コード例 #5
0
 public bool Compatible(PathMatch match) // Determine if the specified match does not contradict to this mapping and can be added to it without removing existing matches
 {
     foreach (PathMatch m in Matches)
     {
         if (!m.Compatible(match))
         {
             return(false);
         }
     }
     return(true); // Compatible and can be added
 }
コード例 #6
0
        public void AddTargetToSchema(DcSchema schema = null) // Ensure that all target elements exist in the specified schema
        {
            // The mapping can reference new elements which are not in the schema yet so we try to find them and add if necessary

            if (schema == null) // Find the schema from the mapping elements
            {
                PathMatch match = Matches.FirstOrDefault(m => m.TargetPath.Output.IsPrimitive);
                schema = match != null ? match.TargetPath.Output.Schema : null; // We assume that primitive tables always have root defined (other tables might not have been added yet).
            }

            ColumnTree tree = GetTargetTree();

            tree.AddToSchema(schema);
        }
コード例 #7
0
        public virtual void FromJson(JObject json, DcSpace ws)
        {
            // No super-object

            Similarity = (double)json["similarity"];

            _sourceTab = (DcTable)Com.Schema.Utils.ResolveJsonRef((JObject)json["source_table"], ws);
            _targetTab = (DcTable)Com.Schema.Utils.ResolveJsonRef((JObject)json["target_table"], ws);

            // List of matches
            foreach (JObject match in json["matches"])
            {
                PathMatch comMatch = (PathMatch)Com.Schema.Utils.CreateObjectFromJson(match);
                if (comMatch != null)
                {
                    comMatch.FromJson(match, ws);
                    this.Matches.Add(comMatch);
                }
            }
        }
コード例 #8
0
        public void AddMatch(PathMatch match)
        {
            Debug.Assert(match != null && match.SourceTab == SourceTab, "Wrong use: source path must start from the source table.");
            Debug.Assert(match != null && match.TargetTab == TargetTab, "Wrong use: target path must start from the target table.");


            // In the case of coverage we do nothing. We want to keep more general matches (between tables) while more specific can be added/removed independently (if they satisfy them).
            // ??? in the case of no coverage, they have a point of intersection. Then - ? Should this point of intersection be within the seconad path or otherwise constrained?
            // Problem: two tables can be matched explcitly or implicitly, that is, their match logically follows from other path matches.
            // Implicit match: intersections of two paths produce a more general match
            // Alternative approach: Incrementally add path segments and checking consistency conditions

            List <PathMatch> toRemove = new List <PathMatch>();

            foreach (PathMatch m in Matches)
            {
                if (!m.Compatible(match))
                {
                    toRemove.Add(m);
                }
            }

            Matches.Add(match); // Now it is guaranteed to be compatible with all existing matches
        }
コード例 #9
0
        /// <summary>
        /// Create and initialize a new mapping which produces a flat target set with all primitive columns for copying primitive data from the source set.
        /// Only identity (PK) source columns are expanded recursively.
        /// For relational source, this means that all primitive columns of the source table will be mapped with their relational names, no FK-referenced tables will be joined and no artifical column names will be used.
        /// If it is necessary to expand entity columns (non-PK columns of joined tables) then a different implementation is needed (which will require joins, artifical column/path names etc.)
        /// </summary>
        public Mapping CreatePrimitive(DcTable sourceSet, DcTable targetSet, DcSchema targetSchema)
        {
            Debug.Assert(!sourceSet.IsPrimitive && !targetSet.IsPrimitive, "Wrong use: copy mapping can be created for only non-primitive tables.");
            Debug.Assert(targetSchema != null || targetSet.Schema != null, "Wrong use: target schema must be specified.");

            Mapping map = new Mapping(sourceSet, targetSet);

            DcSchema sourceSchema = map.SourceTab.Schema;

            if (targetSchema == null)
            {
                targetSchema = targetSet.Schema;
            }

            ColumnPath sp;
            ColumnPath tp;

            DcColumn td;

            PathMatch match;

            if (sourceSchema is SchemaOledb)
            {
                TableRel set = (TableRel)map.SourceTab;
                foreach (ColumnAtt att in set.GreaterPaths)
                {
                    sp = new ColumnAtt(att);

                    // Recommend matching target type (mapping primitive types)
                    this.MapPrimitiveSet(att.Output, targetSchema);
                    DcTable targetType = this.GetBestTargetSet(att.Output, targetSchema);

                    td      = new Schema.Column(att.RelationalColumnName, map.TargetTab, targetType, att.IsKey, false);
                    tp      = new ColumnPath(td);
                    tp.Name = sp.Name;

                    match = new PathMatch(sp, tp, 1.0);

                    map.Matches.Add(match);
                }
            }
            else if (sourceSchema is SchemaCsv)
            {
                DcTable set = (DcTable)map.SourceTab;
                foreach (DcColumn sd in set.Columns)
                {
                    if (sd.IsSuper)
                    {
                        continue;
                    }

                    // Recommend matching target type (mapping primitive types)
                    //this.MapPrimitiveSet(sd, targetSchema);
                    //ComTable targetType = this.GetBestTargetSet(sd.Output, targetSchema);

                    //
                    // Analyze sample values of sd and choose the most specific target type
                    //
                    List <string> values = ((ColumnCsv)sd).SampleValues;

                    string targetTypeName;
                    if (Com.Schema.Utils.isInt32(values.ToArray()))
                    {
                        targetTypeName = "Integer";
                    }
                    else if (Com.Schema.Utils.isDouble(values.ToArray()))
                    {
                        targetTypeName = "Double";
                    }
                    else
                    {
                        targetTypeName = "String";
                    }

                    DcTable targetType = targetSchema.GetPrimitiveType(targetTypeName);

                    td = targetSchema.Space.CreateColumn(sd.Name, map.TargetTab, targetType, sd.IsKey);

                    sp = new ColumnPath(sd);
                    tp = new ColumnPath(td);

                    match = new PathMatch(sp, tp, 1.0);

                    map.Matches.Add(match);
                }
            }

            return(map);
        }
コード例 #10
0
 public PathMatch(PathMatch m)
 {
     SourcePath = new ColumnPath(m.SourcePath);
     TargetPath = new ColumnPath(m.TargetPath);
     Similarity = m.Similarity;
 }
コード例 #11
0
 public bool Matches(PathMatch match) // This is more specific (longer) than argument
 {
     return(MatchesSource(match.SourcePath) && MatchesTarget(match.TargetPath));
 }