private static void ComputeRootsAndSuccessors(AstTask.AstContainerTaskNode container, IEnumerable <AstTaskNode> unsortedTransformations, HashSet <AstTaskNode> roots, Dictionary <AstTaskNode, ICollection <AstTaskNode> > successors)
        {
            AstTaskNode previousTransformation = null;

            foreach (var transformation in unsortedTransformations)
            {
                HashSet <AstTaskNode> predecessors = FindPredecessors(container, transformation, previousTransformation, successors);

                if (predecessors.Count == 0)
                {
                    roots.Add(transformation);
                }

                foreach (var predecessor in predecessors)
                {
                    if (!successors.ContainsKey(predecessor))
                    {
                        successors.Add(predecessor, new HashSet <AstTaskNode>());
                    }

                    successors[predecessor].Add(transformation);
                }

                previousTransformation = transformation;
            }
        }
        private static List <AstTaskNode> SortTasks(AstTask.AstContainerTaskNode container, IEnumerable <AstTaskNode> unsortedTasks)
        {
            var roots      = new HashSet <AstTaskNode>();
            var successors = new Dictionary <AstTaskNode, ICollection <AstTaskNode> >();

            ComputeRootsAndSuccessors(container, unsortedTasks, roots, successors);
            return(FlowSorter.TopologicalSort(roots, successors));
        }
Beispiel #3
0
        // TODO: We've made the call to just use the staging node as the lowered container rather than creating a new one and copying everything over
        public static void ProcessContainers(SymbolTable symbolTable)
        {
            var snapshotSymbolTable = new List<IReferenceableItem>(symbolTable);
            foreach (var astNamedNode in snapshotSymbolTable)
            {
                var stagingNode = astNamedNode as AstStagingContainerTaskNode;
                if (stagingNode != null && astNamedNode.FirstThisOrParent<ITemplate>() == null)
                {
                    var stagingCreateContainer = new AstContainerTaskNode(stagingNode)
                    {
                        Name = String.Format(CultureInfo.InvariantCulture, Properties.Resources.CreateStaging, stagingNode.Name),
                        Log = false,
                    };

                    var stagingDropContainer = new AstContainerTaskNode(stagingNode)
                    {
                        Name = String.Format(CultureInfo.InvariantCulture, Properties.Resources.DropStaging, stagingNode.Name),
                        Log = false,
                    };

                    stagingNode.Tasks.Insert(0, stagingCreateContainer);
                    stagingNode.Tasks.Add(stagingDropContainer);

                    foreach (var baseTable in stagingNode.Tables)
                    {
                        var table = baseTable as AstTableNode;
                        if (table != null)
                        {
                            TableLowerer.LowerTable(
                                stagingCreateContainer,
                                table,
                                String.Format(CultureInfo.InvariantCulture, Properties.Resources.CreateStagingTable, table.Name),
                                stagingNode.ExecuteDuringDesignTime);

                            var dropStagingTemplate = new TemplatePlatformEmitter("DropStagingTable", table.SchemaQualifiedName);
                            var dropTableExecuteSqlTask = new AstExecuteSqlTaskNode(stagingNode)
                                                              {
                                                                  Name = StringManipulation.NameCleanerAndUniqifier(String.Format(CultureInfo.InvariantCulture, Properties.Resources.DropStagingTable, table.Name)),
                                                                  Connection = table.Connection,
                                                                  ExecuteDuringDesignTime = stagingNode.ExecuteDuringDesignTime,
                                                              };
                            dropTableExecuteSqlTask.Query = new AstExecuteSqlQueryNode(dropTableExecuteSqlTask) { QueryType = QueryType.Standard, Body = dropStagingTemplate.Emit() };
                            stagingDropContainer.Tasks.Add(dropTableExecuteSqlTask);
                        }
                        else
                        {
                            throw new System.NotSupportedException("AstLowering - StagingContainer - a Table Template node was found when lowering staging containers and I don't know what to do with it.");
                        }
                    }
                }
            }
        }
        private static void LowerChildren(AstTask.AstContainerTaskNode container, LoweringContext context)
        {
            foreach (AstTask.AstVariableNode variable in container.Variables)
            {
                PhysicalLoweringProcessor.Lower(variable, context);
            }

            var sortedTasks = SortTasks(container, container.Tasks);

            foreach (AstTask.AstTaskNode task in sortedTasks)
            {
                PhysicalLoweringProcessor.Lower(task, context);
            }
        }
Beispiel #5
0
        private static void _packageBuildOnEndEvent(AstPackageBaseNode package)
        {
            var packageEvent = ContainerFindEvent(package.Events, EventType.OnPostExecute);

            if (packageEvent == null)
            {
                packageEvent = new AstTaskEventHandlerNode(package) { EventType = EventType.OnPostExecute };
                package.Events.Add(packageEvent);
            }

            var postExecContainer = new AstContainerTaskNode(packageEvent) { Name = "OnPostExec", ConstraintMode = ContainerConstraintMode.Linear };
            packageEvent.Tasks.Insert(0, postExecContainer);

            var constrainedCont = new AstContainerTaskNode(packageEvent) { Name = "ConstrainedContainer", ConstraintMode = ContainerConstraintMode.Parallel };
            postExecContainer.Tasks.Add(constrainedCont);

            var executeSql = new AstExecuteSqlTaskNode(postExecContainer)
                                 {
                                     Name = "Exec usp_PackageEnd",
                                     ExecuteDuringDesignTime = false,
                                     Connection = package.LogConnection
                                 };
            executeSql.PrecedenceConstraints = new AstTaskflowPrecedenceConstraintsNode(executeSql);
            executeSql.PrecedenceConstraints.Inputs.Add(
                new AstTaskflowInputPathNode(executeSql.PrecedenceConstraints)
                {
                    Expression = "@[System::PackageID] == @[System::SourceID]",
                    EvaluationOperation = TaskEvaluationOperationType.Expression,
                    OutputPath = constrainedCont.OutputPath
                });
            executeSql.Query = new AstExecuteSqlQueryNode(executeSql)
                                   {
                                       Body = "\"EXEC usp_PackageEnd \" + (@[System::PackageName] == \"\" ? \"NULL\" : \"'\"+@[System::PackageName]+\"'\") +\",\"+(@[System::PackageID] == \"\" ? \"NULL\" : \"'\"+@[System::PackageID]+\"'\") +\",\"+(@[User::_parentPackageGuid] == \"\" ? \"NULL\" : \"'\"+@[User::_parentPackageGuid]+\"'\") +\",\"+(@[System::SourceName] == \"\" ? \"NULL\" : \"'\"+@[System::SourceName]+\"'\") +\",\"+(@[System::SourceID] == \"\" ? \"NULL\" : \"'\"+@[System::SourceID]+\"'\") +\",\"+(@[System::SourceParentGUID] == \"\" ? \"NULL\" : \"'\"+@[System::SourceParentGUID]+\"'\") +\",\"+ (@[System::MachineName] == \"\" ? \"NULL\" : \"'\"+@[System::MachineName]+\"'\") +\",\"+(@[System::UserName] == \"\" ? \"NULL\" : \"'\"+@[System::UserName]+\"'\") +\",\"+(@[User::_patchedExecutionGuid] == \"\" ? \"NULL\" : \"'\"+@[User::_patchedExecutionGuid])+\"'\"",
                                       QueryType = QueryType.Expression
                                   };
            postExecContainer.Tasks.Add(executeSql);
        }
        private static HashSet <AstTaskNode> FindPredecessors(AstTask.AstContainerTaskNode container, AstTaskNode task, AstTaskNode previousTask, Dictionary <AstTaskNode, ICollection <AstTaskNode> > successors)
        {
            var predecessors = new HashSet <AstTaskNode>();

            if (task.PrecedenceConstraints != null)
            {
                foreach (var input in task.PrecedenceConstraints.Inputs)
                {
                    if (input.OutputPath != null)
                    {
                        var predecessorNode = input.OutputPath.ParentItem as AstTaskNode;
                        predecessors.Add(predecessorNode);
                    }
                }
            }

            //if (containerTask != null && containerTask.ConstraintMode == ContainerConstraintMode.Linear && predecessors.Count == 0 && previousTask != null)
            if (container.ConstraintMode == ContainerConstraintMode.Linear && predecessors.Count == 0 && previousTask != null)
            {
                predecessors.Add(previousTask);
            }

            return(predecessors);
        }
Beispiel #7
0
        protected Container(AstContainerTaskNode astNode)
            : base(astNode)
        {
            DelayValidation = astNode.DelayValidation;

            switch (astNode.IsolationLevel)
            {
                case IsolationLevel.Chaos:
                    ContainerIsolationLevel = System.Data.IsolationLevel.Chaos;
                    break;
                case IsolationLevel.ReadCommitted:
                    ContainerIsolationLevel = System.Data.IsolationLevel.ReadCommitted;
                    break;
                case IsolationLevel.ReadUncommitted:
                    ContainerIsolationLevel = System.Data.IsolationLevel.ReadUncommitted;
                    break;
                case IsolationLevel.RepeatableRead:
                    ContainerIsolationLevel = System.Data.IsolationLevel.RepeatableRead;
                    break;
                case IsolationLevel.Serializable:
                    ContainerIsolationLevel = System.Data.IsolationLevel.Serializable;
                    break;
                case IsolationLevel.Snapshot:
                    ContainerIsolationLevel = System.Data.IsolationLevel.Snapshot;
                    break;
                case IsolationLevel.Unspecified:
                    ContainerIsolationLevel = System.Data.IsolationLevel.Unspecified;
                    break;
                default:
                    ContainerIsolationLevel = System.Data.IsolationLevel.Serializable;
                    break;
            }

            switch (astNode.ConstraintMode)
            {
                case VulcanEngine.IR.Ast.Task.ContainerConstraintMode.Linear:
                    ConstraintMode = ContainerConstraintMode.Linear;
                    break;
                case VulcanEngine.IR.Ast.Task.ContainerConstraintMode.Parallel:
                    ConstraintMode = ContainerConstraintMode.Parallel;
                    break;
                default:
                    ConstraintMode = ContainerConstraintMode.Linear;
                    break;
            }

            switch (astNode.TransactionMode)
            {
                case ContainerTransactionMode.StartOrJoin:
                    TransactionMode = "Required";
                    if (astNode.ConstraintMode == VulcanEngine.IR.Ast.Task.ContainerConstraintMode.Parallel)
                    {
                        VulcanEngine.Common.MessageEngine.Trace(
                            astNode,
                            Severity.Alert,
                            "CT001",
                                                                "Container {0} has ConstraintMode of {1} and TransactionOption of {2}.  SSIS does not support transactions when the package flow is not linear.  Please configure precedence constraints appropriately for this scenario.",
                                                                astNode.Name,
                                                                astNode.ConstraintMode,
                                                                astNode.TransactionMode);
                    }

                    break;
                case ContainerTransactionMode.Join:
                    TransactionMode = "Supported";
                    break;
                case ContainerTransactionMode.NoTransaction:
                    TransactionMode = "NotSupported";
                    break;
                default:
                    TransactionMode = "Supported";
                    break;
            }
        }
Beispiel #8
0
        internal static void LowerTable(AstContainerTaskNode containerNode, AstTableNode tableNode, string executeSqlTaskName, bool executeDuringDesignTime)
        {
            var tableEmitter = new TableTSqlEmitter(tableNode.SchemaQualifiedName, tableNode.CompressionType.ToString().ToUpper(CultureInfo.InvariantCulture));

            foreach (AstTableColumnBaseNode columnBase in tableNode.Columns)
            {
                ProcessAstTableColumnBaseNode(tableNode, tableEmitter.ColumnsEmitter, columnBase);

                var tableReference = columnBase as AstTableColumnTableReferenceNode;
                var dimReference = columnBase as AstTableColumnDimensionReferenceNode;

                if (tableReference != null && tableReference.EnforceForeignKeyConstraint)
                {
                    tableEmitter.ConstraintsEmitter.AppendForeignKeyConstraintFromReference(tableNode, tableReference.ForeignKeyNameOverride, tableReference.Name, tableReference.Table);
                }

                if (dimReference != null && dimReference.EnforceForeignKeyConstraint)
                {
                    tableEmitter.ConstraintsEmitter.AppendForeignKeyConstraintFromReference(tableNode, dimReference.ForeignKeyNameOverride, dimReference.Name, dimReference.Dimension);
                }
            }

            foreach (AstTableKeyBaseNode keyBase in tableNode.Keys)
            {
                tableEmitter.ConstraintsEmitter.AppendConstraint(keyBase);
            }

            foreach (AstTableIndexNode index in tableNode.Indexes)
            {
                tableEmitter.ConstraintsEmitter.AppendIndex(tableNode.SchemaQualifiedName, index);
            }

            // TODO: Fix this null parent node
            var createTableExecuteSqlTaskNode = new AstExecuteSqlTaskNode(containerNode)
                                                    {
                                                        Name = StringManipulation.NameCleanerAndUniqifier(executeSqlTaskName),
                                                        ResultSet = ExecuteSqlResultSet.None,
                                                        Connection = tableNode.Connection,
                                                        ExecuteDuringDesignTime = executeDuringDesignTime
                                                    };

            createTableExecuteSqlTaskNode.Query = new AstExecuteSqlQueryNode(createTableExecuteSqlTaskNode) { QueryType = QueryType.Standard, Body = tableEmitter.Emit() };
            containerNode.Tasks.Add(createTableExecuteSqlTaskNode);

            bool hasPermissions = false;
            var permissionBuilder = new StringBuilder();
            foreach (var permission in tableNode.Permissions)
            {
                hasPermissions = true;
                permissionBuilder.AppendLine(PermissionsLowerer.ProcessPermission(tableNode, permission));
            }

            foreach (var column in tableNode.Columns)
            {
                foreach (var permission in column.Permissions)
                {
                    hasPermissions = true;
                    permissionBuilder.AppendLine(PermissionsLowerer.ProcessPermission(column, permission));
                }
            }

            if (hasPermissions)
            {
                var permissionsExecuteSqlTask = new AstExecuteSqlTaskNode(containerNode)
                {
                    Name = "__SetPermissions",
                    Connection = tableNode.Connection,
                };
                permissionsExecuteSqlTask.Query = new AstExecuteSqlQueryNode(permissionsExecuteSqlTask)
                {
                    Body = permissionBuilder.ToString(),
                    QueryType = QueryType.Standard
                };
                containerNode.Tasks.Add(permissionsExecuteSqlTask);
            }

            if (tableNode.CustomExtensions != null)
            {
                containerNode.Tasks.Add(tableNode.CustomExtensions);
            }

            foreach (var source in tableNode.Sources)
            {
                var staticSource = source as AstTableStaticSourceNode;
                if (staticSource != null && staticSource.Rows.Count > 0)
                {
                    if (staticSource.EmitMergePackage)
                    {
                        // TODO: This is nasty - we need a way to reference packages and emit paths at lowering time
                        var executeMergePackage = new AstExecutePackageTaskNode(containerNode);
                        executeMergePackage.Name = "__ExecuteMergePackage";
                        executeMergePackage.Package = staticSource.LoweredPackage;
                        containerNode.Tasks.Add(executeMergePackage);
                    }
                    else
                    {
                        containerNode.Tasks.Add(StaticSourcesLowerer.CreateInsertExecuteSql(staticSource, containerNode, tableNode));
                    }
                }
            }
        }