Exemple #1
0
        /// <summary>
        /// Sorts the vertices in topological order
        /// </summary>
        /// <returns>List of topological sorted vertices</returns>
        public List <Vertex> TopologicalSort(ColumnChanges columnChanges)
        {
            IPriorityQueue <Vertex> priorityQueue = new IntervalHeap <Vertex>(new VerticesComparer(Options, columnChanges));
            var sortedVertices = new List <Vertex>();

            var incomingEdges = new Dictionary <Vertex, int>();

            foreach (var v in Vertices)
            {
                incomingEdges[v] = v.IngoingEdges().Count;
                if (incomingEdges[v] == 0)
                {
                    priorityQueue.Add(v);
                }
            }

            while (!priorityQueue.IsEmpty)
            {
                Vertex v = priorityQueue.FindMin();
                sortedVertices.Add(v);
                priorityQueue.DeleteMin();

                foreach (var e in v.OutgoingEdges())
                {
                    incomingEdges[e.Destination]--;
                    if (incomingEdges[e.Destination] == 0)
                    {
                        priorityQueue.Add(e.Destination);
                    }
                }
            }

            return(sortedVertices);
        }
Exemple #2
0
        /// <summary>
        /// Check if a specific flag is set
        /// </summary>
        /// <param name="value">Flag to check</param>
        /// <returns>True if set, false if unset</returns>
        public bool IsSet(ColumnChanges value)
        {
            // If value is None, then the enum must be zero, since no other change could have happened
            if (value == ColumnChanges.None)
            {
                return(value == 0);
            }

            return((ColumnChanges & value) != 0);
        }
Exemple #3
0
        private void ModifyColumn(ColumnChanges columnChanges)
        {
            //数据类型
            if (columnChanges.IsDbTypeChanged)
            {
                this.AddOperation(new AlterColumnType
                {
                    CopyFromColumn = columnChanges.OldColumn,
                    NewType        = columnChanges.NewColumn.DataType,
                    IsRequired     = columnChanges.OldColumn.IsRequired,
                });
            }

            //是否主键
            if (columnChanges.IsPrimaryKeyChanged)
            {
                var column = columnChanges.NewColumn;
                if (column.IsPrimaryKey)
                {
                    this.AddOperation(new AddPKConstraint
                    {
                        CopyFromColumn = column,
                    });
                }
                else
                {
                    this.AddOperation(new RemovePKConstraint
                    {
                        CopyFromColumn = column,
                    });
                }
            }

            //可空性
            if (columnChanges.IsRequiredChanged)
            {
                this.ModifyColumnRequired(columnChanges);
            }

            //外键
            if (columnChanges.ForeignRelationChangeType != ChangeType.UnChanged)
            {
                this.ModifyColumnForeignConstraint(columnChanges);
            }
        }
Exemple #4
0
        private void GenerateOpertions(ColumnChanges columnChanges)
        {
            switch (columnChanges.ChangeType)
            {
            case ChangeType.Added:
                this.AddColumn(columnChanges.NewColumn);
                break;

            case ChangeType.Removed:
                this.RemoveColumn(columnChanges.OldColumn);
                break;

            case ChangeType.Modified:
                this.ModifyColumn(columnChanges);
                break;

            default:
                break;
            }
        }
Exemple #5
0
 private void ModifyColumnRequired(ColumnChanges columnChanges)
 {
     if (columnChanges.NewColumn.IsRequired)
     {
         if (columnChanges.OldColumn.IsForeignKey)
         {
             this.AddOperation(new AddNotNullConstraintFK
             {
                 CopyFromColumn = columnChanges.NewColumn
             });
         }
         else
         {
             this.AddOperation(new AddNotNullConstraint
             {
                 CopyFromColumn = columnChanges.NewColumn
             });
         }
     }
     else
     {
         if (columnChanges.OldColumn.IsForeignKey)
         {
             this.AddOperation(new RemoveNotNullConstraintFK
             {
                 CopyFromColumn = columnChanges.NewColumn
             });
         }
         else
         {
             this.AddOperation(new RemoveNotNullConstraint
             {
                 CopyFromColumn = columnChanges.NewColumn
             });
         }
     }
 }
Exemple #6
0
        private void ModifyColumnForeignConstraint(ColumnChanges columnChanges)
        {
            var value = columnChanges.ForeignRelationChangeType;

            switch (value)
            {
            case ChangeType.Added:
                this.AddOperation(new AddFKConstraint
                {
                    CopyFromConstraint = columnChanges.NewColumn.ForeignConstraint
                });
                break;

            case ChangeType.Removed:
                this.AddOperation(new RemoveFKConstraint
                {
                    CopyFromConstraint = columnChanges.OldColumn.ForeignConstraint
                });
                break;

            case ChangeType.Modified:
                //throw new NotSupportedException("暂时不支持外键修改。");
                this.AddOperation(new RemoveFKConstraint
                {
                    CopyFromConstraint = columnChanges.OldColumn.ForeignConstraint
                });
                this.AddOperation(new AddFKConstraint
                {
                    CopyFromConstraint = columnChanges.NewColumn.ForeignConstraint
                });
                break;

            default:
                break;
            }
        }
Exemple #7
0
 /// <summary>
 /// Unset value flag in enum
 /// </summary>
 /// <param name="value">Flag to unset</param>
 public void Unset(ColumnChanges value)
 {
     ColumnChanges &= ~value;
 }
Exemple #8
0
 /// <summary>
 /// Set value flag in enum
 /// </summary>
 /// <param name="value">Flag to set</param>
 public void Set(ColumnChanges value)
 {
     ColumnChanges |= value;
 }
Exemple #9
0
        /// <summary>
        /// Invoke "fixing" function based on provided change
        /// </summary>
        /// <param name="g">Graph</param>
        /// <param name="v">Vertex to invoke on</param>
        /// <param name="c">Reference to change</param>
        /// <param name="change">Action to perform</param>
        /// <param name="affectedVertices">Vertices affected by an EDS change</param>
        public void InvokeMethod(Vertex v, ColumnMetaChange c, ColumnChanges change, List <Vertex> affectedVertices)
        {
            Attribute a = new Attribute();

            if (change != ColumnChanges.Addition)
            {
                // If attribute isn't available, then it is safe to assume it isn't a part of the job, and won't affect any transformation
                if ((a = GetAttribute(c)) == null)
                {
                    return;
                }
                // If the vertex is not affected by the change, we stop.
                if (!affectedVertices.Contains(v))
                {
                    return;
                }
            }
            else
            {
                a.Change(c);
            }

            // Invoke method on vertex based on the provided change.
            // We've already split the ColumnChanges enum into its components, so it is safe to switch on
            switch (change)
            {
            case ColumnChanges.None:
                break;

            case ColumnChanges.Addition:
                if (v.UsesAttribute(a))
                {
                    v.AdditionAttribute(this, a, c);
                }
                break;

            case ColumnChanges.Deletion:
                v.DeletionAttribute(this, a, c);
                break;

            case ColumnChanges.Rename:
                v.RenameAttribute(this, a, c);
                break;

            case ColumnChanges.DataType:
                v.DataTypeAttribute(this, a, c);
                break;

            case ColumnChanges.Length:
                break;

            case ColumnChanges.Nullable:
                break;

            case ColumnChanges.NonNull:
                break;

            case ColumnChanges.Unique:
                break;

            case ColumnChanges.NonUnique:
                break;

            case ColumnChanges.PrimaryKey:
                break;

            case ColumnChanges.NonPrimary:
                break;
            }
        }
Exemple #10
0
        /// <summary>
        /// Main algorithm used to perform alterations of graph given a ColumnMetaChange
        /// </summary>
        /// <param name="change">Change to perform in graph</param>
        public void Alter(ColumnMetaChange change, ColumnChanges changeType)
        {
            // if partial fix is not enabled quit
            if (Options.UseGlobalBlockingSemantics &&
                Vertices.Any(v => Options.PolicyTable[changeType][v.GetType()] == Policy.BLOCK))
            {
                return;
            }

            List <Vertex> sortedVertices = TopologicalSort(changeType);


            Logger.Debug("Order of fixing transformations:");
            sortedVertices.ForEach(v => Logger.Debug(v.Name));

            List <Vertex> affectedVertices = GetAffectedVertices(change);

            foreach (Vertex v in sortedVertices)
            {
                // Assumes partial fix is enabled.
                if (Options.PolicyTable[changeType][v.GetType()] == Policy.BLOCK)
                {
                    Logger.Debug($"Blocked the propagation at {v.Name}");
                    break;
                }
                v.CleanUpDependencies();
                // TODO: Insert Data type change fix/check here


                // Check for attributes that need to be deleted (and delete vertex if no attributes are left)
                if (!(v is OLEDBSource))
                {
                    foreach (Attribute a in v.OutputAttributes())
                    {
                        // If no dependencies are found for a given attribute, then it is safe to delete

                        if (v.Dependencies[a].Count == 0)
                        {
                            if (v.IsFullyDependent(a))
                            {
                                RemoveVertex(v);
                                break;
                            }
                            // If not, then just remove attribute
                            else
                            {
                                v.RemoveOutputAttribute(a);
                                v.CleanUpRemovedAttribute(a);
                            }
                        }
                    }
                }

                // Since a destination in many scenarioes don't have any output edges, then this specific check is necessary
                if (v is OLEDBDestination && v.IngoingEdges().Count == 0)
                {
                    RemoveVertex(v);
                }

                // If the vertex has not been removed, we continue
                if (Vertices.Contains(v))
                {
                    v.CleanUpInputCollection();
                    InvokeMethod(v, change, changeType, affectedVertices);
                }
            }
        }
Exemple #11
0
 public VerticesComparer(Options.Options options, ColumnChanges columnChange)
 {
     _options      = options;
     _columnChange = columnChange;
 }