Пример #1
0
        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);
            }
        }
Пример #2
0
        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());
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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);
                    }
                }
            }
        }
Пример #5
0
        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);
            }
        }
Пример #6
0
        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;
            }
        }
Пример #7
0
        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);
            }
        }
Пример #8
0
 private void Settings_ValidationEventHandler(object sender, ValidationEventArgs e)
 {
     MessageEngine.Trace(Severity.Error, "TemplateManager: Schema Validation Error: " + e.Message);
 }
Пример #9
0
 private void Settings_ValidationEventHandler(object sender, ValidationEventArgs e)
 {
     MessageEngine.Trace(Severity.Error, "PhaseWorkflowLoader: Schema Validation Error: " + e.Message);
 }
Пример #10
0
        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);
        }
Пример #11
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);
                    }
                }
            }
        }
Пример #12
0
        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);
                            }
                        }
                    }
                }
            }
        }
Пример #13
0
        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();
            }
        }