private void ApplyColumnUsageMapping(Dictionary <string, MergeColumnUsage> columnUsageMapping, AstTableColumnBaseNode column, StringBuilder notEqualBuilder, StringBuilder updateBuilder, StringBuilder insertParamBuilder, StringBuilder insertValueBuilder) { var usage = columnUsageMapping[column.ToString().ToUpperInvariant()]; bool compare = false; bool update = false; bool insert = false; switch (usage) { // Explicit truth table for safety case VulcanEngine.IR.Ast.Task.MergeColumnUsage.Compare: compare = true; update = false; insert = false; break; case VulcanEngine.IR.Ast.Task.MergeColumnUsage.CompareInsert: compare = true; update = false; insert = true; break; case VulcanEngine.IR.Ast.Task.MergeColumnUsage.CompareUpdate: compare = true; update = true; insert = false; break; case VulcanEngine.IR.Ast.Task.MergeColumnUsage.CompareUpdateInsert: compare = true; update = true; insert = true; break; case VulcanEngine.IR.Ast.Task.MergeColumnUsage.Insert: compare = false; update = false; insert = true; break; case VulcanEngine.IR.Ast.Task.MergeColumnUsage.Update: compare = false; update = true; insert = false; break; case VulcanEngine.IR.Ast.Task.MergeColumnUsage.UpdateInsert: compare = false; update = true; insert = true; break; case VulcanEngine.IR.Ast.Task.MergeColumnUsage.Exclude: compare = false; update = false; insert = false; break; default: MessageEngine.Trace(_mergeTask, Severity.Error, "SSISMT02", "MergeColumnUsage: {0} is not supported.", usage); break; } if (compare) { AppendNotEqual(column, notEqualBuilder); } if (update) { AppendUpdate(column, updateBuilder); } if (insert) { AppendInsertValue(column, insertParamBuilder, insertValueBuilder); } }
public string Emit() { // BUGBUG - Currently ColumnName is a string in AstMergeColumnNode. I dont want to change the binding as it would impact // the 2.0 to 2.5 customer ports since it would require a qualified name. var columnUsageMapping = new Dictionary <string, AST.Task.MergeColumnUsage>(); foreach (AST.Task.AstMergeColumnNode mergeColumn in _mergeTask.Columns) { columnUsageMapping[mergeColumn.ColumnName.ToUpperInvariant()] = mergeColumn.ColumnUsage; } var targetTable = (AST.Table.AstTableNode)_mergeTask.TargetConstraint.ParentItem; var joinBuilder = new StringBuilder(); var notEqualBuilder = new StringBuilder(); var updateBuilder = new StringBuilder(); var insertParamBuilder = new StringBuilder(); var insertValueBuilder = new StringBuilder(); bool hasIdentityColumn = false; for (int i = 0; i < _mergeTask.TargetConstraint.Columns.Count; i++) { joinBuilder.AppendFormat("TARGET.[{0}] = SOURCE.[{0}]", _mergeTask.TargetConstraint.Columns[i].Column.Name); if (i < _mergeTask.TargetConstraint.Columns.Count - 1) { joinBuilder.AppendLine("\nAND"); } } foreach (AST.Table.AstTableColumnBaseNode column in targetTable.Columns) { if (!columnUsageMapping.ContainsKey(column.Name.ToUpperInvariant())) { // - Identity Columns, unless explicitly handled in the Usage Mapping, should be excluded from merge. if (column.IsIdentityColumn) { columnUsageMapping[column.Name.ToUpperInvariant()] = AST.Task.MergeColumnUsage.Exclude; } else { columnUsageMapping[column.Name.ToUpperInvariant()] = _mergeTask.UnspecifiedColumnDefaultUsageType; } } if (column.IsIdentityColumn) { switch (columnUsageMapping[column.Name.ToUpperInvariant()]) { case MergeColumnUsage.CompareInsert: hasIdentityColumn = true; break; case MergeColumnUsage.CompareUpdateInsert: hasIdentityColumn = true; break; case MergeColumnUsage.Insert: hasIdentityColumn = true; break; case MergeColumnUsage.UpdateInsert: hasIdentityColumn = true; break; default: break; } } if (column.IsAssignable || column.IsIdentityColumn) { if (columnUsageMapping.ContainsKey(column.ToString().ToUpperInvariant())) { ApplyColumnUsageMapping(columnUsageMapping, column, notEqualBuilder, updateBuilder, insertParamBuilder, insertValueBuilder); } else { MessageEngine.Trace(_mergeTask, AstFramework.Severity.Error, "SSISMT001", "Column {0} does not exist in the target table and could not be mapped.", column.Name); } } } // Complete NotEqualBuilder string notEqualString = notEqualBuilder.Length > 0 ? String.Format(CultureInfo.InvariantCulture, "\nAND\n(\n{0}\n)", notEqualBuilder.ToString()) : string.Empty; string queryHints = _mergeTask.TableLock ? "WITH(TABLOCK)" : String.Empty; TemplatePlatformEmitter te; if (updateTemplateRequired) { te = new TemplatePlatformEmitter("Merge", _mergeTask.SourceTable.SchemaQualifiedName, targetTable.SchemaQualifiedName, joinBuilder.ToString(), notEqualString, updateBuilder.ToString(), insertParamBuilder.ToString(), insertValueBuilder.ToString(), queryHints); } else { te = new TemplatePlatformEmitter("MergeWithoutUpdate", _mergeTask.SourceTable.SchemaQualifiedName, targetTable.SchemaQualifiedName, joinBuilder.ToString(), insertParamBuilder.ToString(), insertValueBuilder.ToString(), queryHints); } var finalBuilder = new StringBuilder(); if (hasIdentityColumn) { finalBuilder.AppendFormat("\nSET IDENTITY_INSERT {0} ON\n", targetTable.SchemaQualifiedName); } finalBuilder.AppendLine(te.Emit()); if (hasIdentityColumn) { finalBuilder.AppendFormat("\nSET IDENTITY_INSERT {0} OFF\n", targetTable.SchemaQualifiedName); } return(finalBuilder.ToString()); }
protected DataType GetDataTypeFromString(ColumnType ColumnType) { switch (ColumnType) { case ColumnType.AnsiString: return(DataType.DT_STR); case ColumnType.Binary: return(DataType.DT_BYTES); case ColumnType.Byte: return(DataType.DT_UI1); case ColumnType.Boolean: return(DataType.DT_BOOL); case ColumnType.Currency: return(DataType.DT_CY); case ColumnType.Date: return(DataType.DT_DBDATE); case ColumnType.DateTime: return(DataType.DT_DBTIMESTAMP); case ColumnType.Decimal: return(DataType.DT_DECIMAL); case ColumnType.Double: return(DataType.DT_R8); case ColumnType.Guid: return(DataType.DT_GUID); case ColumnType.Int16: return(DataType.DT_I2); case ColumnType.Int32: return(DataType.DT_I4); case ColumnType.Int64: return(DataType.DT_I8); case ColumnType.Object: return(DataType.DT_EMPTY); case ColumnType.SByte: return(DataType.DT_I1); case ColumnType.Single: return(DataType.DT_R4); case ColumnType.String: return(DataType.DT_WSTR); case ColumnType.Time: return(DataType.DT_DBTIME); case ColumnType.UInt16: return(DataType.DT_UI2); case ColumnType.UInt32: return(DataType.DT_UI4); case ColumnType.UInt64: return(DataType.DT_UI8); case ColumnType.VarNumeric: return(DataType.DT_NUMERIC); case ColumnType.AnsiStringFixedLength: return(DataType.DT_STR); case ColumnType.StringFixedLength: return(DataType.DT_WSTR); case ColumnType.Xml: return(DataType.DT_NTEXT); case ColumnType.DateTime2: return(DataType.DT_DBTIMESTAMP2); case ColumnType.DateTimeOffset: return(DataType.DT_DBTIMESTAMPOFFSET); default: MessageEngine.Trace(_astDerivedColumnListNode, Severity.Error, "V0104", "Error in Type {0} - Unhandled VULCAN SSIS Type", ColumnType.ToString()); return(DataType.DT_NULL); } }
public static void LowerCloneTable(IReferenceableItem item) { var cloneTableNode = item as AstTableCloneNode; if (cloneTableNode != null && item.FirstThisOrParent <ITemplate>() == null) { foreach (var column in cloneTableNode.Columns) { // The IsNullable rework below is due to a bug in the Clone() function // of the AST. A later version of the AST Framework is necessary to fix this issue. var preClonedColumn = FindColumnInClonedTable(cloneTableNode, column.Name); if (preClonedColumn != null) { if (cloneTableNode.NullClonedColumns) { column.IsNullable = true; } else { column.IsNullable = preClonedColumn.IsNullable; } } else { throw new Exception(String.Format("CloneTableLowerer: Could not find cloned column {0} in original table.", column.Name)); } var columnTableReference = column as AstTableColumnTableReferenceNode; var columnDimensionReference = column as AstTableColumnDimensionReferenceNode; if (columnTableReference != null || columnDimensionReference != null) { var originalColumn = FindColumnInClonedTable(cloneTableNode, column.Name); var originalColumnTableReference = originalColumn as AstTableColumnTableReferenceNode; var originalColumnDimensionReference = originalColumn as AstTableColumnDimensionReferenceNode; if (originalColumnTableReference != null && columnTableReference != null) { columnTableReference.Table = originalColumnTableReference.Table; if (!string.IsNullOrEmpty(originalColumnTableReference.ForeignKeyNameOverride)) { columnTableReference.ForeignKeyNameOverride = string.Empty; } } else if (originalColumnDimensionReference != null && columnDimensionReference != null) { columnDimensionReference.Dimension = originalColumnDimensionReference.Dimension; if (!string.IsNullOrEmpty(columnDimensionReference.ForeignKeyNameOverride)) { columnDimensionReference.ForeignKeyNameOverride = string.Empty; } } ((AstTableColumnTableReferenceBaseNode)column).EnforceForeignKeyConstraint = false; } } if (cloneTableNode.CloneStaticSources) { MessageEngine.Trace(cloneTableNode, Severity.Error, "CT001", "CloneStaticSources=\"true\" is not supported at this time."); } if (cloneTableNode.CloneKeys) { int keyCount = 0; foreach (var key in cloneTableNode.Table.Keys) { var clone = (AstTableKeyBaseNode)key.Clone(); clone.Name = String.Format(CultureInfo.InvariantCulture, "CTK_{0}_{1}", cloneTableNode.Name, keyCount++); cloneTableNode.Keys.Add(clone); } } if (cloneTableNode.CloneIndexes) { int indexCount = 0; foreach (var index in cloneTableNode.Table.Indexes) { var clone = (AstTableIndexNode)index.Clone(); clone.Name = String.Format(CultureInfo.InvariantCulture, "CTX_{0}_{1}", cloneTableNode.Name, indexCount++); cloneTableNode.Indexes.Add(clone); } } } }
public override void Emit(SsisEmitterContext context) { MessageEngine.Trace(Severity.Notification, "Emitting Package {0}", PackagePath); DtsPackage.TransactionOption = (Microsoft.SqlServer.Dts.Runtime.DTSTransactionOption) Enum.Parse(typeof(Microsoft.SqlServer.Dts.Runtime.DTSTransactionOption), TransactionMode); DtsPackage.EnableConfigurations = true; switch (this.PackageProtectionLevel) { case AST.Task.ProtectionLevel.DontSaveSensitive: DtsPackage.ProtectionLevel = DTSProtectionLevel.DontSaveSensitive; break; case AST.Task.ProtectionLevel.EncryptAllWithPassword: DtsPackage.ProtectionLevel = DTSProtectionLevel.EncryptAllWithPassword; break; case AST.Task.ProtectionLevel.EncryptAllWithUserKey: DtsPackage.ProtectionLevel = DTSProtectionLevel.EncryptAllWithUserKey; break; case AST.Task.ProtectionLevel.EncryptSensitiveWithPassword: DtsPackage.ProtectionLevel = DTSProtectionLevel.EncryptSensitiveWithPassword; break; case AST.Task.ProtectionLevel.EncryptSensitiveWithUserKey: DtsPackage.ProtectionLevel = DTSProtectionLevel.EncryptSensitiveWithUserKey; break; case AST.Task.ProtectionLevel.ServerStorage: DtsPackage.ProtectionLevel = DTSProtectionLevel.ServerStorage; break; default: DtsPackage.ProtectionLevel = DTSProtectionLevel.DontSaveSensitive; break; } if (!string.IsNullOrEmpty(this.PackagePassword)) { DtsPackage.PackagePassword = this.PackagePassword; } _DTSApplication.UpdatePackage = true; _DTSApplication.UpdateObjects = true; Directory.CreateDirectory(PackageFolder); context = new SsisEmitterContext(this, this, context.ProjectManager); PackageRootVariable.Initialize(context); PackageRootVariable.Emit(context); try { // Step #1 - i need to emit connection nodes and PackageConfig nodes first first var preEmittedNodeList = new List <PhysicalObject>(); foreach (PhysicalObject po in this) { if (po is Connections.Connection || po is PackageConfiguration) { po.Initialize(context); po.Emit(context); preEmittedNodeList.Add(po); } } // Re-Initialize pre-emitted connection nodes and then remove // unused nodes so they no longer emit in the tree. foreach (var node in preEmittedNodeList) { node.Parent = null; } base.Emit(context); Save(); } catch (Exception e) { Save(); MessageEngine.Trace(Severity.Error, e, e.Message); } }
public override void Emit(SsisEmitterContext context) { ProcessBindings(context); // TODO: Add Input column custom property mapping foreach (var column in _astSlowlyChangingDimensionNode.Mappings) { int columnType; switch (column.MappingType) { case ScdColumnMappingType.ChangingAttribute: columnType = 2; break; case ScdColumnMappingType.FixedAttribute: columnType = 4; break; case ScdColumnMappingType.HistoricalAttribute: columnType = 3; break; case ScdColumnMappingType.Key: columnType = 1; break; case ScdColumnMappingType.Other: columnType = 0; break; default: MessageEngine.Trace(_astSlowlyChangingDimensionNode, Severity.Error, "V0140", "Unrecognized ScdColumnMappingType {0} on column {1}", column.MappingType.ToString(), column.QueryColumnName); return; } IDTSInputColumn100 inputColumn = TransformationUtility.FindInputColumnByName(column.QueryColumnName, Component.InputCollection[0], true); if (inputColumn == null) { IDTSVirtualInputColumn100 virtualInputColumn = TransformationUtility.FindVirtualInputColumnByName(column.QueryColumnName, Component.InputCollection[0], true); if (virtualInputColumn == null) { MessageEngine.Trace(_astSlowlyChangingDimensionNode, Severity.Error, "V0141", "Column {0} could not be found", column.QueryColumnName); return; } inputColumn = Component.InputCollection[0].InputColumnCollection.New(); inputColumn.Name = column.QueryColumnName; inputColumn.LineageID = virtualInputColumn.LineageID; } IDTSCustomProperty100 propColumnType = TransformationUtility.FindCustomPropertyByName("ColumnType", inputColumn.CustomPropertyCollection, true); if (propColumnType == null) { propColumnType = inputColumn.CustomPropertyCollection.New(); propColumnType.Name = "ColumnType"; propColumnType.TypeConverter = "ColumnType"; } propColumnType.Value = columnType; } }
private void LoadWorkflows() { var assembly = Assembly.GetExecutingAssembly(); _phaseWorkflowSchemaSet = new XmlSchemaSet(); _phaseWorkflowSchemaSet.Add(null, XmlReader.Create(assembly.GetManifestResourceStream("VulcanEngine.Content.xsd.VulcanPhaseWorkflows.xsd"))); var settings = new XmlReaderSettings { ValidationType = ValidationType.Schema, Schemas = _phaseWorkflowSchemaSet }; settings.ValidationEventHandler += Settings_ValidationEventHandler; XDocument doc = XDocument.Load(XmlReader.Create(assembly.GetManifestResourceStream("VulcanEngine.VulcanPhaseWorkflows.xml"), settings)); // TODO: VSABELLA: REVIEW Remove hardcode schema for now, and load it from the document itself with XPathNavigator.GetNamespaceInScope. XNamespace ns = "http://schemas.microsoft.com/detego/2007/07/07/VulcanPhaseWorkflows.xsd"; _defaultWorkflowName = doc.Root.Attribute("DefaultWorkflow").Value; var phaseWorkflows = from pw in doc.Descendants(ns + "PhaseWorkflow") select new { Name = pw.Attribute("Name").Value, Phases = from phase in pw.Descendants(ns + "Phase") select new { Name = phase.Attribute("PhaseName").Value, WorkflowUniqueName = phase.Attribute("WorkflowUniqueName").Value, Parameters = from param in phase.Descendants(ns + "Parameter") select new { Name = param.Attribute("Name").Value, Type = param.Attribute("Type").Value, Value = param.Value } }, IRVectors = from irVector in pw.Descendants(ns + "IRFlowVector") select new { SourceWorkflowUniqueName = irVector.Attribute("SourceWorkflowUniqueName").Value, SinkWorkflowUniqueName = irVector.Attribute("SinkWorkflowUniqueName").Value } }; foreach (var phaseWorkflow in phaseWorkflows) { if (!_phaseWorkflowsByName.ContainsKey(phaseWorkflow.Name)) { var workflow = new PhaseWorkflow(phaseWorkflow.Name); _phaseWorkflowsByName.Add(workflow.Name, workflow); foreach (var phase in phaseWorkflow.Phases) { var parametersCollection = new Dictionary <string, object>(); parametersCollection.Add("workflowUniqueName", phase.WorkflowUniqueName); // Error Pathing needs to be reworked in this segment: this is being fixed up and put into Phase.cs foreach (var param in phase.Parameters) { Type paramType = Type.GetType("System." + param.Type, false, false); if (paramType != null) { object convertedValue = param.Value; ////VulcanTypeConverter.Convert(param.Value, paramType); if (!parametersCollection.ContainsKey(param.Name)) { parametersCollection.Add(param.Name, convertedValue); } else { MessageEngine.Trace(Severity.Error, Resources.ErrorDuplicatePhaseParameterSpecified, phase.WorkflowUniqueName, param.Name); return; } } else { MessageEngine.Trace(Severity.Error, Resources.ErrorInvalidPhaseParameterType, phase.WorkflowUniqueName, param.Name); return; } } // end foreach var param workflow.AddPhase(phase.WorkflowUniqueName, _phasePluginLoader.RetrievePhase(phase.Name, parametersCollection)); } // end foreach Phase foreach (var vector in phaseWorkflow.IRVectors) { workflow.AddIRFlowVector(vector.SourceWorkflowUniqueName, vector.SinkWorkflowUniqueName); } // end foreach irVector inside of the phaseWorkflow } else { MessageEngine.Trace(Severity.Error, Resources.ErrorAttemptedWorkflowDuplicatename, phaseWorkflow.Name); } } // end foreach PhaseWorkflows if (!_phaseWorkflowsByName.ContainsKey(_defaultWorkflowName)) { MessageEngine.Trace(Severity.Error, Resources.ErrorInvalidWorkflowDefaultName, _defaultWorkflowName); } }
private void Settings_ValidationEventHandler(object sender, ValidationEventArgs e) { MessageEngine.Trace(Severity.Error, "TemplateManager: Schema Validation Error: " + e.Message); }
private void Settings_ValidationEventHandler(object sender, ValidationEventArgs e) { MessageEngine.Trace(Severity.Error, "PhaseWorkflowLoader: Schema Validation Error: " + e.Message); }
public override bool Execute() { MessageEngine.MSBuildTask = this; MessageEngine.Trace(Severity.Notification, Resources.VulcanStart + Assembly.GetExecutingAssembly().GetName().Version); try { InitializeVulcanParameters(); var workflowLoader = new PhaseWorkflowLoader(); PhaseWorkflow workflow = workflowLoader.PhaseWorkflowsByName[workflowLoader.DefaultWorkflowName]; PathManager.TargetPath = Path.GetFullPath(OutputPath) + Path.DirectorySeparatorChar + Path.DirectorySeparatorChar; var xmlIR = new XmlIR(); if (!String.IsNullOrEmpty(TemplatePath)) { xmlIR.TemplatePath = Path.GetFullPath(TemplatePath) + Path.DirectorySeparatorChar; } if (Sources != null) { foreach (ITaskItem item in Sources) { string filename = item.ItemSpec; if (File.Exists(filename)) { xmlIR.AddXml(Path.GetFullPath(filename), XmlIRDocumentType.Source, true); } else { MessageEngine.Trace(Severity.Error, new FileNotFoundException("Vulcan File Not Found", filename), Resources.VulcanFileNotFound, filename); } } } if (Includes != null) { foreach (ITaskItem item in Includes) { string filename = item.ItemSpec; if (File.Exists(filename)) { xmlIR.AddXml(Path.GetFullPath(filename), XmlIRDocumentType.Include, true); } else { MessageEngine.Trace(Severity.Error, new FileNotFoundException("Vulcan File Not Found", filename), Resources.VulcanFileNotFound, filename); } } } workflow.ExecutePhaseWorkflowGraph(xmlIR); } catch (Exception e) { MessageEngine.Trace(Severity.Error, e, "One or more fatal errors were encountered!"); } return((MessageEngine.ErrorCount + MessageEngine.WarningCount) <= 0); }
protected void ProcessMappings() { IDTSVirtualInput100 cvi = Component.InputCollection[0].GetVirtualInput(); var virtualInputDictionary = new Dictionary <string, IDTSVirtualInputColumn100>(); foreach (IDTSVirtualInputColumn100 vc in cvi.VirtualInputColumnCollection) { virtualInputDictionary["@" + vc.Name.ToUpperInvariant()] = vc; } // Automatically map columns foreach (IDTSExternalMetadataColumn100 extCol in Component.InputCollection[0].ExternalMetadataColumnCollection) { if (virtualInputDictionary.ContainsKey(extCol.Name.ToUpperInvariant())) { IDTSVirtualInputColumn100 vc = virtualInputDictionary[extCol.Name.ToUpperInvariant()]; Instance.SetUsageType(Component.InputCollection[0].ID, cvi, vc.LineageID, DTSUsageType.UT_READONLY); Component.InputCollection[0].InputColumnCollection[vc.Name].ExternalMetadataColumnID = extCol.ID; } } // Map any overrides foreach (AstDataflowColumnMappingNode mapping in _astOleDBCommandNode.Query.Mappings) { if (String.IsNullOrEmpty(mapping.TargetName)) { SetInputColumnUsage(0, mapping.SourceName, DTSUsageType.UT_IGNORED, true); } else { IDTSExternalMetadataColumn100 ecol = TransformationUtility.FindExternalColumnByName(mapping.TargetName, Component.InputCollection[0].ExternalMetadataColumnCollection, true); // Unmap anything else that maps to this external metadata column) foreach (IDTSInputColumn100 inputColumn in Component.InputCollection[0].InputColumnCollection) { if (inputColumn.ExternalMetadataColumnID == ecol.ID) { MessageEngine.Trace(_astOleDBCommandNode, Severity.Debug, "V0401", "{0}: {1} Unmapping Input {2}", GetType(), Component.Name, inputColumn.Name); SetInputColumnUsage(0, inputColumn.Name, DTSUsageType.UT_IGNORED, true); break; } } IDTSInputColumn100 icol = SetInputColumnUsage(0, mapping.SourceName, DTSUsageType.UT_READONLY, false); if (ecol != null) { if (icol != null) { icol.ExternalMetadataColumnID = ecol.ID; } else { MessageEngine.Trace(_astOleDBCommandNode, Severity.Error, "V0105", "Could not find source column {0}", mapping.SourceName); } } else { MessageEngine.Trace(_astOleDBCommandNode, Severity.Error, "V0106", "Could not find destination column {0}", mapping.TargetName); } } } }
public static void ProcessEtlFragments(SymbolTable symbolTable) ////HashSet<AstEtlRootNode> astEtlRootNodes) { var snapshotSymbolTable = new List <IReferenceableItem>(symbolTable); foreach (var astNamedNode in snapshotSymbolTable) { var fragmentReference = astNamedNode as AstEtlFragmentReferenceNode; if (fragmentReference != null && astNamedNode.FirstThisOrParent <ITemplate>() == null) { AstLowererValidation.ValidateEtlFragment(fragmentReference.EtlFragment); AstLowererValidation.ValidateEtlFragmentReference(fragmentReference); var clonedFragment = fragmentReference.EtlFragment.Clone() as AstEtlFragmentNode; var fragmentGraph = new TransformationGraph(clonedFragment.Transformations); GraphNode <AstTransformationNode> sourceNode = fragmentGraph.RootNodes.FirstOrDefault(node => !(node.Item is AstSourceTransformationNode)); GraphNode <AstTransformationNode> sinkNode = fragmentGraph.RootNodes.FirstOrDefault(node => !(node.Item is AstSourceTransformationNode)); Utility.Replace(fragmentReference, clonedFragment.Transformations); var etlGraph = new TransformationGraph(Utility.GetParentTransformationCollection(fragmentReference)); if (sourceNode != null) { GraphNode <AstTransformationNode> etlSourceNode = etlGraph.FindNode(sourceNode.Item); AstSingleInTransformationNode source = etlSourceNode.Item as AstSingleInTransformationNode; if (source != null && etlSourceNode.IncomingEdges.Count == 1) { source.InputPath = new AstDataflowMappedInputPathNode(source); if (fragmentReference.InputPath != null) { source.InputPath.OutputPath = fragmentReference.InputPath.OutputPath; } else if (etlSourceNode.IncomingEdges.Count == 1 && etlSourceNode.IncomingEdges[0].Source.Item.PreferredOutputPath != null) { source.InputPath.OutputPath = etlSourceNode.IncomingEdges[0].Source.Item.PreferredOutputPath; } else { MessageEngine.Trace(fragmentReference, Severity.Error, "V0136", "Cannot find output path to bind to the root node of Etl Fragment {0}", fragmentReference.Name); } foreach (var inputMapping in fragmentReference.Inputs) { var currentMapping = new AstDataflowColumnMappingNode(source.InputPath) { SourceName = inputMapping.SourcePathColumnName, TargetName = inputMapping.DestinationPathColumnName, }; source.InputPath.Mappings.Add(currentMapping); } } } if (sinkNode != null) { GraphNode <AstTransformationNode> etlSinkNode = etlGraph.FindNode(sinkNode.Item); if (etlSinkNode.OutgoingEdges.Count > 1) { MessageEngine.Trace(fragmentReference, Severity.Error, "V0136", "Sink nodes of Etl Fragment {0} can only have a single outgoing edge", fragmentReference.Name); } if (etlSinkNode.OutgoingEdges.Count > 0) { AstSingleInTransformationNode successor = etlSinkNode.OutgoingEdges[0].Sink.Item as AstSingleInTransformationNode; if (successor != null) { ProcessSuccessor(fragmentReference, clonedFragment, etlSinkNode, successor); } } } } } }
private void _loadWorkflows() { string phaseWorkflowDescriptorPath = PathManager.GetToolSubpath(Settings.Default.SubpathDefaultPhaseWorkflowFile); this.Message = MessageEngine.Create(String.Format("__PHASE WORKFLOW LOADER: {0}", phaseWorkflowDescriptorPath)); XDocument doc = XDocument.Load(phaseWorkflowDescriptorPath); //TODO: VSABELLA: REVIEW Remove hardcode schema for now, and load it from the document itself with XPathNavigator.GetNamespaceInScope. XNamespace ns = "http://schemas.microsoft.com/detego/2007/07/07/VulcanPhaseWorkflows.xsd"; this._defaultWorkflowName = doc.Root.Attribute("DefaultWorkflow").Value; var phaseWorkflows = from pw in doc.Descendants(ns + "PhaseWorkflow") select new { Name = pw.Attribute("Name").Value, Phases = (from phase in pw.Descendants(ns + "Phase") select new { Name = phase.Attribute("PhaseName").Value, WorkflowUniqueName = phase.Attribute("WorkflowUniqueName").Value, Parameters = (from param in phase.Descendants(ns + "Parameter") select new { Name = param.Attribute("Name").Value, Type = param.Attribute("Type").Value, Value = param.Value }) }), IRVectors = (from irVector in pw.Descendants(ns + "IRFlowVector") select new { SourceWorkflowUniqueName = irVector.Attribute("SourceWorkflowUniqueName").Value, SinkWorkflowUniqueName = irVector.Attribute("SinkWorkflowUniqueName").Value }) }; foreach (var phaseWorkflow in phaseWorkflows) { if (!this._phaseWorkflowsByName.ContainsKey(phaseWorkflow.Name)) { PhaseWorkflow workflow = new PhaseWorkflow(phaseWorkflow.Name); this._phaseWorkflowsByName.Add(workflow.Name, workflow); foreach (var phase in phaseWorkflow.Phases) { Dictionary <string, object> parametersCollection = new Dictionary <string, object>(); parametersCollection.Add("WorkflowUniqueName", phase.WorkflowUniqueName); // Error Pathing needs to be reworked in this segment: this is being fixed up and put into Phase.cs foreach (var param in phase.Parameters) { Type paramType = Type.GetType("System." + param.Type, false, false); if (paramType != null) { object convertedValue = TypeConverter.Convert(param.Value, paramType); if (!parametersCollection.ContainsKey(param.Name)) { parametersCollection.Add(param.Name, convertedValue); } else { Message.Trace(Severity.Error, Resources.ErrorDuplicatePhaseParameterSpecified, phase.WorkflowUniqueName, param.Name); return; } } else { Message.Trace(Severity.Error, Resources.ErrorInvalidPhaseParameterType, phase.WorkflowUniqueName, param.Name); return; } } // end foreach var param workflow.AddPhase(phase.WorkflowUniqueName, this._phasePluginLoader.RetrievePhase(phase.Name, parametersCollection)); } // end foreach Phase foreach (var irVector in phaseWorkflow.IRVectors) { workflow.AddIRFlowVector(irVector.SourceWorkflowUniqueName, irVector.SinkWorkflowUniqueName); } // end foreach irVector inside of the phaseWorkflow } else { Message.Trace(Severity.Error, Resources.ErrorAttemptedWorkflowDuplicatename, phaseWorkflow.Name); } } // end foreach PhaseWorkflows if (!this._phaseWorkflowsByName.ContainsKey(this._defaultWorkflowName)) { Message.Trace(Severity.Error, Resources.ErrorInvalidWorkflowDefaultName, this._defaultWorkflowName); throw new Exception(); } }