/// <summary> /// Get attribute related to a ColumnMetaChange, which is the database-, table-, and columnname /// </summary> /// <param name="change">ColumnMetaChange to reference</param> /// <returns>Attribute</returns> public Attribute GetAttribute(ColumnMetaChange change) { return(GetAttribute(change.OldColumn.Table.Database.Name, change.OldColumn.Table.FullName, change.OldColumn.Name)); //return AttributeTable[change.OldColumn.Table.Database.Name][change.OldColumn.Table.Name][change.OldColumn.Name]; }
public override void RenameAttribute(Graph g, Attribute a, ColumnMetaChange change) { // Rename all derivations, which contains this attribute foreach (Derivation d in Derivations) { ModifyDerivation(d, Regex.Replace(d.Expr, $"{change.OldColumn.Name}", change.NewColumn.Name)); } }
/// <summary> /// Rename attribute /// </summary> /// <param name="g">Graph</param> /// <param name="a">Attribute</param> /// <param name="change">Column Meta Change</param> public override void RenameAttribute(Graph g, Attribute a, ColumnMetaChange change) { // Iterate through all conditions and change name of attribute inside it foreach (Condition cond in Conditions) { ModifyCondition(cond, Regex.Replace(cond.Expression, $"{change.OldColumn.Name}", change.NewColumn.Name)); } }
public override void RenameAttribute(Graph g, Attribute a, ColumnMetaChange change) { // Could rename the output attribute as well here, but probably best not to //foreach (Conversion conv in Conversions.Where(c => c.A == a)) //{ // conv.Output.Name = a.Name; //} }
public override void DeletionAttribute(Graph g, Attribute a, ColumnMetaChange c) { if (IsFullyDependent(a)) { g.RemoveVertex(this); } else { RemoveAttribute(a); } }
public override void DeletionAttribute(Graph g, Attribute a, ColumnMetaChange change) { // Delete all derivations, which uses this attribute for (int i = Derivations.Count - 1; i >= 0; i--) { Derivation d = Derivations[i]; if (Regex.IsMatch(d.Expr, $@"\b{a.Name}\b")) { RemoveDerivation(d); } } }
public override void RenameAttribute(Graph g, Attribute a, ColumnMetaChange change) { a.Name = change.NewColumn.Name; if (Table.JoinAttributes.Contains(a)) { ChangeJoinExpression(a, change); return; } if (Output[0].Attributes.Contains(a)) { ((IDTSOutputColumn100)a.AttributeRef).CustomPropertyCollection["CopyFromReferenceColumn"].Value = a.Name; return; } }
public override void DeletionAttribute(Graph g, Attribute a, ColumnMetaChange c) { // If no ingoing edges present, then delete vertex if (IngoingEdges().Count == 0) { g.RemoveVertex(this); return; } List <Attribute> attributes = Table.Attributes.Except(InputAttributes()).ToList(); foreach (Attribute attribute in attributes) { RemoveAttribute(attribute); } }
/// <summary> /// Change join expression /// </summary> /// <param name="a">Attribute</param> /// <param name="change">Change</param> private void ChangeJoinExpression(Attribute a, ColumnMetaChange change) { // Change affected join tuples foreach (JoinTuple joinTuple in Joins) { if (joinTuple.JoinCondition.Contains(change.OldColumn.Name)) { joinTuple.JoinCondition = joinTuple.JoinCondition.Replace($@"{change.OldColumn.Name}", a.Name); joinTuple.relatedInputColumnRef.CustomPropertyCollection["JoinToReferenceColumn"].Value = a.Name; } } // Change sql command to reflect change string value = Table.sqlCommandParam.Value; Table.sqlCommandParam.Value = value.Replace($@"{change.OldColumn.Name}", a.Name); }
/// <summary> /// Perform a change on an attribute, this includes renaming and datatype change /// </summary> /// <param name="c">Relevant ColumnMetaChange</param> public void Change(ColumnMetaChange c) { Column newColumn = c.NewColumn; Name = newColumn.Name; SetValues(newColumn); ((IDTSOutputColumn100)AttributeRef).SetDataTypeProperties(SQLtoSSIS[newColumn.DataType], CharacterMaxLength, Precision, Scale, 0); if (ExternalRef != null) { // TODO: Maybe problems if the column doesn't have precision/scale/whatever ExternalRef.DataType = SQLtoSSIS[newColumn.DataType]; ExternalRef.Length = newColumn.CharacterMaxLength; ExternalRef.Precision = newColumn.Precision; ExternalRef.Scale = newColumn.Scale; } }
public override void DeletionAttribute(Graph g, Attribute a, ColumnMetaChange change) { // If vertex is fully dependent on attribute, then delete vertex if (IsFullyDependent(a)) { Graph.RemoveVertex(this); return; } // If attribute is part of the lookup'ed attributes, then just delete it if (Table.Attributes.Contains(a)) { CleanUpRemovedAttribute(a); return; } // If the attribute isn't any of the above, then it is a passthrough and delete from the output edges. OutgoingEdges().ForEach(e => e.Attributes.Remove(a)); }
// Returns a list of vertices that currently (before the change) make use of the changed attribute. private List <Vertex> GetAffectedVertices(ColumnMetaChange change) { List <Vertex> affected = new List <Vertex>(); Attribute attribute = GetAttribute(change) ?? new Attribute { Name = change?.OldColumn.Name ?? change?.NewColumn.Name, SourceTable = change?.OldColumn.Table.Name ?? change?.NewColumn.Table.Name, SourceDatabase = change?.OldColumn.Table.Database.Name ?? change?.NewColumn.Table.Database.Name }; foreach (Vertex v in Vertices) { if (v.UsesAttribute(attribute)) { affected.Add(v); } } return(affected); }
/// <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); } } }
/// <summary> /// Called when an attribute changes datatype /// </summary> /// <param name="g">Graph to affect</param> /// <param name="a">Attribute to change</param> /// <param name="change">Column meta change</param> public abstract void DataTypeAttribute(Graph g, Attribute a, ColumnMetaChange change);
/// <summary> /// Called when an attribute should be renamed /// </summary> /// <param name="g">Graph to affect</param> /// <param name="a">Attribute to rename</param> /// <param name="change">Column meta change</param> public abstract void RenameAttribute(Graph g, Attribute a, ColumnMetaChange change);
/// <summary> /// Called when an attribute should be deleted from a vertex /// </summary> /// <param name="g">Graph to affect</param> /// <param name="a">Attribute to delete</param> /// <param name="change">Column meta change</param> public abstract void DeletionAttribute(Graph g, Attribute a, ColumnMetaChange change);
public override void RenameAttribute(Graph g, Attribute a, ColumnMetaChange change) { // No need to do anything }
/// <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; } }
public override void AdditionAttribute(Graph g, Attribute a, ColumnMetaChange c) { AddAttribute(a); }
public override void RenameAttribute(Graph g, Attribute a, ColumnMetaChange c) { a.Name = c.NewColumn.Name; }
public override void DeletionAttribute(Graph g, Attribute a, ColumnMetaChange change) { CleanUpRemovedAttribute(a); }
public override void RenameAttribute(Graph g, Attribute a, ColumnMetaChange c) { // No renaming required }
public override void DataTypeAttribute(Graph g, Attribute a, ColumnMetaChange change) { throw new NotImplementedException(); }
public override void AdditionAttribute(Graph g, Attribute a, ColumnMetaChange c) { throw new NotImplementedException(); }