protected override void OnExecute(DeploymentPlanContributorContext context) { try { PublishMessage(new ExtensibilityError("Starting AgileSqlClub.DeploymentPlanLogger", Severity.Message)); var next = context.PlanHandle.Head; while (next != null) { var current = next; next = current.Next; DumpDeploymentStep(current); if (current is CreateElementStep) Console.WriteLine("here"); if (current.GetType().DeclaringType != null) { Console.WriteLine("\t"); } } } catch (Exception e) { Console.WriteLine(e); } }
protected override void OnExecute(DeploymentPlanContributorContext context) { if (context.Arguments.ContainsKey("EasyDebugBatchedTableMigration")) { MessageBox.Show("Breaking to let you attach a debugger"); } var rowCount = GetRowCount(context.Arguments); try { Print("Starting...", Severity.Message); var next = context.PlanHandle.Head; while (next != null) { var current = next; next = current.Next; if (current is SqlTableMigrationStep) { var batched = new MigrationStepBatcher(current as SqlTableMigrationStep, rowCount).BatchStep(); Remove(context.PlanHandle, current); AddBefore(context.PlanHandle, next, batched); } } Print("Finished", Severity.Message); } catch (Exception e) { Print(string.Format("Error running contributor, exception: {0}", e), Severity.Error); } }
protected override void OnExecute(DeploymentPlanContributorContext context) { if (context.Arguments.ContainsKey("EasyDebugStopDeploymentsOnBreakingProcedureChanges")) { Debugger.Launch(); } try { Print("Starting...", Severity.Message); foreach (var changeDefinition in context.ComparisonResult.ElementsChanged.Keys) { var change = context.ComparisonResult.ElementsChanged[changeDefinition]; if (change.TargetObject.ObjectType == ModelSchema.Procedure) { VerifyStoredProcedureChange(context, change); } } Print("Finished", Severity.Message); } catch (Exception e) { Print(string.Format("Error running contributor, exception: {0}", e), Severity.Error); } }
/// <inheritdoc /> protected override void OnExecute(DeploymentPlanContributorContext context) { PublishMessage(new ExtensibilityError("Applying schema version change into deployment plan.", Severity.Message)); var isTransactional = context.Options.IncludeTransactionalScripts; EnsureItHasTransactionStep(context, isTransactional); var downgradeInsertionStep = GetSqlBeginTransactionStep(context, isTransactional); if (downgradeInsertionStep != null) { var downgradeStep = new DeploySchemaVersionStep(isTransactional, schemaNameSqlCmdVarName: "ApplicationSchemaName", applicationNameSqlCmdVarName: "ApplicationName", applicationVersionSqlCmdVarName: "ApplicationDowngradeVersion"); AddAfter(context.PlanHandle, downgradeInsertionStep, downgradeStep); } var upgradeInsertionStep = GetSqlEndTransactionStep(context, isTransactional); if (upgradeInsertionStep != null) { var upgradeStep = new DeploySchemaVersionStep(isTransactional, schemaNameSqlCmdVarName: "ApplicationSchemaName", applicationNameSqlCmdVarName: "ApplicationName", applicationVersionSqlCmdVarName: "ApplicationUpgradeVersion"); AddBefore(context.PlanHandle, upgradeInsertionStep, upgradeStep); } }
protected override void OnExecute(DeploymentPlanContributorContext context) { if (context.Arguments.ContainsKey("EasyDebugStopDeploymentsOnBreakingProcedureChanges")) { Debugger.Launch(); } try { Print("Starting...", Severity.Message); foreach (var changeDefinition in context.ComparisonResult.ElementsChanged.Keys) { var change = context.ComparisonResult.ElementsChanged[changeDefinition]; if (change.TargetObject.ObjectType == ModelSchema.Procedure) { VerifyStoredProcedureChange(context, change); } } Print("Finished", Severity.Message); } catch (Exception e) { Print(string.Format("Error running contributor, exception: {0}", e), Severity.Error); } }
/// <summary> /// Iterates over the deployment plan to find the definition for /// </summary> /// <param name="context"></param> protected override void OnExecute(DeploymentPlanContributorContext context) { //DEBUG ONLY! // //System.Diagnostics.Debugger.Launch(); // Run only if a location is defined and we're targeting a serverless (LocalDB) instance if (context.Arguments.TryGetValue(DatabaseName, out string databaseName) && context.Arguments.TryGetValue(DataLocation, out string dataLocation) && context.Arguments.TryGetValue(LogLocation, out string logLocation)) { if (!string.IsNullOrEmpty(dataLocation)) { dataLocation = new DirectoryInfo(dataLocation).FullName + "\\"; } if (!string.IsNullOrEmpty(logLocation)) { logLocation = new DirectoryInfo(logLocation).FullName + "\\"; } try { ChangeNewDatabaseLocation(context, databaseName, dataLocation, logLocation); } catch (Exception ex) { throw ex; } } }
protected override void OnExecute(DeploymentPlanContributorContext context) { try { PublishMessage(new ExtensibilityError("Starting AgileSqlClub.DeploymentPlanLogger", Severity.Message)); var next = context.PlanHandle.Head; while (next != null) { var current = next; next = current.Next; DumpDeploymentStep(current); if (current is CreateElementStep) { Console.WriteLine("here"); } if (current.GetType().DeclaringType != null) { Console.WriteLine("\t"); } } } catch (Exception e) { Console.WriteLine(e); } }
/// <summary> /// If there is no change provided then there is no transaction to bound to. /// Hence we change the aspect of our model to become non transactional. /// We're not able to insert the SqlBeginTransactionStep as this is too late to make it. /// </summary> /// <param name="context">The context of the deployment.</param> /// <param name="isTransactional">Indicator if required transaction, it is usually context.Options.IncludeTransactionalScripts value to be provided.</param> protected void EnsureItHasTransactionStep(DeploymentPlanContributorContext context, bool isTransactional) { if (isTransactional && IsMissingTransactionStep(context)) { AddTransactionStep(context); } }
/// <summary> /// Returns the SqlEndDeploymentStep where you can AddBefore the next steps as part of the transaction. /// </summary> /// <param name="context">The deployment plan context.</param> /// <param name="isTransactional">Indicator if required transaction, it is usually context.Options.IncludeTransactionalScripts value to be provided.</param> /// <returns>The deployment step where the transaction ends.</returns> protected DeploymentStep GetSqlEndTransactionStep(DeploymentPlanContributorContext context, bool isTransactional) { var desiredStep = context.PlanHandle.Head; if (isTransactional) { var endOfTransaction = desiredStep.NextOfType <SqlEndTransactionStep>().LastOrDefault(); if (endOfTransaction != null) { return(endOfTransaction); } var customEndOfTransaction = desiredStep.NextOfType <CustomSqlEndTransactionStep>().LastOrDefault(); if (customEndOfTransaction != null) { return(customEndOfTransaction); } } var beginPostDeploymentStep = desiredStep.NextOfType <BeginPostDeploymentScriptStep>().FirstOrDefault(); if (beginPostDeploymentStep != null) { return(beginPostDeploymentStep); } return(desiredStep); }
/// <summary> /// Iterates over the deployment plan to find the definition for /// </summary> /// <param name="context"></param> protected override void OnExecute(DeploymentPlanContributorContext context) { // Run only if a location is defined and we're targeting a serverless (LocalDB) instance string datalocation, logdatalocation, filePrefix; if (context.Arguments.TryGetValue(DbSaveDataLocationArg, out datalocation) && context.Arguments.TryGetValue(DbFilePrefixArg, out filePrefix)) { logdatalocation = context.Arguments.TryGetValue(DbSaveLogDataLocationArg, out logdatalocation) ? logdatalocation : datalocation; //Assuming the path for SQL Server on Linux starts with "/" if (datalocation.StartsWith("/") && logdatalocation.StartsWith("/")) { if (TargetConnectionMatchesPattern(context)) { ChangeNewDatabaseLocation(context, datalocation, logdatalocation, filePrefix); } } else { if (TargetConnectionMatchesPattern(context)) { datalocation = new DirectoryInfo(datalocation).FullName + "\\"; logdatalocation = new DirectoryInfo(logdatalocation).FullName + "\\"; ChangeNewDatabaseLocation(context, datalocation, logdatalocation, filePrefix); } } } }
private void ChangeNewDatabaseLocation(DeploymentPlanContributorContext context, string databasePath, string logPath) { DeploymentStep nextStep = context.PlanHandle.Head; // Loop through all steps in the deployment plan bool finished = false; while (nextStep != null && !finished) { // Increment the step pointer, saving both the current and next steps DeploymentStep currentStep = nextStep; // Only interrogate up to BeginPreDeploymentScriptStep - setvars must be done before that if (currentStep is BeginPreDeploymentScriptStep) { finished = true; break; } SqlCreateDatabaseStep createDbStep = currentStep as SqlCreateDatabaseStep; if (createDbStep != null) { TSqlFragment fragment = createDbStep.Script; CreateDatabaseStatementVisitor visitor = new CreateDatabaseStatementVisitor(databasePath, logPath); fragment.Accept(visitor); finished = true; } nextStep = currentStep.Next; } }
/// <summary> /// Iterates over the deployment plan to find the definition for /// </summary> /// <param name="context"></param> protected override void OnExecute(DeploymentPlanContributorContext context) { // Publishing Severity.Error message blocks deployment base.PublishMessage(new ExtensibilityError(ErrorViaPublishMessage, Severity.Error)); // Alternatively throwing an exception will also block deployment throw new DeploymentFailedException(ErrorViaThrownException); }
/// <summary> /// Iterates over the deployment plan to find the definition for /// </summary> /// <param name="context"></param> protected override void OnExecute(DeploymentPlanContributorContext context) { // Publishing Severity.Error message blocks deployment base.PublishMessage(new ExtensibilityError(ErrorViaPublishMessage, Severity.Error)); // Alternatively throwing an exception will also block deployment throw new DeploymentFailedException(ErrorViaThrownException); }
protected override void OnExecute(DeploymentPlanContributorContext context) { IList<IndexOption> options = ConvertArgsToOptions(context); if (options.Count > 0) { ChangeCreateIndexOperationalProps(context, options); } }
/// <summary> /// Override the OnExecute method to perform actions when you execute the deployment plan for /// a database project. /// </summary> protected override void OnExecute(DeploymentPlanContributorContext context) { // determine whether the user specified a report is to be generated bool generateReport = false; string generateReportValue; if (context.Arguments.TryGetValue(GenerateExtendedReport, out generateReportValue) == false) { // couldn't find the GenerateUpdateReport argument, so do not generate generateReport = false; } else { // GenerateUpdateReport argument was specified, try to parse the value if (bool.TryParse(generateReportValue, out generateReport)) { // if we end up here, the value for the argument was not valid. // default is false, so do nothing. } } if (generateReport == false) { // if user does not want to generate a report, we are done return; } // We will output to the same directory where the deployment script // is output or to the current directory string reportPrefix = context.Options.TargetDatabaseName; string reportPath; if (string.IsNullOrEmpty(context.DeploymentScriptPath)) { reportPath = Environment.CurrentDirectory; } else { reportPath = Path.GetDirectoryName(context.DeploymentScriptPath); } FileInfo summaryReportFile = new FileInfo(Path.Combine(reportPath, reportPrefix + ".summary.xml")); FileInfo detailsReportFile = new FileInfo(Path.Combine(reportPath, reportPrefix + ".details.xml")); // Generate the reports by using the helper class DeploymentReportWriter DeploymentReportWriter writer = new DeploymentReportWriter(context); writer.WriteReport(summaryReportFile); writer.IncludeScripts = true; writer.WriteReport(detailsReportFile); string msg = "Deployment reports ->" + Environment.NewLine + summaryReportFile.FullName + Environment.NewLine + detailsReportFile.FullName; ExtensibilityError reportMsg = new ExtensibilityError(msg, Severity.Message); base.PublishMessage(reportMsg); }
private void ChangeCreateIndexOperationalProps(DeploymentPlanContributorContext context, IList <IndexOption> options) { DeploymentStep nextStep = context.PlanHandle.Head; // Loop through all steps in the deployment plan bool foundMainSection = false; while (nextStep != null) { DeploymentStep currentStep = nextStep; nextStep = currentStep.Next; // We only want to analyze the main part of the deployment script - we'll skip // any steps until we pass the end of the predeployment section, and stop once // we hit the start of the postdeployment section if (currentStep is EndPreDeploymentScriptStep) { foundMainSection = true; continue; } if (!foundMainSection) { // Haven't gotten past predeployment yet continue; } if (currentStep is BeginPostDeploymentScriptStep) { break; } // We need to care about CreateElementSteps and AlterElementSteps for Indexes. DeploymentScriptDomStep domStep = currentStep as DeploymentScriptDomStep; TSqlObject elementObject = null; if (domStep is CreateElementStep) { elementObject = ((CreateElementStep)domStep).SourceElement; } else if (domStep is AlterElementStep) { elementObject = ((AlterElementStep)domStep).SourceElement; } if (elementObject != null) { if (Index.TypeClass.Equals(elementObject.ObjectType) && !(View.TypeClass.Equals(elementObject.GetParent().ObjectType))) { TSqlFragment fragment = domStep.Script; IndexStatementVisitor visitor = new IndexStatementVisitor(options); fragment.Accept(visitor); } } } }
private void ChangeCreateIndexOperationalProps(DeploymentPlanContributorContext context, IList<IndexOption> options) { DeploymentStep nextStep = context.PlanHandle.Head; // Loop through all steps in the deployment plan bool foundMainSection = false; while (nextStep != null) { DeploymentStep currentStep = nextStep; nextStep = currentStep.Next; // We only want to analyze the main part of the deployment script - we'll skip // any steps until we pass the end of the predeployment section, and stop once // we hit the start of the postdeployment section if (currentStep is EndPreDeploymentScriptStep) { foundMainSection = true; continue; } if (!foundMainSection) { // Haven't gotten past predeployment yet continue; } if (currentStep is BeginPostDeploymentScriptStep) { break; } // We need to care about CreateElementSteps and AlterElementSteps for Indexes. DeploymentScriptDomStep domStep = currentStep as DeploymentScriptDomStep; TSqlObject elementObject = null; if (domStep is CreateElementStep) { elementObject = ((CreateElementStep)domStep).SourceElement; } else if (domStep is AlterElementStep) { elementObject = ((AlterElementStep)domStep).SourceElement; } if (elementObject != null) { if (Index.TypeClass.Equals(elementObject.ObjectType) && !(View.TypeClass.Equals(elementObject.GetParent().ObjectType))) { TSqlFragment fragment = domStep.Script; IndexStatementVisitor visitor = new IndexStatementVisitor(options); fragment.Accept(visitor); } } } }
private void FindAndRenameUnnamedDefaultConstraints(DeploymentPlanContributorContext context) { DeploymentStep nextStep = context.PlanHandle.Head; // Loop through all steps in the deployment plan bool foundMainSection = false; while (nextStep != null) { DeploymentStep currentStep = nextStep; nextStep = currentStep.Next; // We only want to analyze the main part of the deployment script - we'll skip // any steps until we pass the end of the predeployment section, and stop once // we hit the start of the postdeployment section if (currentStep is EndPreDeploymentScriptStep) { foundMainSection = true; continue; } if (!foundMainSection) { // Haven't gotten past predeployment yet continue; } if (currentStep is BeginPostDeploymentScriptStep) { break; } // We need to care about CreateElementSteps and AlterElementSteps for default constraints. DeploymentScriptDomStep domStep = currentStep as DeploymentScriptDomStep; TSqlObject elementObject = null; // most of the default constraints in the deployment plan seem to be deployed as Alter Table statements, but // just in case the default constraint was deployed as part of a Create Table (don't see how it is possible, but just being safe) if (domStep is CreateElementStep) { elementObject = ((CreateElementStep)domStep).SourceElement; } else if (domStep is AlterElementStep) { elementObject = ((AlterElementStep)domStep).SourceElement; } if (elementObject != null) { TSqlFragment fragment = domStep.Script; // call the visitor, which in turn will auto-name these constraints var visitor = new DefaultConstraintDefinitionVisitor(); fragment.Accept(visitor); } } }
protected override void OnExecute(DeploymentPlanContributorContext context) { IList <IndexOption> options = ConvertArgsToOptions(context); if (options.Count > 0) { ChangeCreateIndexOperationalProps(context, options); } }
/// <summary> /// Called by the deployment engine to allow custom contributors to execute their unique tasks /// </summary> /// <param name="context">A <see cref="T:Microsoft.SqlServer.Dac.Deployment.DeploymentContributorContext" /> object</param> protected override void OnExecute(DeploymentPlanContributorContext context) { string mdfFilePath; string ldfFilePath; if (context.Arguments.TryGetValue(MdfFilePath, out mdfFilePath) && context.Arguments.TryGetValue(LdfFilePath, out ldfFilePath)) { SetDatabaseLocation(context, mdfFilePath, ldfFilePath); } }
/// <summary> /// Iterates over the deployment plan to find the definition for /// </summary> /// <param name="context"></param> protected override void OnExecute(DeploymentPlanContributorContext context) { // Run only if a location is defined and we're targeting a serverless (LocalDB) instance if (context.Arguments.TryGetValue(DbSaveLocationArg, out string location) && context.Arguments.TryGetValue(DbFilePrefixArg, out string filePrefix)) { location = new DirectoryInfo(location).FullName + "\\"; ChangeNewDatabaseLocation(context, location, filePrefix); } }
/// <summary> /// Called by the deployment engine to allow custom contributors to execute their unique tasks /// </summary> /// <param name="context">A <see cref="T:Microsoft.SqlServer.Dac.Deployment.DeploymentContributorContext" /> object</param> protected override void OnExecute(DeploymentPlanContributorContext context) { string defaultPath; string defaultFilePrefix; if (context.Arguments.TryGetValue(DefaultPath, out defaultPath) && context.Arguments.TryGetValue(DefaultFilePrefix, out defaultFilePrefix)) { defaultPath = new DirectoryInfo(defaultPath).FullName + "\\"; SetDefaultVariables(context, defaultPath, defaultFilePrefix); } }
private bool TargetConnectionMatchesPattern(DeploymentPlanContributorContext context) { string targetConnectionStringPattern; if (context.Arguments.TryGetValue(TargetConnectionStringPatternArg, out targetConnectionStringPattern)) { string targetConnectionString = context.Options.TargetConnectionString; return(!string.IsNullOrEmpty(targetConnectionString) && targetConnectionString.Contains(targetConnectionStringPattern)); } return(true); }
/// <summary> /// The constructor accepts the same context info /// that was passed to the OnExecute method of the /// deployment contributor. /// </summary> public DeploymentReportWriter(DeploymentPlanContributorContext context) { if (context == null) { throw new ArgumentNullException("context"); } // save the source model, source/target differences, // and the beginning of the deployment plan. _sourceModel = context.Source; _diff = context.ComparisonResult; _planHead = context.PlanHandle.Head; }
private void FindAndMakeAlterColumnsOnline(DeploymentPlanContributorContext context) { DeploymentStep nextStep = context.PlanHandle.Head; // Loop through all steps in the deployment plan bool foundMainSection = false; while (nextStep != null) { DeploymentStep currentStep = nextStep; nextStep = currentStep.Next; // We only want to analyze the main part of the deployment script - we'll skip // any steps until we pass the end of the predeployment section, and stop once // we hit the start of the postdeployment section if (currentStep is EndPreDeploymentScriptStep) { foundMainSection = true; continue; } if (!foundMainSection) { // Haven't gotten past predeployment yet continue; } if (currentStep is BeginPostDeploymentScriptStep) { break; } // We need to care about AlterElementSteps. DeploymentScriptDomStep domStep = currentStep as DeploymentScriptDomStep; TSqlObject elementObject = null; if (domStep is AlterElementStep) { elementObject = ((AlterElementStep)domStep).SourceElement; } if (elementObject != null) { TSqlFragment fragment = domStep.Script; // call the visitor, which in turn will auto-name these constraints var visitor = new AlterTableAlterColumnVisitor(); fragment.Accept(visitor); } } }
protected override void OnExecute(DeploymentPlanContributorContext context) { // Run only if a location is defined and we're targeting a serverless (LocalDB) instance string databasePath, logPath; if (context.Arguments.TryGetValue(MdfFilePathArg, out databasePath) && context.Arguments.TryGetValue(LdfFilePathArg, out logPath) && context.Options.TargetConnectionString.Contains("(localdb)")) { if (TargetConnectionMatchesPattern(context)) { ChangeNewDatabaseLocation(context, databasePath, logPath); } } }
private void ChangeNewDatabaseLocation(DeploymentPlanContributorContext context, string datalocation, string logdatalocation, string filePrefix) { DeploymentStep nextStep = context.PlanHandle.Head; // Loop through all steps in the deployment plan bool foundSetVars = false; while (nextStep != null && !foundSetVars) { // Increment the step pointer, saving both the current and next steps DeploymentStep currentStep = nextStep; // Only interrogate up to BeginPreDeploymentScriptStep - setvars must be done before that // We know this based on debugging a new deployment and examining the output script if (currentStep is BeginPreDeploymentScriptStep) { break; } DeploymentScriptStep scriptStep = currentStep as DeploymentScriptStep; if (scriptStep != null) { IList <string> scripts = scriptStep.GenerateTSQL(); foreach (string script in scripts) { if (script.Contains("DefaultDataPath")) { // This is the step that sets the default data path and log path. foundSetVars = true; // Override setvars before the deployment begins StringBuilder sb = new StringBuilder(); sb.AppendFormat(":setvar DefaultDataPath \"{0}\"", datalocation) .AppendLine() .AppendFormat(":setvar DefaultLogPath \"{0}\"", logdatalocation) .AppendLine() .AppendFormat(":setvar DefaultFilePrefix \"{0}\"", filePrefix) .AppendLine(); // Create a new step for the setvar statements, and add it after the existing step. // That ensures that the updated values are used instead of the defaults DeploymentScriptStep setVarsStep = new DeploymentScriptStep(sb.ToString()); this.AddAfter(context.PlanHandle, scriptStep, setVarsStep); } } } nextStep = currentStep.Next; } }
private void Ignore(DeploymentPlanContributorContext context, string schemas) { var schemasList = schemas.Split(',').ToList(); DeploymentStep nextStep = context.PlanHandle.Head; var stepRemoved = false; while (nextStep != null) { stepRemoved = false; DeploymentStep currentStep = nextStep; if (currentStep is CreateElementStep scriptStep) { IList <string> scripts = currentStep.GenerateTSQL(); var parts = scriptStep.SourceElement.Name.Parts; if (parts.Count() > 0) { foreach (string script in scripts) { foreach (var schema in schemasList) { if (string.Equals(parts[0], schema, StringComparison.OrdinalIgnoreCase)) { nextStep = scriptStep.Next; // This is the step that removes the drop database step base.Remove(context.PlanHandle, scriptStep); stepRemoved = true; break; } } if (stepRemoved) { break; } } } if (stepRemoved) { continue; } } nextStep = currentStep.Next; } }
protected override void OnExecute(DeploymentPlanContributorContext context) { // Run only if a location is defined and we're targeting a serverless (LocalDB) instance string databasePath, logPath; if (context.Arguments.TryGetValue(MdfFilePathArg, out databasePath) && context.Arguments.TryGetValue(LdfFilePathArg, out logPath) && context.Options.TargetConnectionString.Contains("(localdb)")) { if (TargetConnectionMatchesPattern(context)) { ChangeNewDatabaseLocation(context, databasePath, logPath); } } }
protected override void OnExecute(DeploymentPlanContributorContext context) { InitializeFilter(context.Arguments); DeploymentStep next = context.PlanHandle.Head; while (next != null) { DeploymentStep current = next; next = current.Next; CreateElementStep createStep = current as CreateElementStep; if (createStep != null && ShouldFilter(createStep)) { base.Remove(context.PlanHandle, createStep); } } }
/// <summary> /// Iterates over the deployment plan to find the definition for /// </summary> /// <param name="context"></param> protected override void OnExecute(DeploymentPlanContributorContext context) { //DEBUG ONLY! // //System.Diagnostics.Debugger.Launch(); try { if (context.Arguments.TryGetValue(Schemas, out string schemas)) { Ignore(context, schemas); } } catch (Exception ex) { throw ex; } }
/// <summary> /// Iterates over the deployment plan to find the definition for /// </summary> /// <param name="context"></param> protected override void OnExecute(DeploymentPlanContributorContext context) { var planStep = context.PlanHandle.Head; while (planStep != null) { if (planStep is SqlTableMigrationStep) { // Publishing Severity.Error message blocks deployment base.PublishMessage(new ExtensibilityError(ErrorViaPublishMessage, Severity.Error)); // Alternatively throwing an exception will also block deployment throw new DeploymentFailedException(ErrorViaThrownException); } planStep = planStep.Next; } }
protected override void OnExecute(DeploymentPlanContributorContext context) { InitializeFilter(context.Arguments); DeploymentStep next = context.PlanHandle.Head; while (next != null) { DeploymentStep current = next; next = current.Next; CreateElementStep createStep = current as CreateElementStep; if (createStep != null && ShouldFilter(createStep)) { base.Remove(context.PlanHandle, createStep); } } }
/// <summary> /// Iterates over the deployment plan to find the definition for /// </summary> /// <param name="context"></param> protected override void OnExecute(DeploymentPlanContributorContext context) { DeploymentStep next = context.PlanHandle.Head; bool foundDropDb = false; while (next != null) { DeploymentStep current = next; next = current.Next; //works! if (foundDropDb) { base.Remove(context.PlanHandle, current); } DeploymentScriptStep scriptStep = current as DeploymentScriptStep; if (scriptStep != null) { IList <string> scripts = scriptStep.GenerateTSQL(); foreach (string script in scripts) { if (script.Contains("DROP DATABASE")) { // This is the step that removes the drop database step foundDropDb = true; } } } } // Override setvars before the deployment begins StringBuilder sb = new StringBuilder(); sb.AppendFormat("PRINT N'Update complete.';") .AppendLine() .AppendFormat("GO") .AppendLine(); // Create a new step for the setvar statements, and add it after the existing step. // That ensures that the updated values are used instead of the defaults DeploymentScriptStep setVarsStep = new DeploymentScriptStep(sb.ToString()); this.AddAfter(context.PlanHandle, context.PlanHandle.Tail, setVarsStep); }
protected override void OnExecute(DeploymentPlanContributorContext context) { int i = 0; File.WriteAllText(logfilepath, string.Empty); using (StreamWriter w = File.AppendText(logfilepath)) { w.WriteLine($"{DateTime.Now.ToLongTimeString()}, {i++:000} - START"); } using (StreamWriter w = File.AppendText(logfilepath)) { w.WriteLine($"---------------------"); } DeploymentStep nextStep = context.PlanHandle.Head; while (nextStep != null) { DeploymentStep currentStep = nextStep; nextStep = currentStep.Next; logger(currentStep, i++); } }
/// <inheritdoc /> protected override void OnExecute(DeploymentPlanContributorContext context) { if (model == null) { PublishMessage(new ExtensibilityError($"There isn't a static data model available in this deployment.", Severity.Warning)); return; } PublishMessage(new ExtensibilityError("Applying static data model items into deployment plan.", Severity.Message)); var isTransactional = context.Options.IncludeTransactionalScripts; EnsureItHasTransactionStep(context, isTransactional); var deploymentStep = new DeployStaticDataModelStep(model, isTransactional); var insertionStep = GetSqlEndTransactionStep(context, isTransactional); AddBefore(context.PlanHandle, insertionStep, deploymentStep); }
protected override void OnExecute(DeploymentPlanContributorContext context) { // Use target model's collation since that is where we are deploying to, and hence how the // deployment should be comparing collation types InitializeFilter(context.Target, context.Arguments); DeploymentStep next = context.PlanHandle.Head; while (next != null) { DeploymentStep current = next; next = current.Next; CreateElementStep createStep = current as CreateElementStep; if (createStep != null && ShouldFilter(createStep)) { base.Remove(context.PlanHandle, createStep); } } }
protected override void OnExecute(DeploymentPlanContributorContext context) { if (context.Arguments.ContainsKey("EasyDebugEditionAwareCreateIndex")) { Debugger.Launch(); } var stepBuilder = new CreateIndexOnlineStepBuilder(GetEdition(context.Arguments)); try { Print("Starting...", Severity.Message); var next = context.PlanHandle.Head; while (next != null) { var current = next; next = current.Next; if (current is CreateElementStep || current is AlterElementStep) { var replacementStep = stepBuilder.Build(current); if (replacementStep != null) { Remove(context.PlanHandle, current); AddBefore(context.PlanHandle, next, replacementStep); } } } Print("Finished", Severity.Message); } catch (Exception e) { Print(string.Format("Error running contributor, exception: {0}", e), Severity.Error); } }
private IList<IndexOption> ConvertArgsToOptions(DeploymentPlanContributorContext context) { List<IndexOption> options = new List<IndexOption>(); foreach(var entry in context.Arguments) { OptionDefinition optionDefinition; if (_optionArgumentMap.TryGetValue(entry.Key, out optionDefinition)) { IndexOption option = optionDefinition.CreateOption(entry.Value); if (option != null) { options.Add(option); } } } return options; }
private void ChangeNewDatabaseLocation(DeploymentPlanContributorContext context, string location, string filePrefix) { DeploymentStep nextStep = context.PlanHandle.Head; // Loop through all steps in the deployment plan bool foundSetVars = false; while (nextStep != null && !foundSetVars) { // Increment the step pointer, saving both the current and next steps DeploymentStep currentStep = nextStep; // Only interrogate up to BeginPreDeploymentScriptStep - setvars must be done before that // We know this based on debugging a new deployment and examining the output script if (currentStep is BeginPreDeploymentScriptStep) { break; } DeploymentScriptStep scriptStep = currentStep as DeploymentScriptStep; if (scriptStep != null) { IList<string> scripts = scriptStep.GenerateTSQL(); foreach (string script in scripts) { if (script.Contains("DefaultDataPath")) { // This is the step that sets the default data path and log path. foundSetVars = true; // Override setvars before the deployment begins StringBuilder sb = new StringBuilder(); sb.AppendFormat(":setvar DefaultDataPath \"{0}\"", location) .AppendLine() .AppendFormat(":setvar DefaultLogPath \"{0}\"", location) .AppendLine() .AppendFormat(":setvar DefaultFilePrefix \"{0}\"", filePrefix) .AppendLine(); // Create a new step for the setvar statements, and add it after the existing step. // That ensures that the updated values are used instead of the defaults DeploymentScriptStep setVarsStep = new DeploymentScriptStep(sb.ToString()); this.AddAfter(context.PlanHandle, scriptStep, setVarsStep); } } } nextStep = currentStep.Next; } }
private bool TargetConnectionMatchesPattern(DeploymentPlanContributorContext context) { string targetConnectionStringPattern; if (context.Arguments.TryGetValue(TargetConnectionStringPatternArg, out targetConnectionStringPattern)) { string targetConnectionString = context.Options.TargetConnectionString; return !string.IsNullOrEmpty(targetConnectionString) && targetConnectionString.Contains(targetConnectionStringPattern); } return true; }
/// <summary> /// Iterates over the deployment plan to find the definition for /// </summary> /// <param name="context"></param> protected override void OnExecute(DeploymentPlanContributorContext context) { // Run only if a location is defined and we're targeting a serverless (LocalDB) instance string location, filePrefix; if (context.Arguments.TryGetValue(DbSaveLocationArg, out location) && context.Arguments.TryGetValue(DbFilePrefixArg, out filePrefix)) { if (TargetConnectionMatchesPattern(context)) { location = new DirectoryInfo(location).FullName + "\\"; ChangeNewDatabaseLocation(context, location, filePrefix); } } }
private void VerifyStoredProcedureChange(DeploymentPlanContributorContext context, ModelComparisonChangeDefinition change) { var newProcedure = context.Source.GetObject(ModelSchema.Procedure, change.TargetObject.Name, DacQueryScopes.UserDefined); var oldProcedure = context.Target.GetObject(ModelSchema.Procedure, change.TargetObject.Name, DacQueryScopes.UserDefined); if (newProcedure == null) return; foreach (var parameter in newProcedure.GetReferencedRelationshipInstances(Procedure.Parameters)) { if (HasParameterBeenAddedWithoutDefaultValue(parameter, oldProcedure)) { //Severity.Error - fails the build process Print( string.Format( "The procedure {0} has had an additional parameter but no default, parameter name: {1}", change.TargetObject.Name, parameter.ObjectName), Severity.Error); } if (HasDefaultValueBeenRemoved(parameter, oldProcedure)) { Print( string.Format("The procedure {0} has had a parameter default value removed, parameter name: {1}", change.TargetObject.Name, parameter.ObjectName), Severity.Error); } } foreach (var parameter in oldProcedure.GetReferencedRelationshipInstances(Procedure.Parameters)) { if (HasParameterBeenRemoved(parameter, newProcedure)) { Print( string.Format("The procedure {0} has had a parameter removed, parameter name: {1}", change.TargetObject.Name, parameter.ObjectName), Severity.Error); } } }
private void ChangeNewDatabaseLocation(DeploymentPlanContributorContext context, string databasePath, string logPath) { DeploymentStep nextStep = context.PlanHandle.Head; // Loop through all steps in the deployment plan bool finished = false; while (nextStep != null && !finished) { // Increment the step pointer, saving both the current and next steps DeploymentStep currentStep = nextStep; // Only interrogate up to BeginPreDeploymentScriptStep - setvars must be done before that if (currentStep is BeginPreDeploymentScriptStep) { finished = true; break; } SqlCreateDatabaseStep createDbStep = currentStep as SqlCreateDatabaseStep; if (createDbStep != null) { TSqlFragment fragment = createDbStep.Script; CreateDatabaseStatementVisitor visitor = new CreateDatabaseStatementVisitor(databasePath, logPath); fragment.Accept(visitor); finished = true; } nextStep = currentStep.Next; } }