// 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 _packageBuildOnPreExecuteEvent(AstPackageBaseNode package) { var packageEvent = ContainerFindEvent(package.Events, EventType.OnPreExecute); if (packageEvent == null) { packageEvent = new AstTaskEventHandlerNode(package) { EventType = EventType.OnPreExecute }; package.Events.Add(packageEvent); } var preExecContainer = new AstContainerTaskNode(packageEvent) { Name = "OnPreExec", ConstraintMode = ContainerConstraintMode.Linear }; packageEvent.Tasks.Insert(0, preExecContainer); var constrainedCont = new AstContainerTaskNode(packageEvent) { Name = "ConstrainedContainer", ConstraintMode = ContainerConstraintMode.Parallel }; preExecContainer.Tasks.Add(constrainedCont); var executeSql = new AstExecuteSqlTaskNode(preExecContainer) { Name = "Exec usp_PackageStart", 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_PackageStart \" + (@[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 }; preExecContainer.Tasks.Add(executeSql); }
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)); } } } }
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; } }